diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 00a254197d..bc79d68c54 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -133,10 +133,7 @@ endif() set(LAMMPS_BINARY lmp${LAMMPS_MACHINE}) option(BUILD_SHARED_LIBS "Build shared library" OFF) -if(BUILD_SHARED_LIBS) # for all pkg libs, mpi_stubs and linalg - set(CMAKE_POSITION_INDEPENDENT_CODE ON) -endif() - +option(CMAKE_POSITION_INDEPENDENT_CODE "Create object compatible with shared libraries" ON) option(BUILD_TOOLS "Build and install LAMMPS tools (msi2lmp, binary2txt, chain)" OFF) option(BUILD_LAMMPS_SHELL "Build and install the LAMMPS shell" OFF) @@ -303,10 +300,12 @@ else() target_link_libraries(lmp PRIVATE mpi_stubs) target_include_directories(lmp INTERFACE $) target_compile_definitions(lmp INTERFACE $) - endif(MSVC) + endif() target_include_directories(lammps INTERFACE $) target_compile_definitions(lammps INTERFACE $) else() + target_include_directories(lammps INTERFACE $) + target_compile_definitions(lammps INTERFACE $) target_link_libraries(lammps PUBLIC mpi_stubs) endif() add_library(MPI::MPI_CXX ALIAS mpi_stubs) @@ -809,11 +808,17 @@ if(ClangFormat_FOUND) endif() get_target_property(DEFINES lammps COMPILE_DEFINITIONS) +get_property(BUILD_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(BUILD_IS_MULTI_CONFIG) + set(LAMMPS_BUILD_TYPE "Multi-Config") +else() + set(LAMMPS_BUILD_TYPE ${CMAKE_BUILD_TYPE}) +endif() include(FeatureSummary) feature_summary(DESCRIPTION "The following tools and libraries have been found and configured:" WHAT PACKAGES_FOUND) message(STATUS "<<< Build configuration >>> Operating System: ${CMAKE_SYSTEM_NAME} ${CMAKE_LINUX_DISTRO} ${CMAKE_DISTRO_VERSION} - Build type: ${CMAKE_BUILD_TYPE} + Build type: ${LAMMPS_BUILD_TYPE} Install path: ${CMAKE_INSTALL_PREFIX} Generator: ${CMAKE_GENERATOR} using ${CMAKE_MAKE_PROGRAM}") ############################################################################### diff --git a/cmake/CMakeSettings.json b/cmake/CMakeSettings.json index dada2f6752..ee4b3c46d5 100644 --- a/cmake/CMakeSettings.json +++ b/cmake/CMakeSettings.json @@ -1,55 +1,111 @@ { - "configurations": [ + "configurations": [ + { + "name": "x64-Debug-MSVC", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${workspaceRoot}\\build\\${name}", + "installRoot": "${workspaceRoot}\\install\\${name}", + "cmakeCommandArgs": "-S ${workspaceRoot}\\cmake -C ${workspaceRoot}\\cmake\\presets\\windows.cmake -DENABLE_TESTING=on", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [ { - "name": "x64-Debug-MSVC", - "generator": "Ninja", - "configurationType": "Debug", - "buildRoot": "${workspaceRoot}\\build\\${name}", - "installRoot": "${workspaceRoot}\\install\\${name}", - "cmakeCommandArgs": "-S ${workspaceRoot}\\cmake -C ${workspaceRoot}\\cmake\\presets\\windows.cmake", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "msvc_x64_x64" ], - "variables": [ - { - "name": "BUILD_SHARED_LIBS", - "value": "True", - "type": "BOOL" - }, - { - "name": "BUILD_TOOLS", - "value": "True", - "type": "BOOL" - }, - { - "name": "LAMMPS_EXCEPTIONS", - "value": "True", - "type": "BOOL" - } - ] + "name": "BUILD_SHARED_LIBS", + "value": "True", + "type": "BOOL" }, { - "name": "x64-Debug-Clang", - "generator": "Ninja", - "configurationType": "Debug", - "buildRoot": "${workspaceRoot}\\build\\${name}", - "installRoot": "${workspaceRoot}\\install\\${name}", - "cmakeCommandArgs": "-S ${workspaceRoot}\\cmake -C ${workspaceRoot}\\cmake\\presets\\windows.cmake", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "clang_cl_x64" ], - "variables": [ - { - "name": "BUILD_TOOLS", - "value": "True", - "type": "BOOL" - }, - { - "name": "LAMMPS_EXCEPTIONS", - "value": "True", - "type": "BOOL" - } - ] + "name": "BUILD_TOOLS", + "value": "True", + "type": "BOOL" + }, + { + "name": "LAMMPS_EXCEPTIONS", + "value": "True", + "type": "BOOL" } - ] + ] + }, + { + "name": "x64-Debug-Clang", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${workspaceRoot}\\build\\${name}", + "installRoot": "${workspaceRoot}\\install\\${name}", + "cmakeCommandArgs": "-S ${workspaceRoot}\\cmake -C ${workspaceRoot}\\cmake\\presets\\windows.cmake -DENABLE_TESTING=on", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "clang_cl_x64" ], + "variables": [ + { + "name": "BUILD_TOOLS", + "value": "True", + "type": "BOOL" + }, + { + "name": "LAMMPS_EXCEPTIONS", + "value": "True", + "type": "BOOL" + } + ] + }, + { + "name": "x64-Debug-OneAPI", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${workspaceRoot}\\build\\${name}", + "installRoot": "${workspaceRoot}\\install\\${name}", + "cmakeCommandArgs": "-S ${workspaceRoot}\\cmake -C ${workspaceRoot}\\cmake\\presets\\windows.cmake -DENABLE_TESTING=on -DCMAKE_CXX_COMPILER=icx -DCMAKE_C_COMPILER=icx -DBUILD_MPI=off", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [ + { + "name": "BUILD_SHARED_LIBS", + "value": "True", + "type": "BOOL" + }, + { + "name": "BUILD_TOOLS", + "value": "True", + "type": "BOOL" + }, + { + "name": "LAMMPS_EXCEPTIONS", + "value": "True", + "type": "BOOL" + } + ] + }, + { + "name": "x64-Debug-Intel", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${workspaceRoot}\\build\\${name}", + "installRoot": "${workspaceRoot}\\install\\${name}", + "cmakeCommandArgs": "-S ${workspaceRoot}\\cmake -C ${workspaceRoot}\\cmake\\presets\\windows.cmake -DENABLE_TESTING=off -DCMAKE_CXX_COMPILER=icl -DCMAKE_C_COMPILER=icl -DCMAKE_Fortran_COMPILER=ifort -DBUILD_MPI=off", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [ + { + "name": "BUILD_SHARED_LIBS", + "value": "True", + "type": "BOOL" + }, + { + "name": "BUILD_TOOLS", + "value": "True", + "type": "BOOL" + }, + { + "name": "LAMMPS_EXCEPTIONS", + "value": "True", + "type": "BOOL" + } + ] + } + ] } \ No newline at end of file diff --git a/cmake/Modules/ExternalCMakeProject.cmake b/cmake/Modules/ExternalCMakeProject.cmake new file mode 100644 index 0000000000..855ce254c9 --- /dev/null +++ b/cmake/Modules/ExternalCMakeProject.cmake @@ -0,0 +1,33 @@ +# Build a CMake based external library as subdirectory. +# The sources will be unpacked to ${CMAKE_BINARY_DIR}/_deps/${target}-src +# The binaries will be built in ${CMAKE_BINARY_DIR}/_deps/${target}-build +# +function(ExternalCMakeProject target url hash basedir cmakedir cmakefile) + # change settings locally + set(BUILD_SHARED_LIBS OFF) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + + get_filename_component(archive ${url} NAME) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/_deps/src) + message(STATUS "Downloading ${url}") + file(DOWNLOAD ${url} ${CMAKE_BINARY_DIR}/_deps/${archive} EXPECTED_HASH MD5=${hash} SHOW_PROGRESS) + message(STATUS "Unpacking and configuring ${archive}") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf ${CMAKE_BINARY_DIR}/_deps/${archive} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/_deps/src) + file(GLOB TARGET_SOURCE "${CMAKE_BINARY_DIR}/_deps/src/${basedir}*") + list(LENGTH TARGET_SOURCE _num) + if(_num GREATER 1) + message(FATAL_ERROR "Inconsistent ${target} library sources. " + "Please delete ${CMAKE_BINARY_DIR}/_deps/src and re-run cmake") + endif() + file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/_deps/${target}-src) + file(RENAME ${TARGET_SOURCE} ${CMAKE_BINARY_DIR}/_deps/${target}-src) + if(NOT (cmakefile STREQUAL "")) + file(COPY ${cmakefile} DESTINATION ${CMAKE_BINARY_DIR}/_deps/${target}-src/${cmakedir}/) + get_filename_component(_cmakefile ${cmakefile} NAME) + file(RENAME "${CMAKE_BINARY_DIR}/_deps/${target}-src/${cmakedir}/${_cmakefile}" + "${CMAKE_BINARY_DIR}/_deps/${target}-src/${cmakedir}/CMakeLists.txt") + endif() + add_subdirectory("${CMAKE_BINARY_DIR}/_deps/${target}-src/${cmakedir}" + "${CMAKE_BINARY_DIR}/_deps/${target}-build") +endfunction(ExternalCMakeProject) diff --git a/cmake/Modules/GTest.cmake b/cmake/Modules/GTest.cmake deleted file mode 100644 index e012e61ea9..0000000000 --- a/cmake/Modules/GTest.cmake +++ /dev/null @@ -1,81 +0,0 @@ -message(STATUS "Downloading and building Google Test library") - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(GTEST_LIB_POSTFIX d) -else() - set(GTEST_LIB_POSTFIX) -endif() - -include(ExternalProject) -set(GTEST_URL "https://github.com/google/googletest/archive/release-1.11.0.tar.gz" CACHE STRING "URL of googletest source") -set(GTEST_MD5 "e8a8df240b6938bb6384155d4c37d937" CACHE STRING "MD5 sum for googletest source") -mark_as_advanced(GTEST_URL) -mark_as_advanced(GTEST_MD5) -ExternalProject_Add(googletest - URL ${GTEST_URL} - URL_MD5 ${GTEST_MD5} - SOURCE_DIR "${CMAKE_BINARY_DIR}/gtest-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/gtest-build" - CMAKE_ARGS ${CMAKE_REQUEST_PIC} ${CMAKE_EXTRA_GTEST_OPTS} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_INSTALL_PREFIX= - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} - BUILD_BYPRODUCTS /lib/libgtest${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - /lib/libgmock${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - /lib/libgtest_main${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - /lib/libgmock_main${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - LOG_DOWNLOAD ON - LOG_CONFIGURE ON - LOG_BUILD ON - INSTALL_COMMAND "" - TEST_COMMAND "") - -ExternalProject_Get_Property(googletest SOURCE_DIR) -set(GTEST_INCLUDE_DIR ${SOURCE_DIR}/googletest/include) -set(GMOCK_INCLUDE_DIR ${SOURCE_DIR}/googlemock/include) - -# workaround for CMake 3.10 on ubuntu 18.04 -file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIR}) -file(MAKE_DIRECTORY ${GMOCK_INCLUDE_DIR}) - -ExternalProject_Get_Property(googletest BINARY_DIR) -set(GTEST_LIBRARY_PATH ${BINARY_DIR}/lib/libgtest${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) -set(GMOCK_LIBRARY_PATH ${BINARY_DIR}/lib/libgmock${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) -set(GTEST_MAIN_LIBRARY_PATH ${BINARY_DIR}/lib/libgtest_main${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) -set(GMOCK_MAIN_LIBRARY_PATH ${BINARY_DIR}/lib/libgmock_main${GTEST_LIB_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) - -# Prevent GoogleTest from overriding our compiler/linker options -# when building with Visual Studio -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - -find_package(Threads QUIET) - -add_library(GTest::GTest UNKNOWN IMPORTED) -set_target_properties(GTest::GTest PROPERTIES - IMPORTED_LOCATION ${GTEST_LIBRARY_PATH} - INTERFACE_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR} - INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") -add_dependencies(GTest::GTest googletest) - -add_library(GTest::GMock UNKNOWN IMPORTED) -set_target_properties(GTest::GMock PROPERTIES - IMPORTED_LOCATION ${GMOCK_LIBRARY_PATH} - INTERFACE_INCLUDE_DIRECTORIES ${GMOCK_INCLUDE_DIR} - INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") -add_dependencies(GTest::GMock googletest) - -add_library(GTest::GTestMain UNKNOWN IMPORTED) -set_target_properties(GTest::GTestMain PROPERTIES - IMPORTED_LOCATION ${GTEST_MAIN_LIBRARY_PATH} - INTERFACE_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR} - INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") -add_dependencies(GTest::GTestMain googletest) - -add_library(GTest::GMockMain UNKNOWN IMPORTED) -set_target_properties(GTest::GMockMain PROPERTIES - IMPORTED_LOCATION ${GMOCK_MAIN_LIBRARY_PATH} - INTERFACE_INCLUDE_DIRECTORIES ${GMOCK_INCLUDE_DIR} - INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") -add_dependencies(GTest::GMockMain googletest) diff --git a/cmake/Modules/Packages/MSCG.cmake b/cmake/Modules/Packages/MSCG.cmake index cf3d506c82..e4260e059e 100644 --- a/cmake/Modules/Packages/MSCG.cmake +++ b/cmake/Modules/Packages/MSCG.cmake @@ -12,41 +12,12 @@ if(DOWNLOAD_MSCG) mark_as_advanced(MSCG_URL) mark_as_advanced(MSCG_MD5) - # CMake cannot pass BLAS or LAPACK library variable to external project if they are a list - list(LENGTH BLAS_LIBRARIES} NUM_BLAS) - list(LENGTH LAPACK_LIBRARIES NUM_LAPACK) - if((NUM_BLAS GREATER 1) OR (NUM_LAPACK GREATER 1)) - message(FATAL_ERROR "Cannot compile downloaded MSCG library due to a technical limitation") - endif() + include(ExternalCMakeProject) + ExternalCMakeProject(mscg ${MSCG_URL} ${MSCG_MD5} MSCG-release src/CMake "") - include(ExternalProject) - ExternalProject_Add(mscg_build - URL ${MSCG_URL} - URL_MD5 ${MSCG_MD5} - SOURCE_SUBDIR src/CMake - CMAKE_ARGS ${CMAKE_REQUEST_PIC} ${EXTRA_MSCG_OPTS} - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER} - -DBLAS_LIBRARIES=${BLAS_LIBRARIES} -DLAPACK_LIBRARIES=${LAPACK_LIBRARIES} - -DCMAKE_INSTALL_PREFIX= - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} - BUILD_COMMAND ${CMAKE_COMMAND} --build . --target mscg - INSTALL_COMMAND "" - BUILD_BYPRODUCTS /libmscg.a - ) - ExternalProject_get_property(mscg_build BINARY_DIR) - ExternalProject_get_property(mscg_build SOURCE_DIR) - file(MAKE_DIRECTORY ${SOURCE_DIR}/src) - add_library(LAMMPS::MSCG UNKNOWN IMPORTED) - set_target_properties(LAMMPS::MSCG PROPERTIES - IMPORTED_LOCATION "${BINARY_DIR}/libmscg.a" - INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/src" - INTERFACE_LINK_LIBRARIES "${LAPACK_LIBRARIES}") - target_link_libraries(lammps PRIVATE LAMMPS::MSCG) - add_dependencies(LAMMPS::MSCG mscg_build) + # set include and link library + target_include_directories(lammps PRIVATE "${CMAKE_BINARY_DIR}/_deps/mscg-src/src") + target_link_libraries(lammps PRIVATE mscg) else() find_package(MSCG) if(NOT MSCG_FOUND) diff --git a/cmake/Modules/YAML.cmake b/cmake/Modules/YAML.cmake deleted file mode 100644 index 77ee804111..0000000000 --- a/cmake/Modules/YAML.cmake +++ /dev/null @@ -1,47 +0,0 @@ -message(STATUS "Downloading and building YAML library") - -include(ExternalProject) -set(YAML_URL "https://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz" CACHE STRING "URL for libyaml tarball") -set(YAML_MD5 "bb15429d8fb787e7d3f1c83ae129a999" CACHE STRING "MD5 checksum of libyaml tarball") -mark_as_advanced(YAML_URL) -mark_as_advanced(YAML_MD5) - -# support cross-compilation to windows -if(CMAKE_CROSSCOMPILING AND (CMAKE_SYSTEM_NAME STREQUAL "Windows")) - if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") - set(YAML_CROSS_HOST --host=i686-mingw64) - elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - set(YAML_CROSS_HOST --host=x86_64-mingw64) - else() - message(FATAL_ERROR "Unsupported cross-compilation " - " for ${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}" - " on ${CMAKE_HOST_SYSTEM}/${CMAKE_HOST_SYSTEM_PROCESSOR}") - endif() -endif() - -ExternalProject_Add(libyaml - URL ${YAML_URL} - URL_MD5 ${YAML_MD5} - SOURCE_DIR "${CMAKE_BINARY_DIR}/yaml-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/yaml-build" - CONFIGURE_COMMAND /configure ${CONFIGURE_REQUEST_PIC} - CXX=${CMAKE_CXX_COMPILER} CC=${CMAKE_C_COMPILER} - --prefix= --disable-shared ${YAML_CROSS_HOST} - BUILD_BYPRODUCTS /lib/libyaml${CMAKE_STATIC_LIBRARY_SUFFIX} - TEST_COMMAND "") - -ExternalProject_Get_Property(libyaml INSTALL_DIR) -set(YAML_INCLUDE_DIR ${INSTALL_DIR}/include) -set(YAML_LIBRARY_DIR ${INSTALL_DIR}/lib) - -# workaround for CMake 3.10 on ubuntu 18.04 -file(MAKE_DIRECTORY ${YAML_INCLUDE_DIR}) -file(MAKE_DIRECTORY ${YAML_LIBRARY_DIR}) - -set(YAML_LIBRARY_PATH ${INSTALL_DIR}/lib/libyaml${CMAKE_STATIC_LIBRARY_SUFFIX}) - -add_library(Yaml::Yaml UNKNOWN IMPORTED) -set_target_properties(Yaml::Yaml PROPERTIES - IMPORTED_LOCATION ${YAML_LIBRARY_PATH} - INTERFACE_INCLUDE_DIRECTORIES ${YAML_INCLUDE_DIR}) -add_dependencies(Yaml::Yaml libyaml) diff --git a/cmake/presets/most.cmake b/cmake/presets/most.cmake index eb26b38928..27ce57621c 100644 --- a/cmake/presets/most.cmake +++ b/cmake/presets/most.cmake @@ -48,7 +48,6 @@ set(ALL_PACKAGES PHONON PLUGIN POEMS - PYTHON QEQ REACTION REAXFF diff --git a/doc/src/Build_cmake.rst b/doc/src/Build_cmake.rst index 2a64bc3240..9bee18146c 100644 --- a/doc/src/Build_cmake.rst +++ b/doc/src/Build_cmake.rst @@ -150,6 +150,42 @@ for IDEs like Eclipse, CodeBlocks, or Kate can be selected using the *-G* command line flag. A list of available generator settings for your specific CMake version is given when running ``cmake --help``. +.. _cmake_multiconfig: + +Multi-configuration build systems +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Throughout this manual it is mostly assumed that LAMMPS is being built +on a Unix-like operating system with "make" as the underlying "builder", +since this is the most common case. In this case the build "configuration" +is chose using ``-D CMAKE_BUILD_TYPE=`` with ```` +being one of "Release", "Debug", "RelWithDebInfo", or "MinSizeRel". +Some build tools, however, can also use or even require to have a so-called +multi-configuration build system setup. For those the built type (or +configuration) is chosen at compile time using the same build files. E.g. +with: + +.. code-block:: bash + + cmake --build build-multi --config Release + +In that case the resulting binaries are not in the build folder directly +but in sub-directories corresponding to the build type (i.e. Release in +the example from above). Similarly, for running unit tests the +configuration is selected with the *-C* flag: + +.. code-block:: bash + + ctest -C Debug + +The CMake scripts in LAMMPS have basic support for being compiled using a +multi-config build system, but not all of it has been ported. This is in +particular applicable to compiling packages that require additional libraries +that would be downloaded and compiled by CMake. The "windows" preset file +tries to keep track of which packages can be compiled natively with the +MSVC compilers out-of-the box. Not all of those external libraries are +portable to Windows either. + Installing CMake ^^^^^^^^^^^^^^^^ diff --git a/doc/src/Build_windows.rst b/doc/src/Build_windows.rst index fa2296d302..4bb5cfec27 100644 --- a/doc/src/Build_windows.rst +++ b/doc/src/Build_windows.rst @@ -89,6 +89,11 @@ miss the correct master ``CMakeLists.txt``. Try to open the starting point. It is also possible to configure and compile LAMMPS from the command line with a CMake binary from `cmake.org `_. +Please note, that for either approach CMake will create a so-called +:ref:`"multi-configuration" build environment `, and +the command lines for building and testing LAMMPS must be adjusted +accordingly. + To support running in parallel you can compile with OpenMP enabled using the OPENMP package or install Microsoft MPI (including the SDK) and compile LAMMPS with MPI enabled. diff --git a/doc/src/Developer_platform.rst b/doc/src/Developer_platform.rst index c9ecd30cec..cdc4bb6770 100644 --- a/doc/src/Developer_platform.rst +++ b/doc/src/Developer_platform.rst @@ -118,6 +118,9 @@ Environment variable functions .. doxygenfunction:: putenv :project: progguide +.. doxygenfunction:: unsetenv + :project: progguide + .. doxygenfunction:: list_pathenv :project: progguide diff --git a/doc/src/Howto_github.rst b/doc/src/Howto_github.rst index 278b9e4bfd..315bacac69 100644 --- a/doc/src/Howto_github.rst +++ b/doc/src/Howto_github.rst @@ -141,7 +141,8 @@ unrelated feature, you should switch branches! Committing changes to the *develop*, *release*, or *stable* branches is strongly discouraged. While it may be convenient initially, it will create more work in the long run. Various texts and tutorials - on using git effectively discuss the motivation for this. + on using git effectively discuss the motivation for using feature + branches instead. **After changes are made** diff --git a/doc/src/Install_git.rst b/doc/src/Install_git.rst index 7ad6ca18c1..a5dc19fe79 100644 --- a/doc/src/Install_git.rst +++ b/doc/src/Install_git.rst @@ -28,8 +28,9 @@ provides `limited support for subversion clients `_. You can follow the LAMMPS development on 3 different git branches: -* **stable** : this branch is updated with every stable release; - updates are always "fast forward" merges from *develop* +* **stable** : this branch is updated from the *release* branch with + every stable release version and also has selected bug fixes and updates + back-ported from the *develop* branch * **release** : this branch is updated with every patch release; updates are always "fast forward" merges from *develop* * **develop** : this branch follows the ongoing development and @@ -47,20 +48,22 @@ your machine and "release" is one of the 3 branches listed above. (Note that you actually download all 3 branches; you can switch between them at any time using "git checkout ".) -.. note:: +.. admonition:: Saving time and disk space when using ``git clone`` The complete git history of the LAMMPS project is quite large because it contains the entire commit history of the project since fall 2006, - which includes the time when LAMMPS was managed with subversion. This - also includes commits that have added and removed some large files - (mostly by accident). If you do not need access to the entire commit - history, you can speed up the "cloning" process and reduce local disk - space requirements by using the *--depth* git command line flag thus - create a "shallow clone" of the repository that contains only a - subset of the git history. Using a depth of 1000 is usually sufficient - to include the head commits of the *develop* and the *release* branches. - To include the head commit of the *stable* branch you may need a depth - of up to 10000. + which includes the time when LAMMPS was managed with subversion. + This includes a few commits that have added and removed some large + files (mostly by accident). If you do not need access to the entire + commit history (most people don't), you can speed up the "cloning" + process and reduce local disk space requirements by using the + *--depth* git command line flag. That will create a "shallow clone" + of the repository containing only a subset of the git history. Using + a depth of 1000 is usually sufficient to include the head commits of + the *develop* and the *release* branches. To include the head commit + of the *stable* branch you may need a depth of up to 10000. If you + later need more of the git history, you can always convert the + shallow clone into a "full clone". Once the command completes, your directory will contain the same files as if you unpacked a current LAMMPS tarball, with the exception, that diff --git a/doc/src/Manual_version.rst b/doc/src/Manual_version.rst index b705ce8c4a..78ed61cd7c 100644 --- a/doc/src/Manual_version.rst +++ b/doc/src/Manual_version.rst @@ -10,23 +10,31 @@ Whenever we fix a bug or update or add a feature, it will be merged into the *develop* branch of the git repository. When a sufficient number of changes have accumulated *and* the software passes a set of automated tests, we release it in the next *patch* release, which are made every -few weeks. Info on patch releases are on `this website page +few weeks. The *release* branch of the git repository is updated with +every such release. Info on patch releases are on `this website page `_. -Once or twice a year, only bug fixes and small, non-intrusive changes are -included for a period of time, and the code is subjected to more detailed +Once or twice a year, we apply only bug fixes and small, non-intrusive +changes to the *develop* branch and the code is subjected to more detailed and thorough testing than the default automated testing. The latest -patch release after such a period is then labeled as a *stable* version. +patch release after such a period is then also labeled as a *stable* version +and the *stable* branch is updated with it. Between stable releases +we occasionally release some updates to the stable release containing +only bug fixes and updates back-ported from *develop* but no new features +and update the *stable* branch accordingly. -Each version of LAMMPS contains all the features and bug-fixes up to -and including its version date. +Each version of LAMMPS contains all the documented features up to and +including its version date. The version date is printed to the screen and logfile every time you run LAMMPS. It is also in the file src/version.h and in the LAMMPS directory name created when you unpack a tarball. And it is on the first page of the :doc:`manual `. -* If you browse the HTML pages on the LAMMPS WWW site, they always - describe the most current patch release of LAMMPS. +* If you browse the HTML pages on the LAMMPS WWW site, they will by + default describe the most current patch release version of LAMMPS. + In the navigation bar on the bottom left, there is the option to + view instead the documentation for the most recent *stable* version + or the latest version from the current development branch. * If you browse the HTML pages included in your tarball, they describe the version you have, which may be older. diff --git a/doc/src/compute_bond_local.rst b/doc/src/compute_bond_local.rst index 8bdde70dd9..24b0943484 100644 --- a/doc/src/compute_bond_local.rst +++ b/doc/src/compute_bond_local.rst @@ -13,7 +13,7 @@ Syntax * ID, group-ID are documented in :doc:`compute ` command * bond/local = style name of this compute command * one or more values may be appended -* value = *dist* or *engpot* or *force* or *fx* or *fy* or *fz* or *engvib* or *engrot* or *engtrans* or *omega* or *velvib* or *v_name* +* value = *dist* or *dx* or *dy* or *dz* or *engpot* or *force* or *fx* or *fy* or *fz* or *engvib* or *engrot* or *engtrans* or *omega* or *velvib* or *v_name* .. parsed-literal:: @@ -21,6 +21,7 @@ Syntax *engpot* = bond potential energy *force* = bond force + *dx*,\ *dy*,\ *dz* = components of pairwise distance *fx*,\ *fy*,\ *fz* = components of bond force *engvib* = bond kinetic energy of vibration *engrot* = bond kinetic energy of rotation @@ -63,6 +64,9 @@ whether the 2 atoms represent a simple diatomic molecule, or are part of some larger molecule. The value *dist* is the current length of the bond. +The values *dx*, *dy*, and *dz* are the xyz 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. The value *engpot* is the potential energy for the bond, based on the current separation of the pair of atoms in the bond. diff --git a/doc/src/compute_pair_local.rst b/doc/src/compute_pair_local.rst index f464c7cec6..38953d203c 100644 --- a/doc/src/compute_pair_local.rst +++ b/doc/src/compute_pair_local.rst @@ -13,11 +13,12 @@ Syntax * ID, group-ID are documented in :doc:`compute ` command * pair/local = style name of this compute command * one or more values may be appended -* value = *dist* or *eng* or *force* or *fx* or *fy* or *fz* or *pN* +* value = *dist* or *dx* or *dy* or *dz* or *eng* or *force* or *fx* or *fy* or *fz* or *pN* .. parsed-literal:: *dist* = pairwise distance + *dx*,\ *dy*,\ *dz* = components of pairwise distance *eng* = pairwise energy *force* = pairwise force *fx*,\ *fy*,\ *fz* = components of pairwise force @@ -56,6 +57,9 @@ force cutoff distance for that interaction, as defined by the commands. The value *dist* is the distance between the pair of atoms. +The values *dx*, *dy*, and *dz* are the xyz 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. The value *eng* is the interaction energy for the pair of atoms. @@ -89,10 +93,10 @@ from the second of the two sub-styles. If the referenced *pN* is not computed for the specific pairwise interaction (based on atom types), then the output will be 0.0. -The value *dist* will be in distance :doc:`units `. The value -*eng* will be in energy :doc:`units `. The values *force*, *fx*, -*fy*, and *fz* will be in force :doc:`units `. The values *pN* -will be in whatever units the pair style defines. +The value *dist*, *dx*, *dy* and *dz* will be in distance :doc:`units `. +The value *eng* will be in energy :doc:`units `. +The values *force*, *fx*, *fy*, and *fz* will be in force :doc:`units `. +The values *pN* will be in whatever units the pair style defines. The optional *cutoff* keyword determines how the force cutoff distance for an interaction is determined. For the default setting of *type*, diff --git a/doc/src/dump_modify.rst b/doc/src/dump_modify.rst index 33f7141762..da7ccffeb2 100644 --- a/doc/src/dump_modify.rst +++ b/doc/src/dump_modify.rst @@ -710,7 +710,9 @@ default and it can be disabled with the :code:`checksum` keyword. Restrictions """""""""""" - none + +Not all *dump_modify* options can be applied to all dump styles. +Details are in the discussions of the individual options. Related commands """""""""""""""" diff --git a/doc/src/pair_granular.rst b/doc/src/pair_granular.rst index b7f9da9f8b..6f84b0d9c7 100644 --- a/doc/src/pair_granular.rst +++ b/doc/src/pair_granular.rst @@ -205,7 +205,7 @@ For *damping mass_velocity*, the normal damping is given by: \eta_n = \eta_{n0} m_{eff} Here, :math:`\eta_{n0}` is the damping coefficient specified for the normal -contact model, in units of *mass*\ /\ *time* and +contact model, in units of 1/\ *time* and :math:`m_{eff} = m_i m_j/(m_i + m_j)` is the effective mass. Use *damping mass_velocity* to reproduce the damping behavior of *pair gran/hooke/\**. diff --git a/doc/src/pair_hybrid.rst b/doc/src/pair_hybrid.rst index 541cdc1911..1460927add 100644 --- a/doc/src/pair_hybrid.rst +++ b/doc/src/pair_hybrid.rst @@ -74,14 +74,17 @@ atoms interact with each other via an *eam* potential, the surface atoms interact with each other via a *lj/cut* potential, and the metal/surface interaction is also computed via a *lj/cut* potential. The *hybrid/overlay* style could be used as in the second example above, -where multiple potentials are superposed in an additive fashion to +where multiple potentials are superimposed in an additive fashion to compute the interaction between atoms. In this example, using *lj/cut* and *coul/long* together gives the same result as if the *lj/cut/coul/long* potential were used by itself. In this case, it would be more efficient to use the single combined potential, but in general any combination of pair potentials can be used together in to produce an interaction that is not encoded in any single pair_style -file, e.g. adding Coulombic forces between granular particles. +file, e.g. adding Coulombic forces between granular particles. Another +limitation of using the *hybrid/overlay* variant, that it does not generate +*lj/cut* parameters for mixed atom types from a mixing rule due to +restrictions discussed below. If the *hybrid/scaled* style is used instead of *hybrid/overlay*, contributions from sub-styles are weighted by their scale factors, which @@ -150,10 +153,14 @@ with Tersoff, and the cross-interactions with Lennard-Jones: pair_coeff * * tersoff 2 C.tersoff NULL C pair_coeff 1 2 lj/cut 1.0 1.5 -If pair coefficients are specified in the data file read via the -:doc:`read_data ` command, then the same rule applies. -E.g. "eam/alloy" or "lj/cut" must be added after the atom type, for -each line in the "Pair Coeffs" section, e.g. + +It is not recommended to read pair coefficients for a hybrid style from a "Pair Coeffs" +or "PairIJ Coeffs" section of a data file via the :doc:`read_data ` command, +since those sections expect a fixed number of lines, either one line per atom type or +one line pair pair of atom types, respectively. When reading from a data file, the +lines of the "Pair Coeffs" and "PairIJ Coeffs" are changed in the same way as the *pair_coeff* +command, i.e. the name of the pair style to which the parameters apply must follow the +atom type (or atom types), e.g. .. parsed-literal:: @@ -162,6 +169,11 @@ each line in the "Pair Coeffs" section, e.g. 1 lj/cut/coul/cut 1.0 1.0 ... + PairIJ Coeffs + + 1 1 lj/cut/coul/cut 1.0 1.0 + ... + Note that the pair_coeff command for some potentials such as :doc:`pair_style eam/alloy ` includes a mapping specification of elements to all atom types, which in the hybrid case, can include @@ -208,12 +220,22 @@ examples above, or in the data file read by the :doc:`read_data `, or by mixing as described below. Also all sub-styles must be used at least once in a :doc:`pair_coeff ` command. -.. note:: +.. warning:: - LAMMPS never performs mixing of parameters from different sub-styles, - **even** if they use the same type of coefficients, e.g. contain - a Lennard-Jones potential variant. Those parameters must be provided - explicitly. + With hybrid pair styles the use of mixing to generate pair + coefficients is significantly limited compared to the individual pair + styles. LAMMPS **never** performs mixing of parameters from + different sub-styles, **even** if they use the same type of + coefficients, e.g. contain a Lennard-Jones potential variant. Those + parameters must be provided explicitly. Also for *hybrid/overlay* + and *hybrid/scaled* mixing is **only** performed for pairs of atom + types for which only a single pair style is assigned. + + Thus it is strongly recommended to provide all mixed terms + explicitly. For non-hybrid styles those could be generated and + written out using the :doc:`write_coeff command ` and + then edited as needed to comply with the requirements for hybrid + styles as explained above. If you want there to be no interactions between a particular pair of atom types, you have 3 choices. You can assign the pair of atom types diff --git a/doc/src/pair_lebedeva_z.rst b/doc/src/pair_lebedeva_z.rst index 5afd0da92c..80fe1c52cb 100644 --- a/doc/src/pair_lebedeva_z.rst +++ b/doc/src/pair_lebedeva_z.rst @@ -26,15 +26,29 @@ Examples Description """"""""""" -The *lebedeva/z* style computes the Lebedeva interaction -potential as described in :ref:`(Lebedeva et al.) `. An important simplification is made, -which is to take all normals along the z-axis. +The *lebedeva/z* pair style computes the Lebedeva interaction potential +as described in :ref:`(Lebedeva1) ` and :ref:`(Lebedeva2) +`. An important simplification is made, which is to take all +normals along the z-axis. + +The Lebedeva potential is intended for the description of the interlayer +interaction between graphene layers. To perform a realistic simulation, +this potential must be used in combination with an intralayer potential +such as :doc:`AIREBO ` or :doc:`Tersoff ` +facilitated by using pair style :doc:`hybrid/overlay `. To +keep the intralayer properties unaffected, the interlayer interaction +within the same layers should be avoided. This can be achieved by +assigning different atom types to atoms of different layers (e.g. 1 and +2 in the examples above). + +Other interactions can be set to zero using pair_style *none*\ . + .. math:: - E = & \frac{1}{2} \sum_i \sum_{i \neq j} V_{ij}\\ + E = & \frac{1}{2} \sum_i \sum_{j \neq i} V_{ij}\\ V_{ij} = & B e^{-\alpha(r_{ij} - z_0)} \\ - & + C(1 + D_1\rho^2_{ij} + D_2\rho^4_{ij} e^{-\lambda_1\rho^2_{ij}} e^{-\lambda_2 (z^2_{ij} - z^2_0)} \\ + & + C(1 + D_1\rho^2_{ij} + D_2\rho^4_{ij}) e^{-\lambda_1\rho^2_{ij}} e^{-\lambda_2 (z^2_{ij} - z^2_0)} \\ & - A \left(\frac{z_0}{r_ij}\right)^6 + A \left( \frac{z_0}{r_c} \right)^6 \\ \rho^2_{ij} = & x^2_{ij} + y^2_{ij} \qquad (\mathbf{n_i} \equiv \mathbf{\hat{z}}) @@ -43,12 +57,15 @@ Energies are shifted so that they go continuously to zero at the cutoff assuming that the exponential part of :math:`V_{ij}` (first term) decays sufficiently fast. This shift is achieved by the last term in the equation for :math:`V_{ij}` above. -The parameter file (e.g. CC.Lebedeva), is intended for use with metal -:doc:`units `, with energies in meV. An additional parameter, *S*, -is available to facilitate scaling of energies. +The provided parameter file (CC.Lebedeva) contains two sets of parameters. -This potential must be used in combination with hybrid/overlay. -Other interactions can be set to zero using pair_style *none*\ . +- The first set (element name "C") is suitable for normal conditions and + is taken from :ref:`(Popov1) ` +- The second set (element name "C1") is suitable for high-pressure + conditions and is taken from :ref:`(Koziol1) ` + +Both sets contain an additional parameter, *S*, that can be used to +facilitate scaling of energies and is set to 1.0 by default. Restrictions """""""""""" @@ -77,4 +94,16 @@ none .. _Leb01: -**(Lebedeva et al.)** I. V. Lebedeva, A. A. Knizhnik, A. M. Popov, Y. E. Lozovik, B. V. Potapkin, Phys. Rev. B, 84, 245437 (2011) +**(Lebedeva1)** I. V. Lebedeva, A. A. Knizhnik, A. M. Popov, Y. E. Lozovik, B. V. Potapkin, Phys. Rev. B, 84, 245437 (2011) + +.. _Leb02: + +**(Lebedeva2)** I. V. Lebedeva, A. A. Knizhnik, A. M. Popov, Y. E. Lozovik, B. V. Potapkin, Physica E: 44, 949-954 (2012) + +.. _Popov: + +**(Popov1)** A.M. Popov, I. V. Lebedeva, A. A. Knizhnik, Y. E. Lozovik and B. V. Potapkin, Chem. Phys. Lett. 536, 82-86 (2012). + +.. _Koziol: + +**(Koziol1)** Z. Koziol, G. Gawlik and J. Jagielski, Chinese Phys. B 28, 096101 (2019). diff --git a/doc/src/pair_modify.rst b/doc/src/pair_modify.rst index 1a62a4c1a0..4941693fbd 100644 --- a/doc/src/pair_modify.rst +++ b/doc/src/pair_modify.rst @@ -71,21 +71,23 @@ The *mix* keyword affects pair coefficients for interactions between atoms of type I and J, when I != J and the coefficients are not explicitly set in the input script. Note that coefficients for I = J must be set explicitly, either in the input script via the -:doc:`pair_coeff ` command or in the "Pair Coeffs" section of the -:doc:`data file `. For some pair styles it is not +:doc:`pair_coeff ` command or in the "Pair Coeffs" or "PairIJ Coeffs" +sections of the :doc:`data file `. For some pair styles it is not necessary to specify coefficients when I != J, since a "mixing" rule will create them from the I,I and J,J settings. The pair_modify *mix* value determines what formulas are used to compute the mixed coefficients. In each case, the cutoff distance is mixed the same way as sigma. -Note that not all pair styles support mixing and some mix options -are not available for certain pair styles. Also, there are additional -restrictions when using :doc:`pair style hybrid or hybrid/overlay `. -See the page for individual pair styles for those restrictions. Note also that the -:doc:`pair_coeff ` command also can be used to directly set -coefficients for a specific I != J pairing, in which case no mixing is -performed. +Note that not all pair styles support mixing and some mix options are +not available for certain pair styles. Also, there are additional +restrictions when using :doc:`pair style hybrid or hybrid/overlay +`. See the page for individual pair styles for those +restrictions. Note also that the :doc:`pair_coeff ` command +also can be used to directly set coefficients for a specific I != J +pairing, in which case no mixing is performed. If possible, LAMMPS will +print an informational message about how many of the mixed pair +coefficients were generated and which mixing rule was applied. - mix *geometric* diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index d295767519..c8e41faa4c 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1125,6 +1125,7 @@ gaussian gaussians Gaussians Gavhane +Gawlik gayberne gcc gcmc @@ -1483,6 +1484,7 @@ Izz Jacobsen Jadhao Jadhav +Jagielski jagreat Jahn Jalalvand @@ -1609,6 +1611,7 @@ Koslowski Kosovan Koster Kosztin +Koziol Kp kradius Kraker @@ -1995,6 +1998,7 @@ minimizer minimizers minneigh minorder +MinSizeRel minSteps mintcream Mintmire @@ -2784,6 +2788,7 @@ relink relres relTol relu +RelWithDebInfo remappings remd Ren diff --git a/examples/plugins/CMakeLists.txt b/examples/plugins/CMakeLists.txt index 0ca2c025e2..8bef055ad3 100644 --- a/examples/plugins/CMakeLists.txt +++ b/examples/plugins/CMakeLists.txt @@ -14,26 +14,29 @@ endif() project(plugins VERSION 1.0 LANGUAGES CXX) -# ugly hacks for MSVC which by default always reports an old C++ standard in the __cplusplus macro -# and prints lots of pointless warnings about "unsafe" functions -if(MSVC) - add_compile_options(/Zc:__cplusplus) - add_compile_options(/wd4244) - add_compile_options(/wd4267) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) -endif() - -# NOTE: the next line should be commented out when used outside of the LAMMPS package -get_filename_component(LAMMPS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../src ABSOLUTE) -set(LAMMPS_HEADER_DIR ${LAMMPS_SOURCE_DIR} CACHE PATH "Location of LAMMPS headers") -if(NOT LAMMPS_HEADER_DIR) - message(FATAL_ERROR "Must set LAMMPS_HEADER_DIR") -endif() - -# by default, install into $HOME/.local (not /usr/local), -# so that no root access (and sudo) is needed -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "Default install path" FORCE) +# when this file is included as subdirectory in the LAMMPS build, many settings are directly imported +if(LAMMPS_DIR) + set(LAMMPS_HEADER_DIR ${LAMMPS_SOURCE_DIR}) +else() + # NOTE: the next line should be commented out when used outside of the LAMMPS package + get_filename_component(LAMMPS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../src ABSOLUTE) + set(LAMMPS_HEADER_DIR ${LAMMPS_SOURCE_DIR} CACHE PATH "Location of LAMMPS headers") + if(NOT LAMMPS_HEADER_DIR) + message(FATAL_ERROR "Must set LAMMPS_HEADER_DIR") + endif() + # by default, install into $HOME/.local (not /usr/local), + # so that no root access (and sudo) is needed + if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "Default install path" FORCE) + endif() + # ugly hacks for MSVC which by default always reports an old C++ standard in the __cplusplus macro + # and prints lots of pointless warnings about "unsafe" functions + if(MSVC) + add_compile_options(/Zc:__cplusplus) + add_compile_options(/wd4244) + add_compile_options(/wd4267) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + endif() endif() # C++11 is required @@ -45,9 +48,11 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict") endif() -set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) include(CheckIncludeFileCXX) -include(LAMMPSInterfaceCXX) +if(NOT LAMMPS_DIR) + include(LAMMPSInterfaceCXX) +endif() ########################## # building the plugins @@ -66,7 +71,7 @@ add_library(zero2plugin MODULE zero2plugin.cpp pair_zero2.cpp bond_zero2.cpp angle_zero2.cpp dihedral_zero2.cpp improper_zero2.cpp) target_link_libraries(zero2plugin PRIVATE lammps) -set_target_properties(morse2plugin nve2plugin helloplugin zero2plugin PROPERTIES PREFIX "") +set_target_properties(morse2plugin nve2plugin helloplugin zero2plugin PROPERTIES PREFIX "" SUFFIX ".so") # MacOS seems to need this if(CMAKE_SYSTEM_NAME STREQUAL Darwin) @@ -84,3 +89,6 @@ else() set_target_properties(morse2plugin nve2plugin helloplugin zero2plugin PROPERTIES LINK_FLAGS "-rdynamic") endif() + +add_custom_target(plugins ALL ${CMAKE_COMMAND} -E echo "Building Plugins" + DEPENDS morse2plugin nve2plugin helloplugin zero2plugin morse2plugin) diff --git a/potentials/CC.Lebedeva b/potentials/CC.Lebedeva index bc2db03f6b..bc70500687 100644 --- a/potentials/CC.Lebedeva +++ b/potentials/CC.Lebedeva @@ -1,12 +1,13 @@ -# DATE: 2018-11-28 UNITS: metal CONTRIBUTOR: Zbigniew Koziol softquake@gmail.com CITATION: Z. Koziol et al.: https://arxiv.org/abs/1803.05162 +# DATE: 2021-11-04 UNITS: metal CONTRIBUTOR: Zbigniew Koziol softquake@gmail.com CITATION: Z. Koziol et al.: https://arxiv.org/abs/1803.05162 # -# Lebedeva Potential. https://doi.org/10.1016/j.physe.2011.07.018 +# Lebedeva potential: https://doi.org/10.1039/C0CP02614J and https://doi.org/10.1016/j.physe.2011.07.018 # Parameters must be in this order as here, otherwise their values may be changed. +# Energies here are given in meV. # The last one, S, is convenient for scaling the potential amplitude. S is a multiplication factor for A, B, C # A B C z0 alpha D1 D2 lambda1 lambda2 S -# These are values according to Levedeva et al -#C C 10.510 11.6523.34 35.883 3.34 4.16 -0.86232 0.10049 0.48703 0.46445 1.0 +# These are values according to Lebedeva et al.: https://doi.org/10.1016/j.cplett.2012.03.082 +C C 10.510 11.652 29.5 3.34 4.16 -0.86232 0.10049 0.48703 0.46445 1.0 # # These are values by Z. Koziol et al.: https://arxiv.org/abs/1803.05162 -C C 14.558 21.204 1.8 3.198 4.16 -0.862 0.10049 0.6 0.4 1.0 +C1 C1 14.558 21.204 1.8 3.198 4.16 -0.862 0.10049 0.6 0.4 1.0 diff --git a/src/DRUDE/compute_temp_drude.cpp b/src/DRUDE/compute_temp_drude.cpp index 940a7e5328..96344751a7 100644 --- a/src/DRUDE/compute_temp_drude.cpp +++ b/src/DRUDE/compute_temp_drude.cpp @@ -89,9 +89,7 @@ void ComputeTempDrude::dof_compute() int dim = domain->dimension; int *drudetype = fix_drude->drudetype; - fix_dof = 0; - for (int i = 0; i < modify->nfix; i++) - fix_dof += modify->fix[i]->dof(igroup); + adjust_dof_fix(); bigint dof_core_loc = 0, dof_drude_loc = 0; for (int i = 0; i < nlocal; i++) { diff --git a/src/DRUDE/compute_temp_drude.h b/src/DRUDE/compute_temp_drude.h index cef5d8664e..e1cd54edc8 100644 --- a/src/DRUDE/compute_temp_drude.h +++ b/src/DRUDE/compute_temp_drude.h @@ -35,7 +35,6 @@ class ComputeTempDrude : public Compute { int modify_param(int, char **); private: - int fix_dof; class FixDrude *fix_drude; char *id_temp; class Compute *temperature; diff --git a/src/EXTRA-COMPUTE/compute_temp_rotate.h b/src/EXTRA-COMPUTE/compute_temp_rotate.h index afa14000b8..af218e756c 100644 --- a/src/EXTRA-COMPUTE/compute_temp_rotate.h +++ b/src/EXTRA-COMPUTE/compute_temp_rotate.h @@ -43,7 +43,6 @@ class ComputeTempRotate : public Compute { double memory_usage(); private: - int fix_dof; double tfactor, masstotal; double **vbiasall; // stored velocity bias for all atoms int maxbias; // size of vbiasall array diff --git a/src/MACHDYN/atom_vec_smd.cpp b/src/MACHDYN/atom_vec_smd.cpp index b798425e19..81f32ca0a2 100644 --- a/src/MACHDYN/atom_vec_smd.cpp +++ b/src/MACHDYN/atom_vec_smd.cpp @@ -115,6 +115,7 @@ void AtomVecSMD::grow_pointers() vfrac = atom->vfrac; rmass = atom->rmass; x0 = atom->x0; + x = atom->x; radius = atom->radius; contact_radius = atom->contact_radius; molecule = atom->molecule; @@ -129,13 +130,11 @@ void AtomVecSMD::grow_pointers() /* ---------------------------------------------------------------------- clear extra forces starting at atom N nbytes = # of bytes to clear for a per-atom vector - NOTE: does f need to be re-cleared? ------------------------------------------------------------------------- */ void AtomVecSMD::force_clear(int n, size_t nbytes) { memset(&desph[n],0,nbytes); - memset(&f[n][0],0,3*nbytes); } /* ---------------------------------------------------------------------- diff --git a/src/MACHDYN/compute_smd_triangle_vertices.cpp b/src/MACHDYN/compute_smd_triangle_vertices.cpp index 016ae3e85f..89a2a24b89 100644 --- a/src/MACHDYN/compute_smd_triangle_vertices.cpp +++ b/src/MACHDYN/compute_smd_triangle_vertices.cpp @@ -53,7 +53,7 @@ ComputeSMDTriangleVertices::ComputeSMDTriangleVertices(LAMMPS *lmp, int narg, ch /* ---------------------------------------------------------------------- */ ComputeSMDTriangleVertices::~ComputeSMDTriangleVertices() { - memory->sfree(outputVector); + memory->destroy(outputVector); } /* ---------------------------------------------------------------------- */ diff --git a/src/MACHDYN/pair_smd_ulsph.cpp b/src/MACHDYN/pair_smd_ulsph.cpp index 0958cbc7c3..e9eac13126 100644 --- a/src/MACHDYN/pair_smd_ulsph.cpp +++ b/src/MACHDYN/pair_smd_ulsph.cpp @@ -85,7 +85,8 @@ PairULSPH::PairULSPH(LAMMPS *lmp) : PairULSPH::~PairULSPH() { if (allocated) { - //printf("... deallocating\n"); + memory->destroy(setflag); + memory->destroy(cutsq); memory->destroy(Q1); memory->destroy(rho0); memory->destroy(eos); diff --git a/src/compute_bond_local.cpp b/src/compute_bond_local.cpp index ab0fa3fb0a..7c60df057f 100644 --- a/src/compute_bond_local.cpp +++ b/src/compute_bond_local.cpp @@ -34,7 +34,7 @@ using namespace LAMMPS_NS; #define DELTA 10000 #define EPSILON 1.0e-12 -enum{DIST,VELVIB,OMEGA,ENGTRANS,ENGVIB,ENGROT,ENGPOT,FORCE,FX,FY,FZ,VARIABLE}; +enum{DIST,DX,DY,DZ,VELVIB,OMEGA,ENGTRANS,ENGVIB,ENGROT,ENGPOT,FORCE,FX,FY,FZ,VARIABLE}; /* ---------------------------------------------------------------------- */ @@ -63,6 +63,9 @@ ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : int iarg; for (iarg = 3; iarg < narg; iarg++) { if (strcmp(arg[iarg],"dist") == 0) bstyle[nvalues++] = DIST; + else if (strcmp(arg[iarg],"dx") == 0) bstyle[nvalues++] = DX; + else if (strcmp(arg[iarg],"dy") == 0) bstyle[nvalues++] = DY; + else if (strcmp(arg[iarg],"dz") == 0) bstyle[nvalues++] = DZ; else if (strcmp(arg[iarg],"engpot") == 0) bstyle[nvalues++] = ENGPOT; else if (strcmp(arg[iarg],"force") == 0) bstyle[nvalues++] = FORCE; else if (strcmp(arg[iarg],"fx") == 0) bstyle[nvalues++] = FX; @@ -384,11 +387,23 @@ int ComputeBondLocal::compute_bonds(int flag) if (dstr) input->variable->internal_set(dvar,sqrt(rsq)); } + // to make sure dx, dy and dz are always from the lower to the higher id + double directionCorrection = tag[atom1] > tag[atom2] ? -1.0 : 1.0; + for (int n = 0; n < nvalues; n++) { switch (bstyle[n]) { case DIST: ptr[n] = sqrt(rsq); break; + case DX: + ptr[n] = dx*directionCorrection; + break; + case DY: + ptr[n] = dy*directionCorrection; + break; + case DZ: + ptr[n] = dz*directionCorrection; + break; case ENGPOT: ptr[n] = engpot; break; diff --git a/src/compute_pair_local.cpp b/src/compute_pair_local.cpp index af0f20014c..ff9acdc4ef 100644 --- a/src/compute_pair_local.cpp +++ b/src/compute_pair_local.cpp @@ -31,7 +31,7 @@ using namespace LAMMPS_NS; #define DELTA 10000 -enum{DIST,ENG,FORCE,FX,FY,FZ,PN}; +enum{DIST,ENG,FORCE,FX,FY,FZ,PN,DX,DY,DZ}; enum{TYPE,RADIUS}; /* ---------------------------------------------------------------------- */ @@ -56,6 +56,9 @@ ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg],"fx") == 0) pstyle[nvalues++] = FX; else if (strcmp(arg[iarg],"fy") == 0) pstyle[nvalues++] = FY; else if (strcmp(arg[iarg],"fz") == 0) pstyle[nvalues++] = FZ; + else if (strcmp(arg[iarg],"dx") == 0) pstyle[nvalues++] = DX; + else if (strcmp(arg[iarg],"dy") == 0) pstyle[nvalues++] = DY; + else if (strcmp(arg[iarg],"dz") == 0) pstyle[nvalues++] = DZ; else if (arg[iarg][0] == 'p') { int n = atoi(&arg[iarg][1]); if (n <= 0) error->all(FLERR, @@ -92,7 +95,7 @@ ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : singleflag = 0; for (int i = 0; i < nvalues; i++) - if (pstyle[i] != DIST) singleflag = 1; + if (pstyle[i] != DIST && pstyle[i] != DX && pstyle[i] != DY && pstyle[i] != DZ) singleflag = 1; if (nvalues == 1) size_local_cols = 0; else size_local_cols = nvalues; @@ -264,11 +267,20 @@ int ComputePairLocal::compute_pairs(int flag) if (nvalues == 1) ptr = &vlocal[m]; else ptr = alocal[m]; + // to make sure dx, dy and dz are always from the lower to the higher id + double directionCorrection = itag > jtag ? -1.0 : 1.0; + for (n = 0; n < nvalues; n++) { switch (pstyle[n]) { case DIST: ptr[n] = sqrt(rsq); break; + case DX: + ptr[n] = delx*directionCorrection; + case DY: + ptr[n] = dely*directionCorrection; + case DZ: + ptr[n] = delz*directionCorrection; case ENG: ptr[n] = eng; break; diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp index c18a0e23dd..034cecd55a 100644 --- a/src/fix_deposit.cpp +++ b/src/fix_deposit.cpp @@ -569,10 +569,12 @@ void FixDeposit::pre_exchange() // coord is new position of geometric center of mol, not COM // FixShake::set_molecule stores shake info for molecule - if (rigidflag) - fixrigid->set_molecule(nlocalprev,maxtag_all,imol,coord,vnew,quat); - else if (shakeflag) - fixshake->set_molecule(nlocalprev,maxtag_all,imol,coord,vnew,quat); + if (mode == MOLECULE) { + if (rigidflag) + fixrigid->set_molecule(nlocalprev,maxtag_all,imol,coord,vnew,quat); + else if (shakeflag) + fixshake->set_molecule(nlocalprev,maxtag_all,imol,coord,vnew,quat); + } success = 1; break; diff --git a/src/pair.cpp b/src/pair.cpp index 1039875718..0bc698f27e 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -41,6 +41,7 @@ using namespace LAMMPS_NS; using namespace MathConst; enum{NONE,RLINEAR,RSQ,BMP}; +static const std::string mixing_rule_names[Pair::SIXTHPOWER+1] = {"geometric", "arithmetic", "sixthpower" }; // allocate space for static class instance variable and initialize it @@ -217,11 +218,9 @@ void Pair::init() if (tail_flag && domain->nonperiodic && comm->me == 0) error->warning(FLERR,"Using pair tail corrections with non-periodic system"); if (!compute_flag && tail_flag && comm->me == 0) - error->warning(FLERR,"Using pair tail corrections with " - "pair_modify compute no"); + error->warning(FLERR,"Using pair tail corrections with pair_modify compute no"); if (!compute_flag && offset_flag && comm->me == 0) - error->warning(FLERR,"Using pair potential shift with " - "pair_modify compute no"); + error->warning(FLERR,"Using pair potential shift with pair_modify compute no"); // for manybody potentials // check if bonded exclusions could invalidate the neighbor list @@ -259,13 +258,18 @@ void Pair::init() etail = ptail = 0.0; mixed_flag = 1; double cut; + int mixed_count = 0; for (i = 1; i <= atom->ntypes; i++) for (j = i; j <= atom->ntypes; j++) { - if ((i != j) && setflag[i][j]) mixed_flag = 0; + did_mix = false; cut = init_one(i,j); cutsq[i][j] = cutsq[j][i] = cut*cut; cutforce = MAX(cutforce,cut); + if (i != j) { + if (setflag[i][j]) mixed_flag = 0; + if (did_mix) ++mixed_count; + } if (tail_flag) { etail += etail_ij; ptail += ptail_ij; @@ -275,6 +279,12 @@ void Pair::init() } } } + + if (!manybody_flag && (comm->me == 0)) { + const int num_mixed_pairs = atom->ntypes * (atom->ntypes - 1) / 2; + utils::logmesg(lmp," generated {} of {} mixed pair_coeff terms from {} mixing rule\n", + mixed_count, num_mixed_pairs, mixing_rule_names[mix_flag]); + } } /* ---------------------------------------------------------------------- @@ -681,6 +691,7 @@ void Pair::free_disp_tables() double Pair::mix_energy(double eps1, double eps2, double sig1, double sig2) { + did_mix = true; if (mix_flag == GEOMETRIC) return sqrt(eps1*eps2); else if (mix_flag == ARITHMETIC) @@ -688,7 +699,8 @@ double Pair::mix_energy(double eps1, double eps2, double sig1, double sig2) else if (mix_flag == SIXTHPOWER) return (2.0 * sqrt(eps1*eps2) * pow(sig1,3.0) * pow(sig2,3.0) / (pow(sig1,6.0) + pow(sig2,6.0))); - else return 0.0; + else did_mix = false; + return 0.0; } /* ---------------------------------------------------------------------- diff --git a/src/pair.h b/src/pair.h index f37c0732ed..00e6734773 100644 --- a/src/pair.h +++ b/src/pair.h @@ -110,6 +110,7 @@ class Pair : protected Pointers { // public so external driver can check int compute_flag; // 0 if skip compute() int mixed_flag; // 1 if all itype != jtype coeffs are from mixing + bool did_mix; // set to true by mix_energy() to indicate that mixing was performed enum { GEOMETRIC, ARITHMETIC, SIXTHPOWER }; // mixing options diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index b5daa111da..e962e02c9e 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -706,11 +706,10 @@ double PairHybrid::init_one(int i, int j) for (int k = 0; k < nmap[i][j]; k++) { map[j][i][k] = map[i][j][k]; double cut = styles[map[i][j][k]]->init_one(i,j); - styles[map[i][j][k]]->cutsq[i][j] = - styles[map[i][j][k]]->cutsq[j][i] = cut*cut; + if (styles[map[i][j][k]]->did_mix) did_mix = true; + styles[map[i][j][k]]->cutsq[i][j] = styles[map[i][j][k]]->cutsq[j][i] = cut*cut; if (styles[map[i][j][k]]->ghostneigh) - cutghost[i][j] = cutghost[j][i] = - MAX(cutghost[i][j],styles[map[i][j][k]]->cutghost[i][j]); + cutghost[i][j] = cutghost[j][i] = MAX(cutghost[i][j],styles[map[i][j][k]]->cutghost[i][j]); if (tail_flag) { etail_ij += styles[map[i][j][k]]->etail_ij; ptail_ij += styles[map[i][j][k]]->ptail_ij; diff --git a/src/platform.cpp b/src/platform.cpp index c701c37a80..708a42be8a 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -446,11 +446,11 @@ int platform::putenv(const std::string &vardef) auto found = vardef.find_first_of('='); #ifdef _WIN32 - // must assign a value to variable with _putenv() + // must assign a value to variable with _putenv_s() if (found == std::string::npos) - return _putenv(utils::strdup(vardef + "=1")); + return _putenv_s(vardef.c_str(), "1"); else - return _putenv(utils::strdup(vardef)); + return _putenv_s(vardef.substr(0, found).c_str(), vardef.substr(found+1).c_str()); #else if (found == std::string::npos) return setenv(vardef.c_str(), "", 1); @@ -460,6 +460,24 @@ int platform::putenv(const std::string &vardef) return -1; } +/* ---------------------------------------------------------------------- + unset environment variable +------------------------------------------------------------------------- */ + +int platform::unsetenv(const std::string &variable) +{ + if (variable.size() == 0) return -1; +#ifdef _WIN32 + // emulate POSIX semantics by returning -1 on trying to unset non-existing variable + const char *ptr = getenv(variable.c_str()); + if (!ptr) return -1; + // empty _putenv_s() definition deletes variable + return _putenv_s(variable.c_str(),""); +#else + return ::unsetenv(variable.c_str()); +#endif +} + /* ---------------------------------------------------------------------- split a "path" environment variable into a list ------------------------------------------------------------------------- */ diff --git a/src/platform.h b/src/platform.h index 95a0c3cc35..c079fd2cd1 100644 --- a/src/platform.h +++ b/src/platform.h @@ -125,6 +125,13 @@ namespace platform { int putenv(const std::string &vardef); + /*! Delete variable from the environment + * + * \param variable variable name + * \return -1 if failure otherwise 0 */ + + int unsetenv(const std::string &variable); + /*! Get list of entries in a path environment variable * * This provides a list of strings of the entries in an environment diff --git a/src/verlet.cpp b/src/verlet.cpp index aa180f5644..342dc3d951 100644 --- a/src/verlet.cpp +++ b/src/verlet.cpp @@ -54,7 +54,7 @@ void Verlet::init() bool do_time_integrate = false; for (const auto &fix : modify->get_fix_list()) - if (fix->time_integrate) do_time_integrate; + if (fix->time_integrate) do_time_integrate = true; if (!do_time_integrate && (comm->me == 0)) error->warning(FLERR,"No fixes with time integration, atoms won't move"); diff --git a/tools/lammps-shell/.clang-format b/tools/lammps-shell/.clang-format new file mode 120000 index 0000000000..a20dd6aac4 --- /dev/null +++ b/tools/lammps-shell/.clang-format @@ -0,0 +1 @@ +../../unittest/.clang-format \ No newline at end of file diff --git a/tools/lammps-shell/lammps-shell.cpp b/tools/lammps-shell/lammps-shell.cpp index d03e1da70b..19730b8552 100644 --- a/tools/lammps-shell/lammps-shell.cpp +++ b/tools/lammps-shell/lammps-shell.cpp @@ -10,8 +10,8 @@ #include "utils.h" #include -#include #include +#include #include #include @@ -33,9 +33,9 @@ using namespace LAMMPS_NS; -void *lmp = nullptr; -char *omp_threads = nullptr; -constexpr int BUFLEN = 512; +void *lmp = nullptr; +char *omp_threads = nullptr; +constexpr int BUFLEN = 512; char buf[BUFLEN]; enum { @@ -342,14 +342,13 @@ static char *plugin_generator(const char *text, int state) { const char *subcmd[] = {"load", "unload", "list", "clear", nullptr}; const char *sub; - static std::size_t idx=0, len; + static std::size_t idx = 0, len; if (!state) idx = 0; len = strlen(text); while ((sub = subcmd[idx]) != nullptr) { ++idx; - if (strncmp(text,sub,len) == 0) - return dupstring(sub); + if (strncmp(text, sub, len) == 0) return dupstring(sub); } return nullptr; } @@ -358,13 +357,12 @@ static char *plugin_style_generator(const char *text, int state) { const char *styles[] = {"pair", "fix", "command", nullptr}; const char *s; - static std::size_t idx=0, len; + static std::size_t idx = 0, len; if (!state) idx = 0; len = strlen(text); while ((s = styles[idx]) != nullptr) { ++idx; - if (strncmp(text,s,len) == 0) - return dupstring(s); + if (strncmp(text, s, len) == 0) return dupstring(s); } return nullptr; } @@ -376,7 +374,7 @@ static char *plugin_name_generator(const char *text, int state) static std::size_t idx, len, nmax; if (!state) idx = 0; - len = words[3].size(); + len = words[3].size(); nmax = lammps_plugin_count(); while (idx < nmax) { @@ -384,8 +382,7 @@ static char *plugin_name_generator(const char *text, int state) lammps_plugin_name(idx, style, name, BUFLEN); ++idx; if (words[2] == style) { - if (strncmp(name, words[3].c_str(), len) == 0) - return dupstring(name); + if (strncmp(name, words[3].c_str(), len) == 0) return dupstring(name); } } return nullptr; @@ -527,13 +524,11 @@ static char **cmd_completion(const char *text, int start, int) } else if (words.size() == 2) { // expand third word // these commands have a group name as 3rd word - if ((words[0] == "fix") - || (words[0] == "compute") - || (words[0] == "dump")) { + if ((words[0] == "fix") || (words[0] == "compute") || (words[0] == "dump")) { matches = rl_completion_matches(text, group_generator); } else if (words[0] == "region") { matches = rl_completion_matches(text, region_generator); - // plugin style is the third word + // plugin style is the third word } else if ((words[0] == "plugin") && (words[1] == "unload")) { matches = rl_completion_matches(text, plugin_style_generator); } @@ -546,7 +541,7 @@ static char **cmd_completion(const char *text, int start, int) matches = rl_completion_matches(text, compute_generator); } else if (words[0] == "dump") { matches = rl_completion_matches(text, dump_generator); - // plugin name is the fourth word + // plugin name is the fourth word } else if ((words[0] == "plugin") && (words[1] == "unload")) { matches = rl_completion_matches(rl_line_buffer, plugin_name_generator); } @@ -599,7 +594,7 @@ static void init_commands() // read saved history, but not in test mode. if (!test_mode) read_history(".lammps_history"); - // intercept CTRL-C + // intercept CTRL-C #if defined(_WIN32) SetConsoleCtrlHandler(ctrl_c_handler, TRUE); #else @@ -736,7 +731,7 @@ int main(int argc, char **argv) // switch to the user's documents directory. auto curdir = platform::current_directory(); - if (utils::strmatch(curdir,"[Ss]ystem32")) { + if (utils::strmatch(curdir, "[Ss]ystem32")) { std::string docdir = getenv("HOMEDRIVE"); docdir += getenv("HOMEPATH"); docdir += "\\Documents"; diff --git a/tools/replica/reorder_remd_traj.py b/tools/replica/reorder_remd_traj.py index 5033ae1e53..205e5a34f9 100644 --- a/tools/replica/reorder_remd_traj.py +++ b/tools/replica/reorder_remd_traj.py @@ -206,7 +206,7 @@ def get_byte_index(rep_inds, byteindfns, intrajfns): # close the trajfile object fobj.close() - return + return def write_reordered_traj(temp_inds, byte_inds, outtemps, temps, @@ -459,6 +459,8 @@ if __name__ == "__main__": # get (unordered) trajectories temps = np.loadtxt(tempfn) + if not out_temps: + out_temps = temps ntemps = len(temps) intrajfns = ["%s.%d.lammpstrj" % (traj_prefix, k) for k in range(ntemps)] # check if the trajs. (or their zipped versions are present) diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 46f1865989..6489287097 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -1,4 +1,26 @@ -include(GTest) +######################################## +# CMake build for automated testing +# This file is part of LAMMPS +# Created by Axel Kohlmeyer and Richard Berger +######################################## +# download and build googletest framework +message(STATUS "Downloading and building googletest framework") +set(GTEST_URL "https://github.com/google/googletest/archive/release-1.11.0.tar.gz" CACHE STRING "URL of googletest source") +set(GTEST_MD5 "e8a8df240b6938bb6384155d4c37d937" CACHE STRING "MD5 sum for googletest source") +mark_as_advanced(GTEST_URL) +mark_as_advanced(GTEST_MD5) +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +include(ExternalCMakeProject) +ExternalCMakeProject(googletest ${GTEST_URL} ${GTEST_MD5} googletest . "") +add_library(GTest::GTest ALIAS gtest) +add_library(GTest::GMock ALIAS gmock) +add_library(GTest::GTestMain ALIAS gtest_main) +add_library(GTest::GMockMain ALIAS gmock_main) + +######################################## +# General tests using the LAMMPS executable itself +######################################## # check if we can run the compiled executable and whether it prints # the LAMMPS version header in the output for an empty input @@ -7,7 +29,7 @@ add_test(NAME RunLammps COMMAND $ -log none -echo none -in in.empty WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(RunLammps PROPERTIES - ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" + ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?\\)") # check if the compiled executable will print the help message @@ -15,7 +37,7 @@ add_test(NAME HelpMessage COMMAND $ -h WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(HelpMessage PROPERTIES - ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" + ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" PASS_REGULAR_EXPRESSION ".*Large-scale Atomic/Molecular Massively Parallel Simulator -.*Usage example:.*") # check if the compiled executable will error out on an invalid command line flag @@ -23,25 +45,36 @@ add_test(NAME InvalidFlag COMMAND $ -xxx WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(InvalidFlag PROPERTIES - ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" + ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" PASS_REGULAR_EXPRESSION "ERROR: Invalid command-line argument.*") +# convenience function for adding tests requiring to be run in parallel with MPI if(BUILD_MPI) function(add_mpi_test) set(MPI_TEST_NUM_PROCS 1) set(MPI_TEST_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) cmake_parse_arguments(MPI_TEST "" "NAME;NUM_PROCS;WORKING_DIRECTORY" "COMMAND" ${ARGN}) + # Do not add test when oversubscribing + if(MPI_TEST_NUMPROCS GREATER MPIEXEC_MAX_NUMPROCS) + return() + endif() list(GET MPI_TEST_COMMAND 0 EXECUTABLE) list(REMOVE_AT MPI_TEST_COMMAND 0) set(ARGS ${MPI_TEST_COMMAND}) add_test(NAME ${MPI_TEST_NAME} WORKING_DIRECTORY ${MPI_TEST_WORKING_DIRECTORY} - COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPI_TEST_NUM_PROCS} ${MPIEXEC_PREFLAGS} - ${EXECUTABLE} ${MPIEXEC_POSTFLAGS} ${ARGS} - ) + COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPI_TEST_NUM_PROCS} + ${MPIEXEC_PREFLAGS} ${EXECUTABLE} ${MPIEXEC_POSTFLAGS} ${ARGS}) + endfunction() +else() + function(add_mpi_test) + cmake_parse_arguments(MPI_TEST "" "NAME;NUM_PROCS;WORKING_DIRECTORY" "COMMAND" ${ARGN}) + message(STATUS "Skipping test ${NAME} on non-MPI compilation") endfunction() endif() +# incorporate categories of specific tests from subdirectories + add_subdirectory(utils) add_subdirectory(formats) add_subdirectory(commands) @@ -52,6 +85,8 @@ add_subdirectory(python) add_subdirectory(tools) add_subdirectory(force-styles) +# clang-format support for test sources + find_package(ClangFormat 8.0) if(ClangFormat_FOUND) diff --git a/unittest/c-library/CMakeLists.txt b/unittest/c-library/CMakeLists.txt index ee7f323c0f..3d57dbbc90 100644 --- a/unittest/c-library/CMakeLists.txt +++ b/unittest/c-library/CMakeLists.txt @@ -1,24 +1,24 @@ add_executable(test_library_open test_library_open.cpp test_main.cpp) -target_link_libraries(test_library_open PRIVATE lammps GTest::GTest GTest::GMock) +target_link_libraries(test_library_open PRIVATE lammps GTest::GMock) add_test(LibraryOpen test_library_open) add_executable(test_library_commands test_library_commands.cpp test_main.cpp) -target_link_libraries(test_library_commands PRIVATE lammps GTest::GTest GTest::GMock) +target_link_libraries(test_library_commands PRIVATE lammps GTest::GMock) add_test(LibraryCommands test_library_commands) add_executable(test_library_external test_library_external.cpp test_main.cpp) -target_link_libraries(test_library_external PRIVATE lammps GTest::GTest GTest::GMock) +target_link_libraries(test_library_external PRIVATE lammps GTest::GMock) add_test(LibraryExternal test_library_external) add_executable(test_library_properties test_library_properties.cpp test_main.cpp) -target_link_libraries(test_library_properties PRIVATE lammps GTest::GTest GTest::GMock) +target_link_libraries(test_library_properties PRIVATE lammps GTest::GMock) target_compile_definitions(test_library_properties PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) add_test(LibraryProperties test_library_properties) set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_library_scatter_gather test_library_scatter_gather.cpp test_main.cpp) -target_link_libraries(test_library_scatter_gather PRIVATE lammps GTest::GTest GTest::GMock) +target_link_libraries(test_library_scatter_gather PRIVATE lammps GTest::GMock) target_compile_definitions(test_library_scatter_gather PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) add_test(LibraryScatterGather test_library_scatter_gather) set_tests_properties(LibraryScatterGather PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") @@ -63,13 +63,11 @@ foreach(WITH "JPEG" "PNG" "GZIP" "FFMPEG") endforeach() add_executable(test_library_config test_library_config.cpp test_main.cpp) -target_link_libraries(test_library_config PRIVATE lammps GTest::GTest GTest::GMock) +target_link_libraries(test_library_config PRIVATE lammps GTest::GMock) target_compile_definitions(test_library_config PRIVATE ${TEST_CONFIG_DEFS}) add_test(LibraryConfig test_library_config) -if(BUILD_MPI) - add_executable(test_library_mpi test_library_mpi.cpp) - target_link_libraries(test_library_mpi PRIVATE lammps GTest::GTest GTest::GMock) - target_compile_definitions(test_library_mpi PRIVATE ${TEST_CONFIG_DEFS}) - add_mpi_test(NAME LibraryMPI NUM_PROCS 4 COMMAND $) -endif() +add_executable(test_library_mpi test_library_mpi.cpp) +target_link_libraries(test_library_mpi PRIVATE lammps GTest::GMock) +target_compile_definitions(test_library_mpi PRIVATE ${TEST_CONFIG_DEFS}) +add_mpi_test(NAME LibraryMPI NUM_PROCS 4 COMMAND $) diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index 176e22a391..49603a8b22 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -1,44 +1,28 @@ -# build LAMMPS plugins, but not on Windows -if((NOT (CMAKE_SYSTEM_NAME STREQUAL "Windows")) AND PKG_PLUGIN) - ExternalProject_Add(plugins - SOURCE_DIR "${LAMMPS_DIR}/examples/plugins" - BINARY_DIR ${CMAKE_BINARY_DIR}/build-plugins - INSTALL_DIR ${CMAKE_BINARY_DIR} - CMAKE_ARGS ${CMAKE_REQUEST_PIC} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_INSTALL_PREFIX= - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} - BUILD_BYPRODUCTS /morse2plugin${CMAKE_SHARED_MODULE_SUFFIX} - /nve2plugin${CMAKE_SHARED_MODULE_SUFFIX} - /helloplugin${CMAKE_SHARED_MODULE_SUFFIX} - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different - /morse2plugin${CMAKE_SHARED_MODULE_SUFFIX} - /nve2plugin${CMAKE_SHARED_MODULE_SUFFIX} - /helloplugin${CMAKE_SHARED_MODULE_SUFFIX} - ${CMAKE_CURRENT_BINARY_DIR} - TEST_COMMAND "") -endif() - add_executable(test_simple_commands test_simple_commands.cpp) -if(PKG_PLUGIN) + +# tests for the plugin command require the PLUGIN package and won't work on windows +if((NOT (CMAKE_SYSTEM_NAME STREQUAL "Windows")) AND PKG_PLUGIN) + add_subdirectory(${LAMMPS_DIR}/examples/plugins ${CMAKE_BINARY_DIR}/build-plugins) add_dependencies(test_simple_commands plugins) + target_compile_definitions(test_simple_commands PRIVATE -DLMP_PLUGIN) endif() -target_link_libraries(test_simple_commands PRIVATE lammps GTest::GMock GTest::GTest) + +target_link_libraries(test_simple_commands PRIVATE lammps GTest::GMock) add_test(NAME SimpleCommands COMMAND test_simple_commands WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +set_tests_properties(SimpleCommands PROPERTIES + ENVIRONMENT "LAMMPS_PLUGIN_BIN_DIR=${CMAKE_BINARY_DIR}/build-plugins") add_executable(test_lattice_region test_lattice_region.cpp) -target_link_libraries(test_lattice_region PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_lattice_region PRIVATE lammps GTest::GMock) add_test(NAME LatticeRegion COMMAND test_lattice_region WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_groups test_groups.cpp) -target_link_libraries(test_groups PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_groups PRIVATE lammps GTest::GMock) add_test(NAME Groups COMMAND test_groups WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_variables test_variables.cpp) -target_link_libraries(test_variables PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_variables PRIVATE lammps GTest::GMock) add_test(NAME Variables COMMAND test_variables WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_kim_commands test_kim_commands.cpp) @@ -49,17 +33,15 @@ if(KIM_EXTRA_UNITTESTS) message(FATAL_ERROR "CURL not found. Enabling KIM extra unit tests requires to have libcurl installed.") endif() endif() -target_link_libraries(test_kim_commands PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_kim_commands PRIVATE lammps GTest::GMock) add_test(NAME KimCommands COMMAND test_kim_commands WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 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 GTest::GTest) +target_link_libraries(test_reset_ids PRIVATE lammps GTest::GMock) add_test(NAME ResetIDs COMMAND test_reset_ids WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -if(BUILD_MPI) - add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) - target_link_libraries(test_mpi_load_balancing PRIVATE lammps GTest::GTest GTest::GMock) - target_compile_definitions(test_mpi_load_balancing PRIVATE ${TEST_CONFIG_DEFS}) - add_mpi_test(NAME MPILoadBalancing NUM_PROCS 4 COMMAND $) -endif() +add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) +target_link_libraries(test_mpi_load_balancing PRIVATE lammps GTest::GMock) +target_compile_definitions(test_mpi_load_balancing PRIVATE ${TEST_CONFIG_DEFS}) +add_mpi_test(NAME MPILoadBalancing NUM_PROCS 4 COMMAND $) diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index 0c8a7cd83c..52b93fe742 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -246,7 +246,7 @@ TEST_F(GroupTest, Molecular) ASSERT_DOUBLE_EQ(group->mass(group->find("half")), 40); ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->find_region("top")), 10); ASSERT_NEAR(group->charge(group->find("top")), 0, 1.0e-14); - ASSERT_DOUBLE_EQ(group->charge(group->find("right"), domain->find_region("top")), 0); + ASSERT_NEAR(group->charge(group->find("right"), domain->find_region("top")), 0, 1.0e-14); TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three include xxx");); } diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 0ad47f4e96..1844752d33 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -384,7 +384,12 @@ TEST_F(SimpleCommandsTest, Units) #if defined(LMP_PLUGIN) TEST_F(SimpleCommandsTest, Plugin) { - std::string loadfmt("plugin load {}plugin.so"); + const char *bindir = getenv("LAMMPS_PLUGIN_BIN_DIR"); + const char *config = getenv("CMAKE_CONFIG_TYPE"); + if (!bindir) GTEST_SKIP(); + std::string loadfmt = platform::path_join("plugin load ", bindir); + if (config) loadfmt = platform::path_join(loadfmt, config); + loadfmt = platform::path_join(loadfmt, "{}plugin.so"); ::testing::internal::CaptureStdout(); lmp->input->one(fmt::format(loadfmt, "hello")); auto text = ::testing::internal::GetCapturedStdout(); @@ -395,7 +400,7 @@ TEST_F(SimpleCommandsTest, Plugin) lmp->input->one(fmt::format(loadfmt, "xxx")); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Open of file xxx.* failed.*")); + ASSERT_THAT(text, MatchesRegex(".*Open of file .*xxx.* failed.*")); ::testing::internal::CaptureStdout(); lmp->input->one(fmt::format(loadfmt, "nve2")); @@ -426,8 +431,7 @@ TEST_F(SimpleCommandsTest, Plugin) lmp->input->one("plugin unload pair nve2"); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Ignoring unload of pair style nve2: " - "not loaded from a plugin.*")); + ASSERT_THAT(text, MatchesRegex(".*Ignoring unload of pair style nve2: not from a plugin.*")); ::testing::internal::CaptureStdout(); lmp->input->one("plugin unload fix nve2"); @@ -439,8 +443,7 @@ TEST_F(SimpleCommandsTest, Plugin) lmp->input->one("plugin unload fix nve"); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Ignoring unload of fix style nve: " - "not loaded from a plugin.*")); + ASSERT_THAT(text, MatchesRegex(".*Ignoring unload of fix style nve: not from a plugin.*")); ::testing::internal::CaptureStdout(); lmp->input->one("plugin list"); diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index 4f603df5ac..86d880f22c 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -59,8 +59,8 @@ protected: void TearDown() override { LAMMPSTest::TearDown(); - unlink("test_variable.file"); - unlink("test_variable.atomfile"); + platform::unlink("test_variable.file"); + platform::unlink("test_variable.atomfile"); } void atomic_system() @@ -165,7 +165,7 @@ TEST_F(VariableTest, CreateDelete) fputs(" ", fp); fclose(fp); ASSERT_THAT(variable->retrieve("file"), StrEq("1")); - unlink("MYFILE"); + platform::unlink("MYFILE"); ASSERT_THAT(variable->retrieve("file"), StrEq("0")); BEGIN_HIDE_OUTPUT(); diff --git a/unittest/cplusplus/CMakeLists.txt b/unittest/cplusplus/CMakeLists.txt index b0b2550e8c..efd194b9d2 100644 --- a/unittest/cplusplus/CMakeLists.txt +++ b/unittest/cplusplus/CMakeLists.txt @@ -1,13 +1,13 @@ add_executable(test_lammps_class test_lammps_class.cpp) -target_link_libraries(test_lammps_class PRIVATE lammps GTest::GMockMain GTest::GTest GTest::GMock) +target_link_libraries(test_lammps_class PRIVATE lammps GTest::GMockMain) add_test(LammpsClass test_lammps_class) set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=1") add_executable(test_input_class test_input_class.cpp) -target_link_libraries(test_input_class PRIVATE lammps GTest::GTest GTest::GTestMain) +target_link_libraries(test_input_class PRIVATE lammps GTest::GTestMain) add_test(InputClass test_input_class) add_executable(test_error_class test_error_class.cpp) -target_link_libraries(test_error_class PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_error_class PRIVATE lammps GTest::GMock) add_test(ErrorClass test_error_class) diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index 663c7358d9..3a1bde51ff 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -363,11 +363,7 @@ TEST(LAMMPS_init, NoOpenMP) FILE *fp = fopen("in.lammps_class_noomp", "w"); fputs("\n", fp); fclose(fp); -#if defined(__WIN32) - _putenv("OMP_NUM_THREADS"); -#else - unsetenv("OMP_NUM_THREADS"); -#endif + platform::unsetenv("OMP_NUM_THREADS"); const char *args[] = {"LAMMPS_init", "-in", "in.lammps_class_noomp", "-log", "none", "-nocite"}; char **argv = (char **)args; diff --git a/unittest/force-styles/CMakeLists.libyaml b/unittest/force-styles/CMakeLists.libyaml new file mode 100644 index 0000000000..51e8589f7b --- /dev/null +++ b/unittest/force-styles/CMakeLists.libyaml @@ -0,0 +1,34 @@ +# Custom minimal -*- CMake -*- file for libyaml + +cmake_minimum_required(VERSION 3.10) +project(libyaml VERSION 0.2.5 + DESCRIPTION "LibYAML a YAML parser and emitter library" + LANGUAGES C + HOMEPAGE_URL https://pyyaml.org/wiki/LibYAML) + +# compilation settings and options +option(BUILD_SHARED_LIBS "Build libYAML as a shared library" OFF) +option(CMAKE_POSITION_INDEPENDENT_CODE "Create objects compatible with shared libraries" ON) + +include(GNUInstallDirs) + +add_library(yaml + src/api.c + src/dumper.c + src/emitter.c + src/loader.c + src/parser.c + src/reader.c + src/scanner.c + src/writer.c + ) + +set(YAML_VERSION_STRING "${YAML_VERSION_MAJOR}.${YAML_VERSION_MINOR}.${YAML_VERSION_PATCH}") +set(CONFIG_H_FILE "#ifndef LIBYAML_CONFIG_H\n#define LIBYAML_CONFIG_H\n") +set(CONFIG_H_FILE "${CONFIG_H_FILE}#define YAML_VERSION_MAJOR ${libyaml_VERSION_MAJOR}\n") +set(CONFIG_H_FILE "${CONFIG_H_FILE}#define YAML_VERSION_MINOR ${libyaml_VERSION_MINOR}\n") +set(CONFIG_H_FILE "${CONFIG_H_FILE}#define YAML_VERSION_PATCH ${libyaml_VERSION_PATCH}\n") +set(CONFIG_H_FILE "${CONFIG_H_FILE}#define YAML_VERSION_STRING \"${libyaml_VERSION_MAJOR}.${libyaml_VERSION_MINOR}.${libyaml_VERSION_PATCH}\"\n#endif\n") +file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/include/config.h "${CONFIG_H_FILE}") +target_compile_definitions(yaml PRIVATE YAML_DECLARE_STATIC HAVE_CONFIG_H) +target_include_directories(yaml PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt index 75e95c3bf0..39730e6aeb 100644 --- a/unittest/force-styles/CMakeLists.txt +++ b/unittest/force-styles/CMakeLists.txt @@ -1,8 +1,15 @@ find_package(YAML) if(NOT YAML_FOUND) + set(YAML_URL "https://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz" CACHE STRING "URL for libyaml tarball") + set(YAML_MD5 "bb15429d8fb787e7d3f1c83ae129a999" CACHE STRING "MD5 checksum of libyaml tarball") + mark_as_advanced(YAML_URL) + mark_as_advanced(YAML_MD5) + # download and build a local copy of libyaml - include(YAML) + include(ExternalCMakeProject) + ExternalCMakeProject(libyaml ${YAML_URL} ${YAML_MD5} yaml . CMakeLists.libyaml) + add_library(Yaml::Yaml ALIAS yaml) endif() if(CMAKE_VERSION VERSION_LESS 3.12) @@ -24,9 +31,14 @@ endif() set(TEST_INPUT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/tests) add_library(style_tests STATIC yaml_writer.cpp error_stats.cpp test_config_reader.cpp test_main.cpp) -target_compile_definitions(style_tests PRIVATE -DTEST_INPUT_FOLDER=${TEST_INPUT_FOLDER}) +if(YAML_FOUND) + target_compile_definitions(style_tests PRIVATE TEST_INPUT_FOLDER=${TEST_INPUT_FOLDER}) +else() + # we always use static linkage with local compiled libyaml + target_compile_definitions(style_tests PRIVATE TEST_INPUT_FOLDER=${TEST_INPUT_FOLDER} YAML_DECLARE_STATIC) +endif() target_include_directories(style_tests PRIVATE ${LAMMPS_SOURCE_DIR}) -target_link_libraries(style_tests PUBLIC GTest::GTest GTest::GMock Yaml::Yaml lammps) +target_link_libraries(style_tests PUBLIC gmock Yaml::Yaml lammps) if(BUILD_MPI) target_link_libraries(style_tests PUBLIC MPI::MPI_CXX) else() @@ -43,7 +55,7 @@ endif() # unit test for error stats class add_executable(test_error_stats test_error_stats.cpp) target_include_directories(test_error_stats PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LAMMPS_SOURCE_DIR}) -target_link_libraries(test_error_stats PRIVATE GTest::GTestMain GTest::GTest) +target_link_libraries(test_error_stats PRIVATE gtest_main) add_test(NAME ErrorStats COMMAND test_error_stats) # pair style tester diff --git a/unittest/force-styles/test_error_stats.cpp b/unittest/force-styles/test_error_stats.cpp index 52ba3baae3..cadb4e7f2a 100644 --- a/unittest/force-styles/test_error_stats.cpp +++ b/unittest/force-styles/test_error_stats.cpp @@ -9,6 +9,11 @@ #include "fmtlib_format.cpp" #include "fmtlib_os.cpp" +// Windows may define this as a macro +#if defined(max) +#undef max +#endif + TEST(ErrorStats, test) { ErrorStats stats; diff --git a/unittest/force-styles/tests/atomic-pair-eim.yaml b/unittest/force-styles/tests/atomic-pair-eim.yaml index 4814029a3c..e705e88614 100644 --- a/unittest/force-styles/tests/atomic-pair-eim.yaml +++ b/unittest/force-styles/tests/atomic-pair-eim.yaml @@ -1,7 +1,7 @@ --- lammps_version: 10 Feb 2021 date_generated: Fri Feb 26 23:09:02 2021 -epsilon: 1e-11 +epsilon: 2e-11 prerequisites: ! | pair eim pre_commands: ! "" diff --git a/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml b/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml index 5caeee3dca..84b44bcb0a 100644 --- a/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml +++ b/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml @@ -14,7 +14,7 @@ post_commands: ! "" input_file: in.bilayer pair_style: hybrid/overlay lebedeva/z 16.0 pair_coeff: ! | - * * lebedeva/z CC.Lebedeva C C C + * * lebedeva/z CC.Lebedeva C1 C1 C1 extract: ! "" natoms: 48 init_vdwl: 2360.887727742073 diff --git a/unittest/force-styles/tests/manybody-pair-meam.yaml b/unittest/force-styles/tests/manybody-pair-meam.yaml index 4237f5ffc2..fed2a060cf 100644 --- a/unittest/force-styles/tests/manybody-pair-meam.yaml +++ b/unittest/force-styles/tests/manybody-pair-meam.yaml @@ -1,7 +1,7 @@ --- lammps_version: 10 Feb 2021 date_generated: Fri Feb 26 23:09:15 2021 -epsilon: 7.5e-12 +epsilon: 1e-10 prerequisites: ! | pair meam pre_commands: ! | diff --git a/unittest/formats/CMakeLists.txt b/unittest/formats/CMakeLists.txt index 93b48ac1b4..a17707fdf1 100644 --- a/unittest/formats/CMakeLists.txt +++ b/unittest/formats/CMakeLists.txt @@ -1,48 +1,48 @@ add_executable(test_atom_styles test_atom_styles.cpp) -target_link_libraries(test_atom_styles PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_atom_styles PRIVATE lammps GTest::GMock) add_test(NAME AtomStyles COMMAND test_atom_styles WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_image_flags test_image_flags.cpp) -target_link_libraries(test_image_flags PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_image_flags PRIVATE lammps GTest::GMock) add_test(NAME ImageFlags COMMAND test_image_flags WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_input_convert test_input_convert.cpp) -target_link_libraries(test_input_convert PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_input_convert PRIVATE lammps GTest::GMockMain) add_test(NAME InputConvert COMMAND test_input_convert WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_molecule_file test_molecule_file.cpp) -target_link_libraries(test_molecule_file PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_molecule_file PRIVATE lammps GTest::GMock) add_test(NAME MoleculeFile COMMAND test_molecule_file WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_pair_unit_convert test_pair_unit_convert.cpp) -target_link_libraries(test_pair_unit_convert PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_pair_unit_convert PRIVATE lammps GTest::GMock) add_test(NAME PairUnitConvert COMMAND test_pair_unit_convert WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(PairUnitConvert PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_potential_file_reader test_potential_file_reader.cpp) -target_link_libraries(test_potential_file_reader PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_potential_file_reader PRIVATE lammps GTest::GMock) add_test(NAME PotentialFileReader COMMAND test_potential_file_reader WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(PotentialFileReader PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") if(PKG_MANYBODY) add_executable(test_eim_potential_file_reader test_eim_potential_file_reader.cpp) - target_link_libraries(test_eim_potential_file_reader PRIVATE lammps GTest::GMock GTest::GTest) + target_link_libraries(test_eim_potential_file_reader PRIVATE lammps GTest::GMock) add_test(NAME EIMPotentialFileReader COMMAND test_eim_potential_file_reader WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(EIMPotentialFileReader PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") endif() add_executable(test_text_file_reader test_text_file_reader.cpp) -target_link_libraries(test_text_file_reader PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_text_file_reader PRIVATE lammps GTest::GMock) add_test(NAME TextFileReader COMMAND test_text_file_reader WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(TextFileReader PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_file_operations test_file_operations.cpp) -target_link_libraries(test_file_operations PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_file_operations PRIVATE lammps GTest::GMock) add_test(NAME FileOperations COMMAND test_file_operations WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_dump_atom test_dump_atom.cpp) -target_link_libraries(test_dump_atom PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_dump_atom PRIVATE lammps GTest::GMock) add_test(NAME DumpAtom COMMAND test_dump_atom WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(DumpAtom PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") @@ -50,19 +50,19 @@ if(PKG_COMPRESS) find_program(GZIP_BINARY NAMES gzip REQUIRED) add_executable(test_dump_atom_compressed test_dump_atom_compressed.cpp compressed_dump_test_main.cpp) - target_link_libraries(test_dump_atom_compressed PRIVATE lammps GTest::GMock GTest::GTest) + target_link_libraries(test_dump_atom_compressed PRIVATE lammps GTest::GMock) add_executable(test_dump_custom_compressed test_dump_custom_compressed.cpp compressed_dump_test_main.cpp) - target_link_libraries(test_dump_custom_compressed PRIVATE lammps GTest::GMock GTest::GTest) + target_link_libraries(test_dump_custom_compressed PRIVATE lammps GTest::GMock) add_executable(test_dump_cfg_compressed test_dump_cfg_compressed.cpp compressed_dump_test_main.cpp) - target_link_libraries(test_dump_cfg_compressed PRIVATE lammps GTest::GMock GTest::GTest) + target_link_libraries(test_dump_cfg_compressed PRIVATE lammps GTest::GMock) add_executable(test_dump_local_compressed test_dump_local_compressed.cpp compressed_dump_test_main.cpp) - target_link_libraries(test_dump_local_compressed PRIVATE lammps GTest::GMock GTest::GTest) + target_link_libraries(test_dump_local_compressed PRIVATE lammps GTest::GMock) add_executable(test_dump_xyz_compressed test_dump_xyz_compressed.cpp compressed_dump_test_main.cpp) - target_link_libraries(test_dump_xyz_compressed PRIVATE lammps GTest::GMock GTest::GTest) + target_link_libraries(test_dump_xyz_compressed PRIVATE lammps GTest::GMock) add_test(NAME DumpAtomGZ COMMAND test_dump_atom_compressed gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(DumpAtomGZ PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${GZIP_BINARY}") @@ -102,17 +102,17 @@ if(PKG_COMPRESS) endif() add_executable(test_dump_custom test_dump_custom.cpp) -target_link_libraries(test_dump_custom PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_dump_custom PRIVATE lammps GTest::GMock) add_test(NAME DumpCustom COMMAND test_dump_custom WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(DumpCustom PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_dump_cfg test_dump_cfg.cpp) -target_link_libraries(test_dump_cfg PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_dump_cfg PRIVATE lammps GTest::GMock) add_test(NAME DumpCfg COMMAND test_dump_cfg WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(DumpCfg PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_dump_local test_dump_local.cpp) -target_link_libraries(test_dump_local PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_dump_local PRIVATE lammps GTest::GMock) add_test(NAME DumpLocal COMMAND test_dump_local WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(DumpLocal PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") diff --git a/unittest/formats/test_text_file_reader.cpp b/unittest/formats/test_text_file_reader.cpp index f0f695ae54..6fcc21fb33 100644 --- a/unittest/formats/test_text_file_reader.cpp +++ b/unittest/formats/test_text_file_reader.cpp @@ -35,8 +35,8 @@ class TextFileReaderTest : public ::testing::Test { protected: void TearDown() override { - unlink("text_reader_one.file"); - unlink("text_reader_two.file"); + platform::unlink("text_reader_one.file"); + platform::unlink("text_reader_two.file"); } void test_files() @@ -65,16 +65,22 @@ TEST_F(TextFileReaderTest, nofile) FileReaderException); } +// this test cannot work on windows due to its non unix-like permission system + +#if !defined(_WIN32) TEST_F(TextFileReaderTest, permissions) { + platform::unlink("text_reader_noperms.file"); FILE *fp = fopen("text_reader_noperms.file", "w"); + ASSERT_NE(fp,nullptr); fputs("word\n", fp); fclose(fp); chmod("text_reader_noperms.file", 0); ASSERT_THROW({ TextFileReader reader("text_reader_noperms.file", "test"); }, FileReaderException); - unlink("text_reader_noperms.file"); + platform::unlink("text_reader_noperms.file"); } +#endif TEST_F(TextFileReaderTest, nofp) { diff --git a/unittest/fortran/CMakeLists.txt b/unittest/fortran/CMakeLists.txt index fc116c3c40..6e7e165018 100644 --- a/unittest/fortran/CMakeLists.txt +++ b/unittest/fortran/CMakeLists.txt @@ -25,11 +25,11 @@ if(CMAKE_Fortran_COMPILER) add_library(flammps STATIC ${LAMMPS_FORTRAN_MODULE}) add_executable(test_fortran_create wrap_create.cpp test_fortran_create.f90) - target_link_libraries(test_fortran_create PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTest GTest::GTestMain) + target_link_libraries(test_fortran_create PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) add_test(FortranOpen test_fortran_create) add_executable(test_fortran_commands wrap_commands.cpp test_fortran_commands.f90) - target_link_libraries(test_fortran_commands PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTest GTest::GTestMain) + target_link_libraries(test_fortran_commands PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) add_test(FortranCommands test_fortran_commands) else() message(STATUS "Skipping Tests for the LAMMPS Fortran Module: no Fortran compiler") diff --git a/unittest/python/CMakeLists.txt b/unittest/python/CMakeLists.txt index 5d0aad2f54..f61a9c61ab 100644 --- a/unittest/python/CMakeLists.txt +++ b/unittest/python/CMakeLists.txt @@ -21,7 +21,7 @@ else() endif() add_executable(test_python_package test_python_package.cpp) -target_link_libraries(test_python_package PRIVATE lammps GTest::GMock GTest::GTest) +target_link_libraries(test_python_package PRIVATE lammps GTest::GMock) target_compile_definitions(test_python_package PRIVATE -DTEST_INPUT_FOLDER=${TEST_INPUT_FOLDER}) # this requires CMake 3.12. don't care to add backward compatibility for this. if(Python3_Development_FOUND) @@ -34,12 +34,18 @@ set_tests_properties(PythonPackage PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${L if(Python_EXECUTABLE) # prepare to augment the environment so that the LAMMPS python module and the shared library is found. set(PYTHON_TEST_ENVIRONMENT PYTHONPATH=${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}) + get_property(BUILD_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(BUILD_IS_MULTI_CONFIG) + set(LAMMPS_LIB_PATH ${CMAKE_BINARY_DIR}/$) + else() + set(LAMMPS_LIB_PATH ${CMAKE_BINARY_DIR}) + endif() list(APPEND PYTHON_TEST_ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") list(APPEND PYTHON_TEST_ENVIRONMENT "TEST_INPUT_DIR=${CMAKE_CURRENT_SOURCE_DIR}") if(APPLE) - list(APPEND PYTHON_TEST_ENVIRONMENT "DYLD_LIBRARY_PATH=${CMAKE_BINARY_DIR}:$ENV{DYLD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") + list(APPEND PYTHON_TEST_ENVIRONMENT "DYLD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{DYLD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") else() - list(APPEND PYTHON_TEST_ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}:$ENV{LD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") + list(APPEND PYTHON_TEST_ENVIRONMENT "LD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{LD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") endif() if(LAMMPS_MACHINE) # convert from '_machine' to 'machine' diff --git a/unittest/utils/CMakeLists.txt b/unittest/utils/CMakeLists.txt index 9f708861cc..28486048c4 100644 --- a/unittest/utils/CMakeLists.txt +++ b/unittest/utils/CMakeLists.txt @@ -1,21 +1,21 @@ add_executable(test_tokenizer test_tokenizer.cpp) -target_link_libraries(test_tokenizer PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_tokenizer PRIVATE lammps GTest::GMockMain) add_test(Tokenizer test_tokenizer) add_executable(test_mempool test_mempool.cpp) -target_link_libraries(test_mempool PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_mempool PRIVATE lammps GTest::GMockMain) add_test(MemPool test_mempool) add_executable(test_argutils test_argutils.cpp) -target_link_libraries(test_argutils PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_argutils PRIVATE lammps GTest::GMockMain) add_test(ArgUtils test_argutils) add_executable(test_utils test_utils.cpp) -target_link_libraries(test_utils PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_utils PRIVATE lammps GTest::GMockMain) add_test(Utils test_utils) add_executable(test_platform test_platform.cpp) -target_link_libraries(test_platform PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_platform PRIVATE lammps GTest::GMockMain) add_test(Platform test_platform) set_tests_properties(Utils Platform PROPERTIES @@ -34,7 +34,7 @@ if(BUILD_SHARED_LIBS) endif() add_executable(test_fmtlib test_fmtlib.cpp) -target_link_libraries(test_fmtlib PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest) +target_link_libraries(test_fmtlib PRIVATE lammps GTest::GMockMain) add_test(FmtLib test_fmtlib) add_executable(test_math_eigen_impl test_math_eigen_impl.cpp) diff --git a/unittest/utils/test_math_eigen_impl.cpp b/unittest/utils/test_math_eigen_impl.cpp index 895a35080c..47ca8d9cca 100644 --- a/unittest/utils/test_math_eigen_impl.cpp +++ b/unittest/utils/test_math_eigen_impl.cpp @@ -48,7 +48,7 @@ inline static bool SimilarVec(Vector a, Vector b, int n, Scalar eps = 1.0e-06, Scalar ratio = 1.0e-06, Scalar ratio_denom = 1.0) { for (int i = 0; i < n; i++) - if (not Similar(a[i], b[i], eps, ratio, ratio_denom)) return false; + if (! Similar(a[i], b[i], eps, ratio, ratio_denom)) return false; return true; } @@ -61,7 +61,7 @@ inline static bool SimilarVecUnsigned(Vector a, Vector b, int n, Scalar eps = 1. return true; else { for (int i = 0; i < n; i++) - if (not Similar(a[i], -b[i], eps, ratio, ratio_denom)) return false; + if (! Similar(a[i], -b[i], eps, ratio, ratio_denom)) return false; return true; } } diff --git a/unittest/utils/test_platform.cpp b/unittest/utils/test_platform.cpp index 0f39534c31..ace546ba90 100644 --- a/unittest/utils/test_platform.cpp +++ b/unittest/utils/test_platform.cpp @@ -37,7 +37,7 @@ TEST(Platform, clock) ASSERT_GT(ct_used, 1e-4); } -TEST(Platform, putenv) +TEST(Platform, putenv_unsetenv) { const char *var = getenv("UNITTEST_VAR1"); ASSERT_EQ(var, nullptr); @@ -65,6 +65,14 @@ TEST(Platform, putenv) ASSERT_THAT(var, StrEq("one=two")); ASSERT_EQ(platform::putenv(""), -1); + + ASSERT_EQ(platform::unsetenv(""), -1); + ASSERT_EQ(platform::unsetenv("UNITTEST_VAR3=two"), -1); + var = getenv("UNITTEST_VAR1"); + ASSERT_NE(var, nullptr); + ASSERT_EQ(platform::unsetenv("UNITTEST_VAR1"), 0); + var = getenv("UNITTEST_VAR1"); + ASSERT_EQ(var, nullptr); } TEST(Platform, list_pathenv)