diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4e8803fc5a..d31d157858 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,40 +13,45 @@ lib/kim/* @ellio167 lib/mesont/* @iafoss # whole packages +src/ADIOS/* @pnorbert src/AMOEBA/* @sjplimp -src/COMPRESS/* @rbberger -src/GPU/* @ndtrung81 -src/KOKKOS/* @stanmoore1 -src/KIM/* @ellio167 -src/LATTE/* @cnegre -src/MLIAP/* @athomps -src/SNAP/* @athomps -src/SPIN/* @julient31 +src/BPM/* @jtclemm src/BROWNIAN/* @samueljmcameron src/CG-DNA/* @ohenrich src/CG-SPICA/* @yskmiyazaki src/COLVARS/* @giacomofiorin +src/COMPRESS/* @rbberger src/DIELECTRIC/* @ndtrung81 src/ELECTRODE/* @ludwig-ahrens src/FEP/* @agiliopadua -src/ML-HDNNP/* @singraber +src/GPU/* @ndtrung81 +src/GRANULAR/* @jtclemm @dsbolin src/INTEL/* @wmbrownintel +src/KIM/* @ellio167 +src/KOKKOS/* @stanmoore1 +src/LATTE/* @cnegre src/MANIFOLD/* @Pakketeretet2 -src/MDI/* @taylor-a-barnes +src/MDI/* @taylor-a-barnes @sjplimp src/MEAM/* @martok src/MESONT/* @iafoss +src/ML-HDNNP/* @singraber +src/ML-IAP/* @athomps +src/ML-PACE/* @yury-lysogorskiy +src/ML-POD/* @exapde @rohskopf src/MOFFF/* @hheenen src/MOLFILE/* @akohlmey src/NETCDF/* @pastewka -src/ML-PACE/* @yury-lysogorskiy -src/PLUMED/* @gtribello -src/PHONON/* @lingtikong -src/PTM/* @pmla src/OPENMP/* @akohlmey +src/PHONON/* @lingtikong +src/PLUGIN/* @akohlmey +src/PLUMED/* @gtribello +src/PTM/* @pmla src/QMMM/* @akohlmey -src/REAXFF/* @hasanmetin @stanmoore1 src/REACTION/* @jrgissing +src/REAXFF/* @hasanmetin @stanmoore1 src/SCAFACOS/* @rhalver +src/SNAP/* @athomps +src/SPIN/* @julient31 src/TALLY/* @akohlmey src/UEF/* @danicholson src/VTK/* @rbberger @@ -120,27 +125,32 @@ src/dump_movie.* @akohlmey src/exceptions.h @rbberger src/fix_nh.* @athomps src/info.* @akohlmey @rbberger -src/timer.* @akohlmey src/min* @sjplimp @stanmoore1 +src/platform.* @akohlmey +src/timer.* @akohlmey src/utils.* @akohlmey @rbberger src/verlet.* @sjplimp @stanmoore1 src/math_eigen_impl.h @jewettaij # tools -tools/msi2lmp/* @akohlmey +tools/coding_standard/* @akohlmey @rbberger tools/emacs/* @HaoZeke -tools/singularity/* @akohlmey @rbberger -tools/coding_standard/* @rbberger -tools/valgrind/* @akohlmey -tools/swig/* @akohlmey +tools/lammps-shell/* @akohlmey +tools/msi2lmp/* @akohlmey tools/offline/* @rbberger +tools/singularity/* @akohlmey @rbberger +tools/swig/* @akohlmey +tools/valgrind/* @akohlmey tools/vim/* @hammondkd # tests -unittest/* @akohlmey @rbberger +unittest/* @akohlmey # cmake cmake/* @junghans @rbberger +cmake/Modules/LAMMPSInterfacePlugin.cmake @akohlmey +cmake/Modules/MPI4WIN.cmake @akohlmey +cmake/Modules/OpenCLLoader.cmake @akohlmey cmake/Modules/Packages/COLVARS.cmake @junghans @rbberger @giacomofiorin cmake/Modules/Packages/KIM.cmake @junghans @rbberger @ellio167 cmake/presets/*.cmake @akohlmey @@ -149,13 +159,12 @@ cmake/presets/*.cmake @akohlmey python/* @rbberger # fortran -fortran/* @akohlmey +fortran/* @akohlmey @hammondkd # docs -doc/utils/*/* @rbberger -doc/Makefile @rbberger -doc/README @rbberger +doc/* @akohlmey examples/plugin/* @akohlmey +examples/PACKAGES/pace/plugin/* @akohlmey # for releases src/version.h @sjplimp diff --git a/.github/workflows/compile-msvc.yml b/.github/workflows/compile-msvc.yml index 3ec5fc4cb0..2fa2b4fcee 100644 --- a/.github/workflows/compile-msvc.yml +++ b/.github/workflows/compile-msvc.yml @@ -26,15 +26,19 @@ jobs: - name: Select Python version uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: '3.11' - name: Building LAMMPS via CMake shell: bash run: | python3 -m pip install numpy python3 -m pip install pyyaml + nuget install MSMPIsdk + nuget install MSMPIDIST cmake -C cmake/presets/windows.cmake \ -D PKG_PYTHON=on \ + -D WITH_PNG=off \ + -D WITH_JPEG=off \ -S cmake -B build \ -D BUILD_SHARED_LIBS=on \ -D LAMMPS_EXCEPTIONS=on \ diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index efdbfa2840..24522b6480 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -316,6 +316,15 @@ if(PKG_ADIOS) # script that defines the MPI::MPI_C target enable_language(C) find_package(ADIOS2 REQUIRED) + if(BUILD_MPI) + if(NOT ADIOS2_HAVE_MPI) + message(FATAL_ERROR "ADIOS2 must be built with MPI support when LAMMPS has MPI enabled") + endif() + else() + if(ADIOS2_HAVE_MPI) + message(FATAL_ERROR "ADIOS2 must be built without MPI support when LAMMPS has MPI disabled") + endif() + endif() target_link_libraries(lammps PRIVATE adios2::adios2) endif() diff --git a/cmake/Modules/FindZMQ.cmake b/cmake/Modules/FindZMQ.cmake deleted file mode 100644 index 7d612c2eb3..0000000000 --- a/cmake/Modules/FindZMQ.cmake +++ /dev/null @@ -1,19 +0,0 @@ -find_path(ZMQ_INCLUDE_DIR zmq.h) -find_library(ZMQ_LIBRARY NAMES zmq) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(ZMQ DEFAULT_MSG ZMQ_LIBRARY ZMQ_INCLUDE_DIR) - -# Copy the results to the output variables and target. -if(ZMQ_FOUND) - set(ZMQ_LIBRARIES ${ZMQ_LIBRARY}) - set(ZMQ_INCLUDE_DIRS ${ZMQ_INCLUDE_DIR}) - - if(NOT TARGET ZMQ::ZMQ) - add_library(ZMQ::ZMQ UNKNOWN IMPORTED) - set_target_properties(ZMQ::ZMQ PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${ZMQ_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${ZMQ_INCLUDE_DIR}") - endif() -endif() diff --git a/cmake/Modules/LAMMPSInterfacePlugin.cmake b/cmake/Modules/LAMMPSInterfacePlugin.cmake index 95bb707e86..e20ae5f5cb 100644 --- a/cmake/Modules/LAMMPSInterfacePlugin.cmake +++ b/cmake/Modules/LAMMPSInterfacePlugin.cmake @@ -112,45 +112,76 @@ if(BUILD_MPI) set(MPI_CXX_SKIP_MPICXX TRUE) # We use a non-standard procedure to cross-compile with MPI on Windows if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING) - # Download and configure custom MPICH files for Windows - message(STATUS "Downloading and configuring MPICH-1.4.1 for Windows") - set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") - set(MPICH2_WIN32_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win32-devel.tar.gz" CACHE STRING "URL for MPICH2 (win32) tarball") - set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") - set(MPICH2_WIN32_DEVEL_MD5 "a61d153500dce44e21b755ee7257e031" CACHE STRING "MD5 checksum of MPICH2 (win32) tarball") - mark_as_advanced(MPICH2_WIN64_DEVEL_URL) - mark_as_advanced(MPICH2_WIN32_DEVEL_URL) - mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) - mark_as_advanced(MPICH2_WIN32_DEVEL_MD5) + # Download and configure MinGW compatible MPICH development files for Windows + option(USE_MSMPI "Use Microsoft's MS-MPI SDK instead of MPICH2-1.4.1" OFF) + if(USE_MSMPI) + message(STATUS "Downloading and configuring MS-MPI 10.1 for Windows cross-compilation") + set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/msmpi-win64-devel.tar.gz" CACHE STRING "URL for MS-MPI (win64) tarball") + set(MPICH2_WIN64_DEVEL_MD5 "86314daf1bffb809f1fcbefb8a547490" CACHE STRING "MD5 checksum of MS-MPI (win64) tarball") + mark_as_advanced(MPICH2_WIN64_DEVEL_URL) + mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) - include(ExternalProject) - if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - ExternalProject_Add(mpi4win_build - URL ${MPICH2_WIN64_DEVEL_URL} - URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} - CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" - BUILD_BYPRODUCTS /lib/libmpi.a) + include(ExternalProject) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmsmpi.a) + else() + message(FATAL_ERROR "Only x86 64-bit builds are supported with MS-MPI") + endif() + + ExternalProject_get_property(mpi4win_build SOURCE_DIR) + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + add_library(MPI::MPI_CXX UNKNOWN IMPORTED) + set_target_properties(MPI::MPI_CXX PROPERTIES + IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmsmpi.a" + INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" + INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + add_dependencies(MPI::MPI_CXX mpi4win_build) + + # set variables for status reporting at the end of CMake run + set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") + set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmsmpi.a") else() - ExternalProject_Add(mpi4win_build - URL ${MPICH2_WIN32_DEVEL_URL} - URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} - CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" - BUILD_BYPRODUCTS /lib/libmpi.a) + # Download and configure custom MPICH files for Windows + message(STATUS "Downloading and configuring MPICH-1.4.1 for Windows") + set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") + set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") + mark_as_advanced(MPICH2_WIN64_DEVEL_URL) + mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) + + include(ExternalProject) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmpi.a) + else() + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN32_DEVEL_URL} + URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmpi.a) + endif() + + ExternalProject_get_property(mpi4win_build SOURCE_DIR) + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + add_library(MPI::MPI_CXX UNKNOWN IMPORTED) + set_target_properties(MPI::MPI_CXX PROPERTIES + IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmpi.a" + INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" + INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + add_dependencies(MPI::MPI_CXX mpi4win_build) + + # set variables for status reporting at the end of CMake run + set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") + set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmpi.a") endif() - - ExternalProject_get_property(mpi4win_build SOURCE_DIR) - file(MAKE_DIRECTORY "${SOURCE_DIR}/include") - add_library(MPI::MPI_CXX UNKNOWN IMPORTED) - set_target_properties(MPI::MPI_CXX PROPERTIES - IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmpi.a" - INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" - INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") - add_dependencies(MPI::MPI_CXX mpi4win_build) - - # set variables for status reporting at the end of CMake run - set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") - set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") - set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmpi.a") else() find_package(MPI REQUIRED) option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize 'long long' data types" OFF) diff --git a/cmake/Modules/MPI4WIN.cmake b/cmake/Modules/MPI4WIN.cmake index aa0c9e1833..02db6d4744 100644 --- a/cmake/Modules/MPI4WIN.cmake +++ b/cmake/Modules/MPI4WIN.cmake @@ -1,39 +1,74 @@ -# Download and configure custom MPICH files for Windows -message(STATUS "Downloading and configuring MPICH-1.4.1 for Windows") -set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") -set(MPICH2_WIN32_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win32-devel.tar.gz" CACHE STRING "URL for MPICH2 (win32) tarball") -set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") -set(MPICH2_WIN32_DEVEL_MD5 "a61d153500dce44e21b755ee7257e031" CACHE STRING "MD5 checksum of MPICH2 (win32) tarball") -mark_as_advanced(MPICH2_WIN64_DEVEL_URL) -mark_as_advanced(MPICH2_WIN32_DEVEL_URL) -mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) -mark_as_advanced(MPICH2_WIN32_DEVEL_MD5) +# Download and configure MinGW compatible MPICH development files for Windows +option(USE_MSMPI "Use Microsoft's MS-MPI SDK instead of MPICH2-1.4.1" OFF) -include(ExternalProject) -if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - ExternalProject_Add(mpi4win_build - URL ${MPICH2_WIN64_DEVEL_URL} - URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} - CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" - BUILD_BYPRODUCTS /lib/libmpi.a) +if(USE_MSMPI) + message(STATUS "Downloading and configuring MS-MPI 10.1 for Windows cross-compilation") + set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/msmpi-win64-devel.tar.gz" CACHE STRING "URL for MS-MPI (win64) tarball") + set(MPICH2_WIN64_DEVEL_MD5 "86314daf1bffb809f1fcbefb8a547490" CACHE STRING "MD5 checksum of MS-MPI (win64) tarball") + mark_as_advanced(MPICH2_WIN64_DEVEL_URL) + mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) + + include(ExternalProject) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmsmpi.a) + else() + message(FATAL_ERROR "Only x86 64-bit builds are supported with MS-MPI") + endif() + + ExternalProject_get_property(mpi4win_build SOURCE_DIR) + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + add_library(MPI::MPI_CXX UNKNOWN IMPORTED) + set_target_properties(MPI::MPI_CXX PROPERTIES + IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmsmpi.a" + INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" + INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + add_dependencies(MPI::MPI_CXX mpi4win_build) + + # set variables for status reporting at the end of CMake run + set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") + set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmsmpi.a") else() - ExternalProject_Add(mpi4win_build - URL ${MPICH2_WIN32_DEVEL_URL} - URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} - CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" - BUILD_BYPRODUCTS /lib/libmpi.a) + message(STATUS "Downloading and configuring MPICH2-1.4.1 for Windows cross-compilation") + set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") + set(MPICH2_WIN32_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win32-devel.tar.gz" CACHE STRING "URL for MPICH2 (win32) tarball") + set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") + set(MPICH2_WIN32_DEVEL_MD5 "a61d153500dce44e21b755ee7257e031" CACHE STRING "MD5 checksum of MPICH2 (win32) tarball") + mark_as_advanced(MPICH2_WIN64_DEVEL_URL) + mark_as_advanced(MPICH2_WIN32_DEVEL_URL) + mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) + mark_as_advanced(MPICH2_WIN32_DEVEL_MD5) + + include(ExternalProject) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmpi.a) + else() + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN32_DEVEL_URL} + URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmpi.a) + endif() + + ExternalProject_get_property(mpi4win_build SOURCE_DIR) + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + add_library(MPI::MPI_CXX UNKNOWN IMPORTED) + set_target_properties(MPI::MPI_CXX PROPERTIES + IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmpi.a" + INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" + INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + add_dependencies(MPI::MPI_CXX mpi4win_build) + + # set variables for status reporting at the end of CMake run + set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") + set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmpi.a") endif() - -ExternalProject_get_property(mpi4win_build SOURCE_DIR) -file(MAKE_DIRECTORY "${SOURCE_DIR}/include") -add_library(MPI::MPI_CXX UNKNOWN IMPORTED) -set_target_properties(MPI::MPI_CXX PROPERTIES - IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmpi.a" - INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" - INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") -add_dependencies(MPI::MPI_CXX mpi4win_build) - -# set variables for status reporting at the end of CMake run -set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") -set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") -set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmpi.a") diff --git a/doc/src/Commands_all.rst b/doc/src/Commands_all.rst index d7b1609619..54108f5948 100644 --- a/doc/src/Commands_all.rst +++ b/doc/src/Commands_all.rst @@ -31,7 +31,6 @@ table above. * :doc:`bond_style ` * :doc:`bond_write ` * :doc:`boundary ` - * :doc:`box ` * :doc:`change_box ` * :doc:`clear ` * :doc:`comm_modify ` @@ -90,8 +89,7 @@ table above. * :doc:`region ` * :doc:`replicate ` * :doc:`rerun ` - * :doc:`reset_atom_ids ` - * :doc:`reset_mol_ids ` + * :doc:`reset_atoms ` * :doc:`reset_timestep ` * :doc:`restart ` * :doc:`run ` diff --git a/doc/src/Commands_category.rst b/doc/src/Commands_category.rst index 4a08d040b7..7ac747e8fc 100644 --- a/doc/src/Commands_category.rst +++ b/doc/src/Commands_category.rst @@ -25,7 +25,6 @@ Setup simulation box: :columns: 4 * :doc:`boundary ` - * :doc:`box ` * :doc:`change_box ` * :doc:`create_box ` * :doc:`dimension ` diff --git a/doc/src/Commands_removed.rst b/doc/src/Commands_removed.rst index 1000d11e29..8f5219fe8f 100644 --- a/doc/src/Commands_removed.rst +++ b/doc/src/Commands_removed.rst @@ -2,10 +2,11 @@ Removed commands and packages ============================= This page lists LAMMPS commands and packages that have been removed from -the distribution and provides suggestions for alternatives or replacements. -LAMMPS has special dummy styles implemented, that will stop LAMMPS and -print a suitable error message in most cases, when a style/command is used -that has been removed. +the distribution and provides suggestions for alternatives or +replacements. LAMMPS has special dummy styles implemented, that will +stop LAMMPS and print a suitable error message in most cases, when a +style/command is used that has been removed or will replace the command +with the direct alternative (if available) and print a warning. Fix ave/spatial and fix ave/spatial/sphere ------------------------------------------ @@ -17,10 +18,23 @@ ways through the :doc:`compute chunk/atom ` command and then averaging is done using :doc:`fix ave/chunk `. Please refer to the :doc:`chunk HOWTO ` section for an overview. -Reset_ids command ------------------ +Box command +----------- -The reset_ids command has been renamed to :doc:`reset_atom_ids `. +.. deprecated:: TBD + +The *box* command has been removed and the LAMMPS code changed so it won't +be needed. If present, LAMMPS will ignore the command and print a warning. + +Reset_ids, reset_atom_ids, reset_mol_ids commands +------------------------------------------------- + +.. deprecated:: TBD + +The *reset_ids*, *reset_atom_ids*, and *reset_mol_ids* commands have +been folded into the :doc:`reset_atoms ` command. If +present, LAMMPS will replace the commands accordingly and print a +warning. MEAM package ------------ @@ -30,18 +44,21 @@ The code in the :ref:`MEAM package ` is a translation of the Fortran code of MEAM into C++, which removes several restrictions (e.g. there can be multiple instances in hybrid pair styles) and allows for some optimizations leading to better performance. The pair style -:doc:`meam ` has the exact same syntax. +:doc:`meam ` has the exact same syntax. For a transition +period the C++ version of MEAM was called USER-MEAMC so it could +coexist with the Fortran version. REAX package ------------ The REAX package has been removed since it was superseded by the -:ref:`REAXFF package `. The REAXFF -package has been tested to yield equivalent results to the REAX package, -offers better performance, supports OpenMP multi-threading via OPENMP, -and GPU and threading parallelization through KOKKOS. The new pair styles -are not syntax compatible with the removed reax pair style, so input -files will have to be adapted. +:ref:`REAXFF package `. The REAXFF package has been tested +to yield equivalent results to the REAX package, offers better +performance, supports OpenMP multi-threading via OPENMP, and GPU and +threading parallelization through KOKKOS. The new pair styles are not +syntax compatible with the removed reax pair style, so input files will +have to be adapted. The REAXFF package was originally called +USER-REAXC. USER-CUDA package ----------------- @@ -60,5 +77,6 @@ restart2data tool The functionality of the restart2data tool has been folded into the LAMMPS executable directly instead of having a separate tool. A combination of the commands :doc:`read_restart ` and -:doc:`write_data ` can be used to the same effect. For added -convenience this conversion can also be triggered by :doc:`command line flags ` +:doc:`write_data ` can be used to the same effect. For +added convenience this conversion can also be triggered by +:doc:`command line flags ` diff --git a/doc/src/Developer_code_design.rst b/doc/src/Developer_code_design.rst index 820ad47fba..a5c879de82 100644 --- a/doc/src/Developer_code_design.rst +++ b/doc/src/Developer_code_design.rst @@ -78,7 +78,7 @@ LAMMPS makes extensive use of the object oriented programming (OOP) principles of *compositing* and *inheritance*. Classes like the ``LAMMPS`` class are a **composite** containing pointers to instances of other classes like ``Atom``, ``Comm``, ``Force``, ``Neighbor``, -``Modify``, and so on. Each of these classes implement certain +``Modify``, and so on. Each of these classes implements certain functionality by storing and manipulating data related to the simulation and providing member functions that trigger certain actions. Some of those classes like ``Force`` are themselves @@ -87,9 +87,9 @@ interactions. Similarly the ``Modify`` class contains a list of ``Fix`` and ``Compute`` classes. If the input commands that correspond to these classes include the word *style*, then LAMMPS stores only a single instance of that class. E.g. *atom_style*, -*comm_style*, *pair_style*, *bond_style*. It the input command does -not include the word *style*, there can be many instances of that -class defined. E.g. *region*, *fix*, *compute*, *dump*. +*comm_style*, *pair_style*, *bond_style*. If the input command does +**not** include the word *style*, then there may be many instances of +that class defined, for example *region*, *fix*, *compute*, *dump*. **Inheritance** enables creation of *derived* classes that can share common functionality in their base class while providing a consistent diff --git a/doc/src/Developer_unittest.rst b/doc/src/Developer_unittest.rst index 820e911a8f..aff6128e9c 100644 --- a/doc/src/Developer_unittest.rst +++ b/doc/src/Developer_unittest.rst @@ -226,9 +226,9 @@ The following test programs are currently available: * - ``test_kim_commands.cpp`` - KimCommands - Tests for several commands from the :ref:`KIM package ` - * - ``test_reset_ids.cpp`` - - ResetIDs - - Tests to validate the :doc:`reset_atom_ids ` and :doc:`reset_mol_ids ` commands + * - ``test_reset_atoms.cpp`` + - ResetAtoms + - Tests to validate the :doc:`reset_atoms ` sub-commands Tests for the C-style library interface diff --git a/doc/src/Howto_triclinic.rst b/doc/src/Howto_triclinic.rst index 5e952709c9..dd0a949f68 100644 --- a/doc/src/Howto_triclinic.rst +++ b/doc/src/Howto_triclinic.rst @@ -144,11 +144,6 @@ does not change the atom positions due to non-periodicity. In this mode, if you tilt the system to extreme angles, the simulation will simply become inefficient, due to the highly skewed simulation box. -The limitation on not creating a simulation box with a tilt factor -skewing the box more than half the distance of the parallel box length -can be overridden via the :doc:`box ` command. Setting the *tilt* -keyword to *large* allows any tilt factors to be specified. - Box flips that may occur using the :doc:`fix deform ` or :doc:`fix npt ` commands can be turned off using the *flip no* option with either of the commands. diff --git a/doc/src/Run_options.rst b/doc/src/Run_options.rst index f7bb652ea9..73fc37183e 100644 --- a/doc/src/Run_options.rst +++ b/doc/src/Run_options.rst @@ -262,6 +262,8 @@ Disable generating a citation reminder (see above) at all. **-nonbuf** +.. versionadded:: 15Sep2022 + Turn off buffering for screen and logfile output. For performance reasons, output to the screen and logfile is usually buffered, i.e. output is only written to a file if its buffer - typically 4096 bytes - diff --git a/doc/src/angle_gaussian.rst b/doc/src/angle_gaussian.rst index f0a50938e4..6b102a693b 100644 --- a/doc/src/angle_gaussian.rst +++ b/doc/src/angle_gaussian.rst @@ -25,23 +25,25 @@ The *gaussian* angle style uses the potential: .. math:: - E = -k_B T ln\left(\sum_{i=1}^{n} \frac{A_i}{w_i \sqrt{\pi/2}} exp\left( \frac{-(\theta-\theta_{i})^2}{w_i^2})\right) \right) + E = -k_B T ln\left(\sum_{i=1}^{n} \frac{A_i}{w_i \sqrt{\pi/2}} exp\left( \frac{-2(\theta-\theta_{i})^2}{w_i^2}\right) \right) + +This analytical form is a suitable potential for obtaining mesoscale +effective force fields which can reproduce target atomistic +distributions :ref:`(Milano) `. -This analytical form is a suitable potential for obtaining -mesoscale effective force fields which can reproduce target atomistic distributions :ref:`(Milano) ` The following coefficients must be defined for each angle type via the :doc:`angle_coeff ` command as in the example above, or in the data file or restart files read by the :doc:`read_data ` or :doc:`read_restart ` commands: -* T temperature at which the potential was derived +* :math:`T` temperature at which the potential was derived * :math:`n` (integer >=1) -* :math:`A_1` (-) -* :math:`w_1` (-) +* :math:`A_1` (> 0, radians) +* :math:`w_1` (> 0, radians) * :math:`\theta_1` (degrees) * ... -* :math:`A_n` (-) -* :math:`w_n` (-) +* :math:`A_n` (> 0, radians) +* :math:`w_n` (> 0, radians) * :math:`\theta_n` (degrees) diff --git a/doc/src/bond_bpm_rotational.rst b/doc/src/bond_bpm_rotational.rst index 5c43071274..fb1db04b27 100644 --- a/doc/src/bond_bpm_rotational.rst +++ b/doc/src/bond_bpm_rotational.rst @@ -45,6 +45,8 @@ Examples Description """"""""""" +.. versionadded:: 4May2022 + The *bpm/rotational* bond style computes forces and torques based on deviations from the initial reference state of the two atoms. The reference state is stored by each bond when it is first computed in @@ -211,9 +213,9 @@ command, as *b1*, *b2*, ..., *b7*\ . Restrictions """""""""""" -This bond style can only be used if LAMMPS was built with the BPM -package. See the :doc:`Build package ` doc page for -more info. +This bond style is part of the BPM package. It is only enabled if +LAMMPS was built with that package. See the :doc:`Build package +` page for more info. By default if pair interactions are to be disabled, this bond style requires setting diff --git a/doc/src/bond_bpm_spring.rst b/doc/src/bond_bpm_spring.rst index de31357afe..46c300d364 100644 --- a/doc/src/bond_bpm_spring.rst +++ b/doc/src/bond_bpm_spring.rst @@ -45,6 +45,8 @@ Examples Description """"""""""" +.. versionadded:: 4May2022 + The *bpm/spring* bond style computes forces and torques based on deviations from the initial reference state of the two atoms. The reference state is stored by each bond when it is first computed in @@ -167,9 +169,9 @@ extra quantity can be accessed by the Restrictions """""""""""" -This bond style can only be used if LAMMPS was built with the BPM -package. See the :doc:`Build package ` doc page for -more info. +This bond style is part of the BPM package. It is only enabled if +LAMMPS was built with that package. See the :doc:`Build package +` page for more info. By default if pair interactions are to be disabled, this bond style requires setting diff --git a/doc/src/bond_gaussian.rst b/doc/src/bond_gaussian.rst index 9fbcf4778c..74e5b973eb 100644 --- a/doc/src/bond_gaussian.rst +++ b/doc/src/bond_gaussian.rst @@ -25,33 +25,34 @@ The *gaussian* bond style uses the potential: .. math:: - E = -k_B T ln\left(\sum_{i=1}^{n} \frac{A_i}{w_i \sqrt{\pi/2}} exp\left( \frac{-(r-r_{i})^2}{w_i^2})\right) \right) + E = -k_B T ln\left(\sum_{i=1}^{n} \frac{A_i}{w_i \sqrt{\pi/2}} exp\left( \frac{-2(r-r_{i})^2}{w_i^2}\right)\right) -This analytical form is a suitable potential for obtaining -mesoscale effective force fields which can reproduce target atomistic distributions :ref:`(Milano) ` +This analytical form is a suitable potential for obtaining mesoscale +effective force fields which can reproduce target atomistic +distributions :ref:`(Milano) ` The following coefficients must be defined for each bond type via the :doc:`bond_coeff ` command as in the example above, or in the data file or restart files read by the :doc:`read_data ` or :doc:`read_restart ` commands: -* T temperature at which the potential was derived +* :math:`T` temperature at which the potential was derived * :math:`n` (integer >=1) -* :math:`A_1` (-) -* :math:`w_1` (-) -* :math:`r_1` (length) +* :math:`A_1` (> 0, distance) +* :math:`w_1` (> 0, distance) +* :math:`r_1` (>= 0, distance) * ... -* :math:`A_n` (-) -* :math:`w_n` (-) -* :math:`r_n` (length) +* :math:`A_n` (> 0, distance) +* :math:`w_n` (> 0, distance) +* :math:`r_n` (>= 0, distance) Restrictions """""""""""" This bond style can only be used if LAMMPS was built with the -EXTRA-MOLECULE package. See the :doc:`Build package ` doc -page for more info. +EXTRA-MOLECULE package. See the :doc:`Build package ` +doc page for more info. Related commands """""""""""""""" diff --git a/doc/src/box.rst b/doc/src/box.rst deleted file mode 100644 index 096a171249..0000000000 --- a/doc/src/box.rst +++ /dev/null @@ -1,70 +0,0 @@ -.. index:: box - -box command -=========== - -Syntax -"""""" - -.. code-block:: LAMMPS - - box keyword value ... - -* one or more keyword/value pairs may be appended -* keyword = *tilt* - - .. parsed-literal:: - - *tilt* value = *small* or *large* - -Examples -"""""""" - -.. code-block:: LAMMPS - - box tilt large - box tilt small - -Description -""""""""""" - -Set attributes of the simulation box. - -For triclinic (non-orthogonal) simulation boxes, the *tilt* keyword -allows simulation domains to be created with arbitrary tilt factors, -e.g. via the :doc:`create_box ` or -:doc:`read_data ` commands. Tilt factors determine how -skewed the triclinic box is; see the :doc:`Howto triclinic ` page for a discussion of triclinic -boxes in LAMMPS. - -LAMMPS normally requires that no tilt factor can skew the box more -than half the distance of the parallel box length, which is the first -dimension in the tilt factor (x for xz). If *tilt* is set to -*small*, which is the default, then an error will be -generated if a box is created which exceeds this limit. If *tilt* -is set to *large*, then no limit is enforced. You can create -a box with any tilt factors you wish. - -Note that if a simulation box has a large tilt factor, LAMMPS will run -less efficiently, due to the large volume of communication needed to -acquire ghost atoms around a processor's irregular-shaped sub-domain. -For extreme values of tilt, LAMMPS may also lose atoms and generate an -error. - -Restrictions -"""""""""""" - -This command cannot be used after the simulation box is defined by a -:doc:`read_data ` or :doc:`create_box ` command or -:doc:`read_restart ` command. - -Related commands -"""""""""""""""" - -none - - -Default -""""""" - -The default value is tilt = small. diff --git a/doc/src/commands_list.rst b/doc/src/commands_list.rst index ee032bfd9e..9adc397138 100644 --- a/doc/src/commands_list.rst +++ b/doc/src/commands_list.rst @@ -13,7 +13,6 @@ Commands bond_style bond_write boundary - box change_box clear comm_modify @@ -90,8 +89,7 @@ Commands region replicate rerun - reset_atom_ids - reset_mol_ids + reset_atoms reset_timestep restart run diff --git a/doc/src/compute_nbond_atom.rst b/doc/src/compute_nbond_atom.rst index 0e53de3e49..f438836534 100644 --- a/doc/src/compute_nbond_atom.rst +++ b/doc/src/compute_nbond_atom.rst @@ -23,6 +23,8 @@ Examples Description """"""""""" +.. versionadded:: 4May2022 + Define a computation that computes the number of bonds each atom is part of. Bonds which are broken are not counted in the tally. See the :doc:`Howto broken bonds ` page for more information. @@ -40,8 +42,9 @@ LAMMPS output options. Restrictions """""""""""" -This fix can only be used if LAMMPS was built with the BPM package. -See the :doc:`Build package ` doc page for more info. +This compute is part of the BPM package. It is only enabled if LAMMPS was +built with that package. See the :doc:`Build package ` +page for more info. Related commands """""""""""""""" diff --git a/doc/src/compute_pair_local.rst b/doc/src/compute_pair_local.rst index bcfec11f80..dace280dee 100644 --- a/doc/src/compute_pair_local.rst +++ b/doc/src/compute_pair_local.rst @@ -59,7 +59,7 @@ commands. The value *dist* is the distance between the pair of atoms. The values *dx*, *dy*, and *dz* are the :math:`(x,y,z)` components of the *distance* between the pair of atoms. This value is always the -distance from the atom of lower to the one with the higher id. +distance from the atom of higher to the one with the lower atom ID. The value *eng* is the interaction energy for the pair of atoms. diff --git a/doc/src/create_box.rst b/doc/src/create_box.rst index 889a57605d..f930ecea83 100644 --- a/doc/src/create_box.rst +++ b/doc/src/create_box.rst @@ -66,20 +66,21 @@ positive or negative values and are called "tilt factors" because they are the amount of displacement applied to faces of an originally orthogonal box to transform it into the parallelepiped. -By default, a *prism* region used with the create_box command must -have tilt factors :math:`(xy,xz,yz)` that do not skew the box more than half +By default, a *prism* region used with the create_box command must have +tilt factors :math:`(xy,xz,yz)` that do not skew the box more than half the distance of the parallel box length. For example, if :math:`x_\text{lo} = 2` and :math:`x_\text{hi} = 12`, then the :math:`x` -box length is 10 and the :math:`xy` tilt factor must be between :math:`-5` and -:math:`5`. Similarly, both :math:`xz` and :math:`yz` must be between -:math:`-(x_\text{hi}-x_\text{lo})/2` and :math:`+(y_\text{hi}-y_\text{lo})/2`. -Note that this is not a limitation, since if the maximum tilt factor is 5 (as -in this example), then configurations with tilt :math:`= \dots, -15`, -:math:`-5`, :math:`5`, :math:`15`, :math:`25, \dots` -are all geometrically equivalent. If you wish to define a box with tilt -factors that exceed these limits, you can use the :doc:`box tilt ` -command, with a setting of *large*\ ; a setting of *small* is the -default. +box length is 10 and the :math:`xy` tilt factor must be between +:math:`-5` and :math:`5`. Similarly, both :math:`xz` and :math:`yz` +must be between :math:`-(x_\text{hi}-x_\text{lo})/2` and +:math:`+(y_\text{hi}-y_\text{lo})/2`. Note that this is not a +limitation, since if the maximum tilt factor is 5 (as in this example), +then configurations with tilt :math:`= \dots, -15`, :math:`-5`, +:math:`5`, :math:`15`, :math:`25, \dots` are all geometrically +equivalent. Simulations with large tilt factors will run inefficiently, +since they require more ghost atoms and thus more communication. With +very large tilt factors, LAMMPS will eventually produce incorrect +trajectories and stop with errors due to lost atoms or similar. See the :doc:`Howto triclinic ` page for a geometric description of triclinic boxes, as defined by LAMMPS, and diff --git a/doc/src/delete_atoms.rst b/doc/src/delete_atoms.rst index 2fdd152196..c863d0c7d2 100644 --- a/doc/src/delete_atoms.rst +++ b/doc/src/delete_atoms.rst @@ -135,7 +135,7 @@ number of atoms in the system. Note that this is not done for molecular systems (see the :doc:`atom_style ` command), regardless of the *compress* setting, since it would foul up the bond connectivity that has already been assigned. However, the -:doc:`reset_atom_ids ` command can be used after this +:doc:`reset_atoms id ` command can be used after this command to accomplish the same thing. Note that the re-assignment of IDs is not really a compression, where @@ -203,7 +203,7 @@ using molecule template files via the :doc:`molecule ` and Related commands """""""""""""""" -:doc:`create_atoms `, :doc:`reset_atom_ids ` +:doc:`create_atoms `, :doc:`reset_atoms id ` Default """"""" diff --git a/doc/src/dump_image.rst b/doc/src/dump_image.rst index bc2373afac..c9e838b7cf 100644 --- a/doc/src/dump_image.rst +++ b/doc/src/dump_image.rst @@ -69,7 +69,7 @@ Syntax yes/no = do or do not draw simulation box lines diam = diameter of box lines as fraction of shortest box length *axes* values = axes length diam = draw xyz axes - axes = *yes* or *no = do or do not draw xyz axes lines next to simulation box + axes = *yes* or *no* = do or do not draw xyz axes lines next to simulation box length = length of axes lines as fraction of respective box lengths diam = diameter of axes lines as fraction of shortest box length *subbox* values = lines diam = draw outline of processor sub-domains diff --git a/doc/src/fix_bond_react.rst b/doc/src/fix_bond_react.rst index c557d2617d..4377d9d946 100644 --- a/doc/src/fix_bond_react.rst +++ b/doc/src/fix_bond_react.rst @@ -42,13 +42,16 @@ Syntax * template-ID(post-reacted) = ID of a molecule template containing post-reaction topology * map_file = name of file specifying corresponding atom-IDs in the pre- and post-reacted templates * zero or more individual keyword/value pairs may be appended to each react argument -* individual_keyword = *prob* or *max_rxn* or *stabilize_steps* or *custom_charges* or *molecule* or *modify_create* +* individual_keyword = *prob* or *rate_limit* or *max_rxn* or *stabilize_steps* or *custom_charges* or *rescale_charges* or *molecule* or *modify_create* .. parsed-literal:: *prob* values = fraction seed fraction = initiate reaction with this probability if otherwise eligible seed = random number seed (positive integer) + *rate_limit* = Nlimit Nsteps + Nlimit = maximum number of reactions allowed to occur within interval + Nsteps = the interval (number of timesteps) over which to count reactions *max_rxn* value = N N = maximum number of reactions allowed to occur *stabilize_steps* value = timesteps @@ -56,6 +59,9 @@ Syntax *custom_charges* value = *no* or fragment-ID *no* = update all atomic charges (default) fragment-ID = ID of molecule fragment whose charges are updated + *rescale_charges* value = *no* or *yes* + *no* = do not rescale atomic charges (default) + *yes* = rescale charges such that total charge does not change during reaction *molecule* value = *off* or *inter* or *intra* *off* = allow both inter- and intramolecular reactions (default) *inter* = search for reactions between molecules with different IDs @@ -171,12 +177,12 @@ due to the internal dynamic grouping performed by fix bond/react. If the group-ID is an existing static group, react-group-IDs should also be specified as this static group or a subset. -The *reset_mol_ids* keyword invokes the :doc:`reset_mol_ids ` -command after a reaction occurs, to ensure that molecule IDs are -consistent with the new bond topology. The group-ID used for -:doc:`reset_mol_ids ` is the group-ID for this fix. -Resetting molecule IDs is necessarily a global operation, so it can -be slow for very large systems. +The *reset_mol_ids* keyword invokes the :doc:`reset_atoms mol +` command after a reaction occurs, to ensure that +molecule IDs are consistent with the new bond topology. The group-ID +used for :doc:`reset_atoms mol ` is the group-ID for this +fix. Resetting molecule IDs is necessarily a global operation, so it +can be slow for very large systems. The following comments pertain to each *react* argument (in other words, they can be customized for each reaction, or reaction step): @@ -514,28 +520,40 @@ example, the molecule fragment could consist of only the backbone atoms of a polymer chain. This constraint can be used to enforce a specific relative position and orientation between reacting molecules. +.. versionchanged:: TBD + The constraint of type "custom" has the following syntax: .. parsed-literal:: custom *varstring* -where "custom" is the required keyword, and *varstring* is a -variable expression. The expression must be a valid equal-style -variable formula that can be read by the :doc:`variable ` command, +where 'custom' is the required keyword, and *varstring* is a variable +expression. The expression must be a valid equal-style variable +formula that can be read by the :doc:`variable ` command, after any special reaction functions are evaluated. If the resulting expression is zero, the reaction is prevented from occurring; -otherwise, it is permitted to occur. There are two special reaction -functions available, "rxnsum" and "rxnave". These functions operate -over the atoms in a given reaction site, and have one mandatory -argument and one optional argument. The mandatory argument is the -identifier for an atom-style variable. The second, optional argument -is the name of a molecule fragment in the pre-reaction template, and -can be used to operate over a subset of atoms in the reaction site. -The "rxnsum" function sums the atom-style variable over the reaction -site, while the "rxnave" returns the average value. For example, a -constraint on the total potential energy of atoms involved in the -reaction can be imposed as follows: +otherwise, it is permitted to occur. There are three special reaction +functions available, 'rxnbond', 'rxnsum', and 'rxnave'. The 'rxnbond' +function allows per-bond values to be included in the variable strings +of the custom constraint. The 'rxnbond' function has two mandatory +arguments. The first argument is the ID of a previously defined +'compute bond/local' command. This 'compute bond/local' must compute +only one value, e.g. bond force. This value is returned by the +'rxnbond' function. The second argument is the name of a molecule +fragment in the pre-reaction template. The fragment must contain +exactly two atoms, corresponding to the atoms involved in the bond +whose value should be calculated. An example of a constraint that uses +the force experienced by a bond is provided below. The 'rxnsum' and +'rxnave' functions operate over the atoms in a given reaction site, +and have one mandatory argument and one optional argument. The +mandatory argument is the identifier for an atom-style variable. The +second, optional argument is the name of a molecule fragment in the +pre-reaction template, and can be used to operate over a subset of +atoms in the reaction site. The 'rxnsum' function sums the atom-style +variable over the reaction site, while the 'rxnave' returns the +average value. For example, a constraint on the total potential energy +of atoms involved in the reaction can be imposed as follows: .. code-block:: LAMMPS @@ -547,11 +565,32 @@ reaction can be imposed as follows: custom "rxnsum(v_my_pe) > 100" # in Constraints section of map file The above example prevents the reaction from occurring unless the -total potential energy of the reaction site is above 100. The variable -expression can be interpreted as the probability of the reaction -occurring by using an inequality and the :doc:`random(x,y,z) ` -function available for equal-style variables, similar to the 'arrhenius' -constraint above. +total potential energy of the reaction site is above 100. As a second +example, this time using the 'rxnbond' function, consider a modified +Arrhenius constraint that depends on the bond force of a specific bond: + +.. code-block:: LAMMPS + + # in LAMMPS input script + + compute bondforce all bond/local force + + compute ke_atom all ke/atom + variable ke atom c_ke_atom + + variable E_a equal 100.0 # activation energy + variable l0 equal 1.0 # characteristic length + + +.. code-block:: LAMMPS + + # in Constraints section of map file + + custom "exp(-(v_E_a-rxnbond(c_bondforce,bond1frag)*v_l0)/(2/3*rxnave(v_ke))) < random(0,1,12345)" + +By using an inequality and the 'random(x,y,z)' function, the left-hand +side can be interpreted as the probability of the reaction occurring, +similar to the 'arrhenius' constraint above. By default, all constraints must be satisfied for the reaction to occur. In other words, constraints are evaluated as a series of @@ -598,6 +637,15 @@ eligible reaction only occurs if the random number is less than the fraction. Up to :math:`N` reactions are permitted to occur, as optionally specified by the *max_rxn* keyword. +.. versionadded:: TBD + +The *rate_limit* keyword can enforce an upper limit on the overall +rate of the reaction. The number of reaction occurrences is limited to +Nlimit within an interval of Nsteps timesteps. No reactions are +permitted to occur within the first Nsteps timesteps of the first run +after reading a data file. Nlimit can be specified with an equal-style +:doc:`variable `. + The *stabilize_steps* keyword allows for the specification of how many time steps a reaction site is stabilized before being returned to the overall system thermostat. In order to produce the most physical @@ -616,6 +664,19 @@ charges are updated to those specified by the post-reaction template fragment defined in the pre-reaction molecule template. In this case, only the atomic charges of atoms in the molecule fragment are updated. +.. versionadded:: TBD + +The *rescale_charges* keyword can be used to ensure the total charge +of the system does not change as reactions occur. When the argument is +set to *yes*\ , a fixed value is added to the charges of post-reaction +atoms such that their total charge equals that of the pre-reaction +site. If only a subset of atomic charges are updated via the +*custom_charges* keyword, this rescaling is applied to the subset. +This keyword could be useful for systems that contain different +molecules with the same reactive site, if the partial charges on the +reaction site vary from molecule to molecule, or when removing +reaction by-products. + The *molecule* keyword can be used to force the reaction to be intermolecular, intramolecular or either. When the value is set to *off*\ , molecule IDs are not considered when searching for reactions diff --git a/doc/src/fix_ipi.rst b/doc/src/fix_ipi.rst index 6a6ff9aa87..5e13d25971 100644 --- a/doc/src/fix_ipi.rst +++ b/doc/src/fix_ipi.rst @@ -90,6 +90,12 @@ coordinates are transferred. However, one could use this strategy to define an external potential acting on the atoms that are moved by i-PI. +Since the i-PI code uses atomic units internally, this fix needs to +convert LAMMPS data to and from its :doc:`specified units ` +accordingly when communicating with i-PI. This is not possible for +reduced units ("units lj") and thus *fix ipi* will stop with an error in +this case. + This fix is part of the MISC package. It is only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. diff --git a/doc/src/fix_nh_uef.rst b/doc/src/fix_nh_uef.rst index 83cf88b11f..cf20d56ce7 100644 --- a/doc/src/fix_nh_uef.rst +++ b/doc/src/fix_nh_uef.rst @@ -44,19 +44,23 @@ Examples Description """"""""""" -This fix can be used to simulate non-equilibrium molecular dynamics -(NEMD) under diagonal flow fields, including uniaxial and bi-axial -flow. Simulations under continuous extensional flow may be carried -out for an indefinite amount of time. It is an implementation of the -boundary conditions from :ref:`(Dobson) `, and also uses numerical +These fixes can be used to simulate non-equilibrium molecular dynamics +(NEMD) under diagonal flow fields, including uniaxial and bi-axial flow. +Simulations under continuous extensional flow may be carried out for an +indefinite amount of time. It is an implementation of the boundary +conditions from :ref:`(Dobson) `, and also uses numerical lattice reduction as was proposed by :ref:`(Hunt) `. The lattice -reduction algorithm is from :ref:`(Semaev) `. The fix is intended for -simulations of homogeneous flows, and integrates the SLLOD equations -of motion, originally proposed by Hoover and Ladd (see :ref:`(Evans and Morriss) `). Additional detail about this implementation can be -found in :ref:`(Nicholson and Rutledge) `. +reduction algorithm is from :ref:`(Semaev) `. The fix is +intended for simulations of homogeneous flows, and integrates the SLLOD +equations of motion, originally proposed by Hoover and Ladd (see +:ref:`(Evans and Morriss) `). Additional detail about this +implementation can be found in :ref:`(Nicholson and Rutledge) +`. Note that NEMD simulations of a continuously strained system can be -performed using the :doc:`fix deform `, :doc:`fix nvt/sllod `, and :doc:`compute temp/deform ` commands. +performed using the :doc:`fix deform `, :doc:`fix nvt/sllod +`, and :doc:`compute temp/deform ` +commands. The applied flow field is set by the *eps* keyword. The values *edot_x* and *edot_y* correspond to the strain rates in the xx and yy @@ -73,11 +77,11 @@ to -(*edot_x* + *edot_y*). The boundary conditions require a simulation box that does not have a consistent alignment relative to the applied flow field. Since LAMMPS utilizes an upper-triangular simulation box, it is not possible to -express the evolving simulation box in the same coordinate system as -the flow field. This fix keeps track of two coordinate systems: the -flow frame, and the upper triangular LAMMPS frame. The coordinate -systems are related to each other through the QR decomposition, as is -illustrated in the image below. +express the evolving simulation box in the same coordinate system as the +flow field. These fixes keep track of two coordinate systems: the flow +frame, and the upper triangular LAMMPS frame. The coordinate systems are +related to each other through the QR decomposition, as is illustrated in +the image below. .. image:: JPG/uef_frames.jpg :align: center @@ -99,12 +103,12 @@ using the dump command will be in the LAMMPS frame unless the ---------- Temperature control is achieved with the default Nose-Hoover style -thermostat documented in :doc:`fix npt `. When this fix is +thermostat documented in :doc:`fix nvt `. When this fix is active, only the peculiar velocity of each atom is stored, defined as -the velocity relative to the streaming velocity. This is in contrast -to :doc:`fix nvt/sllod `, which uses a lab-frame -velocity, and removes the contribution from the streaming velocity in -order to compute the temperature. +the velocity relative to the streaming velocity. This is in contrast to +:doc:`fix nvt/sllod `, which uses a lab-frame velocity, +and removes the contribution from the streaming velocity in order to +compute the temperature. Pressure control is achieved using the default Nose-Hoover barostat documented in :doc:`fix npt `. There are two ways to control the @@ -156,8 +160,8 @@ The following commands will not work: ---------- -These fix computes a temperature and pressure each timestep. To do -this, it creates its own computes of style "temp/uef" and +These fixes compute a temperature and pressure each timestep. To do +this, they create their own computes of style "temp/uef" and "pressure/uef", as if one of these two sets of commands had been issued: @@ -169,18 +173,19 @@ issued: compute fix-ID_temp all temp/uef compute fix-ID_press all pressure/uef fix-ID_temp -See the :doc:`compute temp/uef ` and :doc:`compute pressure/uef ` commands for details. Note -that the IDs of the new computes are the fix-ID + underscore + "temp" -or fix_ID + underscore + "press". +See the :doc:`compute temp/uef ` and :doc:`compute +pressure/uef ` commands for details. Note that +the IDs of the new computes are the fix-ID + underscore + "temp" or +fix_ID + underscore + "press". Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" The fix writes the state of all the thermostat and barostat variables, -as well as the cumulative strain applied, to :doc:`binary restart files `. See the :doc:`read_restart ` command -for info on how to re-specify a fix in an input script that reads a -restart file, so that the operation of the fix continues in an -uninterrupted fashion. +as well as the cumulative strain applied, to :doc:`binary restart files +`. See the :doc:`read_restart ` command for info +on how to re-specify a fix in an input script that reads a restart file, +so that the operation of the fix continues in an uninterrupted fashion. .. note:: @@ -189,43 +194,41 @@ uninterrupted fashion. not contain the cumulative applied strain, will this keyword be necessary. -This fix can be used with the :doc:`fix_modify ` *temp* and -*press* options. The temperature and pressure computes used must be of -type *temp/uef* and *pressure/uef*\ . +These fixes can be used with the :doc:`fix_modify ` *temp* +and *press* options. The temperature and pressure computes used must be +of type *temp/uef* and *pressure/uef*\ . -This fix computes the same global scalar and vector quantities as :doc:`fix npt `. +These fixes compute the same global scalar and vector quantities as +:doc:`fix nvt andnpt `. -The fix is not invoked during :doc:`energy minimization `. +These fixes are not invoked during :doc:`energy minimization `. Restrictions """""""""""" -This fix is part of the UEF package. It is only enabled if LAMMPS -was built with that package. See the :doc:`Build package ` page for more info. +These fixes are part of the UEF package. They are only enabled if LAMMPS +was built with that package. See the :doc:`Build package +` page for more info. Due to requirements of the boundary conditions, when the *strain* keyword is set to zero (or unset), the initial simulation box must be cubic and have style triclinic. If the box is initially of type ortho, use :doc:`change_box ` before invoking the fix. -.. note:: - - When resuming from restart files, you may need to use :doc:`box tilt - large ` since LAMMPS has internal criteria from lattice - reduction that are not the same as the criteria in the numerical - lattice reduction algorithm. - Related commands """""""""""""""" -:doc:`fix nvt `, :doc:`fix nvt/sllod `, :doc:`compute temp/uef `, :doc:`compute pressure/uef `, :doc:`dump cfg/uef ` +:doc:`fix nvt `, :doc:`fix npt `, `fix nvt/sllod +:doc:`, `compute temp/uef `, +:doc::doc:`compute pressure/uef `, `dump cfg/uef +:doc:` Default """"""" -The default keyword values specific to this fix are exy = xyz, strain -= 0 0. The remaining defaults are the same as for :doc:`fix npt ` -except tchain = 1. The reason for this change is given in +The default keyword values specific to these fixes are exy = xyz, strain += 0 0. The remaining defaults are the same as for :doc:`fix nvt or npt +` except tchain = 1. The reason for this change is given in :doc:`fix nvt/sllod `. ---------- diff --git a/doc/src/fix_nve_bpm_sphere.rst b/doc/src/fix_nve_bpm_sphere.rst index 861586ab2a..ef170605a4 100644 --- a/doc/src/fix_nve_bpm_sphere.rst +++ b/doc/src/fix_nve_bpm_sphere.rst @@ -30,6 +30,8 @@ Examples Description """"""""""" +.. versionadded:: 4May2022 + Perform constant NVE integration to update position, velocity, angular velocity, and quaternion orientation for finite-size spherical particles in the group each timestep. V is volume; E is energy. This @@ -65,6 +67,10 @@ the :doc:`run ` command. This fix is not invoked during Restrictions """""""""""" +This fix is part of the BPM package. It is only enabled if LAMMPS was +built with that package. See the :doc:`Build package ` +page for more info. + This fix requires that atoms store torque, angular velocity (omega), a radius, and a quaternion as defined by the :doc:`atom_style bpm/sphere ` command. diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 9735284280..838b9812ad 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -156,6 +156,8 @@ This fix is part of the REPLICA package. It is only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +Fix pid cannot be used with :doc:`lj units `. + A PIMD simulation can be initialized with a single data file read via the :doc:`read_data ` command. However, this means all quasi-beads in a ring polymer will have identical positions and diff --git a/doc/src/pair_bpm_spring.rst b/doc/src/pair_bpm_spring.rst index 72e0083bd8..7dfa9bc12c 100644 --- a/doc/src/pair_bpm_spring.rst +++ b/doc/src/pair_bpm_spring.rst @@ -22,6 +22,8 @@ Examples Description """"""""""" +.. versionadded:: 4May2022 + Style *bpm/spring* computes pairwise forces with the formula .. math:: @@ -101,7 +103,11 @@ This pair style can only be used via the *pair* keyword of the Restrictions """""""""""" - none + +This pair style is part of the BPM package. It is only enabled if +LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + Related commands """""""""""""""" diff --git a/doc/src/pair_sw.rst b/doc/src/pair_sw.rst index 579e4c6f3f..7b4e52c3d9 100644 --- a/doc/src/pair_sw.rst +++ b/doc/src/pair_sw.rst @@ -176,9 +176,13 @@ are placeholders for atom types that will be used with other potentials. .. note:: - When the *threebody off* keyword is used, multiple pair_coeff commands may - be used to specific the pairs of atoms which don't require three-body term. - In these cases, the first 2 arguments are not required to be \* \*. + When the *threebody off* keyword is used, multiple pair_coeff + commands may be used to specific the pairs of atoms which don't + require three-body term. In these cases, the first 2 arguments are + not required to be \* \*, the potential parameter file is only read + by the first :doc:`pair_coeff command ` and the element + to atom type mappings must be consistent across all *pair_coeff* + statements. If not LAMMPS will abort with an error. Stillinger-Weber files in the *potentials* directory of the LAMMPS distribution have a ".sw" suffix. Lines that are not blank or diff --git a/doc/src/pair_ylz.rst b/doc/src/pair_ylz.rst index 5c3738f509..17cf0ca639 100644 --- a/doc/src/pair_ylz.rst +++ b/doc/src/pair_ylz.rst @@ -82,7 +82,7 @@ mixing as described below: * :math:`\epsilon` = well depth (energy units) * :math:`\sigma` = minimum effective particle radii (distance units) -* :math:`\zeta` = tune parameter for the slope of the attractive branch +* :math:`\zeta` = tuning parameter for the slope of the attractive branch * :math:`\mu` = parameter related to bending rigidity * :math:`\beta` = parameter related to the spontaneous curvature * cutoff (distance units) diff --git a/doc/src/python.rst b/doc/src/python.rst index aad2f636d3..5316fb28a5 100644 --- a/doc/src/python.rst +++ b/doc/src/python.rst @@ -8,14 +8,25 @@ Syntax .. parsed-literal:: - python func keyword args ... + python mode keyword args ... -* func = name of Python function -* one or more keyword/args pairs must be appended +* mode = *source* or name of Python function + + if mode is *source*: .. parsed-literal:: - keyword = *invoke* or *input* or *return* or *format* or *length* or *file* or *here* or *exists* or *source* + keyword = *here* or name of a *Python file* + *here* arg = inline + inline = one or more lines of Python code which defines func + must be a single argument, typically enclosed between triple quotes + *Python file* = name of a file with Python code which will be executed immediately + +* if *mode* is the name of a Python function, one or more keywords with/without arguments must be appended + + .. parsed-literal:: + + keyword = *invoke* or *input* or *return* or *format* or *length* or *file* or *here* or *exists* *invoke* arg = none = invoke the previously defined Python function *input* args = N i1 i2 ... iN N = # of inputs to function @@ -24,7 +35,7 @@ Syntax SELF = reference to LAMMPS itself which can be accessed by Python function variable = v_name, where name = name of LAMMPS variable, e.g. v_abc *return* arg = varReturn - varReturn = v_name = LAMMPS variable name which return value of function will be assigned to + varReturn = v_name = LAMMPS variable name which the return value of the Python function will be assigned to *format* arg = fstring with M characters M = N if no return value, where N = # of inputs M = N+1 if there is a return value @@ -38,10 +49,6 @@ Syntax inline = one or more lines of Python code which defines func must be a single argument, typically enclosed between triple quotes *exists* arg = none = Python code has been loaded by previous python command - *source* arg = *filename* or *inline* - filename = file of Python code which will be executed immediately - inline = one or more lines of Python code which will be executed immediately - must be a single argument, typically enclosed between triple quotes Examples """""""" @@ -70,80 +77,105 @@ Examples lmp.command("pair_style lj/cut ${cut}") # LAMMPS commands lmp.command("pair_coeff * * 1.0 1.0") lmp.command("run 100") - """ + """ + + python source funcdef.py + + python source here "from lammps import lammps" + Description """"""""""" -Define a Python function or execute a previously defined function or -execute some arbitrary python code. +The *python* command allows interfacing LAMMPS with an embedded Python +interpreter and enables either executing arbitrary python code in that +interpreter, registering a Python function for future execution (as a +python style variable, from a fix interfaced with python, or for direct +invocation), or invoking such a previously registered function. + Arguments, including LAMMPS variables, can be passed to the function -from the LAMMPS input script and a value returned by the Python -function to a LAMMPS variable. The Python code for the function can -be included directly in the input script or in a separate Python file. -The function can be standard Python code or it can make "callbacks" to -LAMMPS through its library interface to query or set internal values -within LAMMPS. This is a powerful mechanism for performing complex -operations in a LAMMPS input script that are not possible with the -simple input script and variable syntax which LAMMPS defines. Thus -your input script can operate more like a true programming language. +from the LAMMPS input script and a value returned by the Python function +assigned to a LAMMPS variable. The Python code for the function can be included +directly in the input script or in a separate Python file. The function +can be standard Python code or it can make "callbacks" to LAMMPS through +its library interface to query or set internal values within LAMMPS. +This is a powerful mechanism for performing complex operations in a +LAMMPS input script that are not possible with the simple input script +and variable syntax which LAMMPS defines. Thus your input script can +operate more like a true programming language. Use of this command requires building LAMMPS with the PYTHON package which links to the Python library so that the Python interpreter is embedded in LAMMPS. More details about this process are given below. There are two ways to invoke a Python function once it has been -defined. One is using the *invoke* keyword. The other is to assign +registered. One is using the *invoke* keyword. The other is to assign the function to a :doc:`python-style variable ` defined in -your input script. Whenever the variable is evaluated, it will -execute the Python function to assign a value to the variable. Note -that variables can be evaluated in many different ways within LAMMPS. -They can be substituted for directly in an input script. Or they can -be passed to various commands as arguments, so that the variable is -evaluated during a simulation run. +your input script. Whenever the variable is evaluated, it will execute +the Python function to assign a value to the variable. Note that +variables can be evaluated in many different ways within LAMMPS. They +can be substituted with their result directly in an input script, or +they can be passed to various commands as arguments, so that the +variable is evaluated during a simulation run. -A broader overview of how Python can be used with LAMMPS is given on -the :doc:`Python ` doc page. There is an examples/python -directory which illustrates use of the python command. +A broader overview of how Python can be used with LAMMPS is given in the +:doc:`Use Python with LAMMPS ` section of the +documentation. There also is an ``examples/python`` directory which +illustrates use of the python command. ---------- -The *func* setting specifies the name of the Python function. The -code for the function is defined using the *file* or *here* keywords -as explained below. In case of the *source* keyword, the name of -the function is ignored. +The first argument of the *python* command is either the *source* +keyword or the name of a Python function. This defines the mode +of the python command. + +.. versionchanged:: TBD + +If the *source* keyword is used, it is followed by either a file name or +the *here* keyword. No other keywords can be used. The *here* keyword +is followed by a string with python commands, either on a single line +enclosed in quotes, or as multiple lines enclosed in triple quotes. +These Python commands will be passed to the python interpreter and +executed immediately without registering a Python function for future +execution. The code will be loaded into and run in the "main" module of +the Python interpreter. This allows running arbitrary Python code at +any time while processing the LAMMPS input file. This can be used to +pre-load Python modules, initialize global variables, define functions +or classes, or perform operations using the python programming language. +The Python code will be executed in parallel on all MPI processes. No +arguments can be passed. + +In all other cases, the first argument is the name of a Python function +that will be registered with LAMMPS for future execution. The function +may already be defined (see *exists* keyword) or must be defined using +the *file* or *here* keywords as explained below. If the *invoke* keyword is used, no other keywords can be used, and a -previous python command must have defined the Python function +previous *python* command must have registered the Python function referenced by this command. This invokes the Python function with the -previously defined arguments and return value processed as explained -below. You can invoke the function as many times as you wish in your -input script. - -If the *source* keyword is used, no other keywords can be used. -The argument can be a filename or a string with python commands, -either on a single line enclosed in quotes, or as multiple lines -enclosed in triple quotes. These python commands will be passed -to the python interpreter and executed immediately without registering -a python function for future execution. +previously defined arguments and the return value is processed as +explained below. You can invoke the function as many times as you wish +in your input script. The *input* keyword defines how many arguments *N* the Python function -expects. If it takes no arguments, then the *input* keyword should -not be used. Each argument can be specified directly as a value, -e.g. 6 or 3.14159 or abc (a string of characters). The type of each +expects. If it takes no arguments, then the *input* keyword should not +be used. Each argument can be specified directly as a value, e.g. '6' +or '3.14159' or 'abc' (a string of characters). The type of each argument is specified by the *format* keyword as explained below, so that Python will know how to interpret the value. If the word SELF is used for an argument it has a special meaning. A pointer is passed to -the Python function which it converts into a reference to LAMMPS -itself. This enables the function to call back to LAMMPS through its -library interface as explained below. This allows the Python function -to query or set values internal to LAMMPS which can affect the -subsequent execution of the input script. A LAMMPS variable can also -be used as an argument, specified as v_name, where "name" is the name -of the variable. Any style of LAMMPS variable can be used, as defined -by the :doc:`variable ` command. Each time the Python -function is invoked, the LAMMPS variable is evaluated and its value is -passed to the Python function. +the Python function which it can convert into a reference to LAMMPS +itself using the :doc:`LAMMPS Python module `. This +enables the function to call back to LAMMPS through its library +interface as explained below. This allows the Python function to query +or set values internal to LAMMPS which can affect the subsequent +execution of the input script. A LAMMPS variable can also be used as an +argument, specified as v_name, where "name" is the name of the variable. +Any style of LAMMPS variable returning a scalar or a string can be used, +as defined by the :doc:`variable ` command. The *format* +keyword must be used to set the type of data that is passed to Python. +Each time the Python function is invoked, the LAMMPS variable is +evaluated and its value is passed to the Python function. The *return* keyword is only needed if the Python function returns a value. The specified *varReturn* must be of the form v_name, where @@ -153,8 +185,9 @@ numeric or string value, as specified by the *format* keyword. As explained on the :doc:`variable ` doc page, the definition of a python-style variable associates a Python function name with the -variable. This must match the *func* setting for this command. For -example these two commands would be self-consistent: +variable. This must match the *Python function name* first argument of +the *python* command. For example these two commands would be +consistent: .. code-block:: LAMMPS @@ -163,21 +196,22 @@ example these two commands would be self-consistent: The two commands can appear in either order in the input script so long as both are specified before the Python function is invoked for -the first time. +the first time. Afterwards, the variable 'foo' is associated with +the Python function 'myMultiply'. -The *format* keyword must be used if the *input* or *return* keyword -is used. It defines an *fstring* with M characters, where M = sum of +The *format* keyword must be used if the *input* or *return* keywords +are used. It defines an *fstring* with M characters, where M = sum of number of inputs and outputs. The order of characters corresponds to the N inputs, followed by the return value (if it exists). Each character must be one of the following: "i" for integer, "f" for -floating point, "s" for string, or "p" for SELF. Each character -defines the type of the corresponding input or output value of the -Python function and affects the type conversion that is performed -internally as data is passed back and forth between LAMMPS and Python. -Note that it is permissible to use a :doc:`python-style variable ` in a LAMMPS command that allows for an -equal-style variable as an argument, but only if the output of the -Python function is flagged as a numeric value ("i" or "f") via the -*format* keyword. +floating point, "s" for string, or "p" for SELF. Each character defines +the type of the corresponding input or output value of the Python +function and affects the type conversion that is performed internally as +data is passed back and forth between LAMMPS and Python. Note that it +is permissible to use a :doc:`python-style variable ` in a +LAMMPS command that allows for an equal-style variable as an argument, +but only if the output of the Python function is flagged as a numeric +value ("i" or "f") via the *format* keyword. If the *return* keyword is used and the *format* keyword specifies the output as a string, then the default maximum length of that string is @@ -192,12 +226,13 @@ truncated. Either the *file*, *here*, or *exists* keyword must be used, but only one of them. These keywords specify what Python code to load into the -Python interpreter. The *file* keyword gives the name of a file, -which should end with a ".py" suffix, which contains Python code. The -code will be immediately loaded into and run in the "main" module of -the Python interpreter. Note that Python code which contains a -function definition does not "execute" the function when it is run; it -simply defines the function so that it can be invoked later. +Python interpreter. The *file* keyword gives the name of a file +containing Python code, which should end with a ".py" suffix. The code +will be immediately loaded into and run in the "main" module of the +Python interpreter. The Python code will be executed in parallel on all +MPI processes. Note that Python code which contains a function +definition does not "execute" the function when it is run; it simply +defines the function so that it can be invoked later. The *here* keyword does the same thing, except that the Python code follows as a single argument to the *here* keyword. This can be done @@ -208,14 +243,15 @@ proper indentation, blank lines, and comments, as desired. See the how triple quotes can be used as part of input script syntax. The *exists* keyword takes no argument. It means that Python code -containing the required Python function defined by the *func* setting, -is assumed to have been previously loaded by another python command. +containing the required Python function with the given name has already +been executed, for example by a *python source* command or in the same +file that was used previously with the *file* keyword. -Note that the Python code that is loaded and run must contain a -function with the specified *func* name. To operate properly when -later invoked, the function code must match the *input* and -*return* and *format* keywords specified by the python command. -Otherwise Python will generate an error. +Note that the Python code that is loaded and run must contain a function +with the specified function name. To operate properly when later +invoked, the function code must match the *input* and *return* and +*format* keywords specified by the python command. Otherwise Python +will generate an error. ---------- @@ -225,19 +261,19 @@ LAMMPS. Whether you load Python code from a file or directly from your input script, via the *file* and *here* keywords, the code can be identical. It must be indented properly as Python requires. It can contain -comments or blank lines. If the code is in your input script, it -cannot however contain triple-quoted Python strings, since that will -conflict with the triple-quote parsing that the LAMMPS input script -performs. +comments or blank lines. If the code is in your input script, it cannot +however contain triple-quoted Python strings, since that will conflict +with the triple-quote parsing that the LAMMPS input script performs. All the Python code you specify via one or more python commands is -loaded into the Python "main" module, i.e. __main__. The code can -define global variables or statements that are outside of function -definitions. It can contain multiple functions, only one of which -matches the *func* setting in the python command. This means you can -use the *file* keyword once to load several functions, and the -*exists* keyword thereafter in subsequent python commands to access -the other functions previously loaded. +loaded into the Python "main" module, i.e. ``__name__ == '__main__'``. +The code can define global variables, define global functions, define +classes or execute statements that are outside of function definitions. +It can contain multiple functions, only one of which matches the *func* +setting in the python command. This means you can use the *file* +keyword once to load several functions, and the *exists* keyword +thereafter in subsequent python commands to register the other functions +that were previously loaded with LAMMPS. A Python function you define (or more generally, the code you load) can import other Python modules or classes, it can make calls to other @@ -264,12 +300,13 @@ outside the function: nvaluelast = nvalue return nvalue -Nsteplast stores the previous timestep the function was invoked -(passed as an argument to the function). Nvaluelast stores the return -value computed on the last function invocation. If the function is -invoked again on the same timestep, the previous value is simply -returned, without re-computing it. The "global" statement inside the -Python function allows it to overwrite the global variables. +The variable 'nsteplast' stores the previous timestep the function was +invoked (passed as an argument to the function). The variable +'nvaluelast' stores the return value computed on the last function +invocation. If the function is invoked again on the same timestep, the +previous value is simply returned, without re-computing it. The +"global" statement inside the Python function allows it to overwrite the +global variables from within the local context of the function. Note that if you load Python code multiple times (via multiple python commands), you can overwrite previously loaded variables and functions @@ -285,19 +322,39 @@ copy of the Python function(s) you define. There is no connection between the Python interpreters running on different processors. This implies three important things. -First, if you put a print statement in your Python function, you will -see P copies of the output, when running on P processors. If the -prints occur at (nearly) the same time, the P copies of the output may -be mixed together. Welcome to the world of parallel programming and -debugging. +First, if you put a print or other statement creating output to the +screen in your Python function, you will see P copies of the output, +when running on P processors. If the prints occur at (nearly) the same +time, the P copies of the output may be mixed together. When loading +the LAMMPS Python module into the embedded Python interpreter, it is +possible to pass the pointer to the current LAMMPS class instance and +via the Python interface to the LAMMPS library interface, it is possible +to determine the MPI rank of the current process and thus adapt the +Python code so that output will only appear on MPI rank 0. The +following LAMMPS input demonstrates how this could be done. The text +'Hello, LAMMPS!' should be printed only once, even when running LAMMPS +in parallel. -Second, if your Python code loads modules that are not pre-loaded by -the Python library, then it will load the module from disk. This may -be a bottleneck if 1000s of processors try to load a module at the -same time. On some large supercomputers, loading of modules from disk -by Python may be disabled. In this case you would need to pre-build a -Python library that has the required modules pre-loaded and link -LAMMPS with that library. +.. code-block:: LAMMPS + + python python_hello input 1 SELF format p here """ + def python_hello(handle): + from lammps import lammps + lmp = lammps(ptr=handle) + me = lmp.extract_setting('world_rank') + if me == 0: + print('Hello, LAMMPS!') + """ + + python python_hello invoke + +If your Python code loads Python modules that are not pre-loaded by the +Python library, then it will load the module from disk. This may be a +bottleneck if 1000s of processors try to load a module at the same time. +On some large supercomputers, loading of modules from disk by Python may +be disabled. In this case you would need to pre-build a Python library +that has the required modules pre-loaded and link LAMMPS with that +library. Third, if your Python code calls back to LAMMPS (discussed in the next section) and causes LAMMPS to perform an MPI operation requires @@ -315,22 +372,21 @@ Python function is as follows: .. code-block:: python - def foo(lmpptr,...): + def foo(handle,...): from lammps import lammps - lmp = lammps(ptr=lmpptr) + lmp = lammps(ptr=handle) lmp.command('print "Hello from inside Python"') ... -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 :doc:`"lammps" 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 -string argument which is a LAMMPS input script command for LAMMPS to -execute, the same as if it appeared in your input script. In this case, -LAMMPS should output +The function definition must include a variable ('handle' in this case) +which corresponds to SELF in the *python* command. The first line of +the function imports the :doc:`"lammps" Python module `. +The second line creates a Python object ``lmp`` which wraps the instance +of LAMMPS that called the function. The 'ptr=handle' argument is what +makes that happen. The third line invokes the command() function in the +LAMMPS library interface. It takes a single string argument which is a +LAMMPS input script command for LAMMPS to execute, the same as if it +appeared in your input script. In this case, LAMMPS should output .. parsed-literal:: @@ -344,8 +400,8 @@ The :doc:`Python_head` page describes the syntax for how Python wraps the various functions included in the LAMMPS library interface. -A more interesting example is in the examples/python/in.python script -which loads and runs the following function from examples/python/funcs.py: +A more interesting example is in the ``examples/python/in.python`` script +which loads and runs the following function from ``examples/python/funcs.py``: .. code-block:: python @@ -495,24 +551,35 @@ Restrictions """""""""""" This command is part of the PYTHON package. It is only enabled if -LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +LAMMPS was built with that package. See the :doc:`Build package +` page for more info. -Building LAMMPS with the PYTHON package will link LAMMPS with the -Python library on your system. Settings to enable this are in the +Building LAMMPS with the PYTHON package will link LAMMPS with the 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 :doc:`"lammps" 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 -` 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 +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 +` 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 ` 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. +Another limitation of calling back to Python from the LAMMPS module +using the *python* command in a LAMMPS input is that both, the Python +interpreter and LAMMPS, must be linked to the same Python runtime as a +shared library. If the Python interpreter is linked to Python +statically (which seems to happen with Conda) then loading the shared +LAMMPS library will create a second python "main" module that hides the +one from the Python interpreter and all previous defined function and +global variables will become invisible. + Related commands """""""""""""""" diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 961b92c83e..453208ed3f 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -340,16 +340,20 @@ and are called "tilt factors" because they are the amount of displacement applied to faces of an originally orthogonal box to transform it into the parallelepiped. -By default, the tilt factors (xy,xz,yz) can not skew the box more than -half the distance of the corresponding parallel box length. For -example, if xlo = 2 and xhi = 12, then the x box length is 10 and the -xy tilt factor must be between -5 and 5. Similarly, both xz and yz -must be between -(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not -a limitation, since if the maximum tilt factor is 5 (as in this -example), then configurations with tilt = ..., -15, -5, 5, 15, 25, -... are all geometrically equivalent. If you wish to define a box -with tilt factors that exceed these limits, you can use the :doc:`box tilt ` command, with a setting of *large*\ ; a setting of -*small* is the default. +The tilt factors (xy,xz,yz) should not skew the box more than half the +distance of the corresponding parallel box length. For example, if +:math:`x_\text{lo} = 2` and :math:`x_\text{hi} = 12`, then the :math:`x` +box length is 10 and the :math:`xy` tilt factor must be between +:math:`-5` and :math:`5`. Similarly, both :math:`xz` and :math:`yz` +must be between :math:`-(x_\text{hi}-x_\text{lo})/2` and +:math:`+(y_\text{hi}-y_\text{lo})/2`. Note that this is not a +limitation, since if the maximum tilt factor is 5 (as in this example), +then configurations with tilt :math:`= \dots, -15`, :math:`-5`, +:math:`5`, :math:`15`, :math:`25, \dots` are all geometrically +equivalent. Simulations with large tilt factors will run inefficiently, +since they require more ghost atoms and thus more communication. With +very large tilt factors, LAMMPS will eventually produce incorrect +trajectories and stop with errors due to lost atoms or similar. See the :doc:`Howto triclinic ` page for a geometric description of triclinic boxes, as defined by LAMMPS, and diff --git a/doc/src/reset_atom_ids.rst b/doc/src/reset_atom_ids.rst deleted file mode 100644 index e83d65d546..0000000000 --- a/doc/src/reset_atom_ids.rst +++ /dev/null @@ -1,94 +0,0 @@ -.. index:: reset_atom_ids - -reset_atom_ids command -====================== - -Syntax -"""""" - -.. code-block:: LAMMPS - - reset_atom_ids keyword values ... - - * zero or more keyword/value pairs may be appended - * keyword = *sort* - -.. parsed-literal:: - - *sort* value = *yes* or *no* - -Examples -"""""""" - -.. code-block:: LAMMPS - - reset_atom_ids - reset_atom_ids sort yes - -Description -""""""""""" - -Reset atom IDs for the system, including all the global IDs stored -for bond, angle, dihedral, improper topology data. This will -create a set of IDs that are numbered contiguously from 1 to N -for a N atoms system. - -This can be useful to do after performing a "delete_atoms" command for -a molecular system. The delete_atoms compress yes option will not -perform this operation due to the existence of bond topology. It can -also be useful to do after any simulation which has lost atoms, -e.g. due to atoms moving outside a simulation box with fixed -boundaries (see the "boundary command"), or due to evaporation (see -the "fix evaporate" command). - -If the *sort* keyword is used with a setting of *yes*, then the -assignment of new atom IDs will be the same no matter how many -processors LAMMPS is running on. This is done by first doing a -spatial sort of all the atoms into bins and sorting them within each -bin. Because the set of bins is independent of the number of -processors, this enables a consistent assignment of new IDs to each -atom. - -This can be useful to do after using the "create_atoms" command and/or -"replicate" command. In general those commands do not guarantee -assignment of the same atom ID to the same physical atom when LAMMPS -is run on different numbers of processors. Enforcing consistent IDs -can be useful for debugging or comparing output from two different -runs. - -Note that the spatial sort requires communication of atom IDs and -coordinates between processors in an all-to-all manner. This is done -efficiently in LAMMPS, but it is more expensive than how atom IDs are -reset without sorting. - -Note that whether sorting or not, the resetting of IDs is not a -compression, where gaps in atom IDs are removed by decrementing atom -IDs that are larger. Instead the IDs for all atoms are erased, and -new IDs are assigned so that the atoms owned by an individual -processor have consecutive IDs, as the :doc:`create_atoms -` command explains. - -.. note:: - - If this command is used before a :doc:`pair style ` is - defined, an error about bond topology atom IDs not being found may - result. This is because the cutoff distance for ghost atom - communication was not sufficient to find atoms in bonds, angles, etc - that are owned by other processors. The :doc:`comm_modify cutoff ` command can be used to correct this issue. - Or you can define a pair style before using this command. If you do - the former, you should unset the comm_modify cutoff after using - reset_atom_ids so that subsequent communication is not inefficient. - -Restrictions -"""""""""""" -none - -Related commands -"""""""""""""""" - -:doc:`delete_atoms ` - -Default -""""""" - -By default, *sort* is no. diff --git a/doc/src/reset_atoms.rst b/doc/src/reset_atoms.rst new file mode 100644 index 0000000000..8643eaf725 --- /dev/null +++ b/doc/src/reset_atoms.rst @@ -0,0 +1,283 @@ +.. index:: reset_atoms + +reset_atoms command +=================== + +Syntax +"""""" + +.. code-block:: LAMMPS + + reset_atoms property arguments ... + +* property = *id* or *image* or *mol* +* additional arguments depend on the property + + .. code-block:: LAMMPS + + reset_atoms id keyword value ... + + * zero or more keyword/value pairs can be appended + * keyword = *sort* + + .. parsed-literal:: + + *sort* value = *yes* or *no* + + .. code-block:: LAMMPS + + reset_atoms image group-ID + + * group-ID = ID of group of atoms whose image flags will be reset + + .. code-block:: LAMMPS + + reset atoms mol group-ID keyword value ... + + * group-ID = ID of group of atoms whose molecule IDs will be reset + * zero or more keyword/value pairs can be appended + * keyword = *compress* or *offset* or *single* + + .. parsed-literal:: + + *compress* value = *yes* or *no* + *offset* value = *Noffset* >= -1 + *single* value = *yes* or *no* to treat single atoms (no bonds) as molecules + + +Examples +"""""""" + +.. code-block:: LAMMPS + + reset_atoms id + reset_atoms id sort yes + reset_atoms image all + reset_atoms image mobile + reset_atoms mol all + reset_atoms mol all offset 10 single yes + reset_atoms mol solvent compress yes offset 100 + reset_atoms mol solvent compress no + + +Description +""""""""""" + +.. versionadded:: TBD + +The *reset_atoms* command resets the values of a specified atom +property. In contrast to the set command, it does this in a +collective manner which resets the values for many atoms in a +self-consistent way. This is often useful when the simulated system +has undergone significant modifications like adding or removing atoms +or molecules, joining data files, changing bonds, or large-scale +diffusion. + +The new values can be thought of as a *reset*, similar to values atoms +would have if a new data file were being read or a new simulation +performed. Note that the set command also resets atom properties to +new values, but it treats each atom independently. + +The *property* setting can be *id* or *image* or *mol*. For *id*, the +IDs of all the atoms are reset to contiguous values. For *image*, the +image flags of atoms in the specified *group-ID* are reset so that at +least one atom in each molecule is in the simulation box (image flag = +0). For *mol*, the molecule IDs of all atoms are reset to contiguous +values. + +More details on these operations and their arguments or optional +keyword/value settings are given below. + +---------- + +*Property id* + +Reset atom IDs for the entire system, including all the global IDs +stored for bond, angle, dihedral, improper topology data. This will +create a set of IDs that are numbered contiguously from 1 to N for a N +atoms system. + +This can be useful to do after performing a "delete_atoms" command for +a molecular system. The delete_atoms compress yes option will not +perform this operation due to the existence of bond topology. It can +also be useful to do after any simulation which has lost atoms, +e.g. due to atoms moving outside a simulation box with fixed +boundaries (see the "boundary command"), or due to evaporation (see +the "fix evaporate" command). + +If the *sort* keyword is used with a setting of *yes*, then the +assignment of new atom IDs will be the same no matter how many +processors LAMMPS is running on. This is done by first doing a +spatial sort of all the atoms into bins and sorting them within each +bin. Because the set of bins is independent of the number of +processors, this enables a consistent assignment of new IDs to each +atom. + +This can be useful to do after using the "create_atoms" command and/or +"replicate" command. In general those commands do not guarantee +assignment of the same atom ID to the same physical atom when LAMMPS +is run on different numbers of processors. Enforcing consistent IDs +can be useful for debugging or comparing output from two different +runs. + +Note that the spatial sort requires communication of atom IDs and +coordinates between processors in an all-to-all manner. This is done +efficiently in LAMMPS, but it is more expensive than how atom IDs are +reset without sorting. + +Note that whether sorting or not, the resetting of IDs is not a +compression, where gaps in atom IDs are removed by decrementing atom +IDs that are larger. Instead the IDs for all atoms are erased, and +new IDs are assigned so that the atoms owned by an individual +processor have consecutive IDs, as the :doc:`create_atoms +` command explains. + +.. note:: + + If this command is used before a :doc:`pair style ` is + defined, an error about bond topology atom IDs not being found may + result. This is because the cutoff distance for ghost atom + communication was not sufficient to find atoms in bonds, angles, etc + that are owned by other processors. The :doc:`comm_modify cutoff + ` command can be used to correct this issue. Or you can + define a pair style before using this command. If you do the former, + you should unset the *comm_modify cutoff* after using *reset + atoms id* so that subsequent communication is not inefficient. + +---------- + +*Property image* + +Reset the image flags of atoms so that at least one atom in each +molecule has an image flag of 0. Molecular topology is respected so +that if the molecule straddles a periodic simulation box boundary, the +images flags of all atoms in the molecule will be consistent. This +avoids inconsistent image flags that could result from resetting all +image flags to zero with the :doc:`set ` command. + +.. note:: + + If the system has no bonds, there is no reason to use this command, + since image flags for different atoms do not need to be + consistent. Use the :doc:`set ` command with its *image* + keyword instead. + +Only image flags for atoms in the specified *group-ID* are reset; all +others remain unchanged. No check is made for whether the group +covers complete molecule fragments and thus whether the command will +result in inconsistent image flags. + +Molecular fragments are identified by the algorithm used by the +:doc:`compute fragment/atom ` command. For each +fragment the average of the largest and the smallest image flag in +each direction across all atoms in the fragment is computed and +subtracted from the current image flag in the same direction. + +This can be a useful operation to perform after running longer +equilibration runs of mobile systems where molecules would pass +through the system multiple times and thus produce non-zero image +flags. + +.. note:: + + Same as explained for the :doc:`compute fragment/atom + ` command, molecules are identified using the + current bond topology. This will **not** account for bonds broken by + the :doc:`bond_style quartic ` command, because this + bond style does not perform a full update of the bond topology data + structures within LAMMPS. In that case, using the :doc:`delete_bonds + all bond 0 remove ` will permanently delete such + broken bonds and should thus be used first. + +---------- + +*Property mol* + +Reset molecule IDs for a specified group of atoms based on current +bond connectivity. This will typically create a new set of molecule +IDs for atoms in the group. Only molecule IDs for atoms in the +specified *group-ID* are reset; molecule IDs for atoms not in the +group are not changed. + +For purposes of this operation, molecules are identified by the current +bond connectivity in the system, which may or may not be consistent with +the current molecule IDs. A molecule in this context is a set of atoms +connected to each other with explicit bonds. The specific algorithm +used is the one of :doc:`compute fragment/atom ` +Once the molecules are identified and a new molecule ID computed for +each, this command will update the current molecule ID for all atoms in +the group with the new molecule ID. Note that if the group excludes +atoms within molecules, one (physical) molecule may become two or more +(logical) molecules. For example if the group excludes atoms in the +middle of a linear chain, then each end of the chain is considered an +independent molecule and will be assigned a different molecule ID. + +This can be a useful operation to perform after running reactive +molecular dynamics run with :doc:`fix bond/react `, +:doc:`fix bond/create `, or :doc:`fix bond/break +`, all of which can change molecule topologies. It can +also be useful after molecules have been deleted with the +:doc:`delete_atoms ` command or after a simulation which +has lost molecules, e.g. via the :doc:`fix evaporate ` +command. + +The *compress* keyword determines how new molecule IDs are computed. If +the setting is *yes* (the default) and there are N molecules in the +group, the new molecule IDs will be a set of N contiguous values. See +the *offset* keyword for details on selecting the range of these values. +If the setting is *no*, the molecule ID of every atom in the molecule +will be set to the smallest atom ID of any atom in the molecule. + +The *single* keyword determines whether single atoms (not bonded to +another atom) are treated as one-atom molecules or not, based on the +*yes* or *no* setting. If the setting is *no* (the default), their +molecule IDs are set to 0. This setting can be important if the new +molecule IDs will be used as input to other commands such as +:doc:`compute chunk/atom molecule ` or :doc:`fix +rigid molecule `. + +The *offset* keyword is only used if the *compress* setting is *yes*. +Its default value is *Noffset* = -1. In that case, if the specified +group is *all*, then the new compressed molecule IDs will range from 1 +to N. If the specified group is not *all* and the largest molecule ID +of atoms outside that group is M, then the new compressed molecule IDs will +range from M+1 to M+N, to avoid collision with existing molecule +IDs. If an *Noffset* >= 0 is specified, then the new compressed +molecule IDs will range from *Noffset*\ +1 to *Noffset*\ +N. If the group +is not *all* there may be collisions with the molecule IDs of other atoms. + +.. note:: + + Same as explained for the :doc:`compute fragment/atom + ` command, molecules are identified using the + current bond topology. This will **not** account for bonds broken by + the :doc:`bond_style quartic ` command, because this + bond style does not perform a full update of the bond topology data + structures within LAMMPS. In that case, using the :doc:`delete_bonds + all bond 0 remove ` will permanently delete such broken + bonds and should thus be used first. + + +Restrictions +"""""""""""" + +The *image* property can only be used when the atom style supports bonds. + +Related commands +"""""""""""""""" + +:doc:`compute fragment/atom ` +:doc:`fix bond/react `, +:doc:`fix bond/create `, +:doc:`fix bond/break `, +:doc:`fix evaporate `, +:doc:`delete_atoms `, +:doc:`delete_bonds ` + +Defaults +"""""""" + +For property *id*, the default keyword setting is sort = no. + +For property *mol*, the default keyword settings are compress = yes, +single = no, and offset = -1. diff --git a/doc/src/reset_mol_ids.rst b/doc/src/reset_mol_ids.rst deleted file mode 100644 index 0d6063b3ef..0000000000 --- a/doc/src/reset_mol_ids.rst +++ /dev/null @@ -1,116 +0,0 @@ -.. index:: reset_mol_ids - -reset_mol_ids command -===================== - -Syntax -"""""" - -.. parsed-literal:: - - reset_mol_ids group-ID keyword value ... - -* group-ID = ID of group of atoms whose molecule IDs will be reset -* zero or more keyword/value pairs may be appended -* keyword = *compress* or *offset* or *single* - - .. parsed-literal:: - - *compress* value = *yes* or *no* - *offset* value = *Noffset* >= -1 - *single* value = *yes* or *no* to treat single atoms (no bonds) as molecules - -Examples -"""""""" - -.. code-block:: LAMMPS - - reset_mol_ids all - reset_mol_ids all offset 10 single yes - reset_mol_ids solvent compress yes offset 100 - reset_mol_ids solvent compress no - -Description -""""""""""" - -Reset molecule IDs for a group of atoms based on current bond -connectivity. This will typically create a new set of molecule IDs -for atoms in the group. Only molecule IDs for atoms in the specified -group are reset; molecule IDs for atoms not in the group are not -changed. - -For purposes of this operation, molecules are identified by the current -bond connectivity in the system, which may or may not be consistent with -the current molecule IDs. A molecule in this context is a set of atoms -connected to each other with explicit bonds. The specific algorithm -used is the one of :doc:`compute fragment/atom ` -Once the molecules are identified and a new molecule ID computed for -each, this command will update the current molecule ID for all atoms in -the group with the new molecule ID. Note that if the group excludes -atoms within molecules, one (physical) molecule may become two or more -(logical) molecules. For example if the group excludes atoms in the -middle of a linear chain, then each end of the chain is considered an -independent molecule and will be assigned a different molecule ID. - -This can be a useful operation to perform after running reactive -molecular dynamics run with :doc:`fix bond/react `, -:doc:`fix bond/create `, or :doc:`fix bond/break -`, all of which can change molecule topologies. It can -also be useful after molecules have been deleted with the -:doc:`delete_atoms ` command or after a simulation which -has lost molecules, e.g. via the :doc:`fix evaporate ` -command. - -The *compress* keyword determines how new molecule IDs are computed. If -the setting is *yes* (the default) and there are N molecules in the -group, the new molecule IDs will be a set of N contiguous values. See -the *offset* keyword for details on selecting the range of these values. -If the setting is *no*, the molecule ID of every atom in the molecule -will be set to the smallest atom ID of any atom in the molecule. - -The *single* keyword determines whether single atoms (not bonded to -another atom) are treated as one-atom molecules or not, based on the -*yes* or *no* setting. If the setting is *no* (the default), their -molecule IDs are set to 0. This setting can be important if the new -molecule IDs will be used as input to other commands such as -:doc:`compute chunk/atom molecule ` or :doc:`fix -rigid molecule `. - -The *offset* keyword is only used if the *compress* setting is *yes*. -Its default value is *Noffset* = -1. In that case, if the specified -group is *all*, then the new compressed molecule IDs will range from 1 -to N. If the specified group is not *all* and the largest molecule ID -of atoms outside that group is M, then the new compressed molecule IDs will -range from M+1 to M+N, to avoid collision with existing molecule -IDs. If an *Noffset* >= 0 is specified, then the new compressed -molecule IDs will range from *Noffset*\ +1 to *Noffset*\ +N. If the group -is not *all* there may be collisions with the molecule IDs of other atoms. - -.. note:: - - The same as explained for the :doc:`compute fragment/atom - ` command, molecules are identified using the - current bond topology. This will not account for bonds broken by - the :doc:`bond_style quartic ` command because it - does not perform a full update of the bond topology data structures - within LAMMPS. - -Restrictions -"""""""""""" -none - -Related commands -"""""""""""""""" - -:doc:`reset_atom_ids `, :doc:`fix bond/react `, -:doc:`fix bond/create `, -:doc:`fix bond/break `, -:doc:`fix evaporate `, -:doc:`delete_atoms `, -:doc:`compute fragment/atom ` - -Default -""""""" - -The default keyword settings are compress = yes, single = no, and -offset = -1. diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 61c1d45ba7..9e8fb042a0 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2248,6 +2248,7 @@ MxN myCompute myIndex mylammps +myMultiply MyPool mysocket mySpin @@ -2359,6 +2360,7 @@ Ng nghost Nghost Ngpu +ngpus Ngyuen nh nharmonic @@ -2384,6 +2386,7 @@ nktv nl nlayers nlen +Nlimit nlines Nlines nlo @@ -2473,7 +2476,8 @@ nsq Nstart nstats Nstep -Nsteplast +Nsteps +nsteplast Nstop nsub Nsw @@ -2503,7 +2507,7 @@ numpy Numpy Nurdin Nvalue -Nvaluelast +nvaluelast Nvalues nvc nvcc @@ -3090,6 +3094,7 @@ Rutuparna rx rxd rxnave +rxnbond rxnsum ry Ryckaert diff --git a/examples/PACKAGES/fep/CC-CO/fep01/data.0.lmp b/examples/PACKAGES/fep/CC-CO/fep01/data.0.lmp new file mode 120000 index 0000000000..5c33e53300 --- /dev/null +++ b/examples/PACKAGES/fep/CC-CO/fep01/data.0.lmp @@ -0,0 +1 @@ +../mols/data.0.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CC-CO/fep10/data.1.lmp b/examples/PACKAGES/fep/CC-CO/fep10/data.1.lmp new file mode 120000 index 0000000000..4222a38b76 --- /dev/null +++ b/examples/PACKAGES/fep/CC-CO/fep10/data.1.lmp @@ -0,0 +1 @@ +../mols/data.1.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4-CF4/bar01/data.0.lmp b/examples/PACKAGES/fep/CH4-CF4/bar01/data.0.lmp new file mode 120000 index 0000000000..5c33e53300 --- /dev/null +++ b/examples/PACKAGES/fep/CH4-CF4/bar01/data.0.lmp @@ -0,0 +1 @@ +../mols/data.0.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4-CF4/bar10/data.1.lmp b/examples/PACKAGES/fep/CH4-CF4/bar10/data.1.lmp new file mode 120000 index 0000000000..4222a38b76 --- /dev/null +++ b/examples/PACKAGES/fep/CH4-CF4/bar10/data.1.lmp @@ -0,0 +1 @@ +../mols/data.1.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4-CF4/fep01/data.0.lmp b/examples/PACKAGES/fep/CH4-CF4/fep01/data.0.lmp new file mode 120000 index 0000000000..5c33e53300 --- /dev/null +++ b/examples/PACKAGES/fep/CH4-CF4/fep01/data.0.lmp @@ -0,0 +1 @@ +../mols/data.0.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4-CF4/fep10/data.1.lmp b/examples/PACKAGES/fep/CH4-CF4/fep10/data.1.lmp new file mode 120000 index 0000000000..4222a38b76 --- /dev/null +++ b/examples/PACKAGES/fep/CH4-CF4/fep10/data.1.lmp @@ -0,0 +1 @@ +../mols/data.1.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4hyd/fdti01/data.lmp b/examples/PACKAGES/fep/CH4hyd/fdti01/data.lmp new file mode 120000 index 0000000000..73cccaf269 --- /dev/null +++ b/examples/PACKAGES/fep/CH4hyd/fdti01/data.lmp @@ -0,0 +1 @@ +../mols/data.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4hyd/fdti10/data.lmp b/examples/PACKAGES/fep/CH4hyd/fdti10/data.lmp new file mode 120000 index 0000000000..73cccaf269 --- /dev/null +++ b/examples/PACKAGES/fep/CH4hyd/fdti10/data.lmp @@ -0,0 +1 @@ +../mols/data.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4hyd/fep01/data.lmp b/examples/PACKAGES/fep/CH4hyd/fep01/data.lmp new file mode 120000 index 0000000000..73cccaf269 --- /dev/null +++ b/examples/PACKAGES/fep/CH4hyd/fep01/data.lmp @@ -0,0 +1 @@ +../mols/data.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/CH4hyd/fep10/data.lmp b/examples/PACKAGES/fep/CH4hyd/fep10/data.lmp new file mode 120000 index 0000000000..73cccaf269 --- /dev/null +++ b/examples/PACKAGES/fep/CH4hyd/fep10/data.lmp @@ -0,0 +1 @@ +../mols/data.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/SPCEhyd/fep01/data.lmp b/examples/PACKAGES/fep/SPCEhyd/fep01/data.lmp new file mode 120000 index 0000000000..73cccaf269 --- /dev/null +++ b/examples/PACKAGES/fep/SPCEhyd/fep01/data.lmp @@ -0,0 +1 @@ +../mols/data.lmp \ No newline at end of file diff --git a/examples/PACKAGES/fep/SPCEhyd/fep10/data.lmp b/examples/PACKAGES/fep/SPCEhyd/fep10/data.lmp new file mode 120000 index 0000000000..73cccaf269 --- /dev/null +++ b/examples/PACKAGES/fep/SPCEhyd/fep10/data.lmp @@ -0,0 +1 @@ +../mols/data.lmp \ No newline at end of file diff --git a/examples/PACKAGES/pace/plugin/CMakeLists.txt b/examples/PACKAGES/pace/plugin/CMakeLists.txt index 6ad9c791ba..25fa877ffc 100644 --- a/examples/PACKAGES/pace/plugin/CMakeLists.txt +++ b/examples/PACKAGES/pace/plugin/CMakeLists.txt @@ -38,9 +38,15 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/lammps.ico ${CMAKE_SOURCE_DIR}/lammps-text-logo-wide.bmp ${CMAKE_SOURCE_DIR}/paceplugin.nsis ${CMAKE_BINARY_DIR}) if(BUILD_MPI) - add_custom_target(package ${MAKENSIS_PATH} -V1 -DVERSION=${LAMMPS_VERSION}-MPI paceplugin.nsis - DEPENDS paceplugin - BYPRODUCTS LAMMPS-ML-PACE-plugin-${LAMMPS_VERSION}-MPI.exe) + if(USE_MSMPI) + add_custom_target(package ${MAKENSIS_PATH} -V1 -DVERSION=${LAMMPS_VERSION}-MSMPI paceplugin.nsis + DEPENDS paceplugin + BYPRODUCTS LAMMPS-ML-PACE-plugin-${LAMMPS_VERSION}-MSMPI.exe) + else() + add_custom_target(package ${MAKENSIS_PATH} -V1 -DVERSION=${LAMMPS_VERSION}-MPI paceplugin.nsis + DEPENDS paceplugin + BYPRODUCTS LAMMPS-ML-PACE-plugin-${LAMMPS_VERSION}-MPI.exe) + endif() else() add_custom_target(package ${MAKENSIS_PATH} -V1 -DVERSION=${LAMMPS_VERSION} paceplugin.nsis COMMAND ${CMAKE_COMMAND} -E echo ${PWD} diff --git a/examples/PACKAGES/sph/shock_tube/shock2d.lmp b/examples/PACKAGES/sph/shock_tube/shock2d.lmp index 32cfd8067b..c63b537bc7 100644 --- a/examples/PACKAGES/sph/shock_tube/shock2d.lmp +++ b/examples/PACKAGES/sph/shock_tube/shock2d.lmp @@ -22,7 +22,7 @@ pair_style hybrid/overlay sph/rhosum 1 sph/idealgas pair_coeff * * sph/rhosum 4.0 pair_coeff * * sph/idealgas 0.75 4.0 -compute rhoatom all shp/rho/atom +compute rhoatom all sph/rho/atom compute ieatom all sph/e/atom compute esph all reduce sum c_ieatom # total internal energy compute ke all ke diff --git a/examples/plugins/LAMMPSInterfaceCXX.cmake b/examples/plugins/LAMMPSInterfaceCXX.cmake index a3313215d6..7eef5bd6e4 100644 --- a/examples/plugins/LAMMPSInterfaceCXX.cmake +++ b/examples/plugins/LAMMPSInterfaceCXX.cmake @@ -45,45 +45,80 @@ if(BUILD_MPI) set(MPI_CXX_SKIP_MPICXX TRUE) # We use a non-standard procedure to cross-compile with MPI on Windows if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING) - # Download and configure custom MPICH files for Windows - message(STATUS "Downloading and configuring MPICH-1.4.1 for Windows") - set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") - set(MPICH2_WIN32_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win32-devel.tar.gz" CACHE STRING "URL for MPICH2 (win32) tarball") - set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") - set(MPICH2_WIN32_DEVEL_MD5 "a61d153500dce44e21b755ee7257e031" CACHE STRING "MD5 checksum of MPICH2 (win32) tarball") - mark_as_advanced(MPICH2_WIN64_DEVEL_URL) - mark_as_advanced(MPICH2_WIN32_DEVEL_URL) - mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) - mark_as_advanced(MPICH2_WIN32_DEVEL_MD5) + # Download and configure MinGW compatible MPICH development files for Windows + option(USE_MSMPI "Use Microsoft's MS-MPI SDK instead of MPICH2-1.4.1" OFF) + if(USE_MSMPI) + message(STATUS "Downloading and configuring MS-MPI 10.1 for Windows cross-compilation") + set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/msmpi-win64-devel.tar.gz" CACHE STRING "URL for MS-MPI (win64) tarball") + set(MPICH2_WIN64_DEVEL_MD5 "86314daf1bffb809f1fcbefb8a547490" CACHE STRING "MD5 checksum of MS-MPI (win64) tarball") + mark_as_advanced(MPICH2_WIN64_DEVEL_URL) + mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) - include(ExternalProject) - if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - ExternalProject_Add(mpi4win_build - URL ${MPICH2_WIN64_DEVEL_URL} - URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} - CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" - BUILD_BYPRODUCTS /lib/libmpi.a) + include(ExternalProject) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmsmpi.a) + else() + message(FATAL_ERROR "Only x86 64-bit builds are supported with MS-MPI") + endif() + + ExternalProject_get_property(mpi4win_build SOURCE_DIR) + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + add_library(MPI::MPI_CXX UNKNOWN IMPORTED) + set_target_properties(MPI::MPI_CXX PROPERTIES + IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmsmpi.a" + INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" + INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + add_dependencies(MPI::MPI_CXX mpi4win_build) + + # set variables for status reporting at the end of CMake run + set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") + set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmsmpi.a") else() - ExternalProject_Add(mpi4win_build - URL ${MPICH2_WIN32_DEVEL_URL} - URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} - CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" - BUILD_BYPRODUCTS /lib/libmpi.a) + # Download and configure custom MPICH files for Windows + message(STATUS "Downloading and configuring MPICH-1.4.1 for Windows") + set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") + set(MPICH2_WIN32_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win32-devel.tar.gz" CACHE STRING "URL for MPICH2 (win32) tarball") + set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") + set(MPICH2_WIN32_DEVEL_MD5 "a61d153500dce44e21b755ee7257e031" CACHE STRING "MD5 checksum of MPICH2 (win32) tarball") + mark_as_advanced(MPICH2_WIN64_DEVEL_URL) + mark_as_advanced(MPICH2_WIN32_DEVEL_URL) + mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) + mark_as_advanced(MPICH2_WIN32_DEVEL_MD5) + + include(ExternalProject) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmpi.a) + else() + ExternalProject_Add(mpi4win_build + URL ${MPICH2_WIN32_DEVEL_URL} + URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" + BUILD_BYPRODUCTS /lib/libmpi.a) + endif() + + ExternalProject_get_property(mpi4win_build SOURCE_DIR) + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + add_library(MPI::MPI_CXX UNKNOWN IMPORTED) + set_target_properties(MPI::MPI_CXX PROPERTIES + IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmpi.a" + INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" + INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + add_dependencies(MPI::MPI_CXX mpi4win_build) + + # set variables for status reporting at the end of CMake run + set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") + set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") + set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmpi.a") endif() - - ExternalProject_get_property(mpi4win_build SOURCE_DIR) - file(MAKE_DIRECTORY "${SOURCE_DIR}/include") - add_library(MPI::MPI_CXX UNKNOWN IMPORTED) - set_target_properties(MPI::MPI_CXX PROPERTIES - IMPORTED_LOCATION "${SOURCE_DIR}/lib/libmpi.a" - INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include" - INTERFACE_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") - add_dependencies(MPI::MPI_CXX mpi4win_build) - - # set variables for status reporting at the end of CMake run - set(MPI_CXX_INCLUDE_PATH "${SOURCE_DIR}/include") - set(MPI_CXX_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX") - set(MPI_CXX_LIBRARIES "${SOURCE_DIR}/lib/libmpi.a") else() find_package(MPI REQUIRED) option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize 'long long' data types" OFF) diff --git a/lib/linalg/README b/lib/linalg/README index de2d83dcbd..e3b817cacc 100644 --- a/lib/linalg/README +++ b/lib/linalg/README @@ -1,13 +1,16 @@ -This directory has BLAS and LAPACK files needed by the ATC and -AWPMD packages, and possibly by other packages in the future. +This directory has generic BLAS and LAPACK source files needed by the +ATC, AWPMD, ELECTRODE, LATTE, and ML-POD packages (and possibly by other +packages) in the future that can be used instead of platform or vendor +optimized BLAS/LAPACK library. Note that this is an *incomplete* subset of full BLAS/LAPACK. +The files correspond to LAPACK version 3.11.0. + You should only need to build and use the library in this directory if -you want to build LAMMPS with the ATC and/or AWPMD packages -AND you do not have any other suitable BLAS and LAPACK libraries -installed on your system. E.g. ATLAS, GOTO-BLAS, OpenBLAS, ACML, or -MKL. +you want to build LAMMPS with one of the listed packages AND you do not +have any other suitable BLAS and LAPACK libraries installed on your +system (like ATLAS, GOTO-BLAS, OpenBLAS, ACML, MKL and so on). You can type "make lib-linalg" from the src directory to see help on how to build this library via make commands, or you can do the same @@ -27,3 +30,4 @@ liblinalg.a the library LAMMPS will link against You can then include this library and its path in the Makefile.lammps file of any packages that need it. As an example, see the lib/atc/Makefile.lammps.linalg file. + diff --git a/lib/linalg/dgelss.f b/lib/linalg/dgelss.f index 8ed703fcf2..c4190f2e09 100644 --- a/lib/linalg/dgelss.f +++ b/lib/linalg/dgelss.f @@ -254,11 +254,11 @@ * * Compute space needed for DGEQRF CALL DGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, INFO ) - LWORK_DGEQRF=DUM(1) + LWORK_DGEQRF = INT( DUM(1) ) * Compute space needed for DORMQR CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, DUM(1), B, $ LDB, DUM(1), -1, INFO ) - LWORK_DORMQR=DUM(1) + LWORK_DORMQR = INT( DUM(1) ) MM = N MAXWRK = MAX( MAXWRK, N + LWORK_DGEQRF ) MAXWRK = MAX( MAXWRK, N + LWORK_DORMQR ) @@ -273,15 +273,15 @@ * Compute space needed for DGEBRD CALL DGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1), $ DUM(1), DUM(1), -1, INFO ) - LWORK_DGEBRD=DUM(1) + LWORK_DGEBRD = INT( DUM(1) ) * Compute space needed for DORMBR CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, DUM(1), $ B, LDB, DUM(1), -1, INFO ) - LWORK_DORMBR=DUM(1) + LWORK_DORMBR = INT( DUM(1) ) * Compute space needed for DORGBR CALL DORGBR( 'P', N, N, N, A, LDA, DUM(1), $ DUM(1), -1, INFO ) - LWORK_DORGBR=DUM(1) + LWORK_DORGBR = INT( DUM(1) ) * Compute total workspace needed MAXWRK = MAX( MAXWRK, 3*N + LWORK_DGEBRD ) MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORMBR ) @@ -305,23 +305,23 @@ * Compute space needed for DGELQF CALL DGELQF( M, N, A, LDA, DUM(1), DUM(1), $ -1, INFO ) - LWORK_DGELQF=DUM(1) + LWORK_DGELQF = INT( DUM(1) ) * Compute space needed for DGEBRD CALL DGEBRD( M, M, A, LDA, S, DUM(1), DUM(1), $ DUM(1), DUM(1), -1, INFO ) - LWORK_DGEBRD=DUM(1) + LWORK_DGEBRD = INT( DUM(1) ) * Compute space needed for DORMBR CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, $ DUM(1), B, LDB, DUM(1), -1, INFO ) - LWORK_DORMBR=DUM(1) + LWORK_DORMBR = INT( DUM(1) ) * Compute space needed for DORGBR CALL DORGBR( 'P', M, M, M, A, LDA, DUM(1), $ DUM(1), -1, INFO ) - LWORK_DORGBR=DUM(1) + LWORK_DORGBR = INT( DUM(1) ) * Compute space needed for DORMLQ CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, DUM(1), $ B, LDB, DUM(1), -1, INFO ) - LWORK_DORMLQ=DUM(1) + LWORK_DORMLQ = INT( DUM(1) ) * Compute total workspace needed MAXWRK = M + LWORK_DGELQF MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DGEBRD ) @@ -341,15 +341,15 @@ * Compute space needed for DGEBRD CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1), $ DUM(1), DUM(1), -1, INFO ) - LWORK_DGEBRD=DUM(1) + LWORK_DGEBRD = INT( DUM(1) ) * Compute space needed for DORMBR CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, A, LDA, $ DUM(1), B, LDB, DUM(1), -1, INFO ) - LWORK_DORMBR=DUM(1) + LWORK_DORMBR = INT( DUM(1) ) * Compute space needed for DORGBR CALL DORGBR( 'P', M, N, M, A, LDA, DUM(1), $ DUM(1), -1, INFO ) - LWORK_DORGBR=DUM(1) + LWORK_DORGBR = INT( DUM(1) ) MAXWRK = 3*M + LWORK_DGEBRD MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORMBR ) MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR ) diff --git a/lib/linalg/dlaed4.f b/lib/linalg/dlaed4.f index 3ee3ef920f..b51e23d850 100644 --- a/lib/linalg/dlaed4.f +++ b/lib/linalg/dlaed4.f @@ -328,9 +328,12 @@ IF( C.LT.ZERO ) $ C = ABS( C ) IF( C.EQ.ZERO ) THEN -* ETA = B/A +* ETA = B/A * ETA = RHO - TAU - ETA = DLTUB - TAU +* ETA = DLTUB - TAU +* +* Update proposed by Li, Ren-Cang: + ETA = -W / ( DPSI+DPHI ) ELSE IF( A.GE.ZERO ) THEN ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C ) ELSE diff --git a/lib/linalg/dlascl.f b/lib/linalg/dlascl.f index 05ad1c4f3c..0a4bf21ce1 100644 --- a/lib/linalg/dlascl.f +++ b/lib/linalg/dlascl.f @@ -272,6 +272,8 @@ ELSE MUL = CTOC / CFROMC DONE = .TRUE. + IF (MUL .EQ. ONE) + $ RETURN END IF END IF * diff --git a/lib/linalg/dlatrs.f b/lib/linalg/dlatrs.f index 43f92911d7..be156bee20 100644 --- a/lib/linalg/dlatrs.f +++ b/lib/linalg/dlatrs.f @@ -264,8 +264,8 @@ * .. External Functions .. LOGICAL LSAME INTEGER IDAMAX - DOUBLE PRECISION DASUM, DDOT, DLAMCH - EXTERNAL LSAME, IDAMAX, DASUM, DDOT, DLAMCH + DOUBLE PRECISION DASUM, DDOT, DLAMCH, DLANGE + EXTERNAL LSAME, IDAMAX, DASUM, DDOT, DLAMCH, DLANGE * .. * .. External Subroutines .. EXTERNAL DAXPY, DSCAL, DTRSV, XERBLA @@ -304,6 +304,7 @@ * * Quick return if possible * + SCALE = ONE IF( N.EQ.0 ) $ RETURN * @@ -311,7 +312,6 @@ * SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' ) BIGNUM = ONE / SMLNUM - SCALE = ONE * IF( LSAME( NORMIN, 'N' ) ) THEN * @@ -343,8 +343,67 @@ IF( TMAX.LE.BIGNUM ) THEN TSCAL = ONE ELSE - TSCAL = ONE / ( SMLNUM*TMAX ) - CALL DSCAL( N, TSCAL, CNORM, 1 ) +* +* Avoid NaN generation if entries in CNORM exceed the +* overflow threshold +* + IF( TMAX.LE.DLAMCH('Overflow') ) THEN +* Case 1: All entries in CNORM are valid floating-point numbers + TSCAL = ONE / ( SMLNUM*TMAX ) + CALL DSCAL( N, TSCAL, CNORM, 1 ) + ELSE +* Case 2: At least one column norm of A cannot be represented +* as floating-point number. Find the offdiagonal entry A( I, J ) +* with the largest absolute value. If this entry is not +/- Infinity, +* use this value as TSCAL. + TMAX = ZERO + IF( UPPER ) THEN +* +* A is upper triangular. +* + DO J = 2, N + TMAX = MAX( DLANGE( 'M', J-1, 1, A( 1, J ), 1, SUMJ ), + $ TMAX ) + END DO + ELSE +* +* A is lower triangular. +* + DO J = 1, N - 1 + TMAX = MAX( DLANGE( 'M', N-J, 1, A( J+1, J ), 1, + $ SUMJ ), TMAX ) + END DO + END IF +* + IF( TMAX.LE.DLAMCH('Overflow') ) THEN + TSCAL = ONE / ( SMLNUM*TMAX ) + DO J = 1, N + IF( CNORM( J ).LE.DLAMCH('Overflow') ) THEN + CNORM( J ) = CNORM( J )*TSCAL + ELSE +* Recompute the 1-norm without introducing Infinity +* in the summation + CNORM( J ) = ZERO + IF( UPPER ) THEN + DO I = 1, J - 1 + CNORM( J ) = CNORM( J ) + + $ TSCAL * ABS( A( I, J ) ) + END DO + ELSE + DO I = J + 1, N + CNORM( J ) = CNORM( J ) + + $ TSCAL * ABS( A( I, J ) ) + END DO + END IF + END IF + END DO + ELSE +* At least one entry of A is not a valid floating-point entry. +* Rely on TRSV to propagate Inf and NaN. + CALL DTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 ) + RETURN + END IF + END IF END IF * * Compute a bound on the computed solution vector to see if the diff --git a/lib/linalg/dorgbr.f b/lib/linalg/dorgbr.f index 1b242ff97f..7dfd03961e 100644 --- a/lib/linalg/dorgbr.f +++ b/lib/linalg/dorgbr.f @@ -232,7 +232,7 @@ END IF END IF END IF - LWKOPT = WORK( 1 ) + LWKOPT = INT( WORK( 1 ) ) LWKOPT = MAX (LWKOPT, MN) END IF * diff --git a/lib/linalg/dposv.f b/lib/linalg/dposv.f new file mode 100644 index 0000000000..ee2988e6fd --- /dev/null +++ b/lib/linalg/dposv.f @@ -0,0 +1,190 @@ +*> \brief DPOSV computes the solution to system of linear equations A * X = B for PO matrices +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DPOSV + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DPOSV( UPLO, N, NRHS, A, LDA, B, LDB, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, LDA, LDB, N, NRHS +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DPOSV computes the solution to a real system of linear equations +*> A * X = B, +*> where A is an N-by-N symmetric positive definite matrix and X and B +*> are N-by-NRHS matrices. +*> +*> The Cholesky decomposition is used to factor A as +*> A = U**T* U, if UPLO = 'U', or +*> A = L * L**T, if UPLO = 'L', +*> where U is an upper triangular matrix and L is a lower triangular +*> matrix. The factored form of A is then used to solve the system of +*> equations A * X = B. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A is stored; +*> = 'L': Lower triangle of A is stored. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of linear equations, i.e., the order of the +*> matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in] NRHS +*> \verbatim +*> NRHS is INTEGER +*> The number of right hand sides, i.e., the number of columns +*> of the matrix B. NRHS >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the leading +*> N-by-N upper triangular part of A contains the upper +*> triangular part of the matrix A, and the strictly lower +*> triangular part of A is not referenced. If UPLO = 'L', the +*> leading N-by-N lower triangular part of A contains the lower +*> triangular part of the matrix A, and the strictly upper +*> triangular part of A is not referenced. +*> +*> On exit, if INFO = 0, the factor U or L from the Cholesky +*> factorization A = U**T*U or A = L*L**T. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension (LDB,NRHS) +*> On entry, the N-by-NRHS right hand side matrix B. +*> On exit, if INFO = 0, the N-by-NRHS solution matrix X. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> The leading dimension of the array B. LDB >= max(1,N). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> > 0: if INFO = i, the leading minor of order i of A is not +*> positive definite, so the factorization could not be +*> completed, and the solution has not been computed. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup doublePOsolve +* +* ===================================================================== + SUBROUTINE DPOSV( UPLO, N, NRHS, A, LDA, B, LDB, INFO ) +* +* -- LAPACK driver routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, LDA, LDB, N, NRHS +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DPOTRF, DPOTRS, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( NRHS.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -7 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DPOSV ', -INFO ) + RETURN + END IF +* +* Compute the Cholesky factorization A = U**T*U or A = L*L**T. +* + CALL DPOTRF( UPLO, N, A, LDA, INFO ) + IF( INFO.EQ.0 ) THEN +* +* Solve the system A*X = B, overwriting B with X. +* + CALL DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO ) +* + END IF + RETURN +* +* End of DPOSV +* + END diff --git a/lib/linalg/dpotrs.f b/lib/linalg/dpotrs.f new file mode 100644 index 0000000000..862ee078fd --- /dev/null +++ b/lib/linalg/dpotrs.f @@ -0,0 +1,201 @@ +*> \brief \b DPOTRS +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DPOTRS + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, LDA, LDB, N, NRHS +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DPOTRS solves a system of linear equations A*X = B with a symmetric +*> positive definite matrix A using the Cholesky factorization +*> A = U**T*U or A = L*L**T computed by DPOTRF. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A is stored; +*> = 'L': Lower triangle of A is stored. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in] NRHS +*> \verbatim +*> NRHS is INTEGER +*> The number of right hand sides, i.e., the number of columns +*> of the matrix B. NRHS >= 0. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The triangular factor U or L from the Cholesky factorization +*> A = U**T*U or A = L*L**T, as computed by DPOTRF. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension (LDB,NRHS) +*> On entry, the right hand side matrix B. +*> On exit, the solution matrix X. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> The leading dimension of the array B. LDB >= max(1,N). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup doublePOcomputational +* +* ===================================================================== + SUBROUTINE DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, LDA, LDB, N, NRHS +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL UPPER +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DTRSM, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( NRHS.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -7 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DPOTRS', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 .OR. NRHS.EQ.0 ) + $ RETURN +* + IF( UPPER ) THEN +* +* Solve A*X = B where A = U**T *U. +* +* Solve U**T *X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS, + $ ONE, A, LDA, B, LDB ) +* +* Solve U*X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N, + $ NRHS, ONE, A, LDA, B, LDB ) + ELSE +* +* Solve A*X = B where A = L*L**T. +* +* Solve L*X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Non-unit', N, + $ NRHS, ONE, A, LDA, B, LDB ) +* +* Solve L**T *X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Non-unit', N, NRHS, + $ ONE, A, LDA, B, LDB ) + END IF +* + RETURN +* +* End of DPOTRS +* + END diff --git a/lib/linalg/dscal.f b/lib/linalg/dscal.f index 3713427334..e055d198af 100644 --- a/lib/linalg/dscal.f +++ b/lib/linalg/dscal.f @@ -93,11 +93,14 @@ * * .. Local Scalars .. INTEGER I,M,MP1,NINCX +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER (ONE=1.0D+0) * .. * .. Intrinsic Functions .. INTRINSIC MOD * .. - IF (N.LE.0 .OR. INCX.LE.0) RETURN + IF (N.LE.0 .OR. INCX.LE.0 .OR. DA.EQ.ONE) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 diff --git a/lib/linalg/dsyevd.f b/lib/linalg/dsyevd.f index edbe896fe8..eaaecd8d98 100644 --- a/lib/linalg/dsyevd.f +++ b/lib/linalg/dsyevd.f @@ -257,7 +257,7 @@ LWMIN = 2*N + 1 END IF LOPT = MAX( LWMIN, 2*N + - $ ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) ) + $ N*ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) ) LIOPT = LIWMIN END IF WORK( 1 ) = LOPT diff --git a/lib/linalg/dsygvd.f b/lib/linalg/dsygvd.f index 61134bedce..3b38665a75 100644 --- a/lib/linalg/dsygvd.f +++ b/lib/linalg/dsygvd.f @@ -330,8 +330,8 @@ CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) CALL DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK, LIWORK, $ INFO ) - LOPT = MAX( DBLE( LOPT ), DBLE( WORK( 1 ) ) ) - LIOPT = MAX( DBLE( LIOPT ), DBLE( IWORK( 1 ) ) ) + LOPT = INT( MAX( DBLE( LOPT ), DBLE( WORK( 1 ) ) ) ) + LIOPT = INT( MAX( DBLE( LIOPT ), DBLE( IWORK( 1 ) ) ) ) * IF( WANTZ .AND. INFO.EQ.0 ) THEN * diff --git a/lib/linalg/ieeeck.f b/lib/linalg/ieeeck.f index 74065c3b4e..f9f6332ecf 100644 --- a/lib/linalg/ieeeck.f +++ b/lib/linalg/ieeeck.f @@ -41,7 +41,7 @@ *> \param[in] ISPEC *> \verbatim *> ISPEC is INTEGER -*> Specifies whether to test just for inifinity arithmetic +*> Specifies whether to test just for infinity arithmetic *> or whether to test for infinity and NaN arithmetic. *> = 0: Verify infinity arithmetic only. *> = 1: Verify infinity and NaN arithmetic. diff --git a/lib/linalg/ilaenv.f b/lib/linalg/ilaenv.f index af28503986..a639e0375a 100644 --- a/lib/linalg/ilaenv.f +++ b/lib/linalg/ilaenv.f @@ -469,6 +469,15 @@ ELSE NB = 64 END IF + ELSE IF( C3.EQ.'SYL' ) THEN +* The upper bound is to prevent overly aggressive scaling. + IF( SNAME ) THEN + NB = MIN( MAX( 48, INT( ( MIN( N1, N2 ) * 16 ) / 100) ), + $ 240 ) + ELSE + NB = MIN( MAX( 24, INT( ( MIN( N1, N2 ) * 8 ) / 100) ), + $ 80 ) + END IF END IF ELSE IF( C2.EQ.'LA' ) THEN IF( C3.EQ.'UUM' ) THEN @@ -477,6 +486,12 @@ ELSE NB = 64 END IF + ELSE IF( C3.EQ.'TRS' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF END IF ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN IF( C3.EQ.'EBZ' ) THEN diff --git a/lib/linalg/zdscal.f b/lib/linalg/zdscal.f index b3546ba206..5a16048771 100644 --- a/lib/linalg/zdscal.f +++ b/lib/linalg/zdscal.f @@ -92,17 +92,20 @@ * * .. Local Scalars .. INTEGER I,NINCX +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER (ONE=1.0D+0) * .. * .. Intrinsic Functions .. - INTRINSIC DCMPLX + INTRINSIC DBLE, DCMPLX, DIMAG * .. - IF (N.LE.0 .OR. INCX.LE.0) RETURN + IF (N.LE.0 .OR. INCX.LE.0 .OR. DA.EQ.ONE) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 * DO I = 1,N - ZX(I) = DCMPLX(DA,0.0d0)*ZX(I) + ZX(I) = DCMPLX(DA*DBLE(ZX(I)),DA*DIMAG(ZX(I))) END DO ELSE * @@ -110,7 +113,7 @@ * NINCX = N*INCX DO I = 1,NINCX,INCX - ZX(I) = DCMPLX(DA,0.0d0)*ZX(I) + ZX(I) = DCMPLX(DA*DBLE(ZX(I)),DA*DIMAG(ZX(I))) END DO END IF RETURN diff --git a/lib/linalg/zheevd.f b/lib/linalg/zheevd.f index a6484eb032..7f58c7f726 100644 --- a/lib/linalg/zheevd.f +++ b/lib/linalg/zheevd.f @@ -284,7 +284,7 @@ LIWMIN = 1 END IF LOPT = MAX( LWMIN, N + - $ ILAENV( 1, 'ZHETRD', UPLO, N, -1, -1, -1 ) ) + $ N*ILAENV( 1, 'ZHETRD', UPLO, N, -1, -1, -1 ) ) LROPT = LRWMIN LIOPT = LIWMIN END IF diff --git a/lib/linalg/zlascl.f b/lib/linalg/zlascl.f index 3d53f5ae60..4cce5ff5e0 100644 --- a/lib/linalg/zlascl.f +++ b/lib/linalg/zlascl.f @@ -272,6 +272,8 @@ ELSE MUL = CTOC / CFROMC DONE = .TRUE. + IF (MUL .EQ. ONE) + $ RETURN END IF END IF * diff --git a/lib/linalg/zscal.f b/lib/linalg/zscal.f index 8085f5a399..8b8c2c8ab5 100644 --- a/lib/linalg/zscal.f +++ b/lib/linalg/zscal.f @@ -93,7 +93,11 @@ * .. Local Scalars .. INTEGER I,NINCX * .. - IF (N.LE.0 .OR. INCX.LE.0) RETURN +* .. Parameters .. + COMPLEX*16 ONE + PARAMETER (ONE= (1.0D+0,0.0D+0)) +* .. + IF (N.LE.0 .OR. INCX.LE.0 .OR. ZA.EQ.ONE) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 diff --git a/src/ADIOS/dump_atom_adios.cpp b/src/ADIOS/dump_atom_adios.cpp index a31f3f4f25..8e92300591 100644 --- a/src/ADIOS/dump_atom_adios.cpp +++ b/src/ADIOS/dump_atom_adios.cpp @@ -62,7 +62,11 @@ DumpAtomADIOS::DumpAtomADIOS(LAMMPS *lmp, int narg, char **arg) : DumpAtom(lmp, internal = new DumpAtomADIOSInternal(); try { +#if defined(MPI_STUBS) + internal->ad = new adios2::ADIOS("adios2_config.xml", adios2::DebugON); +#else internal->ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON); +#endif } catch (std::ios_base::failure &e) { error->all(FLERR, "ADIOS initialization failed with error: {}", e.what()); } @@ -84,11 +88,19 @@ void DumpAtomADIOS::openfile() if (multifile) { // if one file per timestep, replace '*' with current timestep auto filecurrent = utils::star_subst(filename, update->ntimestep, padflag); +#if defined(MPI_STUBS) + internal->fh = internal->io.Open(filecurrent, adios2::Mode::Write); +#else internal->fh = internal->io.Open(filecurrent, adios2::Mode::Write, world); +#endif if (!internal->fh) error->one(FLERR, "Cannot open dump file {}", filecurrent); } else { if (!singlefile_opened) { +#if defined(MPI_STUBS) + internal->fh = internal->io.Open(filename, adios2::Mode::Write); +#else internal->fh = internal->io.Open(filename, adios2::Mode::Write, world); +#endif if (!internal->fh) error->one(FLERR, "Cannot open dump file {}", filename); singlefile_opened = 1; } @@ -256,61 +268,63 @@ void DumpAtomADIOS::init_style() else if (scale_flag == 0 && image_flag == 1) pack_choice = &DumpAtomADIOS::pack_noscale_image; - /* Define the group of variables for the atom style here since it's a fixed - * set */ - internal->io = internal->ad->DeclareIO(internal->ioName); - if (!internal->io.InConfigFile()) { - // if not defined by user, we can change the default settings - // BPFile is the default writer - internal->io.SetEngine("BPFile"); - int num_aggregators = multiproc; - if (num_aggregators == 0) num_aggregators = 1; - auto nstreams = std::to_string(num_aggregators); - internal->io.SetParameters({{"substreams", nstreams}}); - if (me == 0) - utils::logmesg(lmp, "ADIOS method for {} is n-to-m (aggregation with {} writers)\n", filename, - nstreams); - } + /* Define the group of variables for the atom style here since it's a fixed set */ - internal->io.DefineVariable("ntimestep"); - internal->io.DefineVariable("natoms"); + if (!internal->io) { + internal->io = internal->ad->DeclareIO(internal->ioName); + if (!internal->io.InConfigFile()) { + // if not defined by user, we can change the default settings + // BPFile is the default writer + internal->io.SetEngine("BPFile"); + int num_aggregators = multiproc; + if (num_aggregators == 0) num_aggregators = 1; + auto nstreams = std::to_string(num_aggregators); + internal->io.SetParameters({{"substreams", nstreams}}); + if (me == 0) + utils::logmesg(lmp, "ADIOS method for {} is n-to-m (aggregation with {} writers)\n", filename, + nstreams); + } - internal->io.DefineVariable("nprocs"); - internal->io.DefineVariable("ncolumns"); + internal->io.DefineVariable("ntimestep"); + internal->io.DefineVariable("natoms"); - internal->io.DefineVariable("boxxlo"); - internal->io.DefineVariable("boxxhi"); - internal->io.DefineVariable("boxylo"); - internal->io.DefineVariable("boxyhi"); - internal->io.DefineVariable("boxzlo"); - internal->io.DefineVariable("boxzhi"); + internal->io.DefineVariable("nprocs"); + internal->io.DefineVariable("ncolumns"); - internal->io.DefineVariable("boxxy"); - internal->io.DefineVariable("boxxz"); - internal->io.DefineVariable("boxyz"); + internal->io.DefineVariable("boxxlo"); + internal->io.DefineVariable("boxxhi"); + internal->io.DefineVariable("boxylo"); + internal->io.DefineVariable("boxyhi"); + internal->io.DefineVariable("boxzlo"); + internal->io.DefineVariable("boxzhi"); - internal->io.DefineAttribute("triclinic", domain->triclinic); - internal->io.DefineAttribute("scaled", scale_flag); - internal->io.DefineAttribute("image", image_flag); + internal->io.DefineVariable("boxxy"); + internal->io.DefineVariable("boxxz"); + internal->io.DefineVariable("boxyz"); - int *boundaryptr = reinterpret_cast(domain->boundary); - internal->io.DefineAttribute("boundary", boundaryptr, 6); + internal->io.DefineAttribute("triclinic", domain->triclinic); + internal->io.DefineAttribute("scaled", scale_flag); + internal->io.DefineAttribute("image", image_flag); - auto nColumns = static_cast(size_one); - internal->io.DefineAttribute("columns", columnNames.data(), nColumns); - internal->io.DefineAttribute("columnstr", columns); - internal->io.DefineAttribute("boundarystr", boundstr); - internal->io.DefineAttribute("LAMMPS/dump_style", "atom"); - internal->io.DefineAttribute("LAMMPS/version", lmp->version); - internal->io.DefineAttribute("LAMMPS/num_ver", std::to_string(lmp->num_ver)); + int *boundaryptr = reinterpret_cast(domain->boundary); + internal->io.DefineAttribute("boundary", boundaryptr, 6); - // local dimension variables - internal->io.DefineVariable("nme", {adios2::LocalValueDim}); - internal->io.DefineVariable("offset", {adios2::LocalValueDim}); + auto nColumns = static_cast(size_one); + internal->io.DefineAttribute("columns", columnNames.data(), nColumns); + internal->io.DefineAttribute("columnstr", columns); + internal->io.DefineAttribute("boundarystr", boundstr); + internal->io.DefineAttribute("LAMMPS/dump_style", "atom"); + internal->io.DefineAttribute("LAMMPS/version", lmp->version); + internal->io.DefineAttribute("LAMMPS/num_ver", std::to_string(lmp->num_ver)); - // atom table size is not known at the moment - // it will be correctly defined at the moment of write - size_t UnknownSizeYet = 1; - internal->varAtoms = internal->io.DefineVariable( + // local dimension variables + internal->io.DefineVariable("nme", {adios2::LocalValueDim}); + internal->io.DefineVariable("offset", {adios2::LocalValueDim}); + + // atom table size is not known at the moment + // it will be correctly defined at the moment of write + size_t UnknownSizeYet = 1; + internal->varAtoms = internal->io.DefineVariable( "atoms", {UnknownSizeYet, nColumns}, {UnknownSizeYet, 0}, {UnknownSizeYet, nColumns}); + } } diff --git a/src/ADIOS/dump_custom_adios.cpp b/src/ADIOS/dump_custom_adios.cpp index 194141c15a..be827f507d 100644 --- a/src/ADIOS/dump_custom_adios.cpp +++ b/src/ADIOS/dump_custom_adios.cpp @@ -70,7 +70,11 @@ DumpCustomADIOS::DumpCustomADIOS(LAMMPS *lmp, int narg, char **arg) : DumpCustom internal = new DumpCustomADIOSInternal(); try { +#if defined(MPI_STUBS) + internal->ad = new adios2::ADIOS("adios2_config.xml", adios2::DebugON); +#else internal->ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON); +#endif } catch (std::ios_base::failure &e) { error->all(FLERR, "ADIOS initialization failed with error: {}", e.what()); } @@ -96,11 +100,19 @@ void DumpCustomADIOS::openfile() if (multifile) { // if one file per timestep, replace '*' with current timestep auto filecurrent = utils::star_subst(filename, update->ntimestep, padflag); +#if defined(MPI_STUBS) + internal->fh = internal->io.Open(filecurrent, adios2::Mode::Write); +#else internal->fh = internal->io.Open(filecurrent, adios2::Mode::Write, world); +#endif if (!internal->fh) error->one(FLERR, "Cannot open dump file {}", filecurrent); } else { if (!singlefile_opened) { +#if defined(MPI_STUBS) + internal->fh = internal->io.Open(filename, adios2::Mode::Write); +#else internal->fh = internal->io.Open(filename, adios2::Mode::Write, world); +#endif if (!internal->fh) error->one(FLERR, "Cannot open dump file {}", filename); singlefile_opened = 1; } diff --git a/src/ADIOS/reader_adios.cpp b/src/ADIOS/reader_adios.cpp index dd389be702..655df98d26 100644 --- a/src/ADIOS/reader_adios.cpp +++ b/src/ADIOS/reader_adios.cpp @@ -82,7 +82,11 @@ ReaderADIOS::ReaderADIOS(LAMMPS *lmp) : Reader(lmp) internal = new ReadADIOSInternal(); try { +#if defined(MPI_STUBS) + internal->ad = new adios2::ADIOS("adios2_config.xml", adios2::DebugON); +#else internal->ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON); +#endif } catch (std::ios_base::failure &e) { error->one(FLERR, "ADIOS initialization failed with error: {}", e.what()); } @@ -134,7 +138,11 @@ void ReaderADIOS::open_file(const std::string &file) if (internal->fh) internal->fh.Close(); try { +#if defined(MPI_STUBS) + internal->fh = internal->io.Open(file, adios2::Mode::Read); +#else internal->fh = internal->io.Open(file, adios2::Mode::Read, world); +#endif } catch (std::ios_base::failure &e) { error->one(FLERR, "Error opening file {}: {}", file, e.what()); } diff --git a/src/AMOEBA/amoeba_polar.cpp b/src/AMOEBA/amoeba_polar.cpp index a0f4fce301..9342b6213d 100644 --- a/src/AMOEBA/amoeba_polar.cpp +++ b/src/AMOEBA/amoeba_polar.cpp @@ -250,10 +250,12 @@ void PairAmoeba::polar_real() double drc3[3],drc5[3],drc7[3]; double urc3[3],urc5[3],tep[3]; double fix[3],fiy[3],fiz[3]; +#if 0 // for poltyp TCG which is currently not supported double uax[3],uay[3],uaz[3]; double ubx[3],uby[3],ubz[3]; double uaxp[3],uayp[3],uazp[3]; double ubxp[3],ubyp[3],ubzp[3]; +#endif double dmpi[9],dmpk[9]; double dmpik[9]; double bn[5]; @@ -320,6 +322,7 @@ void PairAmoeba::polar_real() uixp = uinp[i][0]; uiyp = uinp[i][1]; uizp = uinp[i][2]; +#if 0 // for poltyp TCG which is currently not supported for (m = 0; m < tcgnab; m++) { uax[m] = uad[m][i][0]; uay[m] = uad[m][i][1]; @@ -334,7 +337,7 @@ void PairAmoeba::polar_real() ubyp[m] = ubp[m][i][1]; ubzp[m] = ubp[m][i][2]; } - +#endif if (amoeba) { pdi = pdamp[itype]; pti = thole[itype]; @@ -1030,7 +1033,8 @@ void PairAmoeba::polar_real() // get the dtau/dr terms used for TCG polarization force } else if (poltyp == TCG) { - /* +#if 0 + // poltyp TCG not yet supported for AMOEBA/HIPPO for (m = 0; m < tcgnab; m++) { ukx = ubd[m][j][0]; uky = ubd[m][j][1]; @@ -1131,8 +1135,7 @@ void PairAmoeba::polar_real() frcx += depx; frcy += depy; frcz += depz; - } - */ +#endif } // increment force-based gradient on the interaction sites diff --git a/src/ASPHERE/pair_ylz.cpp b/src/ASPHERE/pair_ylz.cpp index 2d035b6f5d..afedf635d5 100644 --- a/src/ASPHERE/pair_ylz.cpp +++ b/src/ASPHERE/pair_ylz.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Mehdi Baghaee (SUSTech) + Contributing author: Hongyan Yuan (SUSTech) ------------------------------------------------------------------------- */ #include "pair_ylz.h" diff --git a/src/CG-SPICA/angle_spica.cpp b/src/CG-SPICA/angle_spica.cpp index 83a4fbb4ad..3f8a506ed2 100644 --- a/src/CG-SPICA/angle_spica.cpp +++ b/src/CG-SPICA/angle_spica.cpp @@ -297,7 +297,7 @@ void AngleSPICA::init_style() repflag = 0; for (int i = 1; i <= atom->nangletypes; i++) - if (repscale[i] > 0.0) repflag = 1; + if (repscale && (repscale[i] > 0.0)) repflag = 1; // set up pointers to access SPICA LJ parameters for 1-3 interactions diff --git a/src/EXTRA-MOLECULE/angle_gaussian.cpp b/src/EXTRA-MOLECULE/angle_gaussian.cpp index a474195af5..7290cb70cc 100644 --- a/src/EXTRA-MOLECULE/angle_gaussian.cpp +++ b/src/EXTRA-MOLECULE/angle_gaussian.cpp @@ -28,8 +28,8 @@ using namespace LAMMPS_NS; using namespace MathConst; -#define SMAL 0.001 -#define SMALL 1.0e-8 +static constexpr double SMALL = 0.001; +static constexpr double SMALLG = 2.0e-308; /* ---------------------------------------------------------------------- */ @@ -112,7 +112,7 @@ void AngleGaussian::compute(int eflag, int vflag) if (c < -1.0) c = -1.0; s = sqrt(1.0 - c * c); - if (s < SMAL) s = SMAL; + if (s < SMALL) s = SMALL; s = 1.0 / s; // force & energy @@ -123,13 +123,15 @@ void AngleGaussian::compute(int eflag, int vflag) for (int i = 0; i < nterms[type]; i++) { dtheta = theta - theta0[type][i]; prefactor = (alpha[type][i] / (width[type][i] * sqrt(MY_PI2))); - exponent = -2 * dtheta * dtheta / (width[type][i] * width[type][i]); + exponent = -2.0 * dtheta * dtheta / (width[type][i] * width[type][i]); g_i = prefactor * exp(exponent); sum_g_i += g_i; sum_numerator += g_i * dtheta / (width[type][i] * width[type][i]); } - if (sum_g_i < SMALL) sum_g_i = SMALL; + // avoid overflow + if (sum_g_i < sum_numerator * SMALLG) sum_g_i = sum_numerator * SMALLG; + if (eflag) eangle = -(force->boltz * angle_temperature[type]) * log(sum_g_i); // I should check about the sign of this expression @@ -198,14 +200,16 @@ void AngleGaussian::allocate() void AngleGaussian::coeff(int narg, char **arg) { - if (narg < 6) error->all(FLERR, "Incorrect args for angle coefficients"); + if (narg < 6) utils::missing_cmd_args(FLERR, "angle_coeff", error); int ilo, ihi; utils::bounds(FLERR, arg[0], 1, atom->nangletypes, ilo, ihi, error); double angle_temperature_one = utils::numeric(FLERR, arg[1], false, lmp); int n = utils::inumeric(FLERR, arg[2], false, lmp); - if (narg != 3 * n + 3) error->all(FLERR, "Incorrect args for angle coefficients"); + if (n < 1) error->all(FLERR, "Invalid angle style gaussian value for n: {}", n); + + if (narg != 3 * n + 3) utils::missing_cmd_args(FLERR, "angle_coeff", error); if (!allocated) allocate(); @@ -223,7 +227,9 @@ void AngleGaussian::coeff(int narg, char **arg) theta0[i] = new double[n]; for (int j = 0; j < n; j++) { alpha[i][j] = utils::numeric(FLERR, arg[3 + 3 * j], false, lmp); + if (alpha[i][j] <= 0.0) error->all(FLERR, "Invalid value for A_{}: {}", j, alpha[i][j]); width[i][j] = utils::numeric(FLERR, arg[4 + 3 * j], false, lmp); + if (width[i][j] <= 0.0) error->all(FLERR, "Invalid value for w_{}: {}", j, width[i][j]); theta0[i][j] = utils::numeric(FLERR, arg[5 + 3 * j], false, lmp) * MY_PI / 180.0; setflag[i] = 1; } diff --git a/src/EXTRA-MOLECULE/bond_gaussian.cpp b/src/EXTRA-MOLECULE/bond_gaussian.cpp index 655a5e557f..baca0b6e1a 100644 --- a/src/EXTRA-MOLECULE/bond_gaussian.cpp +++ b/src/EXTRA-MOLECULE/bond_gaussian.cpp @@ -27,7 +27,7 @@ using namespace LAMMPS_NS; using namespace MathConst; -#define SMALL 1.0e-10 +static constexpr double SMALL = 2.0e-308; /* ---------------------------------------------------------------------- */ @@ -92,15 +92,16 @@ void BondGaussian::compute(int eflag, int vflag) for (int i = 0; i < nterms[type]; i++) { dr = r - r0[type][i]; prefactor = (alpha[type][i] / (width[type][i] * sqrt(MY_PI2))); - exponent = -2 * dr * dr / (width[type][i] * width[type][i]); + exponent = -2.0 * dr * dr / (width[type][i] * width[type][i]); g_i = prefactor * exp(exponent); sum_g_i += g_i; sum_numerator += g_i * dr / (width[type][i] * width[type][i]); } - // force & energy - if (sum_g_i < SMALL) sum_g_i = SMALL; + // avoid overflow + if (sum_g_i < sum_numerator * SMALL) sum_g_i = sum_numerator * SMALL; + // force & energy if (r > 0.0) fbond = -4.0 * (force->boltz * bond_temperature[type]) * (sum_numerator / sum_g_i) / r; else @@ -153,14 +154,15 @@ void BondGaussian::allocate() void BondGaussian::coeff(int narg, char **arg) { - if (narg < 6) error->all(FLERR, "Incorrect args for bond coefficients"); + if (narg < 6) utils::missing_cmd_args(FLERR, "bond_coeff", error); int ilo, ihi; utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error); double bond_temp_one = utils::numeric(FLERR, arg[1], false, lmp); int n = utils::inumeric(FLERR, arg[2], false, lmp); - if (narg != 3 * n + 3) error->all(FLERR, "Incorrect args for bond coefficients"); + if (n < 1) error->all(FLERR, "Invalid bond style gaussian value for n: {}", n); + if (narg != 3 * n + 3) utils::missing_cmd_args(FLERR, "bond_coeff", error); if (!allocated) allocate(); @@ -176,8 +178,11 @@ void BondGaussian::coeff(int narg, char **arg) r0[i] = new double[n]; for (int j = 0; j < n; j++) { alpha[i][j] = utils::numeric(FLERR, arg[3 + 3 * j], false, lmp); + if (alpha[i][j] <= 0.0) error->all(FLERR, "Invalid value for A_{}: {}", j, alpha[i][j]); width[i][j] = utils::numeric(FLERR, arg[4 + 3 * j], false, lmp); + if (width[i][j] <= 0.0) error->all(FLERR, "Invalid value for w_{}: {}", j, width[i][j]); r0[i][j] = utils::numeric(FLERR, arg[5 + 3 * j], false, lmp); + if (r0[i][j] <= 0.0) error->all(FLERR, "Invalid value for r0_{}: {}", j, r0[i][j]); setflag[i] = 1; } count++; diff --git a/src/EXTRA-PAIR/pair_nm_cut.cpp b/src/EXTRA-PAIR/pair_nm_cut.cpp index 9a39c091b9..18b5810abc 100644 --- a/src/EXTRA-PAIR/pair_nm_cut.cpp +++ b/src/EXTRA-PAIR/pair_nm_cut.cpp @@ -18,8 +18,6 @@ #include "pair_nm_cut.h" -#include -#include #include "atom.h" #include "comm.h" #include "force.h" @@ -28,6 +26,8 @@ #include "memory.h" #include "error.h" +#include +#include using namespace LAMMPS_NS; using namespace MathConst; diff --git a/src/EXTRA-PAIR/pair_nm_cut_coul_cut.cpp b/src/EXTRA-PAIR/pair_nm_cut_coul_cut.cpp index 569fba970f..adc6d5a058 100644 --- a/src/EXTRA-PAIR/pair_nm_cut_coul_cut.cpp +++ b/src/EXTRA-PAIR/pair_nm_cut_coul_cut.cpp @@ -223,8 +223,7 @@ void PairNMCutCoulCut::settings(int narg, char **arg) void PairNMCutCoulCut::coeff(int narg, char **arg) { - if (narg < 6 || narg > 8) - error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg < 6 || narg > 8) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -238,8 +237,8 @@ void PairNMCutCoulCut::coeff(int narg, char **arg) double cut_lj_one = cut_lj_global; double cut_coul_one = cut_coul_global; - if (narg >= 7) cut_coul_one = cut_lj_one = utils::numeric(FLERR,arg[4],false,lmp); - if (narg == 8) cut_coul_one = utils::numeric(FLERR,arg[5],false,lmp); + if (narg >= 7) cut_coul_one = cut_lj_one = utils::numeric(FLERR,arg[6],false,lmp); + if (narg == 8) cut_coul_one = utils::numeric(FLERR,arg[7],false,lmp); int count = 0; for (int i = ilo; i <= ihi; i++) { diff --git a/src/EXTRA-PAIR/pair_nm_cut_coul_long.cpp b/src/EXTRA-PAIR/pair_nm_cut_coul_long.cpp index 464e647227..13171c87dd 100644 --- a/src/EXTRA-PAIR/pair_nm_cut_coul_long.cpp +++ b/src/EXTRA-PAIR/pair_nm_cut_coul_long.cpp @@ -277,7 +277,7 @@ void PairNMCutCoulLong::coeff(int narg, char **arg) double mm_one = utils::numeric(FLERR,arg[5],false,lmp); double cut_lj_one = cut_lj_global; - if (narg == 7) cut_lj_one = utils::numeric(FLERR,arg[4],false,lmp); + if (narg == 7) cut_lj_one = utils::numeric(FLERR,arg[6],false,lmp); int count = 0; for (int i = ilo; i <= ihi; i++) { diff --git a/src/FEP/compute_fep.cpp b/src/FEP/compute_fep.cpp index bb11a64f54..995e2f9f3d 100644 --- a/src/FEP/compute_fep.cpp +++ b/src/FEP/compute_fep.cpp @@ -190,22 +190,34 @@ void ComputeFEP::init() Perturb *pert = &perturb[m]; pert->ivar = input->variable->find(pert->var); - if (pert->ivar < 0) error->all(FLERR, "Variable name for compute fep does not exist"); + if (pert->ivar < 0) + error->all(FLERR, "Variable name {} for compute fep does not exist", pert->var); if (!input->variable->equalstyle(pert->ivar)) - error->all(FLERR, "Variable for compute fep is of invalid style"); + error->all(FLERR, "Variable {} for compute fep is of invalid style", pert->var); if (force->pair == nullptr) error->all(FLERR, "compute fep pair requires pair interactions"); if (pert->which == PAIR) { pairflag = 1; + Pair *pair = nullptr; + if (lmp->suffix_enable) { + if (lmp->suffix) { + auto pstyle = fmt::format("{}/{}", pert->pstyle, lmp->suffix); + pair = force->pair_match(pstyle, 1); + } + if ((pair == nullptr) && lmp->suffix2) { + auto pstyle = fmt::format("{}/{}", pert->pstyle, lmp->suffix2); + pair = force->pair_match(pstyle, 1); + } + } - Pair *pair = force->pair_match(pert->pstyle, 1); + if (pair == nullptr) pair = force->pair_match(pert->pstyle, 1); if (pair == nullptr) - error->all(FLERR, - "compute fep pair style " - "does not exist"); + error->all(FLERR, "compute fep pair style {} does not exist", pert->pstyle); + void *ptr = pair->extract(pert->pparam, pert->pdim); - if (ptr == nullptr) error->all(FLERR, "compute fep pair style param not supported"); + if (ptr == nullptr) + error->all(FLERR, "compute fep pair style param {} not supported", pert->pparam); pert->array = (double **) ptr; diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index 4a652783af..390976dd79 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -20,6 +20,7 @@ #include "modify.h" #include "neigh_list_kokkos.h" #include "pair_kokkos.h" +#include "atom_masks.h" using namespace LAMMPS_NS; @@ -170,6 +171,7 @@ template void FixNeighHistoryKokkos::post_neighbor() { tag = atomKK->k_tag.view(); + atomKK->sync(execution_space,TAG_MASK); k_firstflag.sync(); k_firstvalue.sync(); diff --git a/src/KOKKOS/pair_adp_kokkos.cpp b/src/KOKKOS/pair_adp_kokkos.cpp index 8817e1fc9f..3873f1e31b 100644 --- a/src/KOKKOS/pair_adp_kokkos.cpp +++ b/src/KOKKOS/pair_adp_kokkos.cpp @@ -111,7 +111,6 @@ void PairADPKokkos::compute(int eflag_in, int vflag_in) x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_adp_kokkos.h b/src/KOKKOS/pair_adp_kokkos.h index 15e08cdb89..5714bdb699 100644 --- a/src/KOKKOS/pair_adp_kokkos.h +++ b/src/KOKKOS/pair_adp_kokkos.h @@ -120,7 +120,6 @@ class PairADPKokkos : public PairADP, public KokkosBase typename AT::t_x_array x; typename AT::t_f_array f; typename AT::t_int_1d type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_buck_kokkos.cpp b/src/KOKKOS/pair_buck_kokkos.cpp index 3a6200a7e2..8e69536b38 100644 --- a/src/KOKKOS/pair_buck_kokkos.cpp +++ b/src/KOKKOS/pair_buck_kokkos.cpp @@ -98,7 +98,6 @@ void PairBuckKokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_buck_kokkos.h b/src/KOKKOS/pair_buck_kokkos.h index c6518b1fae..364716453b 100644 --- a/src/KOKKOS/pair_buck_kokkos.h +++ b/src/KOKKOS/pair_buck_kokkos.h @@ -74,7 +74,6 @@ class PairBuckKokkos : public PairBuck { typename AT::t_x_array c_x; typename AT::t_f_array f; typename AT::t_int_1d_randomread type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index 3aeba1c9bf..0be0dffd93 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -110,7 +110,6 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.h b/src/KOKKOS/pair_eam_alloy_kokkos.h index 1e936a7574..c6cb73ca5d 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.h +++ b/src/KOKKOS/pair_eam_alloy_kokkos.h @@ -119,7 +119,6 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { typename AT::t_x_array x; typename AT::t_f_array f; typename AT::t_int_1d type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index bd4bb2a373..bf0f398e60 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -110,7 +110,6 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_eam_fs_kokkos.h b/src/KOKKOS/pair_eam_fs_kokkos.h index f96380ed30..06a395cba7 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.h +++ b/src/KOKKOS/pair_eam_fs_kokkos.h @@ -119,7 +119,6 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { typename AT::t_x_array x; typename AT::t_f_array f; typename AT::t_int_1d type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 9928d6a655..6e1cd1feea 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -105,7 +105,6 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 867908bb6b..006dceb1f2 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -115,7 +115,6 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { typename AT::t_x_array x; typename AT::t_f_array f; typename AT::t_int_1d type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp index 11c2b651f9..2cfbbf0ee7 100644 --- a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp +++ b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp @@ -134,7 +134,6 @@ void PairGranHookeHistoryKokkos::compute(int eflag_in, int vflag_in) torque = atomKK->k_torque.view(); type = atomKK->k_type.view(); mask = atomKK->k_mask.view(); - tag = atomKK->k_tag.view(); rmass = atomKK->k_rmass.view(); radius = atomKK->k_radius.view(); nlocal = atom->nlocal; diff --git a/src/KOKKOS/pair_gran_hooke_history_kokkos.h b/src/KOKKOS/pair_gran_hooke_history_kokkos.h index d7477b066d..ef068e970a 100644 --- a/src/KOKKOS/pair_gran_hooke_history_kokkos.h +++ b/src/KOKKOS/pair_gran_hooke_history_kokkos.h @@ -86,7 +86,6 @@ class PairGranHookeHistoryKokkos : public PairGranHookeHistory { DAT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; - typename AT::t_tagint_1d tag; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; diff --git a/src/KOKKOS/pair_lj_class2_kokkos.cpp b/src/KOKKOS/pair_lj_class2_kokkos.cpp index dbb95b99ab..d37a190b6c 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_kokkos.cpp @@ -99,7 +99,6 @@ void PairLJClass2Kokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_lj_class2_kokkos.h b/src/KOKKOS/pair_lj_class2_kokkos.h index 073c6f38d6..0936399ca8 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.h +++ b/src/KOKKOS/pair_lj_class2_kokkos.h @@ -80,7 +80,6 @@ class PairLJClass2Kokkos : public PairLJClass2 { typename AT::t_x_array c_x; typename AT::t_f_array f; typename AT::t_int_1d_randomread type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_lj_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_kokkos.cpp index e818375762..c6353cc083 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_kokkos.cpp @@ -94,7 +94,6 @@ void PairLJCutKokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_lj_cut_kokkos.h b/src/KOKKOS/pair_lj_cut_kokkos.h index 2659e8a129..106f1a9048 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.h +++ b/src/KOKKOS/pair_lj_cut_kokkos.h @@ -80,7 +80,6 @@ class PairLJCutKokkos : public PairLJCut { DAT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; - typename AT::t_tagint_1d tag; int newton_pair; double special_lj[4]; diff --git a/src/KOKKOS/pair_lj_expand_kokkos.cpp b/src/KOKKOS/pair_lj_expand_kokkos.cpp index 90eb02801b..ecdb3a7b22 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_kokkos.cpp @@ -98,7 +98,6 @@ void PairLJExpandKokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_lj_expand_kokkos.h b/src/KOKKOS/pair_lj_expand_kokkos.h index d5d5fdc731..0df0a6f8f8 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.h +++ b/src/KOKKOS/pair_lj_expand_kokkos.h @@ -80,7 +80,6 @@ class PairLJExpandKokkos : public PairLJExpand { typename AT::t_x_array c_x; typename AT::t_f_array f; typename AT::t_int_1d_randomread type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_lj_spica_kokkos.cpp b/src/KOKKOS/pair_lj_spica_kokkos.cpp index 4612537ab3..345c18bd30 100644 --- a/src/KOKKOS/pair_lj_spica_kokkos.cpp +++ b/src/KOKKOS/pair_lj_spica_kokkos.cpp @@ -98,7 +98,6 @@ void PairLJSPICAKokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_lj_spica_kokkos.h b/src/KOKKOS/pair_lj_spica_kokkos.h index 820d6e4cc5..b330af4bfd 100644 --- a/src/KOKKOS/pair_lj_spica_kokkos.h +++ b/src/KOKKOS/pair_lj_spica_kokkos.h @@ -80,7 +80,6 @@ class PairLJSPICAKokkos : public PairLJSPICA { typename AT::t_x_array c_x; typename AT::t_f_array f; typename AT::t_int_1d_randomread type; - typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; diff --git a/src/KOKKOS/pair_morse_kokkos.cpp b/src/KOKKOS/pair_morse_kokkos.cpp index fcb89b26e4..50df64e3ca 100644 --- a/src/KOKKOS/pair_morse_kokkos.cpp +++ b/src/KOKKOS/pair_morse_kokkos.cpp @@ -101,7 +101,6 @@ void PairMorseKokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_morse_kokkos.h b/src/KOKKOS/pair_morse_kokkos.h index fa8ba8ca21..d06cf2deb1 100644 --- a/src/KOKKOS/pair_morse_kokkos.h +++ b/src/KOKKOS/pair_morse_kokkos.h @@ -80,7 +80,6 @@ class PairMorseKokkos : public PairMorse { DAT::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; - typename ArrayTypes::t_tagint_1d tag; int newton_pair; double special_lj[4]; diff --git a/src/KOKKOS/pair_reaxff_kokkos.cpp b/src/KOKKOS/pair_reaxff_kokkos.cpp index af3ac26663..0bfcef90cf 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.cpp +++ b/src/KOKKOS/pair_reaxff_kokkos.cpp @@ -63,7 +63,7 @@ PairReaxFFKokkos::PairReaxFFKokkos(LAMMPS *lmp) : PairReaxFF(lmp) kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | Q_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | Q_MASK | F_MASK | TAG_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_resize_bo = DAT::tdual_int_scalar("pair:resize_bo"); diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 8ae5bf1269..cae17102a8 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -70,7 +70,7 @@ PairTersoffKokkos::PairTersoffKokkos(LAMMPS *lmp) : PairTersoff(lmp) kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | TAG_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; } diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 0036c7f007..06ef0dcceb 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -60,7 +60,7 @@ PairTersoffMODKokkos::PairTersoffMODKokkos(LAMMPS *lmp) : PairTersof kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | TAG_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; } diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index 44d8757a37..accbe9a863 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -62,7 +62,7 @@ PairTersoffZBLKokkos::PairTersoffZBLKokkos(LAMMPS *lmp) : PairTersof kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | TAG_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; if (strcmp(update->unit_style,"metal") == 0) { diff --git a/src/KOKKOS/pair_yukawa_kokkos.cpp b/src/KOKKOS/pair_yukawa_kokkos.cpp index c288198b1b..7bdb9a9617 100644 --- a/src/KOKKOS/pair_yukawa_kokkos.cpp +++ b/src/KOKKOS/pair_yukawa_kokkos.cpp @@ -173,7 +173,6 @@ void PairYukawaKokkos::compute(int eflag_in, int vflag_in) c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; diff --git a/src/KOKKOS/pair_yukawa_kokkos.h b/src/KOKKOS/pair_yukawa_kokkos.h index b24ff66968..e04f65264b 100644 --- a/src/KOKKOS/pair_yukawa_kokkos.h +++ b/src/KOKKOS/pair_yukawa_kokkos.h @@ -83,7 +83,6 @@ class PairYukawaKokkos : public PairYukawa { DAT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; - typename AT::t_tagint_1d tag; int newton_pair; double special_lj[4]; diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index 5968c12bde..540fd8772c 100644 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -46,6 +46,7 @@ PairSW::PairSW(LAMMPS *lmp) : Pair(lmp) centroidstressflag = CENTROID_NOTAVAIL; unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); skip_threebody_flag = false; + params_mapped = 0; params = nullptr; @@ -225,12 +226,12 @@ void PairSW::compute(int eflag, int vflag) void PairSW::allocate() { allocated = 1; - int n = atom->ntypes; + int np1 = atom->ntypes + 1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(neighshort,maxshort,"pair:neighshort"); - map = new int[n+1]; + memory->create(setflag, np1, np1, "pair:setflag"); + memory->create(cutsq, np1, np1, "pair:cutsq"); + memory->create(neighshort, maxshort, "pair:neighshort"); + map = new int[np1]; } /* ---------------------------------------------------------------------- @@ -262,12 +263,49 @@ void PairSW::coeff(int narg, char **arg) { if (!allocated) allocate(); - map_element2type(narg-3,arg+3); + // read potential file and set up element maps only once + if (one_coeff || !params_mapped) { + // make certain that the setflag array is always fully initialized + // the sw/intel pair style depends on it + if (!one_coeff) { + for (int i = 0; i <= atom->ntypes; i++) { + for (int j = 0; j <= atom->ntypes; j++) { + setflag[i][j] = 0; + } + } + } - // read potential file and initialize potential parameters + map_element2type(narg-3, arg+3, (one_coeff != 0)); - read_file(arg[2]); - setup_params(); + // read potential file and initialize potential parameters + + read_file(arg[2]); + setup_params(); + params_mapped = 1; + } + + if (!one_coeff) { + int ilo, ihi, jlo, jhi; + utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error); + utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + if (((map[i] >= 0) && (strcmp(arg[i+2], elements[map[i]]) != 0)) || + ((map[i] < 0) && (strcmp(arg[i+2], "NULL") != 0))) + error->all(FLERR, "Must use consistent type to element mappings with threebody off"); + if (map[i] < 0) error->all(FLERR, "Must not set pair_coeff mapped to NULL element"); + for (int j = MAX(jlo, i); j <= jhi; j++) { + if (((map[j] >= 0) && (strcmp(arg[j+2], elements[map[j]]) != 0)) || + ((map[j] < 0) && (strcmp(arg[j+2], "NULL") != 0))) + error->all(FLERR, "Must use consistent type to element mappings with threebody off"); + if (map[j] < 0) error->all(FLERR, "Must not set pair_coeff mapped to NULL element"); + setflag[i][j] = 1; + count++; + } + } + if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients"); + } } /* ---------------------------------------------------------------------- diff --git a/src/MANYBODY/pair_sw.h b/src/MANYBODY/pair_sw.h index bf22ce6390..da25871040 100644 --- a/src/MANYBODY/pair_sw.h +++ b/src/MANYBODY/pair_sw.h @@ -54,6 +54,7 @@ class PairSW : public Pair { int maxshort; // size of short neighbor list array int *neighshort; // short neighbor list array int skip_threebody_flag; // whether to run threebody loop + int params_mapped; // whether parameters have been read and mapped to elements void settings(int, char **) override; virtual void allocate(); diff --git a/src/MISC/fix_ipi.cpp b/src/MISC/fix_ipi.cpp index c84607d0af..039ec225d7 100644 --- a/src/MISC/fix_ipi.cpp +++ b/src/MISC/fix_ipi.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -47,12 +46,12 @@ using namespace FixConst; // socket interface #ifndef _WIN32 -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #else #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -65,8 +64,7 @@ using namespace FixConst; /* Utility functions to simplify the interface with POSIX sockets */ -static void open_socket(int &sockfd, int inet, int port, char* host, - Error *error) +static void open_socket(int &sockfd, int inet, int port, char *host, Error *error) /* Opens a socket. Args: @@ -83,9 +81,9 @@ static void open_socket(int &sockfd, int inet, int port, char* host, int ai_err; #ifdef _WIN32 - error->one(FLERR,"i-PI socket implementation requires UNIX environment"); + error->one(FLERR, "i-PI socket implementation requires UNIX environment"); #else - if (inet>0) { // creates an internet socket + if (inet > 0) { // creates an internet socket // fetches information on the host struct addrinfo hints, *res; @@ -96,40 +94,39 @@ static void open_socket(int &sockfd, int inet, int port, char* host, hints.ai_flags = AI_PASSIVE; ai_err = getaddrinfo(host, std::to_string(port).c_str(), &hints, &res); - if (ai_err!=0) - error->one(FLERR,"Error fetching host data. Wrong host name?"); + if (ai_err != 0) error->one(FLERR, "Error fetching host data. Wrong host name?"); // creates socket sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sockfd < 0) - error->one(FLERR,"Error opening socket"); + if (sockfd < 0) error->one(FLERR, "Error opening socket"); // makes connection if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) - error->one(FLERR,"Error opening INET socket: wrong port or server unreachable"); + error->one(FLERR, "Error opening INET socket: wrong port or server unreachable"); freeaddrinfo(res); - } else { // creates a unix socket + } else { // creates a unix socket struct sockaddr_un serv_addr; // fills up details of the socket address memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sun_family = AF_UNIX; strcpy(serv_addr.sun_path, "/tmp/ipi_"); - strcpy(serv_addr.sun_path+9, host); + strcpy(serv_addr.sun_path + 9, host); // creates the socket sockfd = socket(AF_UNIX, SOCK_STREAM, 0); // connects if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - error->one(FLERR,"Error opening UNIX socket: server may not be running " + error->one(FLERR, + "Error opening UNIX socket: server may not be running " "or the path to the socket unavailable"); } #endif } -static void writebuffer(int sockfd, const char *data, int len, Error* error) +static void writebuffer(int sockfd, const char *data, int len, Error *error) /* Writes to a socket. Args: @@ -140,14 +137,11 @@ static void writebuffer(int sockfd, const char *data, int len, Error* error) { int n; - n = write(sockfd,data,len); - if (n < 0) - error->one(FLERR,"Error writing to socket: broken connection"); + n = write(sockfd, data, len); + if (n < 0) error->one(FLERR, "Error writing to socket: broken connection"); } - - -static void readbuffer(int sockfd, char *data, int len, Error* error) +static void readbuffer(int sockfd, char *data, int len, Error *error) /* Reads from a socket. Args: @@ -158,44 +152,52 @@ static void readbuffer(int sockfd, char *data, int len, Error* error) { int n, nr; - n = nr = read(sockfd,data,len); + n = nr = read(sockfd, data, len); - while (nr>0 && n 0 && n < len) { + nr = read(sockfd, &data[n], len - n); + n += nr; } - if (n == 0) - error->one(FLERR,"Error reading from socket: broken connection"); + if (n == 0) error->one(FLERR, "Error reading from socket: broken connection"); } /* ---------------------------------------------------------------------- */ -FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), irregular(nullptr) +FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), irregular(nullptr) { - /* format for fix: - * fix num group_id ipi host port [unix] - */ - if (strcmp(style,"ipi") != 0 && narg < 5) - error->all(FLERR,"Illegal fix ipi command"); + if (narg < 5) utils::missing_cmd_args(FLERR, "fix ipi", error); - if (atom->tag_enable == 0) - error->all(FLERR,"Cannot use fix ipi without atom IDs"); + if (atom->tag_enable == 0) error->all(FLERR, "Cannot use fix ipi without atom IDs"); + if (atom->tag_consecutive() == 0) error->all(FLERR, "Fix ipi requires consecutive atom IDs"); + if (strcmp(update->unit_style, "lj") == 0) error->all(FLERR, "Fix ipi does not support lj units"); - if (atom->tag_consecutive() == 0) - error->all(FLERR,"Fix ipi requires consecutive atom IDs"); - - if (strcmp(arg[1],"all") != 0) - error->warning(FLERR,"Fix ipi always uses group all"); + if ((strcmp(arg[1], "all") != 0) && (comm->me == 0)) + error->warning(FLERR, "Not using group 'all' with fix ipi can result in undefined behavior"); host = strdup(arg[3]); - port = utils::inumeric(FLERR,arg[4],false,lmp); + port = utils::inumeric(FLERR, arg[4], false, lmp); - inet = ((narg > 5) && (strcmp(arg[5],"unix") == 0) ) ? 0 : 1; - master = (comm->me==0) ? 1 : 0; - // check if forces should be reinitialized and set flag - reset_flag = ((narg > 6 && (strcmp(arg[5],"reset") == 0 )) || ((narg > 5) && (strcmp(arg[5],"reset") == 0)) ) ? 1 : 0; + master = (comm->me == 0) ? 1 : 0; + inet = 1; + reset_flag = 0; + + int iarg = 5; + while (iarg < narg) { + if (strcmp(arg[iarg], "unix") == 0) { + inet = 0; + ++iarg; + } else if (strcmp(arg[iarg], "reset") == 0) { + reset_flag = 1; + ++iarg; + } else { + error->all(FLERR, "Unknown fix ipi keyword: {}", arg[iarg]); + } + } + + // sanity check + if (inet && ((port <= 1024) || (port > 65536))) + error->all(FLERR, "Invalid port for fix ipi: {}", port); hasdata = bsize = 0; @@ -223,7 +225,6 @@ FixIPI::~FixIPI() delete irregular; } - /* ---------------------------------------------------------------------- */ int FixIPI::setmask() @@ -240,9 +241,11 @@ void FixIPI::init() { //only opens socket on master process if (master) { - if (!socketflag) open_socket(ipisock, inet, port, host, error); - } else ipisock=0; - //! should check for success in socket opening -- but the current open_socket routine dies brutally if unsuccessful + if (!socketflag) open_socket(ipisock, inet, port, host, error); + } else + ipisock = 0; + // TODO: should check for success in socket opening, + // but the current open_socket routine dies brutally if unsuccessful // tell lammps we have assigned a socket socketflag = 1; @@ -252,11 +255,13 @@ void FixIPI::init() kspace_flag = (force->kspace) ? 1 : 0; - // makes sure that neighbor lists are re-built at each step (cannot make assumptions when cycling over beads!) + // makes sure that neighbor lists are re-built at each step + // (cannot make assumptions when cycling over beads!) neighbor->delay = 0; neighbor->every = 1; } +// clang-format off void FixIPI::initial_integrate(int /*vflag*/) { /* This is called at the beginning of the integration loop, diff --git a/src/ML-PACE/pair_pace_extrapolation.cpp b/src/ML-PACE/pair_pace_extrapolation.cpp index d95c4cfb91..ec185e75df 100644 --- a/src/ML-PACE/pair_pace_extrapolation.cpp +++ b/src/ML-PACE/pair_pace_extrapolation.cpp @@ -96,6 +96,7 @@ PairPACEExtrapolation::PairPACEExtrapolation(LAMMPS *lmp) : Pair(lmp) aceimpl = new ACEALImpl; scale = nullptr; + flag_compute_extrapolation_grade = 0; extrapolation_grade_gamma = nullptr; } diff --git a/src/ML-PACE/pair_pace_extrapolation.h b/src/ML-PACE/pair_pace_extrapolation.h index 4c31fcbc3f..c5d9da23db 100644 --- a/src/ML-PACE/pair_pace_extrapolation.h +++ b/src/ML-PACE/pair_pace_extrapolation.h @@ -51,7 +51,6 @@ class PairPACEExtrapolation : public Pair { void allocate(); std::vector element_names; // list of elements (used by dump pace/extrapolation) - int nelements; // # of unique elements double *extrapolation_grade_gamma; //per-atom gamma value int flag_compute_extrapolation_grade; diff --git a/src/PYTHON/python_impl.cpp b/src/PYTHON/python_impl.cpp index 92668674d1..9177381a35 100644 --- a/src/PYTHON/python_impl.cpp +++ b/src/PYTHON/python_impl.cpp @@ -112,37 +112,42 @@ PythonImpl::~PythonImpl() void PythonImpl::command(int narg, char **arg) { - if (narg < 2) error->all(FLERR, "Invalid python command"); + if (narg < 2) utils::missing_cmd_args(FLERR, "python", error); // if invoke is only keyword, invoke the previously defined function if (narg == 2 && strcmp(arg[1], "invoke") == 0) { int ifunc = find(arg[0]); - if (ifunc < 0) error->all(FLERR, "Python invoke of undefined function"); + if (ifunc < 0) error->all(FLERR, "Python invoke of unknown function: {}", arg[0]); char *str = nullptr; if (pfuncs[ifunc].noutput) { str = input->variable->pythonstyle(pfuncs[ifunc].ovarname, pfuncs[ifunc].name); - if (!str) error->all(FLERR, "Python variable does not match Python function"); + if (!str) + error->all(FLERR, + "Python variable {} does not match variable {} " + "registered with Python function {}", + arg[0], pfuncs[ifunc].ovarname, pfuncs[ifunc].name); } invoke_function(ifunc, str); return; } - // if source is only keyword, execute the python code + // if source is only keyword, execute the python code in file - if (narg == 3 && strcmp(arg[1], "source") == 0) { - int err; + if ((narg > 1) && (strcmp(arg[0], "source") == 0)) { + int err = -1; - FILE *fp = fopen(arg[2], "r"); - if (fp == nullptr) + if ((narg > 2) && (strcmp(arg[1], "here") == 0)) { err = execute_string(arg[2]); - else - err = execute_file(arg[2]); - - if (fp) fclose(fp); - if (err) error->all(FLERR, "Could not process Python source command"); + } else { + if (platform::file_is_readable(arg[1])) + err = execute_file(arg[1]); + else + error->all(FLERR, "Could not open python source file {} for processing", arg[1]); + } + if (err) error->all(FLERR, "Failure in python source command"); return; } @@ -162,48 +167,51 @@ void PythonImpl::command(int narg, char **arg) int iarg = 1; while (iarg < narg) { if (strcmp(arg[iarg], "input") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "python input", error); ninput = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); - if (ninput < 0) error->all(FLERR, "Invalid python command"); + if (ninput < 0) error->all(FLERR, "Invalid number of python input arguments: {}", ninput); iarg += 2; delete[] istr; istr = new char *[ninput]; - if (iarg + ninput > narg) error->all(FLERR, "Invalid python command"); + if (iarg + ninput > narg) utils::missing_cmd_args(FLERR, "python input", error); for (int i = 0; i < ninput; i++) istr[i] = arg[iarg + i]; iarg += ninput; } else if (strcmp(arg[iarg], "return") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "python return", error); noutput = 1; ostr = arg[iarg + 1]; iarg += 2; } else if (strcmp(arg[iarg], "format") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "python format", error); format = utils::strdup(arg[iarg + 1]); iarg += 2; } else if (strcmp(arg[iarg], "length") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "python length", error); length_longstr = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); - if (length_longstr <= 0) error->all(FLERR, "Invalid python command"); + if (length_longstr <= 0) error->all(FLERR, "Invalid python return value length"); iarg += 2; } else if (strcmp(arg[iarg], "file") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "python file", error); delete[] pyfile; pyfile = utils::strdup(arg[iarg + 1]); iarg += 2; } else if (strcmp(arg[iarg], "here") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "python here", error); herestr = arg[iarg + 1]; iarg += 2; } else if (strcmp(arg[iarg], "exists") == 0) { existflag = 1; iarg++; } else - error->all(FLERR, "Invalid python command"); + error->all(FLERR, "Unknown python command keyword: {}", arg[iarg]); } - if (pyfile && herestr) error->all(FLERR, "Invalid python command"); - if (pyfile && existflag) error->all(FLERR, "Invalid python command"); - if (herestr && existflag) error->all(FLERR, "Invalid python command"); + if (pyfile && herestr) + error->all(FLERR, "Must not use python 'file' and 'here' keywords at the same time"); + if (pyfile && existflag) + error->all(FLERR, "Must not use python 'file' and 'exists' keywords at the same time"); + if (herestr && existflag) + error->all(FLERR, "Must not use python 'here' and 'exists' keywords at the same time"); // create or overwrite entry in pfuncs vector with name = arg[0] @@ -221,23 +229,21 @@ void PythonImpl::command(int narg, char **arg) if (fp == nullptr) { PyUtils::Print_Errors(); - error->all(FLERR, "Could not open Python file"); + error->all(FLERR, "Could not open Python file: {}", pyfile); } int err = PyRun_SimpleFile(fp, pyfile); - if (err) { PyUtils::Print_Errors(); - error->all(FLERR, "Could not process Python file"); + error->all(FLERR, "Could not process Python file: {}", pyfile); } - fclose(fp); + } else if (herestr) { int err = PyRun_SimpleString(herestr); - if (err) { PyUtils::Print_Errors(); - error->all(FLERR, "Could not process Python string"); + error->all(FLERR, "Could not process Python string: {}", herestr); } } @@ -280,14 +286,17 @@ void PythonImpl::invoke_function(int ifunc, char *result) int ninput = pfuncs[ifunc].ninput; PyObject *pArgs = PyTuple_New(ninput); - if (!pArgs) { error->all(FLERR, "Could not create Python function arguments"); } + if (!pArgs) + error->all(FLERR, "Could not prepare arguments for Python function {}", pfuncs[ifunc].name); for (int i = 0; i < ninput; i++) { int itype = pfuncs[ifunc].itype[i]; if (itype == INT) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); - if (!str) { error->all(FLERR, "Could not evaluate Python function input variable"); } + if (!str) + error->all(FLERR, "Could not evaluate Python function {} input variable: {}", + pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]); pValue = PY_INT_FROM_LONG(atoi(str)); } else { pValue = PY_INT_FROM_LONG(pfuncs[ifunc].ivalue[i]); @@ -295,7 +304,9 @@ void PythonImpl::invoke_function(int ifunc, char *result) } else if (itype == DOUBLE) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); - if (!str) { error->all(FLERR, "Could not evaluate Python function input variable"); } + if (!str) + error->all(FLERR, "Could not evaluate Python function {} input variable: {}", + pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]); pValue = PyFloat_FromDouble(atof(str)); } else { pValue = PyFloat_FromDouble(pfuncs[ifunc].dvalue[i]); @@ -303,7 +314,9 @@ void PythonImpl::invoke_function(int ifunc, char *result) } else if (itype == STRING) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); - if (!str) { error->all(FLERR, "Could not evaluate Python function input variable"); } + if (!str) + error->all(FLERR, "Could not evaluate Python function {} input variable: {}", + pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]); pValue = PY_STRING_FROM_STRING(str); } else { pValue = PY_STRING_FROM_STRING(pfuncs[ifunc].svalue[i]); @@ -311,7 +324,7 @@ void PythonImpl::invoke_function(int ifunc, char *result) } else if (itype == PTR) { pValue = PY_VOID_POINTER(lmp); } else { - error->all(FLERR, "Unsupported variable type"); + error->all(FLERR, "Unsupported variable type: {}", itype); } PyTuple_SetItem(pArgs, i, pValue); } @@ -324,7 +337,7 @@ void PythonImpl::invoke_function(int ifunc, char *result) if (!pValue) { PyUtils::Print_Errors(); - error->one(FLERR, "Python function evaluation failed"); + error->one(FLERR, "Python evaluation of function {} failed", pfuncs[ifunc].name); } // function returned a value @@ -365,9 +378,9 @@ int PythonImpl::variable_match(const char *name, const char *varname, int numeri { int ifunc = find(name); if (ifunc < 0) return -1; - if (pfuncs[ifunc].noutput == 0) return -1; - if (strcmp(pfuncs[ifunc].ovarname, varname) != 0) return -1; - if (numeric && pfuncs[ifunc].otype == STRING) return -1; + if (pfuncs[ifunc].noutput == 0) return -2; + if (strcmp(pfuncs[ifunc].ovarname, varname) != 0) return -3; + if (numeric && pfuncs[ifunc].otype == STRING) return -4; return ifunc; } @@ -400,9 +413,10 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon pfuncs[ifunc].noutput = noutput; if (!format && ninput + noutput) - error->all(FLERR, "Invalid python command"); + error->all(FLERR, "Missing python format keyword"); else if (format && ((int) strlen(format) != ninput + noutput)) - error->all(FLERR, "Invalid python command"); + error->all(FLERR, "Input/output arguments ({}) and format characters ({}) are inconsistent", + (ninput + noutput), strlen(format)); // process inputs as values or variables @@ -448,7 +462,7 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon if (strcmp(istr[i], "SELF") != 0) error->all(FLERR, "Invalid python command"); } else - error->all(FLERR, "Invalid python command"); + error->all(FLERR, "Invalid python format character: {}", type); } // process output as value or variable @@ -465,7 +479,7 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon else if (type == 's') pfuncs[ifunc].otype = STRING; else - error->all(FLERR, "Invalid python command"); + error->all(FLERR, "Invalid python return format character: {}", type); if (length_longstr) { if (pfuncs[ifunc].otype != STRING) @@ -486,7 +500,9 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon int PythonImpl::execute_string(char *cmd) { PyUtils::GIL lock; - return PyRun_SimpleString(cmd); + int err = PyRun_SimpleString(cmd); + if (err) PyUtils::Print_Errors(); + return err; } /* ---------------------------------------------------------------------- */ @@ -498,6 +514,7 @@ int PythonImpl::execute_file(char *fname) PyUtils::GIL lock; int err = PyRun_SimpleFile(fp, fname); + if (err) PyUtils::Print_Errors(); if (fp) fclose(fp); return err; diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 5dc5967c29..b983172860 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -22,6 +22,7 @@ Contributing Author: Jacob Gissinger (jacob.r.gissinger@gmail.com) #include "atom_vec.h" #include "citeme.h" #include "comm.h" +#include "compute.h" #include "domain.h" #include "error.h" #include "fix_bond_history.h" @@ -38,7 +39,7 @@ Contributing Author: Jacob Gissinger (jacob.r.gissinger@gmail.com) #include "neighbor.h" #include "pair.h" #include "random_mars.h" -#include "reset_mol_ids.h" +#include "reset_atoms_mol.h" #include "respa.h" #include "update.h" #include "variable.h" @@ -80,7 +81,7 @@ static const char cite_fix_bond_react[] = #define DELTA 16 #define MAXGUESS 20 // max # of guesses allowed by superimpose algorithm #define MAXCONARGS 14 // max # of arguments for any type of constraint + rxnID -#define NUMVARVALS 4 // max # of keyword values that have variables as input +#define NUMVARVALS 5 // max # of keyword values that have variables as input // various statuses of superimpose algorithm: // ACCEPT: site successfully matched to pre-reacted template @@ -98,7 +99,7 @@ enum{DISTANCE,ANGLE,DIHEDRAL,ARRHENIUS,RMSD,CUSTOM}; enum{ATOM,FRAG}; // keyword values that accept variables as input -enum{NEVERY,RMIN,RMAX,PROB}; +enum{NEVERY,RMIN,RMAX,PROB,NRATE}; // flag for one-proc vs shared reaction sites enum{LOCAL,GLOBAL}; @@ -118,11 +119,8 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : fix3 = nullptr; reset_mol_ids = nullptr; - if (narg < 8) error->all(FLERR,"Illegal fix bond/react command: " - "too few arguments"); + if (narg < 8) utils::missing_cmd_args(FLERR,"fix bond/react", error); - MPI_Comm_rank(world,&me); - MPI_Comm_size(world,&nprocs); newton_bond = force->newton_bond; restart_global = 1; @@ -138,10 +136,15 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : status = PROCEED; // reaction functions used by 'custom' constraint - nrxnfunction = 2; + nrxnfunction = 3; rxnfunclist.resize(nrxnfunction); + peratomflag.resize(nrxnfunction); rxnfunclist[0] = "rxnsum"; + peratomflag[0] = 1; rxnfunclist[1] = "rxnave"; + peratomflag[1] = 1; + rxnfunclist[2] = "rxnbond"; + peratomflag[2] = 0; nvvec = 0; ncustomvars = 0; vvec = nullptr; @@ -204,7 +207,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (reset_mol_ids_flag) { delete reset_mol_ids; - reset_mol_ids = new ResetMolIDs(lmp); + reset_mol_ids = new ResetAtomsMol(lmp); reset_mol_ids->create_computes(id,group->names[igroup]); } @@ -224,8 +227,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : memory->create(nghostlyskips,nreacts,"bond/react:nghostlyskips"); memory->create(seed,nreacts,"bond/react:seed"); memory->create(limit_duration,nreacts,"bond/react:limit_duration"); + memory->create(rate_limit,3,nreacts,"bond/react:rate_limit"); memory->create(stabilize_steps_flag,nreacts,"bond/react:stabilize_steps_flag"); memory->create(custom_charges_fragid,nreacts,"bond/react:custom_charges_fragid"); + memory->create(rescale_charges_flag,nreacts,"bond/react:rescale_charges_flag"); memory->create(create_atoms_flag,nreacts,"bond/react:create_atoms_flag"); memory->create(modify_create_fragid,nreacts,"bond/react:modify_create_fragid"); memory->create(overlapsq,nreacts,"bond/react:overlapsq"); @@ -249,8 +254,11 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : fraction[i] = 1; seed[i] = 12345; max_rxn[i] = INT_MAX; + for (int j = 0; j < 3; j++) + rate_limit[j][i] = 0; stabilize_steps_flag[i] = 0; custom_charges_fragid[i] = -1; + rescale_charges_flag[i] = 0; create_atoms_flag[i] = 0; modify_create_fragid[i] = -1; overlapsq[i] = 0; @@ -286,55 +294,31 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (groupid == -1) error->all(FLERR,"Could not find fix group ID"); groupbits[rxn] = group->bitmask[groupid]; - if (strncmp(arg[iarg],"v_",2) == 0) { - const char *str = &arg[iarg][2]; - var_id[NEVERY][rxn] = input->variable->find(str); - if (var_id[NEVERY][rxn] < 0) - error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str); - if (!input->variable->equalstyle(var_id[NEVERY][rxn])) - error->all(FLERR,"Fix bond/react: Variable {} is not equal-style", str); - var_flag[NEVERY][rxn] = 1; - } else { + if (strncmp(arg[iarg],"v_",2) == 0) read_variable_keyword(&arg[iarg][2],NEVERY,rxn); + else { nevery[rxn] = utils::inumeric(FLERR,arg[iarg],false,lmp); if (nevery[rxn] <= 0) error->all(FLERR,"Illegal fix bond/react command: " "'Nevery' must be a positive integer"); } iarg++; + double cutoff; if (strncmp(arg[iarg],"v_",2) == 0) { - const char *str = &arg[iarg][2]; - var_id[RMIN][rxn] = input->variable->find(str); - if (var_id[RMIN][rxn] < 0) - error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str); - if (!input->variable->equalstyle(var_id[RMIN][rxn])) - error->all(FLERR,"Fix bond/react: Variable {} is not equal-style", str); - double cutoff = input->variable->compute_equal(var_id[RMIN][rxn]); - cutsq[rxn][0] = cutoff*cutoff; - var_flag[RMIN][rxn] = 1; - } else { - double cutoff = utils::numeric(FLERR,arg[iarg],false,lmp); + read_variable_keyword(&arg[iarg][2],RMIN,rxn); + cutoff = input->variable->compute_equal(var_id[RMIN][rxn]); + } else cutoff = utils::numeric(FLERR,arg[iarg],false,lmp); if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/react command: " "'Rmin' cannot be negative"); cutsq[rxn][0] = cutoff*cutoff; - } iarg++; if (strncmp(arg[iarg],"v_",2) == 0) { - const char *str = &arg[iarg][2]; - var_id[RMAX][rxn] = input->variable->find(str); - if (var_id[RMAX][rxn] < 0) - error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str); - if (!input->variable->equalstyle(var_id[RMAX][rxn])) - error->all(FLERR,"Fix bond/react: Variable is {} not equal-style", str); - double cutoff = input->variable->compute_equal(var_id[RMAX][rxn]); - cutsq[rxn][1] = cutoff*cutoff; - var_flag[RMAX][rxn] = 1; - } else { - double cutoff = utils::numeric(FLERR,arg[iarg],false,lmp); + read_variable_keyword(&arg[iarg][2],RMAX,rxn); + cutoff = input->variable->compute_equal(var_id[RMAX][rxn]); + } else cutoff = utils::numeric(FLERR,arg[iarg],false,lmp); if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/react command:" "'Rmax' cannot be negative"); cutsq[rxn][1] = cutoff*cutoff; - } iarg++; unreacted_mol[rxn] = atom->find_molecule(arg[iarg++]); @@ -344,7 +328,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (reacted_mol[rxn] == -1) error->all(FLERR,"Reacted molecule template ID for " "fix bond/react does not exist"); - // read superimpose file + //read map file files[rxn] = utils::strdup(arg[iarg]); iarg++; @@ -354,14 +338,8 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : "'prob' keyword has too few arguments"); // check if probability is a variable if (strncmp(arg[iarg+1],"v_",2) == 0) { - const char *str = &arg[iarg+1][2]; - var_id[PROB][rxn] = input->variable->find(str); - if (var_id[PROB][rxn] < 0) - error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str); - if (!input->variable->equalstyle(var_id[PROB][rxn])) - error->all(FLERR,"Fix bond/react: Variable {} is not equal-style", str); + read_variable_keyword(&arg[iarg+1][2],PROB,rxn); fraction[rxn] = input->variable->compute_equal(var_id[PROB][rxn]); - var_flag[PROB][rxn] = 1; } else { // otherwise probability should be a number fraction[rxn] = utils::numeric(FLERR,arg[iarg+1],false,lmp); @@ -380,6 +358,14 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (max_rxn[rxn] < 0) error->all(FLERR,"Illegal fix bond/react command: " "'max_rxn' cannot be negative"); iarg += 2; + } else if (strcmp(arg[iarg],"rate_limit") == 0) { + if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/react command: " + "'rate_limit' has too few arguments"); + rate_limit[0][rxn] = 1; // serves as flag for rate_limit keyword + if (strncmp(arg[iarg+1],"v_",2) == 0) read_variable_keyword(&arg[iarg+1][2],NRATE,rxn); + else rate_limit[1][rxn] = utils::numeric(FLERR,arg[iarg+1],false,lmp); + rate_limit[2][rxn] = utils::numeric(FLERR,arg[iarg+2],false,lmp); + iarg += 3; } else if (strcmp(arg[iarg],"stabilize_steps") == 0) { if (stabilization_flag == 0) error->all(FLERR,"Stabilize_steps keyword " "used without stabilization keyword"); @@ -398,6 +384,13 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : "'custom_charges' keyword does not exist"); } iarg += 2; + } else if (strcmp(arg[iarg],"rescale_charges") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: " + "'rescale_charges' has too few arguments"); + if (strcmp(arg[iarg+1],"no") == 0) rescale_charges_flag[rxn] = 0; //default + else if (strcmp(arg[iarg+1],"yes") == 0) rescale_charges_flag[rxn] = 1; + else error->one(FLERR,"Bond/react: Illegal option for 'rescale_charges' keyword"); + iarg += 2; } else if (strcmp(arg[iarg],"molecule") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: " "'molecule' has too few arguments"); @@ -433,21 +426,24 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : } max_natoms = 0; // the number of atoms in largest molecule template + max_rate_limit_steps = 0; for (int myrxn = 0; myrxn < nreacts; myrxn++) { twomol = atom->molecules[reacted_mol[myrxn]]; max_natoms = MAX(max_natoms,twomol->natoms); + max_rate_limit_steps = MAX(max_rate_limit_steps,rate_limit[2][myrxn]); } memory->create(equivalences,max_natoms,2,nreacts,"bond/react:equivalences"); memory->create(reverse_equiv,max_natoms,2,nreacts,"bond/react:reverse_equiv"); memory->create(edge,max_natoms,nreacts,"bond/react:edge"); memory->create(landlocked_atoms,max_natoms,nreacts,"bond/react:landlocked_atoms"); + memory->create(store_rxn_count,max_rate_limit_steps,nreacts,"bond/react:store_rxn_count"); memory->create(custom_charges,max_natoms,nreacts,"bond/react:custom_charges"); memory->create(delete_atoms,max_natoms,nreacts,"bond/react:delete_atoms"); memory->create(create_atoms,max_natoms,nreacts,"bond/react:create_atoms"); memory->create(chiral_atoms,max_natoms,6,nreacts,"bond/react:chiral_atoms"); - for (int j = 0; j < nreacts; j++) + for (int j = 0; j < nreacts; j++) { for (int i = 0; i < max_natoms; i++) { edge[i][j] = 0; custom_charges[i][j] = 1; // update all partial charges by default @@ -462,6 +458,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : equivalences[i][m][j] = i+1; } } + for (int i = 0; i < max_rate_limit_steps; i++) { + store_rxn_count[i][j] = -1; + } + } // read all map files afterward for (int i = 0; i < nreacts; i++) { @@ -471,7 +471,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : onemol->check_attributes(); twomol->check_attributes(); get_molxspecials(); - read(i); + read_map_file(i); fclose(fp); if (ncreate == 0 && onemol->natoms != twomol->natoms) error->all(FLERR,"Fix bond/react: Reaction templates must contain the same number of atoms"); @@ -493,7 +493,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : for (int i = 0; i < nreacts; i++) { for (int j = 0; j < nconstraints[i]; j++) { if (constraints[j][i].type == ARRHENIUS) { - rrhandom[tmp++] = new RanMars(lmp,(int) constraints[j][i].par[4] + me); + rrhandom[tmp++] = new RanMars(lmp,(int) constraints[j][i].par[4] + comm->me); } } } @@ -528,7 +528,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : random = new RanMars*[nreacts]; for (int i = 0; i < nreacts; i++) { - random[i] = new RanMars(lmp,seed[i] + me); + random[i] = new RanMars(lmp,seed[i] + comm->me); } // set comm sizes needed by this fix @@ -598,6 +598,7 @@ FixBondReact::~FixBondReact() memory->destroy(equivalences); memory->destroy(reverse_equiv); memory->destroy(landlocked_atoms); + memory->destroy(store_rxn_count); memory->destroy(custom_charges); memory->destroy(delete_atoms); memory->destroy(create_atoms); @@ -617,8 +618,10 @@ FixBondReact::~FixBondReact() memory->destroy(limit_duration); memory->destroy(var_flag); memory->destroy(var_id); + memory->destroy(rate_limit); memory->destroy(stabilize_steps_flag); memory->destroy(custom_charges_fragid); + memory->destroy(rescale_charges_flag); memory->destroy(molecule_keyword); memory->destroy(nconstraints); memory->destroy(constraintstr); @@ -819,6 +822,16 @@ void FixBondReact::init_list(int /*id*/, NeighList *ptr) void FixBondReact::post_integrate() { + // update store_rxn_count on every step + for (int myrxn = 0; myrxn < nreacts; myrxn++) { + if (rate_limit[0][myrxn] == 1) { + for (int i = rate_limit[2][myrxn]-1; i > 0; i--) { + store_rxn_count[i][myrxn] = store_rxn_count[i-1][myrxn]; + } + store_rxn_count[0][myrxn] = reaction_count_total[myrxn]; + } + } + // check if any reactions could occur on this timestep int nevery_check = 1; for (int i = 0; i < nreacts; i++) { @@ -873,6 +886,8 @@ void FixBondReact::post_integrate() for (int i = 0; i < nreacts; i++) { nattempt[i] = 0; } + // reset per-bond compute map flag + atoms2bondflag = 0; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; @@ -911,8 +926,22 @@ void FixBondReact::post_integrate() int j; for (rxnID = 0; rxnID < nreacts; rxnID++) { + int rate_limit_flag = 1; + if (rate_limit[0][rxnID] == 1) { + int myrxn_count = store_rxn_count[rate_limit[2][rxnID]-1][rxnID]; + if (myrxn_count == -1) rate_limit_flag = 0; + else { + int nrxns_delta = reaction_count_total[rxnID] - myrxn_count; + int my_nrate; + if (var_flag[NRATE][rxnID] == 1) { + my_nrate = input->variable->compute_equal(var_id[NRATE][rxnID]); + } else my_nrate = rate_limit[1][rxnID]; + if (nrxns_delta > my_nrate) rate_limit_flag = 0; + } + } if ((update->ntimestep % nevery[rxnID]) || - (max_rxn[rxnID] <= reaction_count_total[rxnID])) continue; + (max_rxn[rxnID] <= reaction_count_total[rxnID]) || + (rate_limit_flag == 0)) continue; for (int ii = 0; ii < nall; ii++) { partner[ii] = 0; finalpartner[ii] = 0; @@ -1221,6 +1250,7 @@ void FixBondReact::close_partner() void FixBondReact::superimpose_algorithm() { + const int nprocs = comm->nprocs; local_num_mega = 0; ghostly_num_mega = 0; @@ -1370,7 +1400,7 @@ void FixBondReact::superimpose_algorithm() MPI_Allreduce(&local_rxn_count[0],&reaction_count[0],nreacts,MPI_INT,MPI_SUM,world); int rxnflag = 0; - if (me == 0) + if (comm->me == 0) for (int i = 0; i < nreacts; i++) { reaction_count_total[i] += reaction_count[i] + ghostly_rxn_count[i]; rxnflag += reaction_count[i] + ghostly_rxn_count[i]; @@ -1385,18 +1415,37 @@ void FixBondReact::superimpose_algorithm() std::random_device rnd; std::minstd_rand park_rng(rnd()); - // check if we overstepped our reaction limit + // check if we overstepped our reaction limit, via either max_rxn or rate_limit for (int i = 0; i < nreacts; i++) { - if (reaction_count_total[i] > max_rxn[i]) { + int overstep = 0; + int max_rxn_overstep = reaction_count_total[i] - max_rxn[i]; + overstep = MAX(overstep,max_rxn_overstep); + if (rate_limit[0][i] == 1) { + int myrxn_count = store_rxn_count[rate_limit[2][i]-1][i]; + if (myrxn_count != -1) { + int nrxn_delta = reaction_count_total[i] - myrxn_count; + int my_nrate; + if (var_flag[NRATE][i] == 1) { + my_nrate = input->variable->compute_equal(var_id[NRATE][i]); + } else my_nrate = rate_limit[1][i]; + int rate_limit_overstep = nrxn_delta - my_nrate; + overstep = MAX(overstep,rate_limit_overstep); + } + } + + if (overstep > 0) { // let's randomly choose rxns to skip, unbiasedly from local and ghostly int *local_rxncounts; int *all_localskips; memory->create(local_rxncounts,nprocs,"bond/react:local_rxncounts"); memory->create(all_localskips,nprocs,"bond/react:all_localskips"); MPI_Gather(&local_rxn_count[i],1,MPI_INT,local_rxncounts,1,MPI_INT,0,world); - if (me == 0) { - int overstep = reaction_count_total[i] - max_rxn[i]; + if (comm->me == 0) { int delta_rxn = reaction_count[i] + ghostly_rxn_count[i]; + // when using variable input for rate_limit, rate_limit_overstep could be > delta_rxn (below) + // we need to limit overstep to the number of reactions on this timestep + // essentially skipping all reactions, would be more efficient to use a skip_all flag + if (overstep > delta_rxn) overstep = delta_rxn; int *rxn_by_proc; memory->create(rxn_by_proc,delta_rxn,"bond/react:rxn_by_proc"); for (int j = 0; j < delta_rxn; j++) @@ -1414,14 +1463,15 @@ void FixBondReact::superimpose_algorithm() else all_localskips[rxn_by_proc[j]]++; } memory->destroy(rxn_by_proc); + reaction_count_total[i] -= overstep; } - reaction_count_total[i] = max_rxn[i]; MPI_Scatter(&all_localskips[0],1,MPI_INT,&nlocalskips[i],1,MPI_INT,0,world); MPI_Bcast(&nghostlyskips[i],1,MPI_INT,0,world); memory->destroy(local_rxncounts); memory->destroy(all_localskips); } } + MPI_Bcast(&reaction_count_total[0], nreacts, MPI_INT, 0, world); // this updates topology next step next_reneighbor = update->ntimestep; @@ -2118,7 +2168,7 @@ double FixBondReact::get_temperature(tagint **myglove, int row_offset, int col) } /* ---------------------------------------------------------------------- -get per-atom variable names used by custom constraint +get per-atom variable names used by custom constraint ------------------------------------------------------------------------- */ void FixBondReact::customvarnames() @@ -2140,6 +2190,7 @@ void FixBondReact::customvarnames() // find next reaction special function occurrence pos1 = std::string::npos; for (int i = 0; i < nrxnfunction; i++) { + if (peratomflag[i] == 0) continue; pos = varstr.find(rxnfunclist[i],prev3+1); if (pos == std::string::npos) continue; if (pos < pos1) pos1 = pos; @@ -2261,12 +2312,67 @@ double FixBondReact::custom_constraint(const std::string& varstr) } /* ---------------------------------------------------------------------- -currently two 'rxn' functions: rxnsum and rxnave +currently three 'rxn' functions: rxnsum, rxnave, and rxnbond ------------------------------------------------------------------------- */ double FixBondReact::rxnfunction(const std::string& rxnfunc, const std::string& varid, const std::string& fragid) { + int ifrag = -1; + if (fragid != "all") { + ifrag = onemol->findfragment(fragid.c_str()); + if (ifrag < 0) error->one(FLERR,"Bond/react: Molecule fragment " + "in reaction special function does not exist"); + } + + // start with 'rxnbond' per-bond function + // for 'rxnbond', varid corresponds to 'compute bond/local' name, + // and fragid is a pre-reaction fragment containing the two atoms in the bond + if (rxnfunc == "rxnbond") { + int icompute,ibond,nsum; + double perbondval; + std::set aset; + std::string computeid = varid; + std::map,int>::iterator it; + + if (computeid.substr(0,2) != "c_") error->one(FLERR,"Bond/react: Reaction special function compute " + "name should begin with 'c_'"); + computeid = computeid.substr(2); + icompute = modify->find_compute(computeid); + if (icompute < 0) error->one(FLERR,"Bond/react: Reaction special function compute name does not exist"); + cperbond = modify->compute[icompute]; + std::string compute_style = cperbond->style; + if (compute_style != "bond/local") error->one(FLERR,"Bond/react: Compute used by reaction " + "special function 'rxnbond' must be of style 'bond/local'"); + if (cperbond->size_local_cols > 0) error->one(FLERR,"Bond/react: 'Compute bond/local' used by reaction " + "special function 'rxnbond' must compute one value"); + + if (atoms2bondflag == 0) { + atoms2bondflag = 1; + get_atoms2bond(cperbond->groupbit); + } + + nsum = 0; + for (int i = 0; i < onemol->natoms; i++) { + if (onemol->fragmentmask[ifrag][i]) { + aset.insert(glove[i][1]); + nsum++; + } + } + if (nsum != 2) error->one(FLERR,"Bond/react: Molecule fragment of reaction special function 'rxnbond' " + "must contain exactly two atoms"); + + if (cperbond->invoked_local != lmp->update->ntimestep) + cperbond->compute_local(); + + it = atoms2bond.find(aset); + if (it == atoms2bond.end()) error->one(FLERR,"Bond/react: Unable to locate bond referenced by " + "reaction special function 'rxnbond'"); + ibond = it->second; + perbondval = cperbond->vector_local[ibond]; + return perbondval; + } + int ivar = -1; for (int i = 0; i < ncustomvars; i++) { if (varid == customvarstrs[i]) { @@ -2280,13 +2386,6 @@ double FixBondReact::rxnfunction(const std::string& rxnfunc, const std::string& error->one(FLERR,"Fix bond/react: Reaction special function variable " "name does not exist"); - int ifrag = -1; - if (fragid != "all") { - ifrag = onemol->findfragment(fragid.c_str()); - if (ifrag < 0) error->one(FLERR,"Fix bond/react: Molecule fragment " - "in reaction special function does not exist"); - } - int iatom; int nsum = 0; double sumvvec = 0; @@ -2313,6 +2412,39 @@ double FixBondReact::rxnfunction(const std::string& rxnfunc, const std::string& return 0.0; } +/* ---------------------------------------------------------------------- +populate map to get bond index from atom IDs +------------------------------------------------------------------------- */ + +void FixBondReact::get_atoms2bond(int cgroupbit) +{ + int i,m,atom1,atom2,btype,nb; + std::set aset; + + int nlocal = atom->nlocal; + tagint *tag = atom->tag; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + int *mask = atom->mask; + + m = 0; + atoms2bond.clear(); + for (atom1 = 0; atom1 < nlocal; atom1++) { + if (!(mask[atom1] & cgroupbit)) continue; + nb = num_bond[atom1]; + for (i = 0; i < nb; i++) { + btype = bond_type[atom1][i]; + atom2 = atom->map(bond_atom[atom1][i]); + if (atom2 < 0 || !(mask[atom2] & cgroupbit)) continue; + if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; + if (btype == 0) continue; + aset = {tag[atom1], tag[atom2]}; + atoms2bond.insert(std::make_pair(aset,m++)); + } + } +} + /* ---------------------------------------------------------------------- return handedness (1 or -1) of a chiral center, given ordered set of coordinates ------------------------------------------------------------------------- */ @@ -2483,7 +2615,7 @@ void FixBondReact::find_landlocked_atoms(int myrxn) } // also, if atoms change number of bonds, but aren't landlocked, that could be bad - if (me == 0) + if (comm->me == 0) for (int i = 0; i < twomol->natoms; i++) { if ((create_atoms[i][myrxn] == 0) && (twomol_nxspecial[i][0] != onemol_nxspecial[equivalences[i][1][myrxn]-1][0]) && @@ -2815,6 +2947,7 @@ broadcast entries of mega_glove which contain nonlocal atoms for perusal by all void FixBondReact::ghost_glovecast() { #if !defined(MPI_STUBS) + const int nprocs = comm->nprocs; global_megasize = 0; @@ -2833,7 +2966,7 @@ void FixBondReact::ghost_glovecast() int *allstarts = new int[nprocs]; int start = 0; - for (int i = 0; i < me; i++) { + for (int i = 0; i < comm->me; i++) { start += allncols[i]; } MPI_Allgather(&start, 1, MPI_INT, allstarts, 1, MPI_INT, world); @@ -2861,7 +2994,7 @@ void FixBondReact::ghost_glovecast() } } // let's send to root, dedup, then broadcast - if (me == 0) { + if (comm->me == 0) { MPI_Gatherv(MPI_IN_PLACE, ghostly_num_mega, column, // Note: some values ignored for MPI_IN_PLACE &(global_mega_glove[0][0]), allncols, allstarts, column, 0, world); @@ -2871,7 +3004,7 @@ void FixBondReact::ghost_glovecast() column, 0, world); } - if (me == 0) dedup_mega_gloves(GLOBAL); // global_mega_glove mode + if (comm->me == 0) dedup_mega_gloves(GLOBAL); // global_mega_glove mode MPI_Bcast(&global_megasize,1,MPI_INT,0,world); MPI_Bcast(&(global_mega_glove[0][0]), global_megasize, column, 0, world); @@ -2985,6 +3118,8 @@ void FixBondReact::update_everything() } delete [] iskip; + if (update_num_mega == 0) continue; + // if inserted atoms and global map exists, reset map now instead // of waiting for comm since other pre-exchange fixes may use it // invoke map_init() b/c atom count has grown @@ -3012,6 +3147,33 @@ void FixBondReact::update_everything() } } + // get charge rescale delta + double charge_rescale_addend = 0; + if (rescale_charges_flag[rxnID] == 1) { + double sim_total_charge = 0; + double mol_total_charge = 0; + int n_custom_charge = 0; + for (int i = 0; i < update_num_mega; i++) { + rxnID = update_mega_glove[0][i]; + twomol = atom->molecules[reacted_mol[rxnID]]; + for (int j = 0; j < twomol->natoms; j++) { + int jj = equivalences[j][1][rxnID]-1; + if (atom->map(update_mega_glove[jj+1][i]) >= 0 && + atom->map(update_mega_glove[jj+1][i]) < nlocal) { + if (landlocked_atoms[j][rxnID] == 1) + type[atom->map(update_mega_glove[jj+1][i])] = twomol->type[j]; + if (twomol->qflag && atom->q_flag && custom_charges[jj][rxnID] == 1) { + double *q = atom->q; + sim_total_charge += q[atom->map(update_mega_glove[jj+1][i])]; + mol_total_charge += twomol->q[j]; + n_custom_charge++; + } + } + } + } + charge_rescale_addend = (sim_total_charge-mol_total_charge)/n_custom_charge; + } + // update charges and types of landlocked atoms for (int i = 0; i < update_num_mega; i++) { rxnID = update_mega_glove[0][i]; @@ -3024,7 +3186,7 @@ void FixBondReact::update_everything() type[atom->map(update_mega_glove[jj+1][i])] = twomol->type[j]; if (twomol->qflag && atom->q_flag && custom_charges[jj][rxnID] == 1) { double *q = atom->q; - q[atom->map(update_mega_glove[jj+1][i])] = twomol->q[j]; + q[atom->map(update_mega_glove[jj+1][i])] = twomol->q[j]+charge_rescale_addend; } } } @@ -3584,7 +3746,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) Superpose3D superposer(n2superpose); int fitroot = 0; if (ifit >= 0 && ifit < atom->nlocal) { - fitroot = me; + fitroot = comm->me; // get 'temperatere' averaged over site, used for created atoms' vels t = get_temperature(my_mega_glove,1,iupdate); @@ -3602,7 +3764,8 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) int ipre = equivalences[j][1][rxnID]-1; // equiv pre-reaction template index if (!create_atoms[j][rxnID] && !delete_atoms[ipre][rxnID]) { if (atom->map(my_mega_glove[ipre+1][iupdate]) < 0) { - error->warning(FLERR," eligible atoms skipped for created-atoms fit on rank {}\n",me); + error->warning(FLERR," eligible atoms skipped for created-atoms fit on rank {}\n", + comm->me); continue; } iatom = atom->map(my_mega_glove[ipre+1][iupdate]); @@ -3630,7 +3793,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) if (create_atoms[m][rxnID] == 1) { // apply optimal rotation/translation for created atom coords // also map coords back into simulation box - if (fitroot == me) { + if (fitroot == comm->me) { MathExtra::matvec(rotmat,twomol->x[m],coords[m]); for (int i = 0; i < 3; i++) coords[m][i] += superposer.T[i]; imageflags[m] = atom->image[ifit]; @@ -3718,7 +3881,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) int root = 0; if (flag) { - root = me; + root = comm->me; atom->avec->create_atom(twomol->type[m],coords[m]); int n = atom->nlocal - 1; @@ -3795,10 +3958,24 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) } /* ---------------------------------------------------------------------- -read superimpose file +add equal-style variable to keyword argument list ------------------------------------------------------------------------- */ -void FixBondReact::read(int myrxn) +void FixBondReact::read_variable_keyword(const char *myarg, int keyword, int myrxn) +{ + var_id[keyword][myrxn] = input->variable->find(myarg); + if (var_id[keyword][myrxn] < 0) + error->all(FLERR,"Fix bond/react: Variable name {} does not exist",myarg); + if (!input->variable->equalstyle(var_id[keyword][myrxn])) + error->all(FLERR,"Fix bond/react: Variable {} is not equal-style",myarg); + var_flag[keyword][myrxn] = 1; +} + +/* ---------------------------------------------------------------------- +read map file +------------------------------------------------------------------------- */ + +void FixBondReact::read_map_file(int myrxn) { char line[MAXLINE],keyword[MAXLINE]; char *eof,*ptr; @@ -3850,7 +4027,7 @@ void FixBondReact::read(int myrxn) while (strlen(keyword)) { if (strcmp(keyword,"InitiatorIDs") == 0 || strcmp(keyword,"BondingIDs") == 0) { if (strcmp(keyword,"BondingIDs") == 0) - if (me == 0) error->warning(FLERR,"Fix bond/react: The BondingIDs section title has been deprecated. Please use InitiatorIDs instead."); + if (comm->me == 0) error->warning(FLERR,"Fix bond/react: The BondingIDs section title has been deprecated. Please use InitiatorIDs instead."); bondflag = 1; readline(line); sscanf(line,"%d",&ibonding[myrxn]); @@ -4116,7 +4293,7 @@ void FixBondReact::open(char *file) void FixBondReact::readline(char *line) { int n; - if (me == 0) { + if (comm->me == 0) { if (fgets(line,MAXLINE,fp) == nullptr) n = 0; else n = strlen(line) + 1; } @@ -4133,7 +4310,7 @@ void FixBondReact::parse_keyword(int flag, char *line, char *keyword) // eof is set to 1 if any read hits end-of-file int eof = 0; - if (me == 0) { + if (comm->me == 0) { if (fgets(line,MAXLINE,fp) == nullptr) eof = 1; while (eof == 0 && strspn(line," \t\n\r") == strlen(line)) { if (fgets(line,MAXLINE,fp) == nullptr) eof = 1; @@ -4152,7 +4329,7 @@ void FixBondReact::parse_keyword(int flag, char *line, char *keyword) // bcast keyword line to all procs int n; - if (me == 0) n = strlen(line) + 1; + if (comm->me == 0) n = strlen(line) + 1; MPI_Bcast(&n,1,MPI_INT,0,world); MPI_Bcast(line,n,MPI_CHAR,0,world); } @@ -4299,34 +4476,71 @@ void FixBondReact::unpack_reverse_comm(int n, int *list, double *buf) void FixBondReact::write_restart(FILE *fp) { + int revision = 1; set[0].nreacts = nreacts; + set[0].max_rate_limit_steps = max_rate_limit_steps; + for (int i = 0; i < nreacts; i++) { set[i].reaction_count_total = reaction_count_total[i]; + strncpy(set[i].rxn_name,rxn_name[i],MAXLINE-1); set[i].rxn_name[MAXLINE-1] = '\0'; } - if (me == 0) { - int size = nreacts*sizeof(Set); - fwrite(&size,sizeof(int),1,fp); - fwrite(set,sizeof(Set),nreacts,fp); + int rbufcount = max_rate_limit_steps*nreacts; + int *rbuf; + if (rbufcount) { + memory->create(rbuf,rbufcount,"bond/react:rbuf"); + memcpy(rbuf,&store_rxn_count[0][0],sizeof(int)*rbufcount); } + + if (comm->me == 0) { + int size = nreacts*sizeof(Set)+(rbufcount+1)*sizeof(int); + fwrite(&size,sizeof(int),1,fp); + fwrite(&revision,sizeof(int),1,fp); + fwrite(set,sizeof(Set),nreacts,fp); + if (rbufcount) fwrite(rbuf,sizeof(int),rbufcount,fp); + } + if (rbufcount) memory->destroy(rbuf); } /* ---------------------------------------------------------------------- use selected state info from restart file to restart the Fix + bond/react restart revisions numbers added after LAMMPS version 3 Nov 2022 ------------------------------------------------------------------------- */ void FixBondReact::restart(char *buf) { - Set *set_restart = (Set *) buf; - for (int i = 0; i < set_restart[0].nreacts; i++) { + int n,revision,r_nreacts,r_max_rate_limit_steps,ibufcount,n2cpy; + int **ibuf; + + n = 0; + if (lmp->restart_ver > utils::date2num("3 Nov 2022")) revision = buf[n++]; + else revision = 0; + + Set *set_restart = (Set *) &buf[n*sizeof(int)]; + r_nreacts = set_restart[0].nreacts; + + if (revision > 0) { + r_max_rate_limit_steps = set_restart[0].max_rate_limit_steps; + ibufcount = r_max_rate_limit_steps*r_nreacts; + memory->create(ibuf,r_max_rate_limit_steps,r_nreacts,"bond/react:ibuf"); + memcpy(&ibuf[0][0],&buf[sizeof(int)+r_nreacts*sizeof(Set)],sizeof(int)*ibufcount); + n2cpy = r_max_rate_limit_steps; + } else n2cpy = 0; + + if (max_rate_limit_steps < n2cpy) n2cpy = max_rate_limit_steps; + for (int i = 0; i < r_nreacts; i++) { for (int j = 0; j < nreacts; j++) { if (strcmp(set_restart[i].rxn_name,rxn_name[j]) == 0) { reaction_count_total[j] = set_restart[i].reaction_count_total; + // read rate_limit restart information + for (int k = 0; k < n2cpy; k++) + store_rxn_count[k][j] = ibuf[k][i]; } } } + if (revision > 0) memory->destroy(ibuf); } /* ---------------------------------------------------------------------- diff --git a/src/REACTION/fix_bond_react.h b/src/REACTION/fix_bond_react.h index e9ca7ec362..4751bc4eef 100644 --- a/src/REACTION/fix_bond_react.h +++ b/src/REACTION/fix_bond_react.h @@ -26,6 +26,9 @@ FixStyle(bond/react,FixBondReact); #include "fix.h" +#include +#include + namespace LAMMPS_NS { class FixBondReact : public Fix { @@ -51,7 +54,6 @@ class FixBondReact : public Fix { double memory_usage() override; private: - int me, nprocs; int newton_bond; int nreacts; int *nevery; @@ -64,8 +66,11 @@ class FixBondReact : public Fix { int stabilization_flag; int reset_mol_ids_flag; int custom_exclude_flag; + int **rate_limit; + int **store_rxn_count; int *stabilize_steps_flag; int *custom_charges_fragid; + int *rescale_charges_flag; int *create_atoms_flag; int *modify_create_fragid; double *overlapsq; @@ -74,9 +79,11 @@ class FixBondReact : public Fix { int *nconstraints; char **constraintstr; int nrxnfunction; - std::vector rxnfunclist; + std::vector rxnfunclist; // lists current special rxn function + std::vector peratomflag; // 1 if special rxn function uses per-atom variable (vs. per-bond) + int atoms2bondflag; // 1 if atoms2bond map has been populated on this timestep int narrhenius; - int **var_flag, **var_id; // for keyword values with variable inputs + int **var_flag, **var_id; // for keyword values with variable inputs int status; int *groupbits; @@ -86,6 +93,7 @@ class FixBondReact : public Fix { int *reaction_count_total; int nmax; // max num local atoms int max_natoms; // max natoms in a molecule template + int max_rate_limit_steps; // max rate limit interval tagint *partner, *finalpartner; double **distsq; int *nattempt; @@ -102,7 +110,7 @@ class FixBondReact : public Fix { class RanMars **random; // random number for 'prob' keyword class RanMars **rrhandom; // random number for Arrhenius constraint class NeighList *list; - class ResetMolIDs *reset_mol_ids; // class for resetting mol IDs + class ResetAtomsMol *reset_mol_ids; // class for resetting mol IDs int *reacted_mol, *unreacted_mol; int *limit_duration; // indicates how long to relax @@ -160,7 +168,8 @@ class FixBondReact : public Fix { // but whose first neighbors haven't int glove_counter; // used to determine when to terminate Superimpose Algorithm - void read(int); + void read_variable_keyword(const char *, int, int); + void read_map_file(int); void EdgeIDs(char *, int); void Equivalences(char *, int); void DeleteAtoms(char *, int); @@ -184,6 +193,7 @@ class FixBondReact : public Fix { double custom_constraint(const std::string &); // evaulate expression for custom constraint double rxnfunction(const std::string &, const std::string &, const std::string &); // eval rxn_sum and rxn_ave + void get_atoms2bond(int); int get_chirality(double[12]); // get handedness given an ordered set of coordinates void open(char *); @@ -198,16 +208,18 @@ class FixBondReact : public Fix { void ghost_glovecast(); void update_everything(); int insert_atoms(tagint **, int); - void unlimit_bond(); + void unlimit_bond(); // removes atoms from stabilization, and other post-reaction every-step operations void limit_bond(int); void dedup_mega_gloves(int); //dedup global mega_glove void write_restart(FILE *) override; void restart(char *buf) override; + // store restart data struct Set { int nreacts; char rxn_name[MAXLINE]; int reaction_count_total; + int max_rate_limit_steps; }; Set *set; @@ -221,7 +233,9 @@ class FixBondReact : public Fix { int ncustomvars; std::vector customvarstrs; int nvvec; - double **vvec; // per-atom vector to store variable constraint atom-style variable values + double **vvec; // per-atom vector to store custom constraint atom-style variable values + class Compute *cperbond; // pointer to 'compute bond/local' used by custom constraint ('rxnbond' function) + std::map, int> atoms2bond; // maps atom pair to index of local bond array std::vector> constraints; // DEBUG diff --git a/src/REPLICA/fix_pimd.cpp b/src/REPLICA/fix_pimd.cpp index 969d412b89..40e203d3c2 100644 --- a/src/REPLICA/fix_pimd.cpp +++ b/src/REPLICA/fix_pimd.cpp @@ -102,6 +102,9 @@ FixPIMD::FixPIMD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) error->universe_all(FLERR, fmt::format("Unknown keyword {} for fix pimd", arg[i])); } + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Fix pimd does not support lj units"); + /* Initiation */ size_peratom_cols = 12 * nhc_nchain + 3; diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp index b58982928a..9c5befaf36 100644 --- a/src/REPLICA/neb.cpp +++ b/src/REPLICA/neb.cpp @@ -108,9 +108,9 @@ NEB::~NEB() void NEB::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all(FLERR,"NEB command before simulation box is defined"); + error->universe_all(FLERR,"NEB command before simulation box is defined"); - if (narg < 6) error->universe_all(FLERR,"Illegal NEB command"); + if (narg < 6) error->universe_all(FLERR,"Illegal NEB command: missing argument(s)"); etol = utils::numeric(FLERR,arg[0],false,lmp); ftol = utils::numeric(FLERR,arg[1],false,lmp); @@ -120,11 +120,14 @@ void NEB::command(int narg, char **arg) // error checks - if (etol < 0.0) error->all(FLERR,"Illegal NEB command"); - if (ftol < 0.0) error->all(FLERR,"Illegal NEB command"); - if (nevery <= 0) error->universe_all(FLERR,"Illegal NEB command"); - if (n1steps % nevery || n2steps % nevery) - error->universe_all(FLERR,"Illegal NEB command"); + if (etol < 0.0) error->universe_all(FLERR, fmt::format("Illegal NEB energy tolerance: {}", etol)); + if (ftol < 0.0) error->universe_all(FLERR, fmt::format("Illegal NEB force tolerance: {}", ftol)); + if (nevery <= 0) + error->universe_all(FLERR,fmt::format("Illegal NEB command every parameter: {}", nevery)); + if (n1steps % nevery) + error->all(FLERR, fmt::format("NEB N1 value {} incompatible with every {}", n1steps, nevery)); + if (n2steps % nevery) + error->all(FLERR, fmt::format("NEB N2 value {} incompatible with every {}", n2steps, nevery)); // replica info @@ -136,26 +139,38 @@ void NEB::command(int narg, char **arg) // error checks - if (nreplica == 1) error->all(FLERR,"Cannot use NEB with a single replica"); + if (nreplica == 1) error->universe_all(FLERR,"Cannot use NEB with a single replica"); if (atom->map_style == Atom::MAP_NONE) - error->all(FLERR,"Cannot use NEB unless atom map exists"); + error->universe_all(FLERR,"Cannot use NEB without an atom map"); // process file-style setting to setup initial configs for all replicas - - if (strcmp(arg[5],"final") == 0) { - if (narg != 7 && narg !=8) error->universe_all(FLERR,"Illegal NEB command"); - inpfile = arg[6]; - readfile(inpfile,0); - } else if (strcmp(arg[5],"each") == 0) { - if (narg != 7 && narg !=8) error->universe_all(FLERR,"Illegal NEB command"); - inpfile = arg[6]; - readfile(inpfile,1); - } else if (strcmp(arg[5],"none") == 0) { - if (narg != 6 && narg !=7) error->universe_all(FLERR,"Illegal NEB command"); - } else error->universe_all(FLERR,"Illegal NEB command"); - + int iarg = 5; + int filecmd = 0; verbose=false; - if (strcmp(arg[narg-1],"verbose") == 0) verbose=true; + while (iarg < narg) { + if (strcmp(arg[iarg],"final") == 0) { + if (iarg + 2 > narg) error->universe_all(FLERR,"Illegal NEB command: missing arguments"); + inpfile = arg[iarg+1]; + readfile(inpfile,0); + filecmd = 1; + iarg += 2; + } else if (strcmp(arg[iarg],"each") == 0) { + if (iarg + 2 > narg) error->universe_all(FLERR,"Illegal NEB command: missing arguments"); + inpfile = arg[iarg+1]; + readfile(inpfile,1); + filecmd = 1; + iarg += 2; + } else if (strcmp(arg[iarg],"none") == 0) { + filecmd = 1; + ++iarg; + } else if (strcmp(arg[iarg],"verbose") == 0) { + verbose=true; + ++iarg; + } else error->universe_all(FLERR,fmt::format("Unknown NEB command keyword: {}", arg[iarg])); + } + + if (!filecmd) error->universe_all(FLERR, "NEB is missing 'final', 'each', or 'none' keyword"); + // run the NEB calculation run(); @@ -176,7 +191,7 @@ void NEB::run() auto fixes = modify->get_fix_by_style("^neb$"); if (fixes.size() != 1) - error->all(FLERR,"NEB requires use of exactly one fix neb instance"); + error->universe_all(FLERR,"NEB requires use of exactly one fix neb instance"); fneb = dynamic_cast(fixes[0]); if (verbose) numall =7; @@ -194,7 +209,7 @@ void NEB::run() lmp->init(); if (update->minimize->searchflag) - error->all(FLERR,"NEB requires damped dynamics minimizer"); + error->universe_all(FLERR,"NEB requires a damped dynamics minimizer"); // setup regular NEB minimization FILE *uscreen = universe->uscreen; @@ -207,38 +222,43 @@ void NEB::run() update->endstep = update->laststep = update->firststep + n1steps; update->nsteps = n1steps; update->max_eval = n1steps; - if (update->laststep < 0) - error->all(FLERR,"Too many timesteps for NEB"); + if (update->laststep < 0) error->universe_all(FLERR,"Too many timesteps for NEB"); update->minimize->setup(); if (me_universe == 0) { if (uscreen) { + fmt::print(uscreen," Step {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} ", + "MaxReplicaForce", "MaxAtomForce", "GradV0","GradV1","GradVc","EBF", "EBR", "RDT"); + for (int i = 1; i <= nreplica; ++i) + fmt::print(uscreen, "{:^14} {:^14} ", "RD"+std::to_string(i), "PE"+std::to_string(i)); + if (verbose) { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " - "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " - "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - "... ReplicaForceN MaxAtomForceN\n"); - } else { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " - "RDN PEN\n"); + for (int i = 1; i <= nreplica; ++i) { + auto idx = std::to_string(i); + fmt::print(uscreen, "{:^12}{:^12}{:^12} {:^12} {:^12}{:^12} ", + "pathangle"+idx, "angletangrad"+idx, "anglegrad"+idx, "gradV"+idx, + "RepForce"+idx, "MaxAtomForce"+idx); + } } + fprintf(uscreen,"\n"); } if (ulogfile) { + fmt::print(ulogfile," Step {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} ", + "MaxReplicaForce", "MaxAtomForce", "GradV0","GradV1","GradVc","EBF", "EBR", "RDT"); + for (int i = 1; i <= nreplica; ++i) + fmt::print(ulogfile, "{:^14} {:^14} ", "RD"+std::to_string(i), "PE"+std::to_string(i)); + if (verbose) { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " - "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " - "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - "... ReplicaForceN MaxAtomForceN\n"); - } else { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " - "RDN PEN\n"); + for (int i = 1; i <= nreplica; ++i) { + auto idx = std::to_string(i); + fmt::print(ulogfile, "{:^12}{:^12}{:^12} {:^12} {:^12}{:^12} ", + "pathangle"+idx, "angletangrad"+idx, "anglegrad"+idx, "gradV"+idx, + "RepForce"+idx, "MaxAtomForce"+idx); + } } + fprintf(ulogfile,"\n"); } } print_status(); @@ -292,8 +312,7 @@ void NEB::run() update->endstep = update->laststep = update->firststep + n2steps; update->nsteps = n2steps; update->max_eval = n2steps; - if (update->laststep < 0) - error->all(FLERR,"Too many timesteps"); + if (update->laststep < 0) error->universe_all(FLERR,"Too many timesteps"); update->minimize->init(); fneb->rclimber = top; @@ -301,34 +320,37 @@ void NEB::run() if (me_universe == 0) { if (uscreen) { + fmt::print(uscreen," Step {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} ", + "MaxReplicaForce", "MaxAtomForce", "GradV0","GradV1","GradVc","EBF", "EBR", "RDT"); + for (int i = 1; i <= nreplica; ++i) + fmt::print(uscreen, "{:^14} {:^14} ", "RD"+std::to_string(i), "PE"+std::to_string(i)); + if (verbose) { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc EBF EBR RDT " - "RD1 PE1 RD2 PE2 ... RDN PEN " - "pathangle1 angletangrad1 anglegrad1 gradV1 " - "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - "... ReplicaForceN MaxAtomForceN\n"); - } else { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc " - "EBF EBR RDT " - "RD1 PE1 RD2 PE2 ... RDN PEN\n"); + for (int i = 1; i <= nreplica; ++i) { + auto idx = std::to_string(i); + fmt::print(uscreen, "{:^12}{:^12}{:^12} {:^12} {:^12}{:^12} ", + "pathangle"+idx, "angletangrad"+idx, "anglegrad"+idx, "gradV"+idx, + "RepForce"+idx, "MaxAtomForce"+idx); + } } + fprintf(uscreen,"\n"); } + if (ulogfile) { + fmt::print(ulogfile," Step {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} {:^14} ", + "MaxReplicaForce", "MaxAtomForce", "GradV0","GradV1","GradVc","EBF", "EBR", "RDT"); + for (int i = 1; i <= nreplica; ++i) + fmt::print(ulogfile, "{:^14} {:^14} ", "RD"+std::to_string(i), "PE"+std::to_string(i)); + if (verbose) { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc EBF EBR RDT " - "RD1 PE1 RD2 PE2 ... RDN PEN " - "pathangle1 angletangrad1 anglegrad1 gradV1 " - "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - "... ReplicaForceN MaxAtomForceN\n"); - } else { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " - "GradV0 GradV1 GradVc " - "EBF EBR RDT " - "RD1 PE1 RD2 PE2 ... RDN PEN\n"); + for (int i = 1; i <= nreplica; ++i) { + auto idx = std::to_string(i); + fmt::print(ulogfile, "{:^12}{:^12}{:^12} {:^12} {:^12}{:^12} ", + "pathangle"+idx, "angletangrad"+idx, "anglegrad"+idx, "gradV"+idx, + "RepForce"+idx, "MaxAtomForce"+idx); + } } + fprintf(ulogfile,"\n"); } } print_status(); @@ -420,7 +442,7 @@ void NEB::readfile(char *file, int flag) } MPI_Bcast(&nlines,1,MPI_INT,0,world); if (nlines < 0) - error->all(FLERR,"Incorrectly formatted NEB file"); + error->universe_all(FLERR,"Incorrectly formatted NEB file"); } auto buffer = new char[CHUNK*MAXLINE]; @@ -542,11 +564,11 @@ void NEB::open(char *file) if (platform::has_compress_extension(file)) { compressed = 1; fp = platform::compressed_read(file); - if (!fp) error->one(FLERR,"Cannot open compressed file"); + if (!fp) error->one(FLERR,"Cannot open compressed file {}: {}", file, utils::getsyserror()); } else fp = fopen(file,"r"); if (fp == nullptr) - error->one(FLERR,"Cannot open file {}: {}",file,utils::getsyserror()); + error->one(FLERR,"Cannot open file {}: {}", file, utils::getsyserror()); } /* ---------------------------------------------------------------------- @@ -626,19 +648,19 @@ void NEB::print_status() if (me_universe == 0) { constexpr double todeg=180.0/MY_PI; - std::string mesg = fmt::format("{} {:12.8g} {:12.8g} ",update->ntimestep,fmaxreplica,fmaxatom); - mesg += fmt::format("{:12.8g} {:12.8g} {:12.8g} ",gradvnorm0,gradvnorm1,gradvnormc); - mesg += fmt::format("{:12.8g} {:12.8g} {:12.8g} ",ebf,ebr,endpt); - for (int i = 0; i < nreplica; i++) mesg += fmt::format("{:12.8g} {:12.8g} ",rdist[i],all[i][0]); + std::string mesg = fmt::format("{:10} {:<14.8g} {:<14.8g} ",update->ntimestep,fmaxreplica,fmaxatom); + mesg += fmt::format("{:<14.8g} {:<14.8g} {:<14.8g} ",gradvnorm0,gradvnorm1,gradvnormc); + mesg += fmt::format("{:<14.8g} {:<14.8g} {:<14.8g} ",ebf,ebr,endpt); + for (int i = 0; i < nreplica; i++) mesg += fmt::format("{:<14.8g} {:<14.8g} ",rdist[i],all[i][0]); if (verbose) { - mesg += fmt::format("{:12.5g} {:12.5g} {:12.5g} {:12.5g} {:12.5g} {:12.5g}", + mesg += fmt::format("{:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g}", NAN,180-acos(all[0][5])*todeg,180-acos(all[0][6])*todeg, all[0][3],freplica[0],fmaxatomInRepl[0]); for (int i = 1; i < nreplica-1; i++) - mesg += fmt::format("{:12.5g} {:12.5g} {:12.5g} {:12.5g} {:12.5g} {:12.5g}", + mesg += fmt::format("{:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g}", 180-acos(all[i][4])*todeg,180-acos(all[i][5])*todeg, 180-acos(all[i][6])*todeg,all[i][3],freplica[i],fmaxatomInRepl[i]); - mesg += fmt::format("{:12.5g} {:12.5g} {:12.5g} {:12.5g} {:12.5g} {:12.5g}", + mesg += fmt::format("{:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g} {:<12.5g}", NAN,180-acos(all[nreplica-1][5])*todeg,NAN,all[nreplica-1][3], freplica[nreplica-1],fmaxatomInRepl[nreplica-1]); } @@ -650,4 +672,8 @@ void NEB::print_status() fflush(universe->ulogfile); } } + if (verbose) { + delete[] freplica; + delete[] fmaxatomInRepl; + } } diff --git a/src/angle_hybrid.cpp b/src/angle_hybrid.cpp index db768fb243..f0e9002ace 100644 --- a/src/angle_hybrid.cpp +++ b/src/angle_hybrid.cpp @@ -306,6 +306,16 @@ void AngleHybrid::coeff(int narg, char **arg) void AngleHybrid::init_style() { + // error if sub-style is not used + + int used; + for (int istyle = 0; istyle < nstyles; ++istyle) { + used = 0; + for (int itype = 1; itype <= atom->nangletypes; ++itype) + if (map[itype] == istyle) used = 1; + if (used == 0) error->all(FLERR, "Angle hybrid sub-style {} is not used", keywords[istyle]); + } + for (int m = 0; m < nstyles; m++) if (styles[m]) styles[m]->init_style(); } diff --git a/src/bond_hybrid.cpp b/src/bond_hybrid.cpp index 74ee0e3494..1528c25fe8 100644 --- a/src/bond_hybrid.cpp +++ b/src/bond_hybrid.cpp @@ -334,6 +334,16 @@ void BondHybrid::coeff(int narg, char **arg) void BondHybrid::init_style() { + // error if sub-style is not used + + int used; + for (int istyle = 0; istyle < nstyles; ++istyle) { + used = 0; + for (int itype = 1; itype <= atom->nbondtypes; ++itype) + if (map[itype] == istyle) used = 1; + if (used == 0) error->all(FLERR, "Bond hybrid sub-style {} is not used", keywords[istyle]); + } + for (int m = 0; m < nstyles; m++) if (styles[m]) styles[m]->init_style(); diff --git a/src/change_box.cpp b/src/change_box.cpp index 8ecaeaafe0..1cef7c96a5 100644 --- a/src/change_box.cpp +++ b/src/change_box.cpp @@ -281,9 +281,7 @@ void ChangeBox::command(int narg, char **arg) } else if (ops[m].style == BOUNDARY) { domain->set_boundary(3,&arg[ops[m].boundindex],1); if (domain->dimension == 2 && domain->zperiodic == 0) - error->all(FLERR, - "Cannot change box z boundary to " - "non-periodic for a 2d simulation"); + error->all(FLERR, "Cannot change box z boundary to non-periodic for a 2d simulation"); domain->set_initial_box(); domain->set_global_box(); domain->set_local_box(); diff --git a/src/deprecated.cpp b/src/deprecated.cpp index 3558935cb3..c39cab1104 100644 --- a/src/deprecated.cpp +++ b/src/deprecated.cpp @@ -32,16 +32,29 @@ void Deprecated::command(int narg, char **arg) if (cmd == "DEPRECATED") { if (lmp->comm->me == 0) utils::logmesg(lmp, "\nCommand 'DEPRECATED' is a dummy command\n\n"); return; - } else if (cmd == "reset_ids") { + } else if (cmd == "box") { if (lmp->comm->me == 0) - utils::logmesg(lmp, "\n'reset_ids' has been renamed to 'reset_atom_ids'\n\n"); + utils::logmesg(lmp, "\nThe 'box' command has been removed and will be ignored\n\n"); + return; } else if (utils::strmatch(cmd, "^kim_")) { - if (lmp->comm->me == 0) - utils::logmesg(lmp, - "\nWARNING: 'kim_' has been renamed to 'kim '. " - "Please update your input.\n\n"); std::string newcmd("kim"); newcmd += " " + cmd.substr(4); + if (lmp->comm->me == 0) + utils::logmesg(lmp, "\nWARNING: '{}' has been renamed to '{}'. Please update your input.\n\n", + cmd, newcmd); + for (int i = 0; i < narg; ++i) { + newcmd.append(1, ' '); + newcmd.append(arg[i]); + } + input->one(newcmd); + return; + } else if (utils::strmatch(cmd, "^reset_")) { + std::string newcmd("reset_atoms"); + if ((cmd == "reset_ids") || (cmd == "reset_atom_ids")) newcmd += " id"; + if (cmd == "reset_mol_ids") newcmd += " mol"; + if (lmp->comm->me == 0) + utils::logmesg(lmp, "\nWARNING: '{}' has been renamed to '{}'. Please update your input.\n\n", + cmd, newcmd); for (int i = 0; i < narg; ++i) { newcmd.append(1, ' '); newcmd.append(arg[i]); diff --git a/src/deprecated.h b/src/deprecated.h index e2e7e396e9..085bf5d47d 100644 --- a/src/deprecated.h +++ b/src/deprecated.h @@ -14,12 +14,15 @@ #ifdef COMMAND_CLASS // clang-format off CommandStyle(DEPRECATED,Deprecated); -CommandStyle(reset_ids,Deprecated); +CommandStyle(box,Deprecated); CommandStyle(kim_init,Deprecated); CommandStyle(kim_interactions,Deprecated); CommandStyle(kim_param,Deprecated); CommandStyle(kim_property,Deprecated); CommandStyle(kim_query,Deprecated); +CommandStyle(reset_ids,Deprecated); +CommandStyle(reset_atom_ids,Deprecated); +CommandStyle(reset_mol_ids,Deprecated); CommandStyle(message,Deprecated); CommandStyle(server,Deprecated); // clang-format on diff --git a/src/dihedral_hybrid.cpp b/src/dihedral_hybrid.cpp index 129ea9a975..734009b901 100644 --- a/src/dihedral_hybrid.cpp +++ b/src/dihedral_hybrid.cpp @@ -313,6 +313,16 @@ void DihedralHybrid::coeff(int narg, char **arg) void DihedralHybrid::init_style() { + // error if sub-style is not used + + int used; + for (int istyle = 0; istyle < nstyles; ++istyle) { + used = 0; + for (int itype = 1; itype <= atom->ndihedraltypes; ++itype) + if (map[itype] == istyle) used = 1; + if (used == 0) error->all(FLERR, "Dihedral hybrid sub-style {} is not used", keywords[istyle]); + } + for (int m = 0; m < nstyles; m++) if (styles[m]) styles[m]->init_style(); } diff --git a/src/domain.cpp b/src/domain.cpp index fe57aa6a96..97f626cbcd 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -82,7 +82,6 @@ Domain::Domain(LAMMPS *lmp) : Pointers(lmp) minzlo = minzhi = 0.0; triclinic = 0; - tiltsmall = 1; boxlo[0] = boxlo[1] = boxlo[2] = -0.5; boxhi[0] = boxhi[1] = boxhi[2] = 0.5; @@ -212,16 +211,13 @@ void Domain::set_initial_box(int expandflag) if (dimension == 2 && (xz != 0.0 || yz != 0.0)) error->all(FLERR,"Cannot skew triclinic box in z for 2d simulation"); - // error check or warning on triclinic tilt factors + // check on triclinic tilt factors if (triclinic) { - if ((fabs(xy/(boxhi[0]-boxlo[0])) > 0.5 && xperiodic) || - (fabs(xz/(boxhi[0]-boxlo[0])) > 0.5 && xperiodic) || - (fabs(yz/(boxhi[1]-boxlo[1])) > 0.5 && yperiodic)) { - if (tiltsmall) - error->all(FLERR,"Triclinic box skew is too large"); - else if (comm->me == 0) - error->warning(FLERR,"Triclinic box skew is large"); + if ((fabs(xy/(boxhi[1]-boxlo[1])) > 0.5 && yperiodic) || + ((fabs(xz)+fabs(yz))/(boxhi[2]-boxlo[2]) > 0.5 && zperiodic)) { + if (comm->me == 0) + error->warning(FLERR,"Triclinic box skew is large. LAMMPS will run inefficiently."); } } @@ -981,25 +977,33 @@ void Domain::subbox_too_small_check(double thresh) this should not be used if atom has moved infinitely far outside box b/c while could iterate forever e.g. fix shake prediction of new position with highly overlapped atoms - use minimum_image_once() instead + uses minimum_image_once() instead ------------------------------------------------------------------------- */ +static constexpr double MAXIMGCOUNT = 16; + void Domain::minimum_image(double &dx, double &dy, double &dz) { if (triclinic == 0) { if (xperiodic) { + if (fabs(dx) > (MAXIMGCOUNT * xprd)) + error->one(FLERR, "Atoms have moved too far apart ({}) for minimum image\n", dx); while (fabs(dx) > xprd_half) { if (dx < 0.0) dx += xprd; else dx -= xprd; } } if (yperiodic) { + if (fabs(dy) > (MAXIMGCOUNT * yprd)) + error->one(FLERR, "Atoms have moved too far apart ({}) for minimum image\n", dy); while (fabs(dy) > yprd_half) { if (dy < 0.0) dy += yprd; else dy -= yprd; } } if (zperiodic) { + if (fabs(dz) > (MAXIMGCOUNT * zprd)) + error->one(FLERR, "Atoms have moved too far apart ({}) for minimum image\n", dz); while (fabs(dz) > zprd_half) { if (dz < 0.0) dz += zprd; else dz -= zprd; @@ -1008,6 +1012,8 @@ void Domain::minimum_image(double &dx, double &dy, double &dz) } else { if (zperiodic) { + if (fabs(dz) > (MAXIMGCOUNT * zprd)) + error->one(FLERR, "Atoms have moved too far apart ({}) for minimum image\n", dz); while (fabs(dz) > zprd_half) { if (dz < 0.0) { dz += zprd; @@ -1021,6 +1027,8 @@ void Domain::minimum_image(double &dx, double &dy, double &dz) } } if (yperiodic) { + if (fabs(dy) > (MAXIMGCOUNT * yprd)) + error->one(FLERR, "Atoms have moved too far apart ({}) for minimum image\n", dy); while (fabs(dy) > yprd_half) { if (dy < 0.0) { dy += yprd; @@ -1032,6 +1040,8 @@ void Domain::minimum_image(double &dx, double &dy, double &dz) } } if (xperiodic) { + if (fabs(dx) > (MAXIMGCOUNT * xprd)) + error->one(FLERR, "Atoms have moved too far apart ({}) for minimum image\n", dx); while (fabs(dx) > xprd_half) { if (dx < 0.0) dx += xprd; else dx -= xprd; @@ -1040,75 +1050,6 @@ void Domain::minimum_image(double &dx, double &dy, double &dz) } } -/* ---------------------------------------------------------------------- - minimum image convention in periodic dimensions - use 1/2 of box size as test - for triclinic, also add/subtract tilt factors in other dims as needed - changed "if" to "while" to enable distance to - far-away ghost atom returned by atom->map() to be wrapped back into box - could be problem for looking up atom IDs when cutoff > boxsize - this should not be used if atom has moved infinitely far outside box - b/c while could iterate forever - e.g. fix shake prediction of new position with highly overlapped atoms - use minimum_image_once() instead -------------------------------------------------------------------------- */ - -void Domain::minimum_image(double *delta) -{ - if (triclinic == 0) { - if (xperiodic) { - while (fabs(delta[0]) > xprd_half) { - if (delta[0] < 0.0) delta[0] += xprd; - else delta[0] -= xprd; - } - } - if (yperiodic) { - while (fabs(delta[1]) > yprd_half) { - if (delta[1] < 0.0) delta[1] += yprd; - else delta[1] -= yprd; - } - } - if (zperiodic) { - while (fabs(delta[2]) > zprd_half) { - if (delta[2] < 0.0) delta[2] += zprd; - else delta[2] -= zprd; - } - } - - } else { - if (zperiodic) { - while (fabs(delta[2]) > zprd_half) { - if (delta[2] < 0.0) { - delta[2] += zprd; - delta[1] += yz; - delta[0] += xz; - } else { - delta[2] -= zprd; - delta[1] -= yz; - delta[0] -= xz; - } - } - } - if (yperiodic) { - while (fabs(delta[1]) > yprd_half) { - if (delta[1] < 0.0) { - delta[1] += yprd; - delta[0] += xy; - } else { - delta[1] -= yprd; - delta[0] -= xy; - } - } - } - if (xperiodic) { - while (fabs(delta[0]) > xprd_half) { - if (delta[0] < 0.0) delta[0] += xprd; - else delta[0] -= xprd; - } - } - } -} - /* ---------------------------------------------------------------------- minimum image convention in periodic dimensions use 1/2 of box size as test @@ -1929,26 +1870,6 @@ void Domain::set_boundary(int narg, char **arg, int flag) } } -/* ---------------------------------------------------------------------- - set domain attributes -------------------------------------------------------------------------- */ - -void Domain::set_box(int narg, char **arg) -{ - if (narg < 1) utils::missing_cmd_args(FLERR, "box", error); - - int iarg = 0; - while (iarg < narg) { - if (strcmp(arg[iarg],"tilt") == 0) { - if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "box tilt", error); - if (strcmp(arg[iarg+1],"small") == 0) tiltsmall = 1; - else if (strcmp(arg[iarg+1],"large") == 0) tiltsmall = 0; - else error->all(FLERR,"Unknown box tilt argument: {}", arg[iarg+1]); - iarg += 2; - } else error->all(FLERR,"Unknown box keyword: {}", arg[iarg]); - } -} - /* ---------------------------------------------------------------------- print box info, orthogonal or triclinic ------------------------------------------------------------------------- */ diff --git a/src/domain.h b/src/domain.h index 6bb39c747a..7d3194ccc9 100644 --- a/src/domain.h +++ b/src/domain.h @@ -41,7 +41,6 @@ class Domain : protected Pointers { // 3 = shrink-wrap non-per w/ min int triclinic; // 0 = orthog box, 1 = triclinic - int tiltsmall; // 1 if limit tilt, else 0 // orthogonal box @@ -120,7 +119,7 @@ class Domain : protected Pointers { void box_too_small_check(); void subbox_too_small_check(double); void minimum_image(double &, double &, double &); - void minimum_image(double *); + void minimum_image(double *delta) { minimum_image(delta[0], delta[1], delta[2]); } void minimum_image_once(double *); int closest_image(int, int); int closest_image(const double *const, int); @@ -141,7 +140,6 @@ class Domain : protected Pointers { const std::vector get_region_by_style(const std::string &) const; const std::vector get_region_list(); void set_boundary(int, char **, int); - void set_box(int, char **); void print_box(const std::string &); void boundary_string(char *); diff --git a/src/error.cpp b/src/error.cpp index bf0f56d7a6..c49bc6ce58 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -122,7 +122,7 @@ void Error::universe_one(const std::string &file, int line, const std::string &s void Error::universe_warn(const std::string &file, int line, const std::string &str) { ++numwarn; - if ((numwarn > maxwarn) || (allwarn > maxwarn) || (maxwarn < 0)) return; + if ((maxwarn != 0) && ((numwarn > maxwarn) || (allwarn > maxwarn) || (maxwarn < 0))) return; if (universe->uscreen) fmt::print(universe->uscreen,"WARNING on proc {}: {} ({}:{})\n", universe->me,str,truncpath(file),line); @@ -254,7 +254,7 @@ void Error::_one(const std::string &file, int line, fmt::string_view format, void Error::warning(const std::string &file, int line, const std::string &str) { ++numwarn; - if ((numwarn > maxwarn) || (allwarn > maxwarn) || (maxwarn < 0)) return; + if ((maxwarn != 0) && ((numwarn > maxwarn) || (allwarn > maxwarn) || (maxwarn < 0))) return; std::string mesg = fmt::format("WARNING: {} ({}:{})\n", str,truncpath(file),line); if (screen) fputs(mesg.c_str(),screen); diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 68440e4d58..95e25c59b2 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -275,6 +275,7 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint for (int i = 0; i < n; i++) { next = strchr(buf, '\n'); + if (!next) error->all(FLERR, "Unexpected end of file while reading data section"); *next = '\0'; try { @@ -324,12 +325,12 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint } /* ---------------------------------------------------------------------- - return # of lines in section of data file labeled by keyword + return # of lines in section of data file labeled by keyword. -1 signals use # of added atoms ------------------------------------------------------------------------- */ bigint FixPropertyAtom::read_data_skip_lines(char * /*keyword*/) { - return atom->natoms; + return -1; } /* ---------------------------------------------------------------------- diff --git a/src/improper_hybrid.cpp b/src/improper_hybrid.cpp index 6d73ed7cc7..b78e1ab5ca 100644 --- a/src/improper_hybrid.cpp +++ b/src/improper_hybrid.cpp @@ -305,6 +305,16 @@ void ImproperHybrid::coeff(int narg, char **arg) void ImproperHybrid::init_style() { + // error if sub-style is not used + + int used; + for (int istyle = 0; istyle < nstyles; ++istyle) { + used = 0; + for (int itype = 1; itype <= atom->nimpropertypes; ++itype) + if (map[itype] == istyle) used = 1; + if (used == 0) error->all(FLERR, "Improper hybrid sub-style {} is not used", keywords[istyle]); + } + for (int m = 0; m < nstyles; m++) if (styles[m]) styles[m]->init_style(); } diff --git a/src/input.cpp b/src/input.cpp index 5128f0261f..f18ef1efb8 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -749,77 +749,77 @@ int Input::execute_command() { int flag = 1; - if (!strcmp(command,"clear")) clear(); - else if (!strcmp(command,"echo")) echo(); - else if (!strcmp(command,"if")) ifthenelse(); - else if (!strcmp(command,"include")) include(); - else if (!strcmp(command,"jump")) jump(); - else if (!strcmp(command,"label")) label(); - else if (!strcmp(command,"log")) log(); - else if (!strcmp(command,"next")) next_command(); - else if (!strcmp(command,"partition")) partition(); - else if (!strcmp(command,"print")) print(); - else if (!strcmp(command,"python")) python(); - else if (!strcmp(command,"quit")) quit(); - else if (!strcmp(command,"shell")) shell(); - else if (!strcmp(command,"variable")) variable_command(); + std::string mycmd = command; + if (mycmd == "clear") clear(); + else if (mycmd == "echo") echo(); + else if (mycmd == "if") ifthenelse(); + else if (mycmd == "include") include(); + else if (mycmd == "jump") jump(); + else if (mycmd == "label") label(); + else if (mycmd == "log") log(); + else if (mycmd == "next") next_command(); + else if (mycmd == "partition") partition(); + else if (mycmd == "print") print(); + else if (mycmd == "python") python(); + else if (mycmd == "quit") quit(); + else if (mycmd == "shell") shell(); + else if (mycmd == "variable") variable_command(); - else if (!strcmp(command,"angle_coeff")) angle_coeff(); - else if (!strcmp(command,"angle_style")) angle_style(); - else if (!strcmp(command,"atom_modify")) atom_modify(); - else if (!strcmp(command,"atom_style")) atom_style(); - else if (!strcmp(command,"bond_coeff")) bond_coeff(); - else if (!strcmp(command,"bond_style")) bond_style(); - else if (!strcmp(command,"bond_write")) bond_write(); - else if (!strcmp(command,"boundary")) boundary(); - else if (!strcmp(command,"box")) box(); - else if (!strcmp(command,"comm_modify")) comm_modify(); - else if (!strcmp(command,"comm_style")) comm_style(); - else if (!strcmp(command,"compute")) compute(); - else if (!strcmp(command,"compute_modify")) compute_modify(); - else if (!strcmp(command,"dielectric")) dielectric(); - else if (!strcmp(command,"dihedral_coeff")) dihedral_coeff(); - else if (!strcmp(command,"dihedral_style")) dihedral_style(); - else if (!strcmp(command,"dimension")) dimension(); - else if (!strcmp(command,"dump")) dump(); - else if (!strcmp(command,"dump_modify")) dump_modify(); - else if (!strcmp(command,"fix")) fix(); - else if (!strcmp(command,"fix_modify")) fix_modify(); - else if (!strcmp(command,"group")) group_command(); - else if (!strcmp(command,"improper_coeff")) improper_coeff(); - else if (!strcmp(command,"improper_style")) improper_style(); - else if (!strcmp(command,"kspace_modify")) kspace_modify(); - else if (!strcmp(command,"kspace_style")) kspace_style(); - else if (!strcmp(command,"labelmap")) labelmap(); - else if (!strcmp(command,"lattice")) lattice(); - else if (!strcmp(command,"mass")) mass(); - else if (!strcmp(command,"min_modify")) min_modify(); - else if (!strcmp(command,"min_style")) min_style(); - else if (!strcmp(command,"molecule")) molecule(); - else if (!strcmp(command,"neigh_modify")) neigh_modify(); - else if (!strcmp(command,"neighbor")) neighbor_command(); - else if (!strcmp(command,"newton")) newton(); - else if (!strcmp(command,"package")) package(); - else if (!strcmp(command,"pair_coeff")) pair_coeff(); - else if (!strcmp(command,"pair_modify")) pair_modify(); - else if (!strcmp(command,"pair_style")) pair_style(); - else if (!strcmp(command,"pair_write")) pair_write(); - else if (!strcmp(command,"processors")) processors(); - else if (!strcmp(command,"region")) region(); - else if (!strcmp(command,"reset_timestep")) reset_timestep(); - else if (!strcmp(command,"restart")) restart(); - else if (!strcmp(command,"run_style")) run_style(); - else if (!strcmp(command,"special_bonds")) special_bonds(); - else if (!strcmp(command,"suffix")) suffix(); - else if (!strcmp(command,"thermo")) thermo(); - else if (!strcmp(command,"thermo_modify")) thermo_modify(); - else if (!strcmp(command,"thermo_style")) thermo_style(); - else if (!strcmp(command,"timestep")) timestep(); - else if (!strcmp(command,"timer")) timer_command(); - else if (!strcmp(command,"uncompute")) uncompute(); - else if (!strcmp(command,"undump")) undump(); - else if (!strcmp(command,"unfix")) unfix(); - else if (!strcmp(command,"units")) units(); + else if (mycmd == "angle_coeff") angle_coeff(); + else if (mycmd == "angle_style") angle_style(); + else if (mycmd == "atom_modify") atom_modify(); + else if (mycmd == "atom_style") atom_style(); + else if (mycmd == "bond_coeff") bond_coeff(); + else if (mycmd == "bond_style") bond_style(); + else if (mycmd == "bond_write") bond_write(); + else if (mycmd == "boundary") boundary(); + else if (mycmd == "comm_modify") comm_modify(); + else if (mycmd == "comm_style") comm_style(); + else if (mycmd == "compute") compute(); + else if (mycmd == "compute_modify") compute_modify(); + else if (mycmd == "dielectric") dielectric(); + else if (mycmd == "dihedral_coeff") dihedral_coeff(); + else if (mycmd == "dihedral_style") dihedral_style(); + else if (mycmd == "dimension") dimension(); + else if (mycmd == "dump") dump(); + else if (mycmd == "dump_modify") dump_modify(); + else if (mycmd == "fix") fix(); + else if (mycmd == "fix_modify") fix_modify(); + else if (mycmd == "group") group_command(); + else if (mycmd == "improper_coeff") improper_coeff(); + else if (mycmd == "improper_style") improper_style(); + else if (mycmd == "kspace_modify") kspace_modify(); + else if (mycmd == "kspace_style") kspace_style(); + else if (mycmd == "labelmap") labelmap(); + else if (mycmd == "lattice") lattice(); + else if (mycmd == "mass") mass(); + else if (mycmd == "min_modify") min_modify(); + else if (mycmd == "min_style") min_style(); + else if (mycmd == "molecule") molecule(); + else if (mycmd == "neigh_modify") neigh_modify(); + else if (mycmd == "neighbor") neighbor_command(); + else if (mycmd == "newton") newton(); + else if (mycmd == "package") package(); + else if (mycmd == "pair_coeff") pair_coeff(); + else if (mycmd == "pair_modify") pair_modify(); + else if (mycmd == "pair_style") pair_style(); + else if (mycmd == "pair_write") pair_write(); + else if (mycmd == "processors") processors(); + else if (mycmd == "region") region(); + else if (mycmd == "reset_timestep") reset_timestep(); + else if (mycmd == "restart") restart(); + else if (mycmd == "run_style") run_style(); + else if (mycmd == "special_bonds") special_bonds(); + else if (mycmd == "suffix") suffix(); + else if (mycmd == "thermo") thermo(); + else if (mycmd == "thermo_modify") thermo_modify(); + else if (mycmd == "thermo_style") thermo_style(); + else if (mycmd == "timestep") timestep(); + else if (mycmd == "timer") timer_command(); + else if (mycmd == "uncompute") uncompute(); + else if (mycmd == "undump") undump(); + else if (mycmd == "unfix") unfix(); + else if (mycmd == "units") units(); else flag = 0; @@ -827,10 +827,15 @@ int Input::execute_command() if (flag) return 0; + // process "meta-commands", i.e. commands that may have sub-commands + // they return 1 if there was a match and 0 if not + + if (mycmd == "reset_atoms") flag = meta(mycmd); + if (flag) return 0; + // invoke commands added via style_command.h // try suffixed version first - std::string mycmd = command; if (lmp->suffix_enable && lmp->non_pair_suffix()) { mycmd = command + std::string("/") + lmp->non_pair_suffix(); if (command_map->find(mycmd) == command_map->end()) { @@ -1411,15 +1416,6 @@ void Input::boundary() /* ---------------------------------------------------------------------- */ -void Input::box() -{ - if (domain->box_exist) - error->all(FLERR,"Box command after simulation box is defined"); - domain->set_box(narg,arg); -} - -/* ---------------------------------------------------------------------- */ - void Input::comm_modify() { comm->modify_params(narg,arg); @@ -1728,7 +1724,7 @@ void Input::pair_coeff() if (force->pair == nullptr) error->all(FLERR,"Pair_coeff command without a pair style"); if (narg < 2) utils::missing_cmd_args(FLERR,"pair_coeff", error); if (force->pair->one_coeff && ((strcmp(arg[0],"*") != 0) || (strcmp(arg[1],"*") != 0))) - error->all(FLERR,"Pair_coeff must start with * * for this pair style"); + error->all(FLERR,"Pair_coeff must start with * * for pair style {}", force->pair_style); char *newarg0 = utils::expand_type(FLERR, arg[0], Atom::ATOM, lmp); if (newarg0) arg[0] = newarg0; @@ -1988,3 +1984,21 @@ void Input::units() error->all(FLERR,"Units command after simulation box is defined"); update->set_units(arg[0]); } + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + function for meta commands +------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +int Input::meta(const std::string &prefix) +{ + auto mycmd = fmt::format("{}_{}", utils::uppercase(prefix), utils::uppercase(arg[0])); + if (command_map->find(mycmd) != command_map->end()) { + CommandCreator &command_creator = (*command_map)[mycmd]; + Command *cmd = command_creator(lmp); + cmd->command(narg-1,arg+1); + delete cmd; + return 1; + } else return 0; +} diff --git a/src/input.h b/src/input.h index de4c393693..5a29484cbc 100644 --- a/src/input.h +++ b/src/input.h @@ -70,6 +70,8 @@ class Input : protected Pointers { void reallocate(char *&, int &, int); // reallocate a char string int execute_command(); // execute a single command + int meta(const std::string &); // process meta-commands + void clear(); // input script commands void echo(); void ifthenelse(); @@ -94,7 +96,6 @@ class Input : protected Pointers { void bond_style(); void bond_write(); void boundary(); - void box(); void comm_modify(); void comm_style(); void compute(); @@ -143,7 +144,5 @@ class Input : protected Pointers { void unfix(); void units(); }; - } // namespace LAMMPS_NS - #endif diff --git a/src/lammps.cpp b/src/lammps.cpp index 9b9dda4ac8..5e9fed61b7 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -130,6 +130,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : version = (const char *) LAMMPS_VERSION; num_ver = utils::date2num(version); + restart_ver = -1; external_comm = 0; mdicomm = nullptr; @@ -993,6 +994,8 @@ void LAMMPS::destroy() delete python; python = nullptr; + + restart_ver = -1; // reset last restart version id } /* ---------------------------------------------------------------------- diff --git a/src/lammps.h b/src/lammps.h index abe08b45f8..03b019ed43 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -49,6 +49,8 @@ class LAMMPS { // that is constructed so that will be greater // for newer versions in numeric or string // value comparisons + int restart_ver; // -1 or numeric version id of LAMMPS version in restart + // file, in case LAMMPS was initialized from a restart // MPI_Comm world; // MPI communicator FILE *infile; // infile diff --git a/src/library.cpp b/src/library.cpp index a1cc67cfa5..1e3c96cdcf 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -983,7 +983,7 @@ be called without a valid LAMMPS object handle (it is ignored). **Image masks** These settings are related to how LAMMPS stores and interprets periodic images. The values are used -internally by the Fortran interface and are not likely to be useful to users. +internally by the :doc:`Fortran interface ` and are not likely to be useful to users. .. list-table:: :header-rows: 1 @@ -1015,8 +1015,17 @@ internally by the Fortran interface and are not likely to be useful to users. * - box_exist - 1 if the simulation box is defined, 0 if not. See :doc:`create_box`. + * - kokkos_active + - 1 if the KOKKOS package is compiled in **and** activated, 0 if not. + See :doc:`Speed_kokkos`. + * - kokkos_nthreads + - Number of Kokkos threads per MPI process, 0 if Kokkos is not active. + See :doc:`Speed_kokkos`. + * - kokkos_ngpus + - Number of Kokkos gpus per physical node, 0 if Kokkos is not active or no GPU support. + See :doc:`Speed_kokkos`. * - nthreads - - Number of requested OpenMP threads for LAMMPS' execution + - Number of requested OpenMP threads per MPI process for LAMMPS' execution * - newton_bond - 1 if Newton's 3rd law is applied to bonded interactions, 0 if not. * - newton_pair @@ -1126,6 +1135,9 @@ int lammps_extract_setting(void *handle, const char *keyword) if (strcmp(keyword,"dimension") == 0) return lmp->domain->dimension; if (strcmp(keyword,"box_exist") == 0) return lmp->domain->box_exist; + if (strcmp(keyword,"kokkos_active") == 0) return (lmp->kokkos) ? 1 : 0; + if (strcmp(keyword,"kokkos_nthreads") == 0) return (lmp->kokkos) ? lmp->kokkos->nthreads : 0; + if (strcmp(keyword,"kokkos_ngpus") == 0) return (lmp->kokkos) ? lmp->kokkos->ngpus : 0; if (strcmp(keyword,"newton_bond") == 0) return lmp->force->newton_bond; if (strcmp(keyword,"newton_pair") == 0) return lmp->force->newton_pair; if (strcmp(keyword,"triclinic") == 0) return lmp->domain->triclinic; diff --git a/src/pair.cpp b/src/pair.cpp index dad914e012..fc7232d615 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -821,7 +821,7 @@ void Pair::map_element2type(int narg, char **arg, bool update_setflag) // elements = list of element names if (narg != ntypes) - error->all(FLERR,"Incorrect args for pair coefficients"); + error->all(FLERR,"Number of element to type mappings does not match number of atom types"); if (elements) { for (i = 0; i < nelements; i++) delete[] elements[i]; diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 8dbdfa2318..0c1bf1b6d5 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -271,10 +271,9 @@ void PairHybrid::allocate() void PairHybrid::settings(int narg, char **arg) { - if (narg < 1) error->all(FLERR,"Illegal pair_style command"); + if (narg < 1) utils::missing_cmd_args(FLERR, "pair_style hybrid", error); if (lmp->kokkos && !utils::strmatch(force->pair_style,"^hybrid.*/kk$")) - error->all(FLERR,"Must use pair_style {}/kk with Kokkos", - force->pair_style); + error->all(FLERR,"Must use pair_style {}/kk with Kokkos", force->pair_style); // delete old lists, since cannot just change settings @@ -326,9 +325,9 @@ void PairHybrid::settings(int narg, char **arg) nstyles = 0; while (iarg < narg) { if (utils::strmatch(arg[iarg],"^hybrid")) - error->all(FLERR,"Pair style hybrid cannot have hybrid as an argument"); + error->all(FLERR,"Pair style hybrid cannot have hybrid as a sub-style"); if (strcmp(arg[iarg],"none") == 0) - error->all(FLERR,"Pair style hybrid cannot have none as an argument"); + error->all(FLERR,"Pair style hybrid cannot have none as a sub-style"); styles[nstyles] = force->new_pair(arg[iarg],1,dummy); keywords[nstyles] = force->store_style(arg[iarg],0); @@ -478,7 +477,7 @@ void PairHybrid::init_svector() void PairHybrid::coeff(int narg, char **arg) { - if (narg < 3) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg < 3) utils::missing_cmd_args(FLERR,"pair_coeff", error); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; @@ -497,7 +496,7 @@ void PairHybrid::coeff(int narg, char **arg) if (strcmp(arg[2],keywords[m]) == 0) { if (multiple[m]) { multflag = 1; - if (narg < 4) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg < 4) utils::missing_cmd_args(FLERR, "pair_coeff", error); if (multiple[m] == utils::inumeric(FLERR,arg[3],false,lmp)) break; else continue; } else break; @@ -507,7 +506,7 @@ void PairHybrid::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[2],"none") == 0) none = 1; - else error->all(FLERR,"Pair coeff for hybrid has invalid style: {}",arg[2]); + else error->all(FLERR,"Pair coeff for hybrid has invalid style: {}", arg[2]); } // move 1st/2nd args to 2nd/3rd args @@ -527,7 +526,7 @@ void PairHybrid::coeff(int narg, char **arg) if (!none && styles[m]->one_coeff) { if ((strcmp(arg[0],"*") != 0) || (strcmp(arg[1],"*") != 0)) - error->all(FLERR,"Incorrect args for pair coefficients"); + error->all(FLERR,"Pair_coeff must start with * * for sub-style {}", keywords[m]); for (int i = 1; i <= atom->ntypes; i++) for (int j = i; j <= atom->ntypes; j++) if (nmap[i][j] && map[i][j][0] == m) { @@ -578,7 +577,7 @@ void PairHybrid::init_style() for (jtype = itype; jtype <= ntypes; jtype++) for (m = 0; m < nmap[itype][jtype]; m++) if (map[itype][jtype][m] == istyle) used = 1; - if (used == 0) error->all(FLERR,"Pair hybrid sub-style is not used"); + if (used == 0) error->all(FLERR,"Pair hybrid sub-style {} is not used", keywords[istyle]); } // The GPU library uses global data for each pair style, so the diff --git a/src/read_data.cpp b/src/read_data.cpp index ee6399a2d3..5317a4217a 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -875,10 +875,13 @@ void ReadData::command(int narg, char **arg) int i; for (i = 0; i < nfix; i++) if (strcmp(keyword, fix_section[i]) == 0) { - if (firstpass) + if (firstpass) { fix(fix_index[i], keyword); - else - skip_lines(fix_index[i]->read_data_skip_lines(keyword)); + } else { + auto nskip = fix_index[i]->read_data_skip_lines(keyword); + if (nskip < 0) nskip = natoms; + skip_lines(nskip); + } break; } if (i == nfix) @@ -2225,6 +2228,7 @@ void ReadData::fix(Fix *ifix, char *keyword) int nchunk, eof; bigint nline = ifix->read_data_skip_lines(keyword); + if (nline < 0) nline = natoms; bigint nread = 0; while (nread < nline) { diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 35d4629291..d4b455aaf9 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -599,6 +599,8 @@ void ReadRestart::header() if (flag == VERSION) { char *version = read_string(); + lmp->restart_ver = utils::date2num(version); + if (me == 0) utils::logmesg(lmp," restart file = {}, LAMMPS = {}\n", version, lmp->version); delete[] version; diff --git a/src/reset_atom_ids.cpp b/src/reset_atoms_id.cpp similarity index 66% rename from src/reset_atom_ids.cpp rename to src/reset_atoms_id.cpp index 1faa9a8e7d..26685f1972 100644 --- a/src/reset_atom_ids.cpp +++ b/src/reset_atoms_id.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -12,7 +11,7 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "reset_atom_ids.h" +#include "reset_atoms_id.h" #include "atom.h" #include "atom_vec.h" @@ -32,7 +31,7 @@ using namespace LAMMPS_NS; #if defined(LMP_QSORT) // allocate space for static class variable // prototype for non-class function -ResetIDs::AtomRvous *ResetIDs::sortrvous; +ResetAtomsID::AtomRvous *ResetAtomsID::sortrvous; static int compare_coords(const void *, const void *); #else // prototype for non-class function @@ -44,22 +43,21 @@ static int compare_coords(const int, const int, void *); /* ---------------------------------------------------------------------- */ -ResetIDs::ResetIDs(LAMMPS *lmp) : Command(lmp) {} +ResetAtomsID::ResetAtomsID(LAMMPS *lmp) : Command(lmp) {} /* ---------------------------------------------------------------------- */ -void ResetIDs::command(int narg, char **arg) +void ResetAtomsID::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all(FLERR,"Reset_ids command before simulation box is defined"); - if (atom->tag_enable == 0) - error->all(FLERR,"Cannot use reset_atom_ids unless atoms have IDs"); + error->all(FLERR, "Reset_atoms id command before simulation box is defined"); + if (atom->tag_enable == 0) error->all(FLERR, "Cannot use reset_atoms id unless atoms have IDs"); for (int i = 0; i < modify->nfix; i++) if (modify->fix[i]->stores_ids) - error->all(FLERR,"Cannot use reset_atom_ids when a fix exists that stores atom IDs"); + error->all(FLERR, "Cannot use reset_atoms id when a fix exists that stores atom IDs"); - if (comm->me == 0) utils::logmesg(lmp,"Resetting atom IDs ...\n"); + if (comm->me == 0) utils::logmesg(lmp, "Resetting atom IDs ...\n"); // process args @@ -67,11 +65,12 @@ void ResetIDs::command(int narg, char **arg) int iarg = 0; while (iarg < narg) { - if (strcmp(arg[iarg],"sort") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal reset_atom_ids command"); - sortflag = utils::logical(FLERR,arg[iarg+1],false,lmp); + if (strcmp(arg[iarg], "sort") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "reset_atoms id", error); + sortflag = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else error->all(FLERR,"Illegal reset_atom_ids command"); + } else + error->all(FLERR, "Unknown reset_atoms id keyword: {}", arg[iarg]); } // create an atom map if one doesn't exist already @@ -99,7 +98,7 @@ void ResetIDs::command(int narg, char **arg) comm->setup(); comm->exchange(); comm->borders(); - if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + if (domain->triclinic) domain->lamda2x(atom->nlocal + atom->nghost); // oldIDs = copy of current owned IDs @@ -108,7 +107,7 @@ void ResetIDs::command(int narg, char **arg) int nall = nlocal + atom->nghost; tagint *oldIDs; - memory->create(oldIDs,nlocal,"reset_atom_ids:oldIDs"); + memory->create(oldIDs, nlocal, "reset_atom_ids:oldIDs"); for (int i = 0; i < nlocal; i++) { oldIDs[i] = tag[i]; @@ -119,22 +118,24 @@ void ResetIDs::command(int narg, char **arg) // if sortflag = no: use fast tag_extend() // if sortflag = yes: use slower full spatial sort plus rendezvous comm - if (sortflag == 0) atom->tag_extend(); - else sort(); + if (sortflag == 0) + atom->tag_extend(); + else + sort(); // newIDs = copy of new IDs // restore old IDs, consistent with existing atom map // forward_comm_array acquires new IDs for ghost atoms double **newIDs; - memory->create(newIDs,nall,1,"reset_atom_ids:newIDs"); + memory->create(newIDs, nall, 1, "reset_atom_ids:newIDs"); for (int i = 0; i < nlocal; i++) { newIDs[i][0] = ubuf(tag[i]).d; tag[i] = oldIDs[i]; } - comm->forward_comm_array(1,newIDs); + comm->forward_comm_array(1, newIDs); // loop over bonds, angles, etc and reset IDs in stored topology arrays // only necessary for molecular = Atom::MOLECULAR, not molecular = Atom::TEMPLATE @@ -143,7 +144,7 @@ void ResetIDs::command(int narg, char **arg) int badcount = 0; if (atom->molecular == Atom::MOLECULAR) { - int j,m; + int j, m; tagint oldID; if (atom->avec->bonds_allow) { @@ -153,8 +154,10 @@ void ResetIDs::command(int narg, char **arg) for (j = 0; j < num_bond[i]; j++) { oldID = bond_atom[i][j]; m = atom->map(oldID); - if (m >= 0) bond_atom[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + bond_atom[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; } } } @@ -168,18 +171,24 @@ void ResetIDs::command(int narg, char **arg) for (j = 0; j < num_angle[i]; j++) { oldID = angle_atom1[i][j]; m = atom->map(oldID); - if (m >= 0) angle_atom1[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + angle_atom1[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = angle_atom2[i][j]; m = atom->map(oldID); - if (m >= 0) angle_atom2[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + angle_atom2[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = angle_atom3[i][j]; m = atom->map(oldID); - if (m >= 0) angle_atom3[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + angle_atom3[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; } } } @@ -194,23 +203,31 @@ void ResetIDs::command(int narg, char **arg) for (j = 0; j < num_dihedral[i]; j++) { oldID = dihedral_atom1[i][j]; m = atom->map(oldID); - if (m >= 0) dihedral_atom1[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + dihedral_atom1[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = dihedral_atom2[i][j]; m = atom->map(oldID); - if (m >= 0) dihedral_atom2[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + dihedral_atom2[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = dihedral_atom3[i][j]; m = atom->map(oldID); - if (m >= 0) dihedral_atom3[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + dihedral_atom3[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = dihedral_atom4[i][j]; m = atom->map(oldID); - if (m >= 0) dihedral_atom4[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + dihedral_atom4[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; } } } @@ -225,23 +242,31 @@ void ResetIDs::command(int narg, char **arg) for (j = 0; j < num_improper[i]; j++) { oldID = improper_atom1[i][j]; m = atom->map(oldID); - if (m >= 0) improper_atom1[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + improper_atom1[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = improper_atom2[i][j]; m = atom->map(oldID); - if (m >= 0) improper_atom2[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + improper_atom2[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = improper_atom3[i][j]; m = atom->map(oldID); - if (m >= 0) improper_atom3[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + improper_atom3[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; oldID = improper_atom4[i][j]; m = atom->map(oldID); - if (m >= 0) improper_atom4[i][j] = (tagint) ubuf(newIDs[m][0]).i; - else badcount++; + if (m >= 0) + improper_atom4[i][j] = (tagint) ubuf(newIDs[m][0]).i; + else + badcount++; } } } @@ -250,10 +275,10 @@ void ResetIDs::command(int narg, char **arg) // error check int all; - MPI_Allreduce(&badcount,&all,1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(&badcount, &all, 1, MPI_INT, MPI_SUM, world); if (all) - error->all(FLERR,"Reset_ids missing {} bond topology atom IDs - " - "use comm_modify cutoff",all); + error->all(FLERR, + "reset_atoms id is missing {} bond topology atom IDs - use comm_modify cutoff", all); // reset IDs and atom map for owned atoms @@ -287,9 +312,9 @@ void ResetIDs::command(int narg, char **arg) spatial sort of atoms followed by rendezvous comm to reset atom IDs ------------------------------------------------------------------------- */ -void ResetIDs::sort() +void ResetAtomsID::sort() { - double mylo[3],myhi[3],bboxlo[3],bboxhi[3]; + double mylo[3], myhi[3], bboxlo[3], bboxhi[3]; int me = comm->me; int nprocs = comm->nprocs; @@ -306,12 +331,12 @@ void ResetIDs::sort() myhi[0] = myhi[1] = myhi[2] = -BIG; for (int i = 0; i < nlocal; i++) { - mylo[0] = MIN(mylo[0],x[i][0]); - mylo[1] = MIN(mylo[1],x[i][1]); - mylo[2] = MIN(mylo[2],x[i][2]); - myhi[0] = MAX(myhi[0],x[i][0]); - myhi[1] = MAX(myhi[1],x[i][1]); - myhi[2] = MAX(myhi[2],x[i][2]); + mylo[0] = MIN(mylo[0], x[i][0]); + mylo[1] = MIN(mylo[1], x[i][1]); + mylo[2] = MIN(mylo[2], x[i][2]); + myhi[0] = MAX(myhi[0], x[i][0]); + myhi[1] = MAX(myhi[1], x[i][1]); + myhi[2] = MAX(myhi[2], x[i][2]); } if (dim == 2) mylo[2] = myhi[2] = 0.0; @@ -325,15 +350,15 @@ void ResetIDs::sort() } } - MPI_Allreduce(mylo,bboxlo,3,MPI_DOUBLE,MPI_MIN,world); - MPI_Allreduce(myhi,bboxhi,3,MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(mylo, bboxlo, 3, MPI_DOUBLE, MPI_MIN, world); + MPI_Allreduce(myhi, bboxhi, 3, MPI_DOUBLE, MPI_MAX, world); - bboxlo[0] -= 0.0001 * (bboxhi[0]-bboxlo[0]); - bboxlo[1] -= 0.0001 * (bboxhi[1]-bboxlo[1]); - bboxlo[2] -= 0.0001 * (bboxhi[2]-bboxlo[2]); - bboxhi[0] += 0.0001 * (bboxhi[0]-bboxlo[0]); - bboxhi[1] += 0.0001 * (bboxhi[1]-bboxlo[1]); - bboxhi[2] += 0.0001 * (bboxhi[2]-bboxlo[2]); + bboxlo[0] -= 0.0001 * (bboxhi[0] - bboxlo[0]); + bboxlo[1] -= 0.0001 * (bboxhi[1] - bboxlo[1]); + bboxlo[2] -= 0.0001 * (bboxhi[2] - bboxlo[2]); + bboxhi[0] += 0.0001 * (bboxhi[0] - bboxlo[0]); + bboxhi[1] += 0.0001 * (bboxhi[1] - bboxlo[1]); + bboxhi[2] += 0.0001 * (bboxhi[2] - bboxlo[2]); // nbin_estimate = estimate of total number of bins, each with PERBIN atoms // binsize = edge length of a cubic bin @@ -342,19 +367,23 @@ void ResetIDs::sort() bigint nbin_estimate = atom->natoms / PERBIN + 1; double vol; - if (dim == 2) vol = (bboxhi[0]-bboxlo[0]) * (bboxhi[1]-bboxlo[1]); - else vol = (bboxhi[0]-bboxlo[0]) * (bboxhi[1]-bboxlo[1]) * (bboxhi[2]-bboxlo[2]); - double binsize = pow(vol/nbin_estimate,1.0/dim); + if (dim == 2) + vol = (bboxhi[0] - bboxlo[0]) * (bboxhi[1] - bboxlo[1]); + else + vol = (bboxhi[0] - bboxlo[0]) * (bboxhi[1] - bboxlo[1]) * (bboxhi[2] - bboxlo[2]); + double binsize = pow(vol / nbin_estimate, 1.0 / dim); - int nbinx = static_cast ((bboxhi[0]-bboxlo[0]) / binsize) + 1; - int nbiny = static_cast ((bboxhi[1]-bboxlo[1]) / binsize) + 1; - int nbinz = static_cast ((bboxhi[2]-bboxlo[2]) / binsize) + 1; + int nbinx = static_cast((bboxhi[0] - bboxlo[0]) / binsize) + 1; + int nbiny = static_cast((bboxhi[1] - bboxlo[1]) / binsize) + 1; + int nbinz = static_cast((bboxhi[2] - bboxlo[2]) / binsize) + 1; - double invx = 1.0 / (bboxhi[0]-bboxlo[0]); - double invy = 1.0 / (bboxhi[1]-bboxlo[1]); + double invx = 1.0 / (bboxhi[0] - bboxlo[0]); + double invy = 1.0 / (bboxhi[1] - bboxlo[1]); double invz; - if (dim == 2) invz = 0.0; - else invz = 1.0 / (bboxhi[2]-bboxlo[2]); + if (dim == 2) + invz = 0.0; + else + invz = 1.0 / (bboxhi[2] - bboxlo[2]); // nbins = actual total number of bins // bins are split evenly across procs @@ -366,18 +395,18 @@ void ResetIDs::sort() // binlo to binhi-1 = bin indices this proc will own in Rvous decomp // bins are numbered from 0 to Nbins-1 - bigint nbins = (bigint) nbinx*nbiny*nbinz; + bigint nbins = (bigint) nbinx * nbiny * nbinz; bigint nlo = nbins / nprocs; bigint nhi = nlo + 1; bigint nplo = nprocs - (nbins % nprocs); - bigint nbinlo = nplo*nlo; + bigint nbinlo = nplo * nlo; if (me < nplo) { binlo = me * nlo; - binhi = (me+1) * nlo; + binhi = (me + 1) * nlo; } else { - binlo = nbinlo + (me-nplo) * nhi; - binhi = nbinlo + (me+1-nplo) * nhi; + binlo = nbinlo + (me - nplo) * nhi; + binhi = nbinlo + (me + 1 - nplo) * nhi; } // fill atombuf with info on my atoms @@ -385,20 +414,23 @@ void ResetIDs::sort() // proclist = proc that owns ibin int *proclist; - memory->create(proclist,nlocal,"special:proclist"); - auto atombuf = (AtomRvous *) memory->smalloc((bigint) nlocal*sizeof(AtomRvous),"resetIDs:idbuf"); + memory->create(proclist, nlocal, "special:proclist"); + auto atombuf = + (AtomRvous *) memory->smalloc((bigint) nlocal * sizeof(AtomRvous), "resetIDs:idbuf"); - int ibinx,ibiny,ibinz,iproc; + int ibinx, ibiny, ibinz, iproc; bigint ibin; for (int i = 0; i < nlocal; i++) { - ibinx = static_cast ((x[i][0]-bboxlo[0])*invx * nbinx); - ibiny = static_cast ((x[i][1]-bboxlo[1])*invy * nbiny); - ibinz = static_cast ((x[i][2]-bboxlo[2])*invz * nbinz); - ibin = (bigint) ibinz*nbiny*nbinx + (bigint) ibiny*nbinx + ibinx; + ibinx = static_cast((x[i][0] - bboxlo[0]) * invx * nbinx); + ibiny = static_cast((x[i][1] - bboxlo[1]) * invy * nbiny); + ibinz = static_cast((x[i][2] - bboxlo[2]) * invz * nbinz); + ibin = (bigint) ibinz * nbiny * nbinx + (bigint) ibiny * nbinx + ibinx; - if (ibin < nbinlo) iproc = ibin / nlo; - else iproc = nplo + (ibin-nbinlo) / nhi; + if (ibin < nbinlo) + iproc = ibin / nlo; + else + iproc = nplo + (ibin - nbinlo) / nhi; proclist[i] = iproc; atombuf[i].ibin = ibin; @@ -412,8 +444,8 @@ void ResetIDs::sort() // perform rendezvous operation, send atombuf to other procs char *buf; - int nreturn = comm->rendezvous(1,nlocal,(char *) atombuf,sizeof(AtomRvous),0,proclist, - sort_bins,0,buf,sizeof(IDRvous),(void *) this); + int nreturn = comm->rendezvous(1, nlocal, (char *) atombuf, sizeof(AtomRvous), 0, proclist, + sort_bins, 0, buf, sizeof(IDRvous), (void *) this); auto outbuf = (IDRvous *) buf; memory->destroy(proclist); @@ -437,11 +469,11 @@ void ResetIDs::sort() outbuf = list of N IDRvous datums, sent back to sending proc ------------------------------------------------------------------------- */ -int ResetIDs::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&outbuf, void *ptr) +int ResetAtomsID::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&outbuf, void *ptr) { - int i,ibin,index; + int i, ibin, index; - auto rptr = (ResetIDs *) ptr; + auto rptr = (ResetAtomsID *) ptr; Memory *memory = rptr->memory; Error *error = rptr->error; MPI_Comm world = rptr->world; @@ -451,13 +483,13 @@ int ResetIDs::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&ou // nbins = my subset of bins from binlo to binhi-1 // initialize linked lists of my Rvous atoms in each bin - int *next,*head,*last,*count; + int *next, *head, *last, *count; int nbins = binhi - binlo; - memory->create(next,n,"resetIDs:next"); - memory->create(head,nbins,"resetIDs:head"); - memory->create(last,nbins,"resetIDs:last"); - memory->create(count,nbins,"resetIDs:count"); + memory->create(next, n, "resetIDs:next"); + memory->create(head, nbins, "resetIDs:head"); + memory->create(last, nbins, "resetIDs:last"); + memory->create(count, nbins, "resetIDs:count"); for (i = 0; i < n; i++) next[i] = -1; @@ -472,7 +504,7 @@ int ResetIDs::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&ou if (in[i].ibin < binlo || in[i].ibin >= binhi) { //printf("BAD me %d i %d %d ibin %d binlohi %d %d\n", // rptr->comm->me,i,n,in[i].ibin,binlo,binhi); - error->one(FLERR,"Bad spatial bin assignment in reset_atom_ids sort"); + error->one(FLERR, "Bad spatial bin assignment in reset_atoms id sort"); } ibin = in[i].ibin - binlo; if (head[ibin] < 0) head[ibin] = i; @@ -482,11 +514,10 @@ int ResetIDs::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&ou } int maxcount = 0; - for (ibin = 0; ibin < nbins; ibin++) - maxcount = MAX(maxcount,count[ibin]); + for (ibin = 0; ibin < nbins; ibin++) maxcount = MAX(maxcount, count[ibin]); int *order; - memory->create(order,maxcount,"resetIDs:order"); + memory->create(order, maxcount, "resetIDs:order"); // sort atoms in each bin by their spatial position // recreate linked list for each bin based on sorted order @@ -498,12 +529,11 @@ int ResetIDs::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&ou index = next[index]; } - #if defined(LMP_QSORT) sortrvous = in; - qsort(order,count[ibin],sizeof(int),compare_coords); + qsort(order, count[ibin], sizeof(int), compare_coords); #else - utils::merge_sort(order,count[ibin],(void *) in,compare_coords); + utils::merge_sort(order, count[ibin], (void *) in, compare_coords); #endif head[ibin] = last[ibin] = -1; @@ -518,15 +548,15 @@ int ResetIDs::sort_bins(int n, char *inbuf, int &flag, int *&proclist, char *&ou tagint ntag = n; tagint nprev; - MPI_Scan(&ntag,&nprev,1,MPI_LMP_TAGINT,MPI_SUM,world); + MPI_Scan(&ntag, &nprev, 1, MPI_LMP_TAGINT, MPI_SUM, world); nprev -= n; // loop over bins and sorted atoms in each bin, reset ids to be consecutive // pass outbuf of IDRvous datums back to comm->rendezvous int nout = n; - memory->create(proclist,nout,"resetIDs:proclist"); - auto out = (IDRvous *) memory->smalloc(nout*sizeof(IDRvous),"resetIDs:out"); + memory->create(proclist, nout, "resetIDs:proclist"); + auto out = (IDRvous *) memory->smalloc(nout * sizeof(IDRvous), "resetIDs:out"); tagint one = nprev + 1; for (ibin = 0; ibin < nbins; ibin++) { @@ -567,7 +597,7 @@ int compare_coords(const void *iptr, const void *jptr) { int i = *((int *) iptr); int j = *((int *) jptr); - ResetIDs::AtomRvous *rvous = ResetIDs::sortrvous; + ResetAtomsID::AtomRvous *rvous = ResetAtomsID::sortrvous; double *xi = rvous[i].x; double *xj = rvous[j].x; if (xi[0] < xj[0]) return -1; @@ -588,7 +618,7 @@ int compare_coords(const void *iptr, const void *jptr) int compare_coords(const int i, const int j, void *ptr) { - auto rvous = (ResetIDs::AtomRvous *) ptr; + auto rvous = (ResetAtomsID::AtomRvous *) ptr; double *xi = rvous[i].x; double *xj = rvous[j].x; if (xi[0] < xj[0]) return -1; diff --git a/src/reset_atom_ids.h b/src/reset_atoms_id.h similarity index 88% rename from src/reset_atom_ids.h rename to src/reset_atoms_id.h index 0da02a0ffc..9d80505586 100644 --- a/src/reset_atom_ids.h +++ b/src/reset_atoms_id.h @@ -13,18 +13,18 @@ #ifdef COMMAND_CLASS // clang-format off -CommandStyle(reset_atom_ids,ResetIDs); +CommandStyle(RESET_ATOMS_ID,ResetAtomsID); // clang-format on #else -#ifndef LMP_RESET_IDS_H -#define LMP_RESET_IDS_H +#ifndef LMP_RESET_ATOMS_ID_H +#define LMP_RESET_ATOMS_ID_H #include "command.h" namespace LAMMPS_NS { -class ResetIDs : public Command { +class ResetAtomsID : public Command { public: struct AtomRvous { bigint ibin; @@ -42,7 +42,7 @@ class ResetIDs : public Command { static AtomRvous *sortrvous; #endif - ResetIDs(class LAMMPS *); + ResetAtomsID(class LAMMPS *); void command(int, char **) override; private: @@ -54,8 +54,6 @@ class ResetIDs : public Command { void sort(); }; - } // namespace LAMMPS_NS - #endif #endif diff --git a/src/reset_atoms_image.cpp b/src/reset_atoms_image.cpp new file mode 100644 index 0000000000..5f02ced963 --- /dev/null +++ b/src/reset_atoms_image.cpp @@ -0,0 +1,141 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + 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. +------------------------------------------------------------------------- */ + +#include "reset_atoms_image.h" + +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "compute.h" +#include "domain.h" +#include "error.h" +#include "group.h" +#include "input.h" +#include "modify.h" +#include "variable.h" + +#include +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +ResetAtomsImage::ResetAtomsImage(LAMMPS *lmp) : Command(lmp) {} + +/* ---------------------------------------------------------------------- + called as reset_atoms image command in input script +------------------------------------------------------------------------- */ + +void ResetAtomsImage::command(int narg, char **arg) +{ + if (domain->box_exist == 0) + error->all(FLERR, "Reset_atoms image command before simulation box is defined"); + if (atom->tag_enable == 0) + error->all(FLERR, "Cannot use reset_atoms image unless atoms have IDs"); + if (atom->avec->bonds_allow == 0) + error->all(FLERR, "Cannot use reset_atoms image used when bonds are not allowed"); + + // process args + + if (narg < 1) utils::missing_cmd_args(FLERR, "reset_atoms image", error); + if (narg > 1) error->all(FLERR, "Unknown reset_atoms image keyword: {}", arg[1]); + int igroup = group->find(arg[0]); + if (igroup < 0) error->all(FLERR, "Could not find reset_atoms image group {}", arg[0]); + int groupbit = group->bitmask[igroup]; + + if (comm->me == 0) utils::logmesg(lmp, "Resetting image flags ...\n"); + + // record wall time for resetting molecule IDs + + MPI_Barrier(world); + double time1 = platform::walltime(); + + // initialize system since comm->borders() will be invoked + + lmp->init(); + + // setup domain, communication + // exchange will clear map, borders will reset + // this is the map needed to lookup current global IDs for bond topology + + if (domain->triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + domain->reset_box(); + comm->setup(); + comm->exchange(); + comm->borders(); + if (domain->triclinic) domain->lamda2x(atom->nlocal + atom->nghost); + + // create computes and variables + + auto frags = modify->add_compute("frags_r_i_f all fragment/atom single yes"); + auto chunk = modify->add_compute("chunk_r_i_f all chunk/atom c_frags_r_i_f compress yes"); + auto flags = modify->add_compute("flags_r_i_f all property/atom ix iy iz"); + input->variable->set("ix_r_i_f atom c_flags_r_i_f[1]"); + input->variable->set("iy_r_i_f atom c_flags_r_i_f[2]"); + input->variable->set("iz_r_i_f atom c_flags_r_i_f[3]"); + auto ifmin = modify->add_compute("ifmin_r_i_f all reduce/chunk chunk_r_i_f min " + "v_ix_r_i_f v_iy_r_i_f v_iz_r_i_f"); + auto ifmax = modify->add_compute("ifmax_r_i_f all reduce/chunk chunk_r_i_f max " + "v_ix_r_i_f v_iy_r_i_f v_iz_r_i_f"); + auto cdist = modify->add_compute("cdist_r_i_f all chunk/spread/atom chunk_r_i_f " + "c_ifmax_r_i_f[*] c_ifmin_r_i_f[*]"); + + // trigger computes + + frags->compute_peratom(); + chunk->compute_peratom(); + flags->compute_peratom(); + ifmin->compute_array(); + ifmax->compute_array(); + cdist->compute_peratom(); + + // reset image flags for atoms in group + + const int *const mask = atom->mask; + const int nlocal = atom->nlocal; + imageint *image = atom->image; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + int ix = (image[i] & IMGMASK) - IMGMAX; + int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; + int iz = (image[i] >> IMG2BITS) - IMGMAX; + ix -= (int) floor(0.5 * (cdist->array_atom[i][0] + cdist->array_atom[i][3])); + iy -= (int) floor(0.5 * (cdist->array_atom[i][1] + cdist->array_atom[i][4])); + iz -= (int) floor(0.5 * (cdist->array_atom[i][2] + cdist->array_atom[i][5])); + image[i] = ((imageint) (ix + IMGMAX) & IMGMASK) | + (((imageint) (iy + IMGMAX) & IMGMASK) << IMGBITS) | + (((imageint) (iz + IMGMAX) & IMGMASK) << IMG2BITS); + } + } + + // cleanup + + modify->delete_compute("cdist_r_i_f"); + modify->delete_compute("ifmax_r_i_f"); + modify->delete_compute("ifmin_r_i_f"); + modify->delete_compute("flags_r_i_f"); + modify->delete_compute("chunk_r_i_f"); + modify->delete_compute("frags_r_i_f"); + input->variable->set("ix_r_i_f delete"); + input->variable->set("iy_r_i_f delete"); + input->variable->set("iz_r_i_f delete"); + + // total time + + MPI_Barrier(world); + if (comm->me == 0) + utils::logmesg(lmp, " reset_atoms image CPU = {:.3f} seconds\n", platform::walltime() - time1); +} diff --git a/src/reset_atoms_image.h b/src/reset_atoms_image.h new file mode 100644 index 0000000000..314f2dd086 --- /dev/null +++ b/src/reset_atoms_image.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + 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. +------------------------------------------------------------------------- */ + +#ifdef COMMAND_CLASS +// clang-format off +CommandStyle(RESET_ATOMS_IMAGE,ResetAtomsImage); +// clang-format on +#else + +#ifndef LMP_RESET_ATOMS_IMAGE_H +#define LMP_RESET_ATOMS_IMAGE_H + +#include "command.h" + +namespace LAMMPS_NS { + +class ResetAtomsImage : public Command { + public: + ResetAtomsImage(class LAMMPS *); + void command(int, char **) override; +}; +} // namespace LAMMPS_NS +#endif +#endif diff --git a/src/reset_mol_ids.cpp b/src/reset_atoms_mol.cpp similarity index 62% rename from src/reset_mol_ids.cpp rename to src/reset_atoms_mol.cpp index 0a0f9dfa1a..ee4c28136f 100644 --- a/src/reset_mol_ids.cpp +++ b/src/reset_atoms_mol.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -16,7 +15,7 @@ Contributing author: Jacob Gissinger (jacob.gissinger@colorado.edu) ------------------------------------------------------------------------- */ -#include "reset_mol_ids.h" +#include "reset_atoms_mol.h" #include "atom.h" #include "comm.h" @@ -33,10 +32,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -ResetMolIDs::ResetMolIDs(LAMMPS *lmp) : Command(lmp) { - cfa = nullptr; - cca = nullptr; - +ResetAtomsMol::ResetAtomsMol(LAMMPS *lmp) : Command(lmp), cfa(nullptr), cca(nullptr) +{ // default settings compressflag = 1; @@ -49,49 +46,49 @@ ResetMolIDs::ResetMolIDs(LAMMPS *lmp) : Command(lmp) { /* ---------------------------------------------------------------------- */ -ResetMolIDs::~ResetMolIDs() +ResetAtomsMol::~ResetAtomsMol() { if (!idfrag.empty()) modify->delete_compute(idfrag); if (compressflag && !idchunk.empty()) modify->delete_compute(idchunk); } /* ---------------------------------------------------------------------- - called as reset_mol_ids command in input script + called as reset_atoms mol command in input script ------------------------------------------------------------------------- */ -void ResetMolIDs::command(int narg, char **arg) +void ResetAtomsMol::command(int narg, char **arg) { if (domain->box_exist == 0) - error->all(FLERR,"Reset_mol_ids command before simulation box is defined"); - if (atom->tag_enable == 0) - error->all(FLERR,"Cannot use reset_mol_ids unless atoms have IDs"); + error->all(FLERR, "Reset_atoms mol command before simulation box is defined"); + if (atom->tag_enable == 0) error->all(FLERR, "Cannot use reset_atoms mol unless atoms have IDs"); if (atom->molecular != Atom::MOLECULAR) - error->all(FLERR,"Can only use reset_mol_ids on molecular systems"); + error->all(FLERR, "Can only use reset_atoms mol on molecular systems"); // process args - if (narg < 1) error->all(FLERR,"Illegal reset_mol_ids command"); + if (narg < 1) utils::missing_cmd_args(FLERR, "reset_atoms mol", error); char *groupid = arg[0]; int iarg = 1; while (iarg < narg) { - if (strcmp(arg[iarg],"compress") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal reset_mol_ids command"); - compressflag = utils::logical(FLERR,arg[iarg+1],false,lmp); + if (strcmp(arg[iarg], "compress") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "reset_atoms mol compress", error); + compressflag = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"single") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal reset_mol_ids command"); - singleflag = utils::logical(FLERR,arg[iarg+1],false,lmp); + } else if (strcmp(arg[iarg], "single") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "reset_atoms mol single", error); + singleflag = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"offset") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal reset_mol_ids command"); - offset = utils::tnumeric(FLERR,arg[iarg+1],true,lmp); - if (offset < -1) error->all(FLERR,"Illegal reset_mol_ids command"); + } else if (strcmp(arg[iarg], "offset") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "reset_atoms mol offset", error); + offset = utils::tnumeric(FLERR, arg[iarg + 1], true, lmp); + if (offset < -1) error->all(FLERR, "Illegal reset_atoms mol offset: {}", offset); iarg += 2; - } else error->all(FLERR,"Illegal reset_mol_ids command"); + } else + error->all(FLERR, "Unknown reset_atoms mol keyword: {}", arg[iarg]); } - if (comm->me == 0) utils::logmesg(lmp,"Resetting molecule IDs ...\n"); + if (comm->me == 0) utils::logmesg(lmp, "Resetting molecule IDs ...\n"); // record wall time for resetting molecule IDs @@ -112,11 +109,11 @@ void ResetMolIDs::command(int narg, char **arg) comm->setup(); comm->exchange(); comm->borders(); - if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + if (domain->triclinic) domain->lamda2x(atom->nlocal + atom->nghost); // create computes - create_computes((char *) "COMMAND",groupid); + create_computes((char *) "COMMAND", groupid); // reset molecule IDs @@ -128,44 +125,43 @@ void ResetMolIDs::command(int narg, char **arg) if (comm->me == 0) { if (nchunk < 0) - utils::logmesg(lmp," number of new molecule IDs = unknown\n"); + utils::logmesg(lmp, " number of new molecule IDs = unknown\n"); else - utils::logmesg(lmp," number of new molecule IDs = {}\n",nchunk); - utils::logmesg(lmp," reset_mol_ids CPU = {:.3f} seconds\n", - platform::walltime()-time1); + utils::logmesg(lmp, " number of new molecule IDs = {}\n", nchunk); + utils::logmesg(lmp, " reset_atoms mol CPU = {:.3f} seconds\n", platform::walltime() - time1); } } /* ---------------------------------------------------------------------- - create computes used by reset_mol_ids + create computes used by reset_atoms_mol ------------------------------------------------------------------------- */ -void ResetMolIDs::create_computes(char *fixid, char *groupid) +void ResetAtomsMol::create_computes(char *fixid, char *groupid) { int igroup = group->find(groupid); - if (igroup == -1) error->all(FLERR,"Could not find reset_mol_ids group ID"); + if (igroup < 0) error->all(FLERR, "Could not find reset_atoms mol group {}", groupid); groupbit = group->bitmask[igroup]; // create instances of compute fragment/atom, compute reduce (if needed), // and compute chunk/atom. all use the group-ID for this command. // 'fixid' allows for creating independent instances of the computes - idfrag = fmt::format("{}_reset_mol_ids_FRAGMENT_ATOM",fixid); + idfrag = fmt::format("{}_reset_atoms_mol_FRAGMENT_ATOM", fixid); auto use_single = singleflag ? "yes" : "no"; - cfa = dynamic_cast( - modify->add_compute(fmt::format("{} {} fragment/atom single {}",idfrag,groupid,use_single))); + cfa = dynamic_cast(modify->add_compute( + fmt::format("{} {} fragment/atom single {}", idfrag, groupid, use_single))); - idchunk = fmt::format("{}_reset_mol_ids_CHUNK_ATOM",fixid); + idchunk = fmt::format("{}_reset_atoms_mol_CHUNK_ATOM", fixid); if (compressflag) - cca = dynamic_cast( - modify->add_compute(fmt::format("{} {} chunk/atom molecule compress yes",idchunk,groupid))); + cca = dynamic_cast(modify->add_compute( + fmt::format("{} {} chunk/atom molecule compress yes", idchunk, groupid))); } /* ---------------------------------------------------------------------- called from command() and directly from fixes that update molecules ------------------------------------------------------------------------- */ -void ResetMolIDs::reset() +void ResetAtomsMol::reset() { // invoke peratom method of compute fragment/atom // walks bond connectivity and assigns each atom a fragment ID @@ -181,8 +177,7 @@ void ResetMolIDs::reset() int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - molecule[i] = static_cast (fragIDs[i]); + if (mask[i] & groupbit) molecule[i] = static_cast(fragIDs[i]); // if compressflag = 0, done // set nchunk = -1 since cannot easily determine # of new molecule IDs @@ -208,7 +203,7 @@ void ResetMolIDs::reset() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (fragIDs[i] == 0.0) mysingle = 1; - MPI_Allreduce(&mysingle,&singleexist,1,MPI_INT,MPI_MAX,world); + MPI_Allreduce(&mysingle, &singleexist, 1, MPI_INT, MPI_MAX, world); if (singleexist) nchunk--; } @@ -220,10 +215,10 @@ void ResetMolIDs::reset() if (groupbit != 1) { tagint mymol = 0; for (int i = 0; i < nlocal; i++) - if (!(mask[i] & groupbit)) - mymol = MAX(mymol,molecule[i]); - MPI_Allreduce(&mymol,&offset,1,MPI_LMP_TAGINT,MPI_MAX,world); - } else offset = 0; + if (!(mask[i] & groupbit)) mymol = MAX(mymol, molecule[i]); + MPI_Allreduce(&mymol, &offset, 1, MPI_LMP_TAGINT, MPI_MAX, world); + } else + offset = 0; } // reset molecule ID for all atoms in group @@ -231,11 +226,14 @@ void ResetMolIDs::reset() for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { - auto newid = static_cast(chunkIDs[i]); + auto newid = static_cast(chunkIDs[i]); if (singleexist) { - if (newid == 1) newid = 0; - else newid += offset - 1; - } else newid += offset; + if (newid == 1) + newid = 0; + else + newid += offset - 1; + } else + newid += offset; molecule[i] = newid; } } diff --git a/src/reset_mol_ids.h b/src/reset_atoms_mol.h similarity index 85% rename from src/reset_mol_ids.h rename to src/reset_atoms_mol.h index c25cb96726..3fad2560df 100644 --- a/src/reset_mol_ids.h +++ b/src/reset_atoms_mol.h @@ -13,21 +13,21 @@ #ifdef COMMAND_CLASS // clang-format off -CommandStyle(reset_mol_ids,ResetMolIDs); +CommandStyle(RESET_ATOMS_MOL,ResetAtomsMol); // clang-format on #else -#ifndef LMP_RESET_MOL_IDS_H -#define LMP_RESET_MOL_IDS_H +#ifndef LMP_RESET_ATOMS_MOL_H +#define LMP_RESET_ATOMS_MOL_H #include "command.h" namespace LAMMPS_NS { -class ResetMolIDs : public Command { +class ResetAtomsMol : public Command { public: - ResetMolIDs(class LAMMPS *); - ~ResetMolIDs() override; + ResetAtomsMol(class LAMMPS *); + ~ResetAtomsMol() override; void command(int, char **) override; void create_computes(char *, char *); void reset(); @@ -43,7 +43,6 @@ class ResetMolIDs : public Command { class ComputeFragmentAtom *cfa; class ComputeChunkAtom *cca; }; - } // namespace LAMMPS_NS #endif diff --git a/src/respa.cpp b/src/respa.cpp index 3e90a8baf9..71878a5af3 100644 --- a/src/respa.cpp +++ b/src/respa.cpp @@ -372,7 +372,7 @@ void Respa::setup(int flag) mesg += fmt::format(" {}:{}", ilevel + 1, step[ilevel]); mesg += "\n r-RESPA fixes :"; - for (int l = 0; l < modify->n_post_force_respa_any; ++l) { + for (int l = 0; l < modify->n_post_force_respa; ++l) { Fix *f = modify->get_fix_by_index(modify->list_post_force_respa[l]); if (f->respa_level >= 0) mesg += fmt::format(" {}:{}[{}]", MIN(f->respa_level + 1, nlevels), f->style, f->id); diff --git a/src/variable.cpp b/src/variable.cpp index 819f130a02..bb45649208 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -985,8 +985,21 @@ char *Variable::retrieve(const char *name) str = data[ivar][1] = utils::strdup(result); } else if (style[ivar] == PYTHON) { int ifunc = python->variable_match(data[ivar][0],name,0); - if (ifunc < 0) - error->all(FLERR,"Python variable {} does not match Python function {}", name, data[ivar][0]); + if (ifunc < 0) { + if (ifunc == -1) { + error->all(FLERR, "Could not find Python function {} linked to variable {}", + data[ivar][0], name); + } else if (ifunc == -2) { + error->all(FLERR, "Python function {} for variable {} does not have a return value", + data[ivar][0], name); + } else if (ifunc == -3) { + error->all(FLERR,"Python variable {} does not match variable name registered with " + "Python function {}", name, data[ivar][0]); + } else { + error->all(FLERR, "Unknown error verifying function {} linked to python style variable {}", + data[ivar][0],name); + } + } python->invoke_function(ifunc,data[ivar][1]); str = data[ivar][1]; // if Python func returns a string longer than VALUELENGTH diff --git a/tools/coding_standard/versiontags.py b/tools/coding_standard/versiontags.py index 75a37dfbcc..0b4597046f 100644 --- a/tools/coding_standard/versiontags.py +++ b/tools/coding_standard/versiontags.py @@ -36,7 +36,7 @@ patterns: """ def check_pending_tag(f): - pattern = re.compile(r'^ *\.\. +version(changed|added):: +TBD') + pattern = re.compile(r'^ *\.\. +(version(changed|added)|deprecated):: +TBD') last_line = "\n" lineno = 1 errors = set() diff --git a/tools/singularity/ubuntu18.04.def b/tools/singularity/ubuntu18.04.def index 4f8dd22c43..02351d9ecb 100644 --- a/tools/singularity/ubuntu18.04.def +++ b/tools/singularity/ubuntu18.04.def @@ -5,7 +5,7 @@ From: ubuntu:18.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu18.04_amd_rocm.def b/tools/singularity/ubuntu18.04_amd_rocm.def index 721591c589..38eaa6e322 100644 --- a/tools/singularity/ubuntu18.04_amd_rocm.def +++ b/tools/singularity/ubuntu18.04_amd_rocm.def @@ -45,7 +45,7 @@ From: ubuntu:18.04 ########################################################################### # Common Software ########################################################################### - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get install --no-install-recommends -y \ bc \ diff --git a/tools/singularity/ubuntu18.04_gpu.def b/tools/singularity/ubuntu18.04_gpu.def index d6947bb742..cab62c623f 100644 --- a/tools/singularity/ubuntu18.04_gpu.def +++ b/tools/singularity/ubuntu18.04_gpu.def @@ -48,7 +48,7 @@ From: ubuntu:18.04 ########################################################################### # Common Software ########################################################################### - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get install --no-install-recommends -y \ bc \ diff --git a/tools/singularity/ubuntu18.04_intel_opencl.def b/tools/singularity/ubuntu18.04_intel_opencl.def index a1df05fe0e..2d562771bb 100644 --- a/tools/singularity/ubuntu18.04_intel_opencl.def +++ b/tools/singularity/ubuntu18.04_intel_opencl.def @@ -5,7 +5,7 @@ From: ubuntu:18.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu18.04_nvidia.def b/tools/singularity/ubuntu18.04_nvidia.def index 7c0819a7ab..2a3a34b1b2 100644 --- a/tools/singularity/ubuntu18.04_nvidia.def +++ b/tools/singularity/ubuntu18.04_nvidia.def @@ -5,7 +5,7 @@ From: nvidia/cuda:11.6.2-devel-ubuntu18.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu20.04.def b/tools/singularity/ubuntu20.04.def index 8b3c92ada0..2a2a1dd660 100644 --- a/tools/singularity/ubuntu20.04.def +++ b/tools/singularity/ubuntu20.04.def @@ -5,7 +5,7 @@ From: ubuntu:20.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu20.04_amd_rocm.def b/tools/singularity/ubuntu20.04_amd_rocm.def index 3e018363b2..f947de9ee9 100644 --- a/tools/singularity/ubuntu20.04_amd_rocm.def +++ b/tools/singularity/ubuntu20.04_amd_rocm.def @@ -36,7 +36,7 @@ From: ubuntu:20.04 ########################################################################### # Common Software ########################################################################### - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get install --no-install-recommends -y \ bc \ diff --git a/tools/singularity/ubuntu20.04_gpu.def b/tools/singularity/ubuntu20.04_gpu.def index 9c9dea571d..f84c1f8926 100644 --- a/tools/singularity/ubuntu20.04_gpu.def +++ b/tools/singularity/ubuntu20.04_gpu.def @@ -39,7 +39,7 @@ From: ubuntu:20.04 # Common Software ########################################################################### apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get install --no-install-recommends -y \ bc \ diff --git a/tools/singularity/ubuntu20.04_intel_opencl.def b/tools/singularity/ubuntu20.04_intel_opencl.def index 96769516d4..cc547fef29 100644 --- a/tools/singularity/ubuntu20.04_intel_opencl.def +++ b/tools/singularity/ubuntu20.04_intel_opencl.def @@ -5,7 +5,7 @@ From: ubuntu:20.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu20.04_nvidia.def b/tools/singularity/ubuntu20.04_nvidia.def index 654b69f0b9..8ec334ad8b 100644 --- a/tools/singularity/ubuntu20.04_nvidia.def +++ b/tools/singularity/ubuntu20.04_nvidia.def @@ -5,7 +5,7 @@ From: nvidia/cuda:11.6.2-devel-ubuntu20.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu20.04_oneapi.def b/tools/singularity/ubuntu20.04_oneapi.def index 8b66d8d441..25c913f392 100644 --- a/tools/singularity/ubuntu20.04_oneapi.def +++ b/tools/singularity/ubuntu20.04_oneapi.def @@ -5,7 +5,7 @@ From: ubuntu:20.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/tools/singularity/ubuntu22.04.def b/tools/singularity/ubuntu22.04.def index a1a2a45b49..8a4f262f75 100644 --- a/tools/singularity/ubuntu22.04.def +++ b/tools/singularity/ubuntu22.04.def @@ -5,7 +5,7 @@ From: ubuntu:22.04 export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install --no-install-recommends -y software-properties-common gpg gpg-agent - add-apt-repository ppa:openkim/latest + add-apt-repository ppa:openkim/latest -y apt-get update apt-get upgrade --no-install-recommends -y apt-get install --no-install-recommends -y \ diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index bbb363dfab..bb0f6e2894 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -209,6 +209,10 @@ TEST_F(LibraryProperties, setting) lammps_command(lmp, "dimension 3"); if (!verbose) ::testing::internal::GetCapturedStdout(); + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_active"), 0); + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 0); + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 0); + EXPECT_EQ(lammps_extract_setting(lmp, "world_size"), 1); EXPECT_EQ(lammps_extract_setting(lmp, "world_rank"), 0); EXPECT_EQ(lammps_extract_setting(lmp, "universe_size"), 1); @@ -545,3 +549,27 @@ TEST_F(AtomProperties, position) EXPECT_DOUBLE_EQ(x[1][1], 0.1); EXPECT_DOUBLE_EQ(x[1][2], 0.1); } + +TEST(SystemSettings, kokkos) +{ + if (!lammps_config_has_package("KOKKOS")) GTEST_SKIP(); + if (!lammps_config_accelerator("KOKKOS", "api", "openmp")) GTEST_SKIP(); + + // clang-format off + const char *args[] = {"SystemSettings", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + // clang-format on + char **argv = (char **)args; + int argc = sizeof(args) / sizeof(char *); + + ::testing::internal::CaptureStdout(); + void *lmp = lammps_open_no_mpi(argc, argv, nullptr); + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + EXPECT_THAT(output, StartsWith("LAMMPS (")); + + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_active"), 1); + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 4); + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 0); + lammps_close(lmp); +} diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index c9a7c7df59..aa1bd22fa4 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -53,10 +53,10 @@ endif() target_link_libraries(test_kim_commands PRIVATE lammps GTest::GMock) add_test(NAME KimCommands COMMAND test_kim_commands) -add_executable(test_reset_ids test_reset_ids.cpp) -target_compile_definitions(test_reset_ids PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(test_reset_ids PRIVATE lammps GTest::GMock) -add_test(NAME ResetIDs COMMAND test_reset_ids) +add_executable(test_reset_atoms test_reset_atoms.cpp) +target_compile_definitions(test_reset_atoms PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(test_reset_atoms PRIVATE lammps GTest::GMock) +add_test(NAME ResetAtoms COMMAND test_reset_atoms) if(PKG_MOLECULE) add_executable(test_compute_global test_compute_global.cpp) diff --git a/unittest/commands/test_reset_ids.cpp b/unittest/commands/test_reset_atoms.cpp similarity index 68% rename from unittest/commands/test_reset_ids.cpp rename to unittest/commands/test_reset_atoms.cpp index a31f665159..a0afe36324 100644 --- a/unittest/commands/test_reset_ids.cpp +++ b/unittest/commands/test_reset_atoms.cpp @@ -17,6 +17,7 @@ #include "info.h" #include "input.h" #include "lammps.h" +#include "library.h" #include "output.h" #include "update.h" #include "utils.h" @@ -36,11 +37,11 @@ namespace LAMMPS_NS { #define STRINGIFY(val) XSTR(val) #define XSTR(val) #val -class ResetIDsTest : public LAMMPSTest { +class ResetAtomsIDTest : public LAMMPSTest { protected: void SetUp() override { - testbinary = "ResetIDsTest"; + testbinary = "ResetAtomsIDTest"; LAMMPSTest::SetUp(); if (info->has_style("atom", "full")) { BEGIN_HIDE_OUTPUT(); @@ -51,7 +52,7 @@ protected: } }; -TEST_F(ResetIDsTest, MolIDAll) +TEST_F(ResetAtomsIDTest, MolIDAll) { if (lmp->atom->natoms == 0) GTEST_SKIP(); @@ -89,7 +90,7 @@ TEST_F(ResetIDsTest, MolIDAll) // the original data file has two different molecule IDs // for two residues of the same molecule/fragment. BEGIN_HIDE_OUTPUT(); - command("reset_mol_ids all"); + command("reset_atoms mol all"); END_HIDE_OUTPUT(); ASSERT_EQ(molid[GETIDX(1)], 1); @@ -123,7 +124,7 @@ TEST_F(ResetIDsTest, MolIDAll) ASSERT_EQ(molid[GETIDX(29)], 5); } -TEST_F(ResetIDsTest, DeletePlusAtomID) +TEST_F(ResetAtomsIDTest, DeletePlusAtomID) { if (lmp->atom->natoms == 0) GTEST_SKIP(); @@ -134,7 +135,7 @@ TEST_F(ResetIDsTest, DeletePlusAtomID) command("group allwater molecule 3:6"); command("group twowater molecule 4:6:2"); command("delete_atoms group twowater compress no bond yes"); - command("reset_mol_ids all"); + command("reset_atoms mol all"); END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->natoms, 23); ASSERT_EQ(lmp->atom->map_tag_max, 26); @@ -193,7 +194,7 @@ TEST_F(ResetIDsTest, DeletePlusAtomID) ASSERT_GE(GETIDX(26), 0); BEGIN_HIDE_OUTPUT(); - command("reset_atom_ids"); + command("reset_atoms id"); END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->map_tag_max, 23); @@ -201,7 +202,7 @@ TEST_F(ResetIDsTest, DeletePlusAtomID) ASSERT_GE(GETIDX(i), 0); } -TEST_F(ResetIDsTest, PartialOffset) +TEST_F(ResetAtomsIDTest, PartialOffset) { if (lmp->atom->natoms == 0) GTEST_SKIP(); @@ -211,7 +212,7 @@ TEST_F(ResetIDsTest, PartialOffset) BEGIN_HIDE_OUTPUT(); command("group allwater molecule 3:6"); command("group nowater subtract all allwater"); - command("reset_mol_ids allwater offset 4"); + command("reset_atoms mol allwater offset 4"); END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->natoms, 29); ASSERT_EQ(lmp->atom->map_tag_max, 29); @@ -247,7 +248,7 @@ TEST_F(ResetIDsTest, PartialOffset) ASSERT_EQ(molid[GETIDX(29)], 8); BEGIN_HIDE_OUTPUT(); - command("reset_mol_ids nowater offset 0"); + command("reset_atoms mol nowater offset 0"); END_HIDE_OUTPUT(); ASSERT_EQ(molid[GETIDX(1)], 1); @@ -281,7 +282,7 @@ TEST_F(ResetIDsTest, PartialOffset) ASSERT_EQ(molid[GETIDX(29)], 8); } -TEST_F(ResetIDsTest, DeleteAdd) +TEST_F(ResetAtomsIDTest, DeleteAdd) { if (lmp->atom->natoms == 0) GTEST_SKIP(); @@ -293,7 +294,7 @@ TEST_F(ResetIDsTest, DeleteAdd) command("group twowater molecule 4:6:2"); command("group nowater subtract all allwater"); command("delete_atoms group twowater compress no bond yes mol yes"); - command("reset_mol_ids allwater"); + command("reset_atoms mol allwater"); END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->natoms, 23); ASSERT_EQ(lmp->atom->map_tag_max, 26); @@ -352,7 +353,7 @@ TEST_F(ResetIDsTest, DeleteAdd) ASSERT_GE(GETIDX(26), 0); BEGIN_HIDE_OUTPUT(); - command("reset_atom_ids sort yes"); + command("reset_atoms id sort yes"); END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->map_tag_max, 23); @@ -360,7 +361,7 @@ TEST_F(ResetIDsTest, DeleteAdd) ASSERT_GE(GETIDX(i), 0); BEGIN_HIDE_OUTPUT(); - command("reset_mol_ids nowater offset 1"); + command("reset_atoms mol nowater offset 1"); END_HIDE_OUTPUT(); ASSERT_EQ(molid[GETIDX(1)], 2); @@ -392,7 +393,7 @@ TEST_F(ResetIDsTest, DeleteAdd) command("create_atoms 2 single 1.0 0.0 0.0"); command("create_atoms 3 single 2.0 0.0 0.0"); command("create_atoms 4 single 3.0 0.0 0.0"); - command("reset_mol_ids all single yes"); + command("reset_atoms mol all single yes"); END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->natoms, 27); ASSERT_EQ(lmp->atom->map_tag_max, 27); @@ -406,7 +407,7 @@ TEST_F(ResetIDsTest, DeleteAdd) ASSERT_EQ(molid[GETIDX(27)], 7); BEGIN_HIDE_OUTPUT(); - command("reset_mol_ids all single no"); + command("reset_atoms mol all single no"); END_HIDE_OUTPUT(); ASSERT_EQ(molid[GETIDX(21)], 3); @@ -418,7 +419,7 @@ TEST_F(ResetIDsTest, DeleteAdd) ASSERT_EQ(molid[GETIDX(27)], 0); BEGIN_HIDE_OUTPUT(); - command("reset_mol_ids all compress no single yes"); + command("reset_atoms mol all compress no single yes"); END_HIDE_OUTPUT(); ASSERT_EQ(molid[GETIDX(21)], 21); @@ -430,7 +431,7 @@ TEST_F(ResetIDsTest, DeleteAdd) ASSERT_EQ(molid[GETIDX(27)], 27); } -TEST_F(ResetIDsTest, TopologyData) +TEST_F(ResetAtomsIDTest, TopologyData) { if (lmp->atom->natoms == 0) GTEST_SKIP(); @@ -525,7 +526,7 @@ TEST_F(ResetIDsTest, TopologyData) ASSERT_EQ(angle_atom3[GETIDX(24)][0], 26); BEGIN_HIDE_OUTPUT(); - command("reset_atom_ids sort yes"); + command("reset_atoms id sort yes"); END_HIDE_OUTPUT(); num_bond = lmp->atom->num_bond; @@ -618,63 +619,186 @@ TEST_F(ResetIDsTest, TopologyData) ASSERT_EQ(angle_atom3[GETIDX(22)][0], 23); } -TEST_F(ResetIDsTest, DeathTests) +TEST_F(ResetAtomsIDTest, DeathTests) { if (lmp->atom->natoms == 0) GTEST_SKIP(); - TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids");); - TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", - command("reset_mol_ids all offset 1 1");); - TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", - command("reset_mol_ids all offset -2");); - TEST_FAILURE(".*ERROR on proc 0: Expected integer.*", command("reset_mol_ids all offset xxx");); + TEST_FAILURE(".*ERROR: Illegal reset_atoms mol command.*", command("reset_atoms mol");); + TEST_FAILURE(".*ERROR: Unknown reset_atoms mol keyword: 1.*", + command("reset_atoms mol all offset 1 1");); + TEST_FAILURE(".*ERROR: Illegal reset_atoms mol offset: -2.*", + command("reset_atoms mol all offset -2");); TEST_FAILURE(".*ERROR on proc 0: Expected integer.*", - command("reset_mol_ids all compress yes single no offset xxx");); - TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids all offset");); - TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", - command("reset_mol_ids all compress");); + command("reset_atoms mol all offset xxx");); + TEST_FAILURE(".*ERROR on proc 0: Expected integer.*", + command("reset_atoms mol all compress yes single no offset xxx");); + TEST_FAILURE(".*ERROR: Illegal reset_atoms mol offset command: missing argument.*", + command("reset_atoms mol all offset");); + TEST_FAILURE(".*ERROR: Illegal reset_atoms mol compress command: missing argument.*", + command("reset_atoms mol all compress");); TEST_FAILURE(".*ERROR: Expected boolean parameter instead of 'xxx'.*", - command("reset_mol_ids all compress xxx");); - TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids all single");); + command("reset_atoms mol all compress xxx");); + TEST_FAILURE(".*ERROR: Illegal reset_atoms mol single command: missing argument.*", + command("reset_atoms mol all single");); TEST_FAILURE(".*ERROR: Expected boolean parameter instead of 'xxx'.*", - command("reset_mol_ids all single xxx");); + command("reset_atoms mol all single xxx");); + + TEST_FAILURE(".*ERROR: Illegal reset_atoms image command: missing argument.*", + command("reset_atoms image");); + TEST_FAILURE(".*ERROR: Unknown reset_atoms image keyword: xxx.*", + command("reset_atoms image all xxx");); + TEST_FAILURE(".*ERROR: Could not find reset_atoms image group xxx.*", + command("reset_atoms image xxx");); } -class ResetMolIDsTest : public LAMMPSTest { +class ResetAtomsMolTest : public LAMMPSTest { protected: void SetUp() override { - testbinary = "ResetIDsTest"; + testbinary = "ResetAtomsMolTest"; LAMMPSTest::SetUp(); } }; -TEST_F(ResetMolIDsTest, FailBeforeBox) +TEST_F(ResetAtomsMolTest, FailBeforeBox) { - TEST_FAILURE(".*ERROR: Reset_mol_ids command before simulation box is.*", - command("reset_mol_ids all");); + TEST_FAILURE(".*ERROR: Reset_atoms id command before simulation box is.*", + command("reset_atoms id");); + TEST_FAILURE(".*ERROR: Reset_atoms mol command before simulation box is.*", + command("reset_atoms mol all");); + TEST_FAILURE(".*ERROR: Reset_atoms image command before simulation box is.*", + command("reset_atoms image all");); } -TEST_F(ResetMolIDsTest, FailMissingId) +TEST_F(ResetAtomsMolTest, FailMissingId) { BEGIN_HIDE_OUTPUT(); command("atom_modify id no"); command("region box block 0 1 0 1 0 1"); command("create_box 1 box"); END_HIDE_OUTPUT(); - TEST_FAILURE(".*ERROR: Cannot use reset_mol_ids unless.*", command("reset_mol_ids all");); + TEST_FAILURE(".*ERROR: Cannot use reset_atoms mol unless.*", command("reset_atoms mol all");); + TEST_FAILURE(".*ERROR: Cannot use reset_atoms image unless.*", + command("reset_atoms image all");); } -TEST_F(ResetMolIDsTest, FailOnlyMolecular) +TEST_F(ResetAtomsMolTest, FailOnlyMolecular) { BEGIN_HIDE_OUTPUT(); command("clear"); command("region box block 0 1 0 1 0 1"); command("create_box 1 box"); END_HIDE_OUTPUT(); - TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", command("reset_mol_ids all");); + TEST_FAILURE(".*ERROR: Can only use reset_atoms mol.*", command("reset_atoms mol all");); } + +class ResetAtomsImageTest : public LAMMPSTest { +protected: + void SetUp() override + { + testbinary = "ResetAtomsImageTest"; + LAMMPSTest::SetUp(); + if (info->has_style("atom", "full")) { + BEGIN_HIDE_OUTPUT(); + command("variable input_dir index \"" STRINGIFY(TEST_INPUT_FOLDER) "\""); + command("include \"${input_dir}/in.fourmol\""); + command("create_atoms 1 single 1.0 1.0 1.0"); + command("create_atoms 1 single 2.0 1.0 1.0"); + command("create_atoms 1 single 1.0 2.0 1.0"); + command("set atom 1*7 image 1 1 -1"); + command("set atom 8*9 image 2 -1 0"); + command("set atom 8*9 image 2 -1 0"); + command("set atom 10 image 2 0 0"); + command("set atom 11*12 image 2 0 -1"); + command("set atom 13*15 image 1 0 0"); + command("set atom 16*17 image 0 1 1"); + command("set atom 18*19 image 0 1 0"); + command("set atom 20 image 0 2 0"); + command("set atom 21*23 image 20 -1 0"); + command("set atom 27*28 image 1 0 0"); + command("set atom 29 image 1 2 0"); + command("set atom 31 image -2 0 1"); + command("set atom 32 image 0 20 0"); + END_HIDE_OUTPUT(); + } + } +}; + +TEST_F(ResetAtomsImageTest, ResetAtomsImage) +{ + if (lmp->atom->natoms == 0) GTEST_SKIP(); + EXPECT_EQ(lmp->atom->image[GETIDX(1)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(2)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(3)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(4)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(5)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(6)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(7)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(8)], lammps_encode_image_flags(2, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(9)], lammps_encode_image_flags(2, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(10)], lammps_encode_image_flags(2, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(11)], lammps_encode_image_flags(2, 0, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(12)], lammps_encode_image_flags(2, 0, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(13)], lammps_encode_image_flags(1, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(14)], lammps_encode_image_flags(1, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(15)], lammps_encode_image_flags(1, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(16)], lammps_encode_image_flags(0, 1, 1)); + EXPECT_EQ(lmp->atom->image[GETIDX(17)], lammps_encode_image_flags(0, 1, 1)); + EXPECT_EQ(lmp->atom->image[GETIDX(18)], lammps_encode_image_flags(0, 1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(19)], lammps_encode_image_flags(0, 1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(20)], lammps_encode_image_flags(0, 2, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(21)], lammps_encode_image_flags(20, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(22)], lammps_encode_image_flags(20, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(23)], lammps_encode_image_flags(20, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(24)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(25)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(26)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(27)], lammps_encode_image_flags(1, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(28)], lammps_encode_image_flags(1, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(29)], lammps_encode_image_flags(1, 2, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(30)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(31)], lammps_encode_image_flags(-2, 0, 1)); + EXPECT_EQ(lmp->atom->image[GETIDX(32)], lammps_encode_image_flags(0, 20, 0)); + BEGIN_HIDE_OUTPUT(); + command("group subset id 5:32"); + command("reset_atoms image subset"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->atom->image[GETIDX(1)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(2)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(3)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(4)], lammps_encode_image_flags(1, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(5)], lammps_encode_image_flags(0, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(6)], lammps_encode_image_flags(0, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(7)], lammps_encode_image_flags(0, 1, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(8)], lammps_encode_image_flags(1, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(9)], lammps_encode_image_flags(1, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(10)], lammps_encode_image_flags(1, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(11)], lammps_encode_image_flags(1, 0, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(12)], lammps_encode_image_flags(1, 0, -1)); + EXPECT_EQ(lmp->atom->image[GETIDX(13)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(14)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(15)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(16)], lammps_encode_image_flags(-1, 1, 1)); + EXPECT_EQ(lmp->atom->image[GETIDX(17)], lammps_encode_image_flags(-1, 1, 1)); + EXPECT_EQ(lmp->atom->image[GETIDX(18)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(19)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(20)], lammps_encode_image_flags(0, 1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(21)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(22)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(23)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(24)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(25)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(26)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(27)], lammps_encode_image_flags(0, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(28)], lammps_encode_image_flags(0, -1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(29)], lammps_encode_image_flags(0, 1, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(30)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(30)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(31)], lammps_encode_image_flags(0, 0, 0)); + EXPECT_EQ(lmp->atom->image[GETIDX(32)], lammps_encode_image_flags(0, 0, 0)); +} + } // namespace LAMMPS_NS int main(int argc, char **argv) diff --git a/unittest/force-styles/tests/bond-gaussian.yaml b/unittest/force-styles/tests/bond-gaussian.yaml index e6e259b32a..e85d14fba3 100644 --- a/unittest/force-styles/tests/bond-gaussian.yaml +++ b/unittest/force-styles/tests/bond-gaussian.yaml @@ -1,6 +1,7 @@ --- -lammps_version: 17 Feb 2022 -date_generated: Fri Mar 18 22:17:50 2022 +lammps_version: 3 Nov 2022 +tags: generated +date_generated: Mon Nov 21 21:52:14 2022 epsilon: 1e-12 skip_tests: prerequisites: ! | @@ -19,70 +20,70 @@ bond_coeff: ! | equilibrium: 5 1.45 1.37 1.61 2.45 2.85 extract: ! "" natoms: 29 -init_energy: 194.9780382216324 -init_stress: ! |- - -2.4024989684355553e+01 -3.8521513996632500e+01 -1.0851224048428129e+01 1.2562604359180053e+01 1.3677283516797356e+01 4.3206731051245653e+00 +init_energy: 4638.6541482649545 +init_stress: ! |2- + 1.8359565872923367e+03 1.1685750963854580e+03 2.2772768476286187e+03 9.0129794950892881e+02 4.5431504423505157e+02 5.8087298633263757e+01 init_forces: ! |2 - 1 -1.7791337913398690e+00 -5.2745532425491986e+00 -1.9333096530222391e+00 - 2 7.8999913149794128e-293 6.5010830500033665e-293 -9.2980646648301405e-293 + 1 -2.6166538657523114e+02 -2.1914087860149658e+02 3.0394540432772982e+02 + 2 2.5988625278389128e+02 2.1386632535894739e+02 -3.0587871398075208e+02 3 2.4197086198752562e+01 -1.2911571268065043e+01 -1.2153319969868038e+01 4 -3.5002110421521651e+00 9.8124800657318079e-01 -2.4834895420880554e+00 5 -8.7934593181833831e-01 -1.3513167937313169e+00 4.4900533574430685e+00 - 6 -1.9224405194016612e+01 1.9525383982308810e+01 1.1251608936919853e+01 - 7 2.6580140740726381e-131 -1.3633763941647238e-130 -6.8018769495047054e-130 - 8 1.4462104594211977e+00 -1.2568711136582216e+00 7.3991622652588918e-01 - 9 1.2099652614352605e-300 1.3032068217192395e-300 5.3545155818429412e-300 + 6 -3.1076039081690663e+01 8.0316024755627467e+01 3.1453576435533836e+02 + 7 1.1851633887674051e+01 -6.0790640773318657e+01 -3.0328415541841849e+02 + 8 -9.7268051920198786e+01 -1.0757818812527627e+02 -4.3610490313202450e+02 + 9 9.8714262379619981e+01 1.0632131701161805e+02 4.3684481935855041e+02 10 1.8282673669124623e+01 -6.7893037436650294e-01 1.0475143579619905e+01 11 -9.5181855408160265e-01 -2.3577388099405021e+00 -3.8685744266264179e+00 12 -1.1761121482537199e+01 -1.1840691118605761e+01 8.9587696830512531e+00 13 3.9348879648968196e+00 -1.5566010373601853e+00 -7.3956496855403397e-02 14 -1.5580348688551586e+00 3.1703943744370217e-01 -4.0404862787928506e+00 15 -1.0483110905921594e-01 4.0280962447539723e+00 1.4354708657826634e+00 - 16 -8.1019563183350432e+00 1.2376506087197068e+01 -1.2797826282089627e+01 - 17 -9.6845722000297944e-125 6.7536031200741501e-125 2.5693469616608658e-124 - 18 5.0042083741224387e-291 3.2014176819490257e-291 6.0624670892900674e-291 - 19 -5.0042167517970120e-291 -3.2014265949545701e-291 -6.0624614384187022e-291 - 20 8.3776745733654894e-297 8.9130055442585484e-297 -5.6508713648842736e-297 - 21 5.0373663727594610e-296 1.1676684296048456e-296 8.1823232295641435e-296 - 22 -5.1857245273845906e-296 -1.2567112623130275e-296 -8.1358238807042024e-296 - 23 1.4835815462512912e-297 8.9042832708182009e-298 -4.6499348859940937e-298 - 24 6.5124799547612842e-295 -1.0579059065054233e-295 5.4786730014873485e-295 - 25 -6.5176382072810523e-295 1.0492453069148130e-295 -5.4792561056911984e-295 - 26 5.1582525197680877e-298 8.6605995906103569e-298 5.8310420384964103e-299 - 27 -1.5677247388593395e-295 -1.8232011058192963e-295 -3.8038051984576450e-296 - 28 -3.2483754529644398e-299 1.3960035208884715e-299 -2.1978823514938368e-299 - 29 1.5680495764046360e-295 1.8230615054672073e-295 3.8060030808091389e-296 -run_energy: 194.9688901668597 -run_stress: ! |- - -2.4084235648269384e+01 -3.8596877573973650e+01 -1.0971337511117875e+01 1.2627485208541385e+01 1.3589007837800324e+01 4.4518443361436777e+00 + 16 9.5774980977037984e+01 -6.0062791522626100e+01 -2.8838655412045694e+02 + 17 -1.0387693729537303e+02 7.2439297609823171e+01 2.7558872783836733e+02 + 18 -1.7290589161548496e+01 -1.3179016873564919e+02 5.1586854877010114e+02 + 19 -2.6734331696703003e+02 -1.7103176128697325e+02 -3.2387856688053216e+02 + 20 2.8463390612857853e+02 3.0282193002262244e+02 -1.9198998188956895e+02 + 21 -1.3595471277589198e+02 -1.6879175531311859e+02 5.0125731248385966e+02 + 22 -2.4366036541914886e+02 -5.9048783595141884e+01 -3.8227595956741493e+02 + 23 3.7961507819504084e+02 2.2784053890826047e+02 -1.1898135291644472e+02 + 24 1.1246873070738241e+02 -4.4920523111996721e+02 2.6503426336875481e+02 + 25 -3.4676635177604459e+02 5.5824357785083230e+01 -2.9151996318153743e+02 + 26 2.3429762106866218e+02 3.9338087333488397e+02 2.6485699812782624e+01 + 27 6.4413473322621542e+01 -4.9624245043025996e+02 1.7125457908457409e+02 + 28 -3.5866433728099020e+02 1.5413756350253817e+02 -2.4267577083822729e+02 + 29 2.9425086395836865e+02 3.4210488692772179e+02 7.1421191753653204e+01 +run_energy: 4618.705952125554 +run_stress: ! |2- + 1.8397902589595653e+03 1.1724487863122602e+03 2.2782759319716897e+03 9.0366417527896033e+02 4.5574598799336053e+02 5.9672689485998390e+01 run_forces: ! |2 - 1 -1.7800915383536471e+00 -5.2662174638478936e+00 -1.9311810441446928e+00 - 2 9.1200716389742962e-293 7.5205784896271243e-293 -1.0695855329374170e-292 - 3 2.4188774318819682e+01 -1.2910730800434983e+01 -1.2139174094227805e+01 - 4 -3.4905807721708837e+00 9.7423802985974728e-01 -2.4827066691937869e+00 - 5 -8.7826414385513407e-01 -1.3507945719900971e+00 4.4847167409249762e+00 - 6 -1.9198711248640532e+01 1.9501343007070176e+01 1.1259539605043198e+01 - 7 4.0781500460380220e-131 -2.0934766207882755e-130 -1.0411772151605081e-129 - 8 1.4035232720380466e+00 -1.2181526258990241e+00 7.2552718656771575e-01 - 9 1.4877356608185432e-300 1.5947265521745610e-300 6.5759628249586203e-300 - 10 1.8340705485218969e+01 -7.9602516938863732e-01 1.0533434146468263e+01 - 11 -9.4713695434855716e-01 -2.3455928036230933e+00 -3.8477133980837270e+00 - 12 -1.1753841378581289e+01 -1.1839528950721563e+01 8.9356024501072664e+00 - 13 3.9289793641831325e+00 -1.5460483921060724e+00 -7.3078087497547045e-02 - 14 -1.5515717239320088e+00 3.1019421574866657e-01 -4.0233193667488729e+00 - 15 -1.1312732638809736e-01 4.0290637402465492e+00 1.4439547691915919e+00 - 16 -8.1486573539896803e+00 1.2458251785086224e+01 -1.2885602238406578e+01 - 17 -8.5522515805489358e-125 5.9749160301406998e-125 2.2702237597406565e-124 - 18 2.5382954259673697e-291 1.6282298856292719e-291 3.0672317979786876e-291 - 19 -2.5383561239391082e-291 -1.6282944740463789e-291 -3.0671910793881731e-291 - 20 6.0697971738423079e-296 6.4588417107197222e-296 -4.0718590514496707e-296 - 21 3.1636825215784415e-296 7.4502521705718285e-297 5.0914419661316058e-296 - 22 -3.2413538119513539e-296 -7.9143971383319095e-297 -5.0672219270657353e-296 - 23 7.7671290372912634e-298 4.6414496776008138e-298 -2.4220039065870281e-298 - 24 1.1528889554480086e-295 -1.8584672369333140e-296 9.7061626349018667e-296 - 25 -1.1544439355951613e-295 1.8323577266329387e-296 -9.7079719071127095e-296 - 26 1.5549801471527681e-298 2.6109510300375245e-298 1.8092722108425850e-299 - 27 -1.0502291554946705e-295 -1.2226612584790533e-295 -2.5738911540368265e-296 - 28 -1.8342692926757559e-299 7.8715078988712594e-300 -1.2385711775450889e-299 - 29 1.0504125824239381e-295 1.2225825434000646e-295 2.5751297252143716e-296 + 1 -2.6123247146110606e+02 -2.1919307263372883e+02 3.0237555508171170e+02 + 2 2.5946481985769248e+02 2.1395800468042034e+02 -3.0429922592566089e+02 + 3 2.4104808395110172e+01 -1.2865854073142392e+01 -1.2083882913387207e+01 + 4 -3.4905809559903060e+00 9.7423804418107429e-01 -2.4827069981835161e+00 + 5 -8.7826407777385485e-01 -1.3507948021059526e+00 4.4847171151687837e+00 + 6 -3.1019740486745086e+01 8.0315470917380424e+01 3.1385270827879697e+02 + 7 1.1855512952124167e+01 -6.0859047439602143e+01 -3.0267942216207678e+02 + 8 -9.7139239668224732e+01 -1.0689115264867354e+02 -4.3492337910287688e+02 + 9 9.8566534070284817e+01 1.0565669621976006e+02 4.3567718006870649e+02 + 10 1.8332862345492853e+01 -7.7546447474524260e-01 1.0479498854248916e+01 + 11 -9.4713700870724160e-01 -2.3455930111707550e+00 -3.8477135785159731e+00 + 12 -1.1753839309353248e+01 -1.1839526860590677e+01 8.9356008317611710e+00 + 13 3.9289793641852362e+00 -1.5460483921084245e+00 -7.3078087496756511e-02 + 14 -1.5515717239340792e+00 3.1019421574772799e-01 -4.0233193667504690e+00 + 15 -1.1312732638930625e-01 4.0290637402491614e+00 1.4439547691937924e+00 + 16 9.5584985328403420e+01 -6.0034377008082046e+01 -2.8814471939578698e+02 + 17 -1.0371253029506924e+02 7.2457263526211193e+01 2.7530823253114755e+02 + 18 -1.6734173006461219e+01 -1.3081888486925550e+02 5.1373496074962804e+02 + 19 -2.6689091522155491e+02 -1.7109178558868115e+02 -3.2299073527643651e+02 + 20 2.8362508822801612e+02 3.0191067045793665e+02 -1.9074422547319156e+02 + 21 -1.3584009311603779e+02 -1.6741847021957338e+02 4.9993505971275158e+02 + 22 -2.4342958636297089e+02 -5.9309435913166546e+01 -3.8123078015208006e+02 + 23 3.7926967947900869e+02 2.2672790613273992e+02 -1.1870427956067151e+02 + 24 1.1263526323552287e+02 -4.4826736307529882e+02 2.6440276469069875e+02 + 25 -3.4626849198042515e+02 5.5368312528579615e+01 -2.9134479497708327e+02 + 26 2.3363322874490228e+02 3.9289905054671920e+02 2.6942030286384533e+01 + 27 6.4905554146281361e+01 -4.9580198077236491e+02 1.7016719858461872e+02 + 28 -3.5803172302507875e+02 1.5409360889763499e+02 -2.4188045098816568e+02 + 29 2.9312616887879739e+02 3.4170837187472995e+02 7.1713252403546960e+01 ... diff --git a/unittest/force-styles/tests/mol-pair-nm_cut_coul_cut.yaml b/unittest/force-styles/tests/mol-pair-nm_cut_coul_cut.yaml index e10d630408..dc09f6242b 100644 --- a/unittest/force-styles/tests/mol-pair-nm_cut_coul_cut.yaml +++ b/unittest/force-styles/tests/mol-pair-nm_cut_coul_cut.yaml @@ -1,7 +1,7 @@ --- -lammps_version: 17 Feb 2022 -date_generated: Fri Mar 18 22:17:35 2022 -epsilon: 5e-13 +lammps_version: 3 Nov 2022 +date_generated: Wed Nov 23 12:21:08 2022 +epsilon: 2e-12 skip_tests: prerequisites: ! | atom full @@ -33,72 +33,72 @@ extract: ! | nn 2 mm 2 natoms: 29 -init_vdwl: 184.28678589160327 -init_coul: -135.3222017722983 +init_vdwl: 184.287044185624 +init_coul: -137.87932620011787 init_stress: ! |2- - 5.1099535412443879e+02 4.9267015856417487e+02 1.0972826650625757e+03 -1.9179119371088936e+02 -3.5985836516943652e+00 1.6890666491875683e+02 + 5.0652399415102809e+02 4.9736621002026737e+02 1.0945023745733126e+03 -1.9301832865224381e+02 1.8762224642096914e-01 1.7162238049862481e+02 init_forces: ! |2 - 1 -3.3237622364758597e+00 6.7713954997753760e+01 8.3067188829067177e+01 - 2 3.9621008700560012e+01 3.0171229889604540e+01 -4.8145332639882334e+01 - 3 -3.5364644744971940e+01 -9.6539501255026011e+01 -3.5029548782863188e+01 - 4 -5.3015461109817663e-01 1.6289587757514515e-01 -7.2423374326431356e-01 - 5 -5.9482314827521177e-01 3.6012564229132904e-01 7.9763541784878933e-01 - 6 -2.0517469128198312e+02 2.3641073678086124e+02 2.8403110395134235e+02 - 7 1.4287738299209584e+01 -8.3042673557006708e+01 -4.2404138177988466e+02 - 8 3.4432579872496632e+01 -2.3062478463316680e+01 1.0196257581358861e+02 - 9 2.1504316475975024e+01 1.5520947058320779e+01 8.8721284584619994e+01 - 10 1.3156277736186865e+02 -1.5256269193303697e+02 -4.7528776206099316e+01 - 11 -1.1549608580120421e+00 7.0751627315313514e-01 -1.2306532477500820e+00 - 12 8.2305373454600836e+00 2.8332067643232048e+00 -1.6285990412442382e+00 - 13 2.2152653863898988e-01 -2.5442239617884921e-01 -1.7821156240885982e-02 - 14 -1.4864243248803288e+00 4.9691633196181018e-01 -6.5591950906426355e-01 - 15 1.9536455977505707e-01 4.6553673584615141e-01 -7.3823010387388632e-01 - 16 1.1408068052592634e+02 -8.3363365075734180e+01 -2.9358101411834207e+02 - 17 -1.1530269288646562e+02 8.4705249217102178e+01 2.9252691476710731e+02 - 18 1.2607896146319246e+00 6.6515350853351460e+00 -9.8941034529134715e+00 - 19 1.6182226631729169e+00 -1.6594283813607693e+00 5.6553541079235838e+00 - 20 -3.4521573063242741e+00 -3.1789176785999720e+00 4.2591620921699045e+00 - 21 -1.5230523428245663e+01 -1.8827777303529409e+01 4.5543598985413915e+01 - 22 -2.5331360436022880e+01 -5.4301878248720961e+00 -3.5349975516643234e+01 - 23 4.0112972843495513e+01 2.2949867135700025e+01 -9.6970781334064569e+00 + 1 -3.5396501309981954e+00 6.6944364611585584e+01 8.3059219120660856e+01 + 2 3.9621008700560019e+01 3.0171229889604543e+01 -4.8145332639882334e+01 + 3 -3.5309288471259912e+01 -9.6592073986045776e+01 -3.5059191984527324e+01 + 4 -5.3015461109817674e-01 1.6289587757514493e-01 -7.2423374326431356e-01 + 5 -5.9482314827521177e-01 3.6012564229132926e-01 7.9763541784878955e-01 + 6 -2.0517469128198312e+02 2.3641073678086121e+02 2.8403110395134229e+02 + 7 1.4287738299209584e+01 -8.3042673557006694e+01 -4.2404138177988466e+02 + 8 3.4432579872496632e+01 -2.3062478463316697e+01 1.0196257581358860e+02 + 9 2.1504316475975028e+01 1.5520947058320786e+01 8.8721284584619994e+01 + 10 1.3157989652366749e+02 -1.5248002606214345e+02 -4.7534699865938585e+01 + 11 -1.1549608580120423e+00 7.0751627315313514e-01 -1.2306532477500822e+00 + 12 7.2669942071383717e+00 2.0827730884953919e+00 -9.0483043978096866e-01 + 13 2.2152653863898994e-01 -2.5442239617884937e-01 -1.7821156240885788e-02 + 14 -1.4864243248803288e+00 4.9691633196180973e-01 -6.5591950906426388e-01 + 15 1.9536455977505737e-01 4.6553673584615107e-01 -7.3823010387388610e-01 + 16 1.1427944925864990e+02 -8.2676440560459525e+01 -2.9356712075009648e+02 + 17 -1.1530269288646562e+02 8.4705249217102164e+01 2.9252691476710731e+02 + 18 1.2607896146319251e+00 6.6515350853351460e+00 -9.8941034529134697e+00 + 19 1.6182226631729160e+00 -1.6594283813607693e+00 5.6553541079235821e+00 + 20 -3.4521573063242741e+00 -3.1789176785999724e+00 4.2591620921699054e+00 + 21 -1.5285879701957692e+01 -1.8775204572509647e+01 4.5573242187078066e+01 + 22 -2.5331360436022880e+01 -5.4301878248720943e+00 -3.5349975516643234e+01 + 23 4.0112972843495520e+01 2.2949867135700025e+01 -9.6970781334064569e+00 24 6.6473466694181287e+00 -4.2720688813774373e+01 2.5475101119120744e+01 25 -3.3278855135511762e+01 2.8247579501663811e+00 -2.7042493390233950e+01 26 2.5709355480930235e+01 3.9014887914531776e+01 2.6900053403817590e+00 - 27 1.0035511306793698e+01 -4.5249946085110551e+01 1.8136503701331897e+01 - 28 -3.9953070294941519e+01 1.3962092508592026e+01 -2.6231057257176037e+01 - 29 3.0657392434855581e+01 3.0940622604427993e+01 8.6697893689665211e+00 -run_vdwl: 182.40565476045293 -run_coul: -135.3428229317011 + 27 1.0999054445115412e+01 -4.4499512409282737e+01 1.7412735099868630e+01 + 28 -3.9953070294941519e+01 1.3962092508592027e+01 -2.6231057257176040e+01 + 29 3.0657392434855577e+01 3.0940622604427993e+01 8.6697893689665193e+00 +run_vdwl: 182.40627457531505 +run_coul: -137.89878255208336 run_stress: ! |2- - 5.0949331883645084e+02 4.9079274612266465e+02 1.0779924919705209e+03 -1.8978874005409725e+02 -2.3414288930535676e+00 1.6680086396779814e+02 + 5.0502284487804911e+02 4.9549254038893065e+02 1.0752131218453601e+03 -1.9101402318764428e+02 1.4448370451390913e+00 1.6951693900962570e+02 run_forces: ! |2 - 1 -3.0222512967714557e+00 6.7548505252631742e+01 8.2368596588550062e+01 - 2 3.9249247328631569e+01 2.9923489231546629e+01 -4.7570871930892892e+01 - 3 -3.5327226055520775e+01 -9.6102750283993871e+01 -3.4890589040756382e+01 - 4 -5.2696455605069259e-01 1.6213860296922811e-01 -7.2430457126338410e-01 - 5 -5.9400169113171586e-01 3.6136912208033589e-01 7.9530286564994024e-01 - 6 -2.0274433560773628e+02 2.3284786713406370e+02 2.7401951211582013e+02 - 7 1.4053553144930220e+01 -8.1102084254822103e+01 -4.1219124551744085e+02 - 8 3.2718675446198795e+01 -2.1551046804011083e+01 1.0097962112112319e+02 - 9 2.1323856224128093e+01 1.5222193966786529e+01 8.7834851199368813e+01 - 10 1.3130268818222987e+02 -1.5219622702094762e+02 -4.7515342312770102e+01 - 11 -1.1541261444752642e+00 7.1381752451384339e-01 -1.2230561924848902e+00 - 12 8.2264000446385346e+00 2.8299212831552727e+00 -1.6299507774035358e+00 - 13 2.1792987819368359e-01 -2.5267817510362128e-01 -1.9040070778804069e-02 - 14 -1.4863827602148627e+00 4.9691341825375590e-01 -6.4929126993868946e-01 - 15 1.9516446161304488e-01 4.6409461483290748e-01 -7.4066880359248788e-01 - 16 1.1245063534493042e+02 -8.2380964098503739e+01 -2.8939941367324343e+02 - 17 -1.1367888495468203e+02 8.3736413965239862e+01 2.8833591319216583e+02 - 18 1.2131213413750925e+00 6.6087858905244472e+00 -9.8443684782076062e+00 - 19 1.6546892701962139e+00 -1.6335518483372100e+00 5.6675264381026587e+00 - 20 -3.4406155231052553e+00 -3.1608955862760086e+00 4.2021081664244280e+00 - 21 -1.5380842837515630e+01 -1.8832663749099712e+01 4.5639191584555739e+01 - 22 -2.5437261250740086e+01 -5.4851555768258553e+00 -3.5409747254511750e+01 - 23 4.0368809860056317e+01 2.3008461599616822e+01 -9.7324663526701478e+00 - 24 7.1229399666679027e+00 -4.3444645139181588e+01 2.6085435505612736e+01 - 25 -3.4137823679541398e+01 2.8946896673905611e+00 -2.7774080649897098e+01 - 26 2.6093689208699011e+01 3.9671650206452789e+01 2.8124886686652082e+00 - 27 1.0189565500107717e+01 -4.5358416256293751e+01 1.8141445825723800e+01 - 28 -4.0123206182868742e+01 1.4015089779144132e+01 -2.6301107890805710e+01 - 29 3.0672957337757669e+01 3.0995677534193614e+01 8.7335515148952023e+00 + 1 -3.2370828229989943e+00 6.6780774771428867e+01 8.2360566992843957e+01 + 2 3.9248669659652556e+01 2.9923101710814461e+01 -4.7570156486162247e+01 + 3 -3.5272405495891725e+01 -9.6156898011190052e+01 -3.4920858821878639e+01 + 4 -5.2696307806019427e-01 1.6213782144861011e-01 -7.2430297098202856e-01 + 5 -5.9400132072875222e-01 3.6136881819958322e-01 7.9530174833943768e-01 + 6 -2.0274433109253258e+02 2.3284785750828254e+02 2.7401951291433039e+02 + 7 1.4053553193905296e+01 -8.1102076691627317e+01 -4.1219125509985423e+02 + 8 3.2718449282709940e+01 -2.1550864085726676e+01 1.0097970359571399e+02 + 9 2.1323849598698548e+01 1.5222193680732165e+01 8.7834847272654116e+01 + 10 1.3131984144877813e+02 -1.5211385896116542e+02 -4.7521267129265915e+01 + 11 -1.1541259655305498e+00 7.1381836660091746e-01 -1.2230539280652590e+00 + 12 7.2630852175005964e+00 2.0798061880380749e+00 -9.0633631991268937e-01 + 13 2.1792142656044974e-01 -2.5267485273151963e-01 -1.9040900180560982e-02 + 14 -1.4863809886398240e+00 4.9691277039032383e-01 -6.4928587974626595e-01 + 15 1.9516412586808574e-01 4.6408847437290568e-01 -7.4067142611860370e-01 + 16 1.1264998906650452e+02 -8.1693726909197835e+01 -2.8938652282069330e+02 + 17 -1.1367940494205878e+02 8.3736184613376594e+01 2.8833692617302631e+02 + 18 1.2131256191519586e+00 6.6087841118467869e+00 -9.8443636765781175e+00 + 19 1.6546867296048959e+00 -1.6335521580158148e+00 5.6675246971307507e+00 + 20 -3.4406162815803181e+00 -3.1608941993411719e+00 4.2021061175034422e+00 + 21 -1.5436168448451303e+01 -1.8780058922578032e+01 4.5668818732530838e+01 + 22 -2.5437256643599888e+01 -5.4851610900512116e+00 -3.5409746057405300e+01 + 23 4.0368779518163102e+01 2.3008433743607917e+01 -9.7324579117657564e+00 + 24 7.1229403171558960e+00 -4.3444642379685369e+01 2.6085431366299698e+01 + 25 -3.4137823381351410e+01 2.8946870622451546e+00 -2.7774076485443004e+01 + 26 2.6093689507109417e+01 3.9671649820489279e+01 2.8124906008412616e+00 + 27 1.1152133422843132e+01 -4.4609063038241878e+01 1.7417265391517304e+01 + 28 -4.0123145645809892e+01 1.4014953690801475e+01 -2.6300937504650808e+01 + 29 3.0673827973027787e+01 3.0996718146876649e+01 8.7338378159710270e+00 ... diff --git a/unittest/force-styles/tests/mol-pair-nm_cut_coul_long.yaml b/unittest/force-styles/tests/mol-pair-nm_cut_coul_long.yaml index b3c77b862c..8bc69e85f4 100644 --- a/unittest/force-styles/tests/mol-pair-nm_cut_coul_long.yaml +++ b/unittest/force-styles/tests/mol-pair-nm_cut_coul_long.yaml @@ -1,6 +1,6 @@ --- -lammps_version: 17 Feb 2022 -date_generated: Fri Mar 18 22:17:35 2022 +lammps_version: 3 Nov 2022 +date_generated: Wed Nov 23 12:21:08 2022 epsilon: 7.5e-13 skip_tests: prerequisites: ! | @@ -39,72 +39,72 @@ extract: ! | mm 2 cut_coul 0 natoms: 29 -init_vdwl: 184.28678589160327 +init_vdwl: 184.287044185624 init_coul: 225.82181512692495 init_stress: ! |2- - 5.1535561642229106e+02 5.0058662653359033e+02 1.1159625282020661e+03 -1.8397466102442883e+02 -2.0220636765660638e+00 1.7544854550792292e+02 + 5.1535625659153879e+02 5.0058721227699067e+02 1.1159628277106565e+03 -1.8397448571567824e+02 -2.0224936628921029e+00 1.7544839728662993e+02 init_forces: ! |2 - 1 -3.0654526282473653e+00 6.6615864099533127e+01 8.2943973715838268e+01 - 2 3.9068866013811309e+01 2.9455617832505151e+01 -4.7591021495719247e+01 - 3 -3.5280048507313708e+01 -9.6589706921967377e+01 -3.5074530442718626e+01 - 4 -6.6290078829733745e-01 1.7069498108397532e-01 -6.5698974844320646e-01 - 5 -7.3666031116459629e-01 3.1866503947918778e-01 8.0597153193899140e-01 - 6 -2.0569141405030027e+02 2.3627567491105717e+02 2.8443813098936624e+02 - 7 1.4533357696957466e+01 -8.2901362570668283e+01 -4.2411675286042595e+02 - 8 3.4572734326141102e+01 -2.2709011166557751e+01 1.0190201388959704e+02 - 9 2.1302134918689685e+01 1.5382116555420744e+01 8.8486496066808485e+01 - 10 1.3163065394972341e+02 -1.5255187760681488e+02 -4.7566872183542166e+01 - 11 -1.0673114564038046e+00 6.0655281622864732e-01 -1.2545988594461333e+00 - 12 7.7809585200300058e+00 3.1160398793201316e+00 -1.4701791888504216e+00 - 13 5.3014557250212346e-01 -2.5075115207640880e-01 -1.8692015200156273e-01 - 14 -1.3123789187002088e+00 4.0626415990577358e-01 -7.3662740015731798e-01 - 15 3.2883564820812672e-01 4.2874288932750715e-01 -7.8340375997477496e-01 - 16 1.1459556574512777e+02 -8.2820743414973677e+01 -2.9444590351113385e+02 - 17 -1.1537978255115650e+02 8.4825361701504292e+01 2.9365401995966459e+02 - 18 3.5910667886316144e-01 4.7762805533526835e+00 -7.8633657965049659e+00 - 19 1.9899962970618248e+00 -7.2139551998620521e-01 5.5216058955830674e+00 - 20 -2.9130824841870520e+00 -3.9872076040781708e+00 4.1253374345150986e+00 - 21 -1.5875835643064573e+01 -1.5889863208570942e+01 4.7172258432278930e+01 - 22 -2.5015657684773860e+01 -7.0704088600117272e+00 -3.6174324111002065e+01 - 23 4.0477622003880207e+01 2.3373134480751212e+01 -1.0495870801503438e+01 + 1 -3.0654561493791848e+00 6.6615850470254358e+01 8.2943973912197166e+01 + 2 3.9068866013811295e+01 2.9455617832505151e+01 -4.7591021495719239e+01 + 3 -3.5280084914007190e+01 -9.6589672345953218e+01 -3.5074510946988802e+01 + 4 -6.6290078829733778e-01 1.7069498108397516e-01 -6.5698974844320646e-01 + 5 -7.3666031116459629e-01 3.1866503947918762e-01 8.0597153193899174e-01 + 6 -2.0569141405030027e+02 2.3627567491105717e+02 2.8443813098936630e+02 + 7 1.4533357696957466e+01 -8.2901362570668297e+01 -4.2411675286042589e+02 + 8 3.4572734326141102e+01 -2.2709011166557758e+01 1.0190201388959706e+02 + 9 2.1302134918689685e+01 1.5382116555420737e+01 8.8486496066808471e+01 + 10 1.3163065501356638e+02 -1.5255187246967631e+02 -4.7566872551658555e+01 + 11 -1.0673114564038049e+00 6.0655281622864710e-01 -1.2545988594461335e+00 + 12 7.7810444548679740e+00 3.1161068077157283e+00 -1.4702437390869596e+00 + 13 5.3014557250212357e-01 -2.5075115207640869e-01 -1.8692015200156262e-01 + 14 -1.3123789187002091e+00 4.0626415990577341e-01 -7.3662740015731820e-01 + 15 3.2883564820812672e-01 4.2874288932750720e-01 -7.8340375997477496e-01 + 16 1.1459556820241663e+02 -8.2820734922833438e+01 -2.9444590333937629e+02 + 17 -1.1537978255115650e+02 8.4825361701504292e+01 2.9365401995966465e+02 + 18 3.5910667886316239e-01 4.7762805533526844e+00 -7.8633657965049650e+00 + 19 1.9899962970618255e+00 -7.2139551998620499e-01 5.5216058955830682e+00 + 20 -2.9130824841870520e+00 -3.9872076040781712e+00 4.1253374345150977e+00 + 21 -1.5875799236371092e+01 -1.5889897784585100e+01 4.7172238936549107e+01 + 22 -2.5015657684773856e+01 -7.0704088600117272e+00 -3.6174324111002072e+01 + 23 4.0477622003880199e+01 2.3373134480751215e+01 -1.0495870801503438e+01 24 7.4996662349142147e+00 -4.3426856761904077e+01 2.2815324534810056e+01 25 -3.3807147976811798e+01 2.9988027310973613e+00 -2.7577372367283733e+01 - 26 2.5746888892709649e+01 4.0174454060022633e+01 4.1505216253578832e+00 - 27 1.0861995979992932e+01 -4.6328822142297405e+01 1.8883010243779164e+01 - 28 -4.0470174882584459e+01 1.5020795051869365e+01 -2.6766823901697389e+01 - 29 2.9999319404392626e+01 3.1302945187447804e+01 7.8628922608669090e+00 -run_vdwl: 182.40255929507265 -run_coul: 225.80523122237145 + 26 2.5746888892709649e+01 4.0174454060022640e+01 4.1505216253578832e+00 + 27 1.0861910045154971e+01 -4.6328889070692995e+01 1.8883074794015705e+01 + 28 -4.0470174882584466e+01 1.5020795051869364e+01 -2.6766823901697389e+01 + 29 2.9999319404392619e+01 3.1302945187447808e+01 7.8628922608669081e+00 +run_vdwl: 182.4028175410934 +run_coul: 225.8052312234039 run_stress: ! |2- - 5.1384631551491782e+02 4.9870417055031982e+02 1.0966342093912015e+03 -1.8197324336578851e+02 -7.7105078556388151e-01 1.7333789878387816e+02 + 5.1384695555524797e+02 4.9870475622702440e+02 1.0966345088415544e+03 -1.8197306815785140e+02 -7.7148065920433828e-01 1.7333775064278868e+02 run_forces: ! |2 - 1 -2.7683190788522740e+00 6.6449095933852917e+01 8.2247798763054263e+01 - 2 3.8702194737017720e+01 2.9212212087553127e+01 -4.7019606503568262e+01 - 3 -3.5243454712977965e+01 -9.6154953753202179e+01 -3.4936504547233788e+01 - 4 -6.5977694961123645e-01 1.7011044348999105e-01 -6.5636000725760957e-01 - 5 -7.3566520752177100e-01 3.2004552783623724e-01 8.0428279587216267e-01 - 6 -2.0326269571945986e+02 2.3271299846462981e+02 2.7442711029956843e+02 - 7 1.4300022426556877e+01 -8.0959802783401827e+01 -4.1226588339681336e+02 - 8 3.2858865815794836e+01 -2.1199692716643838e+01 1.0091081448967174e+02 - 9 2.1122712553671928e+01 1.5084944366082448e+01 8.7605507483986727e+01 - 10 1.3136998924075732e+02 -1.5218480626807963e+02 -4.7552578947927799e+01 - 11 -1.0661815519248918e+00 6.1243966630893298e-01 -1.2462619432373649e+00 - 12 7.7760226803888877e+00 3.1127903917502313e+00 -1.4744683960464942e+00 - 13 5.2674567614856260e-01 -2.4917750370694214e-01 -1.8723948852408964e-01 - 14 -1.3120520030459297e+00 4.0614121490067551e-01 -7.2914653810616858e-01 - 15 3.2867638556545775e-01 4.2750422420803547e-01 -7.8475645386864112e-01 - 16 1.1296204426736116e+02 -8.1834725178344044e+01 -2.9024712497341085e+02 - 17 -1.1375160210673371e+02 8.3851461683740141e+01 2.8944627577285223e+02 - 18 3.0738271507674780e-01 4.7275452047652715e+00 -7.8225407640491564e+00 - 19 2.0274564843313856e+00 -6.9333851982762851e-01 5.5367198586609998e+00 - 20 -2.8992094355719793e+00 -3.9662518101373307e+00 4.0716447585419049e+00 - 21 -1.6026802334504676e+01 -1.5883942063853187e+01 4.7256123626066532e+01 - 22 -2.5118526633549543e+01 -7.1302229414472507e+00 -3.6226155173751806e+01 - 23 4.0731190500597606e+01 2.3426593800522156e+01 -1.0527512154067734e+01 - 24 7.9759015134187958e+00 -4.4140032709411031e+01 2.3421942671527756e+01 - 25 -3.4663427794559517e+01 3.0656502790867206e+00 -2.8305771158291158e+01 - 26 2.6127821098995337e+01 4.0822834309889892e+01 4.2748874027969199e+00 - 27 1.1011144648995060e+01 -4.6436392031462617e+01 1.8878782007839565e+01 - 28 -4.0634772085359785e+01 1.5071357955251854e+01 -2.6829753884337045e+01 - 29 3.0014314868995513e+01 3.1359612725649200e+01 7.9297744000519685e+00 + 1 -2.7683225482283809e+00 6.6449082401023148e+01 8.2247798981789643e+01 + 2 3.8702194726711895e+01 2.9212212080708927e+01 -4.7019606490893651e+01 + 3 -3.5243491151797656e+01 -9.6154919282511642e+01 -3.4936485094808461e+01 + 4 -6.5977694998018921e-01 1.7011044357157604e-01 -6.5636000759126256e-01 + 5 -7.3566520753163211e-01 3.2004552769599226e-01 8.0428279621249554e-01 + 6 -2.0326269572309553e+02 2.3271299846832454e+02 2.7442711030170454e+02 + 7 1.4300022426979604e+01 -8.0959802783845490e+01 -4.1226588339625141e+02 + 8 3.2858865805990142e+01 -2.1199692705942155e+01 1.0091081449262803e+02 + 9 2.1122712553325698e+01 1.5084944366414280e+01 8.7605507484381420e+01 + 10 1.3136999033009897e+02 -1.5218480112815018e+02 -4.7552579328976627e+01 + 11 -1.0661815520486129e+00 6.1243966623508861e-01 -1.2462619432216921e+00 + 12 7.7761085744513680e+00 3.1128572757481363e+00 -1.4745329169765931e+00 + 13 5.2674567689395169e-01 -2.4917750397088440e-01 -1.8723948847901425e-01 + 14 -1.3120520033096184e+00 4.0614121494992139e-01 -7.2914653857642009e-01 + 15 3.2867638550341521e-01 4.2750422476572436e-01 -7.8475645363096747e-01 + 16 1.1296204673281163e+02 -8.1834716679121783e+01 -2.9024712481379936e+02 + 17 -1.1375160211353307e+02 8.3851461680840046e+01 2.8944627578500337e+02 + 18 3.0738271486215951e-01 4.7275452050710545e+00 -7.8225407641446587e+00 + 19 2.0274564844173879e+00 -6.9333851990195527e-01 5.5367198587099775e+00 + 20 -2.8992094355377156e+00 -3.9662518102337199e+00 4.0716447585813889e+00 + 21 -1.6026765950606343e+01 -1.5883976653313633e+01 4.7256104141803178e+01 + 22 -2.5118526637643978e+01 -7.1302229387234384e+00 -3.6226155173665845e+01 + 23 4.0731190519921540e+01 2.3426593817372833e+01 -1.0527512159329465e+01 + 24 7.9759015134016398e+00 -4.4140032709414839e+01 2.3421942671485997e+01 + 25 -3.4663427794542088e+01 3.0656502790778966e+00 -2.8305771158233721e+01 + 26 2.6127821099004976e+01 4.0822834309892897e+01 4.2748874028091679e+00 + 27 1.1011058821774000e+01 -4.6436458847462333e+01 1.8878846579362040e+01 + 28 -4.0634772090200137e+01 1.5071357967752173e+01 -2.6829753899915300e+01 + 29 3.0014314791906596e+01 3.1359612633147766e+01 7.9297743740230970e+00 ... diff --git a/unittest/force-styles/tests/mol-pair-nm_cut_coul_table.yaml b/unittest/force-styles/tests/mol-pair-nm_cut_coul_table.yaml index f53a664d2a..c6c13ec92a 100644 --- a/unittest/force-styles/tests/mol-pair-nm_cut_coul_table.yaml +++ b/unittest/force-styles/tests/mol-pair-nm_cut_coul_table.yaml @@ -1,6 +1,6 @@ --- -lammps_version: 17 Feb 2022 -date_generated: Fri Mar 18 22:17:35 2022 +lammps_version: 3 Nov 2022 +date_generated: Wed Nov 23 12:21:08 2022 epsilon: 5e-12 skip_tests: gpu prerequisites: ! | @@ -39,72 +39,72 @@ extract: ! | mm 2 cut_coul 0 natoms: 29 -init_vdwl: 184.28678589160327 -init_coul: 225.82185134782813 +init_vdwl: 184.287044185624 +init_coul: 225.8218513478281 init_stress: ! |2- - 5.1535563668501300e+02 5.0058663228965906e+02 1.1159625416266908e+03 -1.8397465772983549e+02 -2.0220541814186075e+00 1.7544854959858193e+02 + 5.1535627685426095e+02 5.0058721803305957e+02 1.1159628411352805e+03 -1.8397448242108504e+02 -2.0224841677449517e+00 1.7544840137728934e+02 init_forces: ! |2 - 1 -3.0654541322175968e+00 6.6615863677171617e+01 8.2943971924222254e+01 + 1 -3.0654576533494127e+00 6.6615850047892891e+01 8.2943972120581122e+01 2 3.9068865513677615e+01 2.9455617099928201e+01 -4.7591020157569005e+01 - 3 -3.5280048398649157e+01 -9.6589707037291518e+01 -3.5074530567243464e+01 - 4 -6.6290079171346505e-01 1.7069544377339213e-01 -6.5698955820925042e-01 - 5 -7.3666014335594099e-01 3.1866598696678072e-01 8.0597176706748563e-01 - 6 -2.0569141450616158e+02 2.3627567585415383e+02 2.8443812919367736e+02 - 7 1.4533356899344014e+01 -8.2901362616912394e+01 -4.2411675492205256e+02 - 8 3.4572733596567637e+01 -2.2709011431274082e+01 1.0190201593114163e+02 - 9 2.1302136717273982e+01 1.5382115964517633e+01 8.8486497965632879e+01 - 10 1.3163065406656153e+02 -1.5255187717021275e+02 -4.7566872791707098e+01 - 11 -1.0673115707973471e+00 6.0655351752474329e-01 -1.2545987554013556e+00 - 12 7.7809586887870594e+00 3.1160399372388605e+00 -1.4701800924466619e+00 - 13 5.3014565234400191e-01 -2.5075128500262650e-01 -1.8692002168697544e-01 - 14 -1.3123790631110117e+00 4.0626403937555045e-01 -7.3662725812128549e-01 - 15 3.2883559728278194e-01 4.2874259749687393e-01 -7.8340316469885862e-01 - 16 1.1459556694004317e+02 -8.2820744612264363e+01 -2.9444590318663785e+02 - 17 -1.1537978278388316e+02 8.4825361961770099e+01 2.9365401989722858e+02 - 18 3.5910722977056597e-01 4.7762805084795117e+00 -7.8633666628226111e+00 - 19 1.9899942949153411e+00 -7.2139693846497077e-01 5.5216057638120377e+00 - 20 -2.9130806625761494e+00 -3.9872064081602967e+00 4.1253385233400710e+00 - 21 -1.5875836014985955e+01 -1.5889862643744696e+01 4.7172259002528357e+01 - 22 -2.5015660385936844e+01 -7.0704105161901349e+00 -3.6174325746867012e+01 - 23 4.0477625196492205e+01 2.3373135655738206e+01 -1.0495869916757165e+01 + 3 -3.5280084805342639e+01 -9.6589672461277360e+01 -3.5074511071513633e+01 + 4 -6.6290079171346505e-01 1.7069544377339210e-01 -6.5698955820925031e-01 + 5 -7.3666014335594110e-01 3.1866598696678072e-01 8.0597176706748597e-01 + 6 -2.0569141450616158e+02 2.3627567585415389e+02 2.8443812919367736e+02 + 7 1.4533356899344010e+01 -8.2901362616912380e+01 -4.2411675492205251e+02 + 8 3.4572733596567609e+01 -2.2709011431274096e+01 1.0190201593114163e+02 + 9 2.1302136717273982e+01 1.5382115964517647e+01 8.8486497965632879e+01 + 10 1.3163065513040453e+02 -1.5255187203307418e+02 -4.7566873159823480e+01 + 11 -1.0673115707973471e+00 6.0655351752474307e-01 -1.2545987554013558e+00 + 12 7.7810446236250250e+00 3.1161068656344568e+00 -1.4702446426831981e+00 + 13 5.3014565234400202e-01 -2.5075128500262667e-01 -1.8692002168697544e-01 + 14 -1.3123790631110113e+00 4.0626403937555039e-01 -7.3662725812128527e-01 + 15 3.2883559728278206e-01 4.2874259749687393e-01 -7.8340316469885873e-01 + 16 1.1459556939733203e+02 -8.2820736120124138e+01 -2.9444590301488040e+02 + 17 -1.1537978278388316e+02 8.4825361961770113e+01 2.9365401989722858e+02 + 18 3.5910722977056608e-01 4.7762805084795099e+00 -7.8633666628226058e+00 + 19 1.9899942949153395e+00 -7.2139693846497099e-01 5.5216057638120368e+00 + 20 -2.9130806625761498e+00 -3.9872064081602954e+00 4.1253385233400701e+00 + 21 -1.5875799608292471e+01 -1.5889897219758861e+01 4.7172239506798533e+01 + 22 -2.5015660385936840e+01 -7.0704105161901358e+00 -3.6174325746867005e+01 + 23 4.0477625196492198e+01 2.3373135655738203e+01 -1.0495869916757163e+01 24 7.4996665312988062e+00 -4.3426856369883282e+01 2.2815324088130364e+01 25 -3.3807149952465473e+01 2.9988014337987989e+00 -2.7577373212676150e+01 - 26 2.5746891183225689e+01 4.0174455514363842e+01 4.1505232593253609e+00 - 27 1.0861995864629581e+01 -4.6328821976580151e+01 1.8883010049856995e+01 - 28 -4.0470177594126923e+01 1.5020794116966732e+01 -2.6766825117758021e+01 - 29 2.9999322027766638e+01 3.1302945696716428e+01 7.8628937666919105e+00 -run_vdwl: 182.40255928657774 -run_coul: 225.80526621801556 + 26 2.5746891183225689e+01 4.0174455514363835e+01 4.1505232593253609e+00 + 27 1.0861909929791622e+01 -4.6328888904975756e+01 1.8883074600093536e+01 + 28 -4.0470177594126930e+01 1.5020794116966732e+01 -2.6766825117758025e+01 + 29 2.9999322027766638e+01 3.1302945696716428e+01 7.8628937666919114e+00 +run_vdwl: 182.40281753260578 +run_coul: 225.80526621917056 run_stress: ! |2- - 5.1384633450263470e+02 4.9870417152157029e+02 1.0966342229480442e+03 -1.8197323856665997e+02 -7.7104387031605370e-01 1.7333790492919763e+02 + 5.1384697454379841e+02 4.9870475719746798e+02 1.0966345223981718e+03 -1.8197306335846980e+02 -7.7147374345845032e-01 1.7333775678806884e+02 run_forces: ! |2 - 1 -2.7683205204507280e+00 6.6449095490165703e+01 8.2247797711895885e+01 - 2 3.8702193821877493e+01 2.9212211419425969e+01 -4.7019604804325617e+01 - 3 -3.5243454585514591e+01 -9.6154953863738911e+01 -3.4936504643788560e+01 - 4 -6.5977687131041252e-01 1.7011085278366439e-01 -6.5635985341126124e-01 - 5 -7.3566505234358270e-01 3.2004653103552905e-01 8.0428307532511589e-01 - 6 -2.0326269614835340e+02 2.3271299913843555e+02 2.7442710822013873e+02 - 7 1.4300021996054623e+01 -8.0959802494991251e+01 -4.1226588541677728e+02 - 8 3.2858865265765651e+01 -2.1199693568720125e+01 1.0091081733429107e+02 - 9 2.1122714604067934e+01 1.5084943250328770e+01 8.7605509332947179e+01 - 10 1.3136998941143941e+02 -1.5218480590048722e+02 -4.7552579577409830e+01 - 11 -1.0661815608329375e+00 6.1244026211185132e-01 -1.2462619124968015e+00 - 12 7.7760233760077231e+00 3.1127902634122728e+00 -1.4744694804987457e+00 - 13 5.2674586924271427e-01 -2.4917758586878880e-01 -1.8723934835850795e-01 - 14 -1.3120523259791150e+00 4.0614108203397964e-01 -7.2914636677516875e-01 - 15 3.2867610981988737e-01 4.2750390948272482e-01 -7.8475586802253572e-01 - 16 1.1296204447867072e+02 -8.1834725270478103e+01 -2.9024712501702589e+02 - 17 -1.1375160235079549e+02 8.3851462518713276e+01 2.8944627514695969e+02 - 18 3.0738345014064944e-01 4.7275451584201162e+00 -7.8225421226147951e+00 - 19 2.0274544872239728e+00 -6.9334025263478072e-01 5.5367196067976767e+00 - 20 -2.8992075327228490e+00 -3.9662506277601803e+00 4.0716458277265861e+00 - 21 -1.6026802838192324e+01 -1.5883941405520059e+01 4.7256124362739875e+01 - 22 -2.5118529350290316e+01 -7.1302246487029537e+00 -3.6226156710291576e+01 - 23 4.0731193744183564e+01 2.3426594982025247e+01 -1.0527511305357223e+01 - 24 7.9759015601633747e+00 -4.4140032390736621e+01 2.3421941942737131e+01 - 25 -3.4663429593566200e+01 3.0656489475373521e+00 -2.8305771699474640e+01 - 26 2.6127823323620827e+01 4.0822835743219649e+01 4.2748889953069069e+00 - 27 1.1011144344413010e+01 -4.6436391929690870e+01 1.8878781879279799e+01 - 28 -4.0634774700271556e+01 1.5071357061734957e+01 -2.6829755168650092e+01 - 29 3.0014317587931910e+01 3.1359613328463354e+01 7.9297758591329561e+00 + 1 -2.7683239898506331e+00 6.6449081957468636e+01 8.2247797930661747e+01 + 2 3.8702193811582511e+01 2.9212211412571293e+01 -4.7019604791653393e+01 + 3 -3.5243491024333295e+01 -9.6154919393054271e+01 -3.4936485191359907e+01 + 4 -6.5977687168190458e-01 1.7011085284653316e-01 -6.5635985375283568e-01 + 5 -7.3566505234995705e-01 3.2004653083828444e-01 8.0428307567331736e-01 + 6 -2.0326269615165228e+02 2.3271299914190627e+02 2.7442710822226110e+02 + 7 1.4300021996095619e+01 -8.0959802495291143e+01 -4.1226588541635073e+02 + 8 3.2858865255384757e+01 -2.1199693557841638e+01 1.0091081733750200e+02 + 9 2.1122714603970017e+01 1.5084943250468159e+01 8.7605509333063679e+01 + 10 1.3136999050087155e+02 -1.5218480076049869e+02 -4.7552579958511345e+01 + 11 -1.0661815608470382e+00 6.1244026210440039e-01 -1.2462619124717631e+00 + 12 7.7761092701979475e+00 3.1128571473156490e+00 -1.4745340012267927e+00 + 13 5.2674586999352180e-01 -2.4917758618970665e-01 -1.8723934833596209e-01 + 14 -1.3120523262243908e+00 4.0614108204631622e-01 -7.2914636724809301e-01 + 15 3.2867610975969386e-01 4.2750391001876636e-01 -7.8475586778582129e-01 + 16 1.1296204694413225e+02 -8.1834716771070589e+01 -2.9024712485782527e+02 + 17 -1.1375160235744099e+02 8.3851462515852432e+01 2.8944627515943881e+02 + 18 3.0738344999939127e-01 4.7275451584991384e+00 -7.8225421226024254e+00 + 19 2.0274544872772347e+00 -6.9334025264774690e-01 5.5367196067971562e+00 + 20 -2.8992075326987843e+00 -3.9662506277824492e+00 4.0716458277284353e+00 + 21 -1.6026766454385204e+01 -1.5883975994889351e+01 4.7256104878610991e+01 + 22 -2.5118529354380893e+01 -7.1302246459886085e+00 -3.6226156710215299e+01 + 23 4.0731193763533284e+01 2.3426594998848003e+01 -1.0527511310640200e+01 + 24 7.9759015601568057e+00 -4.4140032390724294e+01 2.3421941942726932e+01 + 25 -3.4663429593560622e+01 3.0656489475121842e+00 -2.8305771699451558e+01 + 26 2.6127823323623851e+01 4.0822835743217404e+01 4.2748889953099694e+00 + 27 1.1011058517091254e+01 -4.6436458745736758e+01 1.8878846450788387e+01 + 28 -4.0634774705109990e+01 1.5071357074236101e+01 -2.6829755184229253e+01 + 29 3.0014317510846237e+01 3.1359613235965710e+01 7.9297758330981845e+00 ... diff --git a/unittest/formats/test_file_operations.cpp b/unittest/formats/test_file_operations.cpp index 6149b0c99c..d48dee34b2 100644 --- a/unittest/formats/test_file_operations.cpp +++ b/unittest/formats/test_file_operations.cpp @@ -303,6 +303,7 @@ TEST_F(FileOperationsTest, error_all_one) TEST_F(FileOperationsTest, write_restart) { + ASSERT_EQ(lmp->restart_ver, -1); BEGIN_HIDE_OUTPUT(); command("echo none"); END_HIDE_OUTPUT(); @@ -356,6 +357,7 @@ TEST_F(FileOperationsTest, write_restart) BEGIN_HIDE_OUTPUT(); command("clear"); END_HIDE_OUTPUT(); + ASSERT_EQ(lmp->restart_ver, -1); ASSERT_EQ(lmp->atom->natoms, 0); ASSERT_EQ(lmp->update->ntimestep, 0); ASSERT_EQ(lmp->domain->triclinic, 0); @@ -369,18 +371,21 @@ TEST_F(FileOperationsTest, write_restart) command("change_box all triclinic"); command("write_restart triclinic.restart"); END_HIDE_OUTPUT(); + ASSERT_EQ(lmp->restart_ver, lmp->num_ver); ASSERT_EQ(lmp->atom->natoms, 1); ASSERT_EQ(lmp->update->ntimestep, 333); ASSERT_EQ(lmp->domain->triclinic, 1); BEGIN_HIDE_OUTPUT(); command("clear"); END_HIDE_OUTPUT(); + ASSERT_EQ(lmp->restart_ver, -1); ASSERT_EQ(lmp->atom->natoms, 0); ASSERT_EQ(lmp->update->ntimestep, 0); ASSERT_EQ(lmp->domain->triclinic, 0); BEGIN_HIDE_OUTPUT(); command("read_restart triclinic.restart"); END_HIDE_OUTPUT(); + ASSERT_EQ(lmp->restart_ver, lmp->num_ver); ASSERT_EQ(lmp->atom->natoms, 1); ASSERT_EQ(lmp->update->ntimestep, 333); ASSERT_EQ(lmp->domain->triclinic, 1); @@ -464,6 +469,8 @@ TEST_F(FileOperationsTest, write_data) TEST_FAILURE(".*ERROR: Cannot open file noexist.data: No such file or directory.*", command("read_data noexist.data");); + TEST_FAILURE(".*ERROR: Unknown read_data keyword xxx.*", + command("read_data noexist.data xxx");); BEGIN_HIDE_OUTPUT(); command("pair_style zero 1.0"); @@ -496,6 +503,116 @@ TEST_F(FileOperationsTest, write_data) delete_file("triclinic.data"); } +#define GETIDX(i) lmp->atom->map(i) +TEST_F(FileOperationsTest, read_data_fix) +{ + ASSERT_EQ(lmp->restart_ver, -1); + BEGIN_HIDE_OUTPUT(); + command("echo none"); + command("atom_modify map array"); + command("fix MoleculeIDs all property/atom mol"); + command("region box block -2 2 -2 2 -2 2"); + command("create_box 1 box"); + command("create_atoms 1 single 1.0 0.0 0.0"); + command("create_atoms 1 single 0.0 1.0 0.0"); + command("create_atoms 1 single 1.0 0.0 1.0"); + command("create_atoms 1 single 0.0 1.0 1.0"); + command("mass 1 1.0"); + command("set atom 1*2 mol 1"); + command("set atom 3*4 mol 2"); + command("write_data test_mol_id.data"); + lmp->atom->molecule[0] = 5; + lmp->atom->molecule[1] = 6; + lmp->atom->molecule[2] = 5; + lmp->atom->molecule[3] = 6; + lmp->atom->tag[0] = 9; + lmp->atom->tag[1] = 6; + lmp->atom->tag[2] = 7; + lmp->atom->tag[3] = 8; + lmp->atom->map_init(1); + lmp->atom->map_set(); + command("write_data test_mol_id_merge.data"); + command("clear"); + END_HIDE_OUTPUT(); + TEST_FAILURE(".*ERROR: Cannot use read_data add before simulation box is defined.*", + command("read_data test_mol_id.data add append");); + + BEGIN_HIDE_OUTPUT(); + command("atom_modify map array"); + command("fix MoleculeIDs all property/atom mol"); + command("read_data test_mol_id.data fix MoleculeIDs NULL Molecules"); + command("read_data test_mol_id_merge.data add merge fix MoleculeIDs NULL Molecules"); + END_HIDE_OUTPUT(); + + EXPECT_EQ(lmp->atom->natoms, 8); + EXPECT_EQ(lmp->atom->molecule[GETIDX(1)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(2)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(3)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(4)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(6)], 6); + EXPECT_EQ(lmp->atom->molecule[GETIDX(7)], 5); + EXPECT_EQ(lmp->atom->molecule[GETIDX(8)], 6); + EXPECT_EQ(lmp->atom->molecule[GETIDX(9)], 5); + EXPECT_EQ(lmp->atom->tag[GETIDX(1)], 1); + EXPECT_EQ(lmp->atom->tag[GETIDX(2)], 2); + EXPECT_EQ(lmp->atom->tag[GETIDX(3)], 3); + EXPECT_EQ(lmp->atom->tag[GETIDX(4)], 4); + EXPECT_EQ(lmp->atom->tag[GETIDX(6)], 6); + EXPECT_EQ(lmp->atom->tag[GETIDX(7)], 7); + EXPECT_EQ(lmp->atom->tag[GETIDX(8)], 8); + EXPECT_EQ(lmp->atom->tag[GETIDX(9)], 9); + + BEGIN_HIDE_OUTPUT(); + command("clear"); + command("atom_modify map array"); + command("fix MoleculeIDs all property/atom mol"); + command("read_data test_mol_id.data fix MoleculeIDs NULL Molecules"); + command("read_data test_mol_id.data add append fix MoleculeIDs NULL Molecules"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->atom->natoms, 8); + EXPECT_EQ(lmp->atom->molecule[GETIDX(1)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(2)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(3)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(4)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(5)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(6)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(7)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(8)], 2); + EXPECT_EQ(lmp->atom->tag[GETIDX(1)], 1); + EXPECT_EQ(lmp->atom->tag[GETIDX(2)], 2); + EXPECT_EQ(lmp->atom->tag[GETIDX(3)], 3); + EXPECT_EQ(lmp->atom->tag[GETIDX(4)], 4); + EXPECT_EQ(lmp->atom->tag[GETIDX(5)], 5); + EXPECT_EQ(lmp->atom->tag[GETIDX(6)], 6); + EXPECT_EQ(lmp->atom->tag[GETIDX(7)], 7); + EXPECT_EQ(lmp->atom->tag[GETIDX(8)], 8); + + BEGIN_HIDE_OUTPUT(); + command("clear"); + command("atom_modify map array"); + command("fix MoleculeIDs all property/atom mol"); + command("read_data test_mol_id.data fix MoleculeIDs NULL Molecules"); + command("read_data test_mol_id.data add 6 4 fix MoleculeIDs NULL Molecules"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->atom->natoms, 8); + EXPECT_EQ(lmp->atom->molecule[GETIDX(1)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(2)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(3)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(4)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(7)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(8)], 1); + EXPECT_EQ(lmp->atom->molecule[GETIDX(9)], 2); + EXPECT_EQ(lmp->atom->molecule[GETIDX(10)], 2); + EXPECT_EQ(lmp->atom->tag[GETIDX(1)], 1); + EXPECT_EQ(lmp->atom->tag[GETIDX(2)], 2); + EXPECT_EQ(lmp->atom->tag[GETIDX(3)], 3); + EXPECT_EQ(lmp->atom->tag[GETIDX(4)], 4); + EXPECT_EQ(lmp->atom->tag[GETIDX(7)], 7); + EXPECT_EQ(lmp->atom->tag[GETIDX(8)], 8); + EXPECT_EQ(lmp->atom->tag[GETIDX(9)], 9); + EXPECT_EQ(lmp->atom->tag[GETIDX(10)], 10); +} + int main(int argc, char **argv) { MPI_Init(&argc, &argv); diff --git a/unittest/python/test_python_package.cpp b/unittest/python/test_python_package.cpp index 4e5aa53b0c..f998ebbcd8 100644 --- a/unittest/python/test_python_package.cpp +++ b/unittest/python/test_python_package.cpp @@ -276,7 +276,7 @@ TEST_F(PythonPackageTest, RunSource) { // execute python script from file auto output = CAPTURE_OUTPUT([&] { - command("python xyz source ${input_dir}/run.py"); + command("python source ${input_dir}/run.py"); }); ASSERT_THAT(output, HasSubstr(LOREM_IPSUM)); @@ -286,7 +286,7 @@ TEST_F(PythonPackageTest, RunSourceInline) { // execute inline python script auto output = CAPTURE_OUTPUT([&] { - command("python xyz source \"\"\"\n" + command("python source here \"\"\"\n" "from __future__ import print_function\n" "print(2+2)\n" "\"\"\"");