diff --git a/.github/workflows/compile-msvc.yml b/.github/workflows/compile-msvc.yml index e8cfcd4788..e71a2950e6 100644 --- a/.github/workflows/compile-msvc.yml +++ b/.github/workflows/compile-msvc.yml @@ -1,5 +1,5 @@ # GitHub action to build LAMMPS on Windows with Visual C++ -name: "Native Windows Compilation" +name: "Native Windows Compilation and Unit Tests" on: push: @@ -23,7 +23,8 @@ jobs: cmake -C cmake/presets/windows.cmake \ -S cmake -B build \ -D BUILD_SHARED_LIBS=on \ - -D LAMMPS_EXCEPTIONS=on + -D LAMMPS_EXCEPTIONS=on \ + -D ENABLE_TESTING=on cmake --build build --config Release - name: Run LAMMPS executable @@ -31,3 +32,8 @@ jobs: run: | ./build/Release/lmp.exe -h ./build/Release/lmp.exe -in bench/in.lj + + - name: Run Unit Tests + working-directory: build + shell: bash + run: ctest -V -C Release diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 408528f6dd..7ee4563b6e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -19,6 +19,9 @@ set(SOVERSION 0) get_filename_component(LAMMPS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE) get_filename_component(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib ABSOLUTE) +# collect all executables and shared libs in the top level build folder +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(LAMMPS_SOURCE_DIR ${LAMMPS_DIR}/src) set(LAMMPS_LIB_SOURCE_DIR ${LAMMPS_DIR}/lib) @@ -280,35 +283,19 @@ if(BUILD_MPI) # We use a non-standard procedure to cross-compile with MPI on Windows if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING) include(MPI4WIN) - target_link_libraries(lammps PUBLIC MPI::MPI_CXX) else() find_package(MPI REQUIRED) - target_link_libraries(lammps PUBLIC MPI::MPI_CXX) option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize 'long long' data types" OFF) if(LAMMPS_LONGLONG_TO_LONG) target_compile_definitions(lammps PRIVATE -DLAMMPS_LONGLONG_TO_LONG) endif() endif() + target_link_libraries(lammps PUBLIC MPI::MPI_CXX) else() - file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.cpp) - add_library(mpi_stubs STATIC ${MPI_SOURCES}) - set_target_properties(mpi_stubs PROPERTIES OUTPUT_NAME lammps_mpi_stubs${LAMMPS_MACHINE}) - target_include_directories(mpi_stubs PUBLIC $) - if(BUILD_SHARED_LIBS) - target_link_libraries(lammps PRIVATE mpi_stubs) - if(MSVC) - target_link_libraries(lmp PRIVATE mpi_stubs) - target_include_directories(lmp INTERFACE $) - target_compile_definitions(lmp INTERFACE $) - 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) + target_sources(lammps PRIVATE ${LAMMPS_SOURCE_DIR}/STUBS/mpi.cpp) + add_library(mpi_stubs INTERFACE) + target_include_directories(mpi_stubs INTERFACE $) + target_link_libraries(lammps PUBLIC mpi_stubs) endif() set(LAMMPS_SIZES "smallbig" CACHE STRING "LAMMPS integer sizes (smallsmall: all 32-bit, smallbig: 64-bit #atoms #timesteps, bigbig: also 64-bit imageint, 64-bit atom ids)") @@ -590,11 +577,10 @@ if(PKG_ATC) if(LAMMPS_SIZES STREQUAL "BIGBIG") message(FATAL_ERROR "The ATC Package is not compatible with -DLAMMPS_BIGBIG") endif() - target_link_libraries(atc PRIVATE ${LAPACK_LIBRARIES}) if(BUILD_MPI) - target_link_libraries(atc PRIVATE MPI::MPI_CXX) + target_link_libraries(atc PRIVATE ${LAPACK_LIBRARIES} MPI::MPI_CXX) else() - target_link_libraries(atc PRIVATE mpi_stubs) + target_link_libraries(atc PRIVATE ${LAPACK_LIBRARIES} mpi_stubs) endif() target_include_directories(atc PRIVATE ${LAMMPS_SOURCE_DIR}) target_compile_definitions(atc PRIVATE -DLAMMPS_${LAMMPS_SIZES}) @@ -690,6 +676,7 @@ endif() set_target_properties(lammps PROPERTIES OUTPUT_NAME lammps${LAMMPS_MACHINE}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) +set_target_properties(lammps PROPERTIES PREFIX "lib") target_include_directories(lammps PUBLIC $) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/includes/lammps) foreach(_HEADER ${LAMMPS_CXX_HEADERS}) @@ -709,6 +696,9 @@ foreach(_DEF ${LAMMPS_DEFINES}) endforeach() if(BUILD_SHARED_LIBS) install(TARGETS lammps EXPORT LAMMPS_Targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + if(NOT BUILD_MPI) + install(TARGETS mpi_stubs EXPORT LAMMPS_Targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() configure_file(pkgconfig/liblammps.pc.in ${CMAKE_CURRENT_BINARY_DIR}/liblammps${LAMMPS_MACHINE}.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/liblammps${LAMMPS_MACHINE}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(EXPORT LAMMPS_Targets FILE LAMMPS_Targets.cmake NAMESPACE LAMMPS:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LAMMPS) diff --git a/cmake/Modules/Packages/GPU.cmake b/cmake/Modules/Packages/GPU.cmake index 048c0ed473..fe15917f47 100644 --- a/cmake/Modules/Packages/GPU.cmake +++ b/cmake/Modules/Packages/GPU.cmake @@ -422,13 +422,12 @@ RegisterStylesExt(${GPU_SOURCES_DIR} gpu GPU_SOURCES) RegisterFixStyle(${GPU_SOURCES_DIR}/fix_gpu.h) get_property(GPU_SOURCES GLOBAL PROPERTY GPU_SOURCES) - -if(NOT BUILD_MPI) - # mpistubs is aliased to MPI::MPI_CXX, but older versions of cmake won't work forward the include path - target_link_libraries(gpu PRIVATE mpi_stubs) -else() +if(BUILD_MPI) target_link_libraries(gpu PRIVATE MPI::MPI_CXX) +else() + target_link_libraries(gpu PRIVATE mpi_stubs) endif() + target_compile_definitions(gpu PRIVATE -DLAMMPS_${LAMMPS_SIZES}) set_target_properties(gpu PROPERTIES OUTPUT_NAME lammps_gpu${LAMMPS_MACHINE}) target_sources(lammps PRIVATE ${GPU_SOURCES}) diff --git a/cmake/Modules/Packages/KOKKOS.cmake b/cmake/Modules/Packages/KOKKOS.cmake index 25211268e9..ebc5adff5b 100644 --- a/cmake/Modules/Packages/KOKKOS.cmake +++ b/cmake/Modules/Packages/KOKKOS.cmake @@ -109,6 +109,12 @@ if(PKG_KSPACE) endif() endif() + +if(PKG_PHONON) + list(APPEND KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/dynamical_matrix_kokkos.cpp) + list(APPEND KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/third_order_kokkos.cpp) +endif() + set_property(GLOBAL PROPERTY "KOKKOS_PKG_SOURCES" "${KOKKOS_PKG_SOURCES}") # detects styles which have KOKKOS version diff --git a/cmake/Modules/generate_lmpgitversion.cmake b/cmake/Modules/generate_lmpgitversion.cmake index b19716d74b..f066269723 100644 --- a/cmake/Modules/generate_lmpgitversion.cmake +++ b/cmake/Modules/generate_lmpgitversion.cmake @@ -24,10 +24,10 @@ if(GIT_FOUND AND EXISTS ${LAMMPS_DIR}/.git) OUTPUT_STRIP_TRAILING_WHITESPACE) endif() -set(temp "${temp}const bool LAMMPS_NS::LAMMPS::has_git_info = ${temp_git_info};\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_commit[] = \"${temp_git_commit}\";\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_branch[] = \"${temp_git_branch}\";\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_descriptor[] = \"${temp_git_describe}\";\n") +set(temp "${temp}bool LAMMPS_NS::LAMMPS::has_git_info() { return ${temp_git_info}; }\n") +set(temp "${temp}const char *LAMMPS_NS::LAMMPS::git_commit() { return \"${temp_git_commit}\"; }\n") +set(temp "${temp}const char *LAMMPS_NS::LAMMPS::git_branch() { return \"${temp_git_branch}\"; }\n") +set(temp "${temp}const char *LAMMPS_NS::LAMMPS::git_descriptor() { return \"${temp_git_describe}\"; }\n") set(temp "${temp}#endif\n\n") message(STATUS "Generating lmpgitversion.h...") diff --git a/cmake/presets/gcc.cmake b/cmake/presets/gcc.cmake index c2dbacf674..cb626ea019 100644 --- a/cmake/presets/gcc.cmake +++ b/cmake/presets/gcc.cmake @@ -3,19 +3,19 @@ set(CMAKE_CXX_COMPILER "g++" CACHE STRING "" FORCE) set(CMAKE_C_COMPILER "gcc" CACHE STRING "" FORCE) set(CMAKE_Fortran_COMPILER "gfortran" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Og -g" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2 -DNDEBUG" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "" FORCE) set(MPI_CXX "g++" CACHE STRING "" FORCE) set(MPI_CXX_COMPILER "mpicxx" CACHE STRING "" FORCE) set(MPI_C "gcc" CACHE STRING "" FORCE) set(MPI_C_COMPILER "mpicc" CACHE STRING "" FORCE) -set(CMAKE_C_FLAGS_DEBUG "-Wall -g" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS_DEBUG "-Wall -Og -g" CACHE STRING "" FORCE) set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -O2 -DNDEBUG" CACHE STRING "" FORCE) set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "" FORCE) set(MPI_Fortran "gfortran" CACHE STRING "" FORCE) set(MPI_Fortran_COMPILER "mpifort" CACHE STRING "" FORCE) -set(CMAKE_Fortran_FLAGS_DEBUG "-Wall -g -std=f2003" CACHE STRING "" FORCE) +set(CMAKE_Fortran_FLAGS_DEBUG "-Wall -Og -g -std=f2003" CACHE STRING "" FORCE) set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-g -O2 -DNDEBUG -std=f2003" CACHE STRING "" FORCE) set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -DNDEBUG -std=f2003" CACHE STRING "" FORCE) unset(HAVE_OMP_H_INCLUDE CACHE) diff --git a/doc/src/Commands_all.rst b/doc/src/Commands_all.rst index c708228be7..8995ffdcc4 100644 --- a/doc/src/Commands_all.rst +++ b/doc/src/Commands_all.rst @@ -47,7 +47,7 @@ An alphabetic list of all general LAMMPS commands. * :doc:`displace_atoms ` * :doc:`dump ` * :doc:`dump_modify ` - * :doc:`dynamical_matrix ` + * :doc:`dynamical_matrix (k) ` * :doc:`echo ` * :doc:`fix ` * :doc:`fix_modify ` @@ -117,7 +117,7 @@ An alphabetic list of all general LAMMPS commands. * :doc:`thermo ` * :doc:`thermo_modify ` * :doc:`thermo_style ` - * :doc:`third_order ` + * :doc:`third_order (k) ` * :doc:`timer ` * :doc:`timestep ` * :doc:`uncompute ` diff --git a/doc/src/dynamical_matrix.rst b/doc/src/dynamical_matrix.rst index 37b9e5b4a5..93e4c2a1aa 100644 --- a/doc/src/dynamical_matrix.rst +++ b/doc/src/dynamical_matrix.rst @@ -1,8 +1,11 @@ .. index:: dynamical_matrix +.. index:: dynamical_matrix/kk dynamical_matrix command ======================== +Accelerator Variants: dynamical_matrix/kk + Syntax """""" @@ -56,6 +59,12 @@ If the style eskm is selected, the dynamical matrix will be in units of inverse squared femtoseconds. These units will then conveniently leave frequencies in THz. +---------- + +.. include:: accel_styles.rst + +---------- + Restrictions """""""""""" diff --git a/doc/src/third_order.rst b/doc/src/third_order.rst index f020511aad..b163844365 100644 --- a/doc/src/third_order.rst +++ b/doc/src/third_order.rst @@ -1,8 +1,11 @@ .. index:: third_order +.. index:: third_order/kk third_order command =================== +Accelerator Variants: third_order/kk + Syntax """""" @@ -49,6 +52,12 @@ If the style eskm is selected, the tensor will be using energy units of 10 J/mol These units conform to eskm style from the dynamical_matrix command, which will simplify operations using dynamical matrices with third order tensors. +---------- + +.. include:: accel_styles.rst + +---------- + Restrictions """""""""""" diff --git a/examples/PACKAGES/cgdna/examples/test.sh b/examples/PACKAGES/cgdna/examples/test.sh index 795be9ef88..152047b94b 100755 --- a/examples/PACKAGES/cgdna/examples/test.sh +++ b/examples/PACKAGES/cgdna/examples/test.sh @@ -1,20 +1,24 @@ #! /bin/bash -DATE='2Jul21' -LMPDIR=/Users/ohenrich/Work/code/lammps +DATE='14Dec21' +TOL=1e-8 +LMPDIR=/Users/ohenrich/Work/code/lammps SRCDIR=$LMPDIR/src EXDIR=$LMPDIR/examples/PACKAGES/cgdna/examples if [ $# -eq 1 ] && [ $1 = run ]; then - echo '# Compiling executable in' $SRCDIR + echo '# Compiling executable in' $SRCDIR | tee -a $EXDIR/test.log cd $SRCDIR - make clean-all - make -j8 mpi + make clean-all | tee -a $EXDIR/test.log + make purge | tee -a $EXDIR/test.log + make pu | tee -a $EXDIR/test.log + make ps | tee -a $EXDIR/test.log + make -j8 mpi | tee -a $EXDIR/test.log ###################################################### - echo '# Running oxDNA duplex1 test' + echo '# Running oxDNA duplex1 test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA/duplex1 mkdir test cd test @@ -24,20 +28,32 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex1 > /dev/null mv log.lammps log.$DATE.duplex1.g++.1 - grep etot log.$DATE.duplex1.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex1.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex1 > /dev/null mv log.lammps log.$DATE.duplex1.g++.4 - grep etot log.$DATE.duplex1.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex1.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxDNA duplex2 test' + echo '# Running oxDNA duplex2 test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA/duplex2 mkdir test cd test @@ -47,20 +63,32 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex2 > /dev/null mv log.lammps log.$DATE.duplex2.g++.1 - grep etot log.$DATE.duplex2.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex2.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex2 > /dev/null mv log.lammps log.$DATE.duplex2.g++.4 - grep etot log.$DATE.duplex2.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex2.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxDNA2 duplex1 test' + echo '# Running oxDNA2 duplex1 test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA2/duplex1 mkdir test cd test @@ -70,20 +98,32 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex1 > /dev/null mv log.lammps log.$DATE.duplex1.g++.1 - grep etot log.$DATE.duplex1.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex1.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex1 > /dev/null mv log.lammps log.$DATE.duplex1.g++.4 - grep etot log.$DATE.duplex1.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex1.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxDNA2 duplex2 test' + echo '# Running oxDNA2 duplex2 test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA2/duplex2 mkdir test cd test @@ -93,20 +133,32 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex2 > /dev/null mv log.lammps log.$DATE.duplex2.g++.1 - grep etot log.$DATE.duplex2.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex2.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex2 > /dev/null mv log.lammps log.$DATE.duplex2.g++.4 - grep etot log.$DATE.duplex2.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex2.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxDNA2 duplex3 test' + echo '# Running oxDNA2 duplex3 test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA2/duplex3 mkdir test cd test @@ -116,20 +168,32 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex3 > /dev/null mv log.lammps log.$DATE.duplex3.g++.1 - grep etot log.$DATE.duplex3.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex3.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex3 > /dev/null mv log.lammps log.$DATE.duplex3.g++.4 - grep etot log.$DATE.duplex3.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex3.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxDNA2 unique_bp test' + echo '# Running oxDNA2 unique_bp test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA2/unique_bp mkdir test cd test @@ -141,32 +205,56 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex4.4type > /dev/null mv log.lammps log.$DATE.duplex4.4type.g++.1 - grep etot log.$DATE.duplex4.4type.g++.1 > e_test.dat - grep etot ../log*4type*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex4.4type.g++.1 > e_test.4type.1.dat + grep etot ../log*4type*1 > e_old.4type.1.dat + ndiff -relerr $TOL e_test.4type.1.dat e_old.4type.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task 4 types passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task 4 types unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex4.4type > /dev/null mv log.lammps log.$DATE.duplex4.4type.g++.4 - grep etot log.$DATE.duplex4.4type.g++.4 > e_test.dat - grep etot ../log*4type*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex4.4type.g++.4 > e_test.4type.4.dat + grep etot ../log*4type*4 > e_old.4type.4.dat + ndiff -relerr $TOL e_test.4type.4.dat e_old.4type.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks 4 types passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks 4 types unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 1 ./lmp_mpi < in.duplex4.8type > /dev/null mv log.lammps log.$DATE.duplex4.8type.g++.1 - grep etot log.$DATE.duplex4.8type.g++.1 > e_test.dat - grep etot ../log*8type*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex4.8type.g++.1 > e_test.8type.1.dat + grep etot ../log*8type*1 > e_old.8type.1.dat + ndiff -relerr $TOL e_test.8type.1.dat e_old.8type.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task 8 types passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task 8 types unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex4.8type > /dev/null mv log.lammps log.$DATE.duplex4.8type.g++.4 - grep etot log.$DATE.duplex4.8type.g++.4 > e_test.dat - grep etot ../log*8type*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex4.8type.g++.4 > e_test.8type.4.dat + grep etot ../log*8type*4 > e_old.8type.4.dat + ndiff -relerr $TOL e_test.8type.4.dat e_old.8type.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks 8 types passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks 8 types unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxDNA2 dsring test' + echo '# Running oxDNA2 dsring test' | tee -a $EXDIR/test.log cd $EXDIR/oxDNA2/dsring mkdir test cd test @@ -176,20 +264,32 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.dsring > /dev/null mv log.lammps log.$DATE.dsring.g++.1 - grep etot log.$DATE.dsring.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.dsring.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.dsring > /dev/null mv log.lammps log.$DATE.dsring.g++.4 - grep etot log.$DATE.dsring.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.dsring.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### ###################################################### - echo '# Running oxRNA2 duplex2 test' + echo '# Running oxRNA2 duplex2 test' | tee -a $EXDIR/test.log cd $EXDIR/oxRNA2/duplex2 mkdir test cd test @@ -199,18 +299,30 @@ if [ $# -eq 1 ] && [ $1 = run ]; then mpirun -np 1 ./lmp_mpi < in.duplex2 > /dev/null mv log.lammps log.$DATE.duplex2.g++.1 - grep etot log.$DATE.duplex2.g++.1 > e_test.dat - grep etot ../log*1 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex2.g++.1 > e_test.1.dat + grep etot ../log*1 > e_old.1.dat + ndiff -relerr $TOL e_test.1.dat e_old.1.dat + if [ $? -eq 0 ]; + then + echo "# 1 MPI-task passed" | tee -a $EXDIR/test.log + else + echo "# 1 MPI-task unsuccessful" | tee -a $EXDIR/test.log + fi mpirun -np 4 ./lmp_mpi < in.duplex2 > /dev/null mv log.lammps log.$DATE.duplex2.g++.4 - grep etot log.$DATE.duplex2.g++.4 > e_test.dat - grep etot ../log*4 > e_old.dat - ndiff -relerr 1e-8 e_test.dat e_old.dat + grep etot log.$DATE.duplex2.g++.4 > e_test.4.dat + grep etot ../log*4 > e_old.4.dat + ndiff -relerr $TOL e_test.4.dat e_old.4.dat + if [ $? -eq 0 ]; + then + echo "# 4 MPI-tasks passed" | tee -a $EXDIR/test.log + else + echo "# 4 MPI-tasks unsuccessful" | tee -a $EXDIR/test.log + fi ###################################################### - echo '# Done' + echo '# Done' | tee -a $EXDIR/test.log elif [ $# -eq 1 ] && [ $1 = clean ]; then echo '# Deleting test directories' @@ -222,6 +334,7 @@ elif [ $# -eq 1 ] && [ $1 = clean ]; then rm -rf $EXDIR/oxDNA2/unique_bp/test rm -rf $EXDIR/oxDNA2/dsring/test rm -rf $EXDIR/oxRNA2/duplex2/test + rm -rf $EXDIR/test.log echo '# Done' else diff --git a/python/lammps/core.py b/python/lammps/core.py index 0bc8d0cb3f..62b0f5d8b6 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -89,6 +89,9 @@ class lammps(object): modpath = dirname(abspath(getsourcefile(lambda:0))) # for windows installers the shared library is in a different folder winpath = abspath(os.path.join(modpath,'..','..','bin')) + # allow override for running tests on Windows + if (os.environ.get("LAMMPSDLLPATH")): + winpath = os.environ.get("LAMMPSDLLPATH") self.lib = None self.lmp = None diff --git a/src/CG-DNA/bond_oxdna_fene.cpp b/src/CG-DNA/bond_oxdna_fene.cpp index 6b720f6a7f..4db0fb4cf1 100644 --- a/src/CG-DNA/bond_oxdna_fene.cpp +++ b/src/CG-DNA/bond_oxdna_fene.cpp @@ -26,6 +26,7 @@ #include "atom_vec_ellipsoid.h" #include "math_extra.h" +#include "pair.h" #include @@ -145,16 +146,16 @@ void BondOxdnaFene::ev_tally_xyz(int i, int j, int nlocal, int newton_bond, doub ------------------------------------------------------------------------- */ void BondOxdnaFene::compute(int eflag, int vflag) { - int a, b, in, type; - double delf[3], delta[3], deltb[3]; // force, torque increment;; - double delr[3], ebond, fbond; - double rsq, Deltasq, rlogarg; - double r, rr0, rr0sq; + int a,b,in,type; + double delf[3],delta[3],deltb[3]; // force, torque increment;; + double delr[3],ebond,fbond; + double rsq,Deltasq,rlogarg; + double r,rr0,rr0sq; // vectors COM-backbone site in lab frame - double ra_cs[3], rb_cs[3]; - - double *qa, ax[3], ay[3], az[3]; - double *qb, bx[3], by[3], bz[3]; + double ra_cs[3],rb_cs[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -172,6 +173,12 @@ void BondOxdnaFene::compute(int eflag, int vflag) ebond = 0.0; ev_init(eflag, vflag); + // n(x/y/z)_xtrct = extracted local unit vectors in lab frame from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over FENE bonds for (in = 0; in < nbondlist; in++) { @@ -180,10 +187,24 @@ void BondOxdnaFene::compute(int eflag, int vflag) b = bondlist[in][0]; type = bondlist[in][2]; - qa = bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa, ax, ay, az); - qb = bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb, bx, by, bz); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; + ay[0] = ny_xtrct[a][0]; + ay[1] = ny_xtrct[a][1]; + ay[2] = ny_xtrct[a][2]; + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; + by[0] = ny_xtrct[b][0]; + by[1] = ny_xtrct[b][1]; + by[2] = ny_xtrct[b][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; // vector COM-backbone site a and b compute_interaction_sites(ax, ay, az, ra_cs); diff --git a/src/CG-DNA/bond_oxdna_fene.h b/src/CG-DNA/bond_oxdna_fene.h index d2e4eed183..d2aa84612a 100644 --- a/src/CG-DNA/bond_oxdna_fene.h +++ b/src/CG-DNA/bond_oxdna_fene.h @@ -40,6 +40,7 @@ class BondOxdnaFene : public Bond { protected: double *k, *Delta, *r0; // FENE + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors void allocate(); void ev_tally_xyz(int, int, int, int, double, double, double, double, double, double, double); diff --git a/src/CG-DNA/pair_oxdna2_coaxstk.cpp b/src/CG-DNA/pair_oxdna2_coaxstk.cpp index e8ab197be1..8b3609983b 100644 --- a/src/CG-DNA/pair_oxdna2_coaxstk.cpp +++ b/src/CG-DNA/pair_oxdna2_coaxstk.cpp @@ -118,9 +118,9 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) double ra_cs[3],ra_cst[3]; double rb_cs[3],rb_cst[3]; - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -149,6 +149,11 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // n(x/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -156,8 +161,9 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; // vector COM a - stacking site a ra_cst[0] = d_cst*ax[0]; @@ -180,8 +186,9 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; // vector COM b - stacking site b rb_cst[0] = d_cst*bx[0]; @@ -232,6 +239,13 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) // early rejection criterium if (f4f6t1) { + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; + cost4 = MathExtra::dot3(az,bz); if (cost4 > 1.0) cost4 = 1.0; if (cost4 < -1.0) cost4 = -1.0; @@ -306,7 +320,7 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) DF4(theta6p, a_cxst6[atype][btype], theta_cxst6_0[atype][btype], dtheta_cxst6_ast[atype][btype], b_cxst6[atype][btype], dtheta_cxst6_c[atype][btype])*rsint; - // force, torque and virial contribution for forces between stacking sites + // force, torque and virial contribution for forces between stacking sites fpair = 0.0; diff --git a/src/CG-DNA/pair_oxdna2_coaxstk.h b/src/CG-DNA/pair_oxdna2_coaxstk.h index 4fe52b6e9b..6bf763a1fe 100644 --- a/src/CG-DNA/pair_oxdna2_coaxstk.h +++ b/src/CG-DNA/pair_oxdna2_coaxstk.h @@ -46,20 +46,16 @@ class PairOxdna2Coaxstk : public Pair { double **k_cxst, **cut_cxst_0, **cut_cxst_c, **cut_cxst_lo, **cut_cxst_hi; double **cut_cxst_lc, **cut_cxst_hc, **b_cxst_lo, **b_cxst_hi; double **cutsq_cxst_hc; - double **a_cxst1, **theta_cxst1_0, **dtheta_cxst1_ast; double **b_cxst1, **dtheta_cxst1_c; - double **a_cxst4, **theta_cxst4_0, **dtheta_cxst4_ast; double **b_cxst4, **dtheta_cxst4_c; - double **a_cxst5, **theta_cxst5_0, **dtheta_cxst5_ast; double **b_cxst5, **dtheta_cxst5_c; - double **a_cxst6, **theta_cxst6_0, **dtheta_cxst6_ast; double **b_cxst6, **dtheta_cxst6_c; - double **AA_cxst1, **BB_cxst1; + double **nx_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors virtual void allocate(); }; diff --git a/src/CG-DNA/pair_oxdna2_dh.cpp b/src/CG-DNA/pair_oxdna2_dh.cpp index 1a587e82e1..cf79fd07cf 100644 --- a/src/CG-DNA/pair_oxdna2_dh.cpp +++ b/src/CG-DNA/pair_oxdna2_dh.cpp @@ -87,10 +87,9 @@ void PairOxdna2Dh::compute(int eflag, int vflag) // vectors COM-backbone sites in lab frame double ra_cs[3],rb_cs[3]; - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; - double *special_lj = force->special_lj; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -100,6 +99,7 @@ void PairOxdna2Dh::compute(int eflag, int vflag) int nlocal = atom->nlocal; int newton_pair = force->newton_pair; int *alist,*blist,*numneigh,**firstneigh; + double *special_lj = force->special_lj; AtomVecEllipsoid *avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); AtomVecEllipsoid::Bonus *bonus = avec->bonus; @@ -115,6 +115,12 @@ void PairOxdna2Dh::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // n(x/y/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -122,8 +128,15 @@ void PairOxdna2Dh::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; + ay[0] = ny_xtrct[a][0]; + ay[1] = ny_xtrct[a][1]; + ay[2] = ny_xtrct[a][2]; + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; // vector COM-backbone site a compute_interaction_sites(ax,ay,az,ra_cs); @@ -142,8 +155,15 @@ void PairOxdna2Dh::compute(int eflag, int vflag) b &= NEIGHMASK; btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; + by[0] = ny_xtrct[b][0]; + by[1] = ny_xtrct[b][1]; + by[2] = ny_xtrct[b][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; // vector COM-backbone site b compute_interaction_sites(bx,by,bz,rb_cs); diff --git a/src/CG-DNA/pair_oxdna2_dh.h b/src/CG-DNA/pair_oxdna2_dh.h index 5c79641935..db37ba0d43 100644 --- a/src/CG-DNA/pair_oxdna2_dh.h +++ b/src/CG-DNA/pair_oxdna2_dh.h @@ -45,6 +45,7 @@ class PairOxdna2Dh : public Pair { protected: double **qeff_dh_pf, **kappa_dh; double **b_dh, **cut_dh_ast, **cutsq_dh_ast, **cut_dh_c, **cutsq_dh_c; + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors virtual void allocate(); }; diff --git a/src/CG-DNA/pair_oxdna_coaxstk.cpp b/src/CG-DNA/pair_oxdna_coaxstk.cpp index 2715b7c5e2..49b25bb81b 100644 --- a/src/CG-DNA/pair_oxdna_coaxstk.cpp +++ b/src/CG-DNA/pair_oxdna_coaxstk.cpp @@ -106,7 +106,6 @@ PairOxdnaCoaxstk::~PairOxdnaCoaxstk() void PairOxdnaCoaxstk::compute(int eflag, int vflag) { - double delf[3],delt[3],delta[3],deltb[3]; // force, torque increment; double evdwl,fpair,finc,tpair,factor_lj; double v1tmp[3],v2tmp[3],v3tmp[3]; @@ -129,10 +128,9 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) // vectors COM-backbone site, COM-stacking site in lab frame double ra_cs[3],ra_cst[3]; double rb_cs[3],rb_cst[3]; - - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -161,6 +159,12 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // n(x/y/z)_xtrct = extracted local unit vectors in lab frame from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -168,8 +172,10 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; + // a(y/z) not needed here as oxDNA(1) co-linear // vector COM a - stacking site a ra_cst[0] = d_cst*ax[0]; @@ -192,8 +198,10 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; + // b(y/z) not needed here as oxDNA(1) co-linear // vector COM b - stacking site b rb_cst[0] = d_cst*bx[0]; @@ -245,6 +253,13 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) // early rejection criterium if (f4t1) { + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; + cost4 = MathExtra::dot3(az,bz); if (cost4 > 1.0) cost4 = 1.0; if (cost4 < -1.0) cost4 = -1.0; @@ -380,6 +395,10 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) // cosphi3 and cosphi4 (=cosphi3) force and virial if (cosphi3) { + ay[0] = ny_xtrct[a][0]; + ay[1] = ny_xtrct[a][1]; + ay[2] = ny_xtrct[a][2]; + finc = -f2 * f4t1* f4t4 * f4t5 * f4t6 * 2.0 * f5c3 * df5c3 * factor_lj; fpair += finc; diff --git a/src/CG-DNA/pair_oxdna_coaxstk.h b/src/CG-DNA/pair_oxdna_coaxstk.h index 86538a432f..62ffb7f2c1 100644 --- a/src/CG-DNA/pair_oxdna_coaxstk.h +++ b/src/CG-DNA/pair_oxdna_coaxstk.h @@ -47,21 +47,17 @@ class PairOxdnaCoaxstk : public Pair { double **k_cxst, **cut_cxst_0, **cut_cxst_c, **cut_cxst_lo, **cut_cxst_hi; double **cut_cxst_lc, **cut_cxst_hc, **b_cxst_lo, **b_cxst_hi; double **cutsq_cxst_hc; - double **a_cxst1, **theta_cxst1_0, **dtheta_cxst1_ast; double **b_cxst1, **dtheta_cxst1_c; - double **a_cxst4, **theta_cxst4_0, **dtheta_cxst4_ast; double **b_cxst4, **dtheta_cxst4_c; - double **a_cxst5, **theta_cxst5_0, **dtheta_cxst5_ast; double **b_cxst5, **dtheta_cxst5_c; - double **a_cxst6, **theta_cxst6_0, **dtheta_cxst6_ast; double **b_cxst6, **dtheta_cxst6_c; - double **a_cxst3p, **cosphi_cxst3p_ast, **b_cxst3p, **cosphi_cxst3p_c; double **a_cxst4p, **cosphi_cxst4p_ast, **b_cxst4p, **cosphi_cxst4p_c; + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors virtual void allocate(); }; diff --git a/src/CG-DNA/pair_oxdna_excv.cpp b/src/CG-DNA/pair_oxdna_excv.cpp index d41976e86c..ae5752028a 100644 --- a/src/CG-DNA/pair_oxdna_excv.cpp +++ b/src/CG-DNA/pair_oxdna_excv.cpp @@ -39,6 +39,9 @@ PairOxdnaExcv::PairOxdnaExcv(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; writedata = 1; + + // set comm size needed by this Pair + comm_forward = 9; } /* ---------------------------------------------------------------------- */ @@ -47,6 +50,10 @@ PairOxdnaExcv::~PairOxdnaExcv() { if (allocated) { + memory->destroy(nx); + memory->destroy(ny); + memory->destroy(nz); + memory->destroy(setflag); memory->destroy(cutsq); @@ -108,7 +115,6 @@ void PairOxdnaExcv::compute_interaction_sites(double e1[3], double /*e2*/[3], void PairOxdnaExcv::compute(int eflag, int vflag) { - double delf[3],delta[3],deltb[3]; // force, torque increment; double evdwl,fpair,factor_lj; double rtmp_s[3],rtmp_b[3]; @@ -118,10 +124,10 @@ void PairOxdnaExcv::compute(int eflag, int vflag) // vectors COM-backbone site, COM-base site in lab frame double ra_cs[3],ra_cb[3]; double rb_cs[3],rb_cb[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; double *special_lj = force->special_lj; double **x = atom->x; @@ -137,7 +143,7 @@ void PairOxdnaExcv::compute(int eflag, int vflag) AtomVecEllipsoid::Bonus *bonus = avec->bonus; int *ellipsoid = atom->ellipsoid; - int a,b,ia,ib,anum,bnum,atype,btype; + int n,a,b,in,ia,ib,anum,bnum,atype,btype; evdwl = 0.0; ev_init(eflag,vflag); @@ -147,6 +153,29 @@ void PairOxdnaExcv::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // loop over all local atoms, calculation of local reference frame + for (in = 0; in < atom->nlocal; in++) { + + int n = alist[in]; + double *qn,nx_temp[3],ny_temp[3],nz_temp[3]; // quaternion and Cartesian unit vectors in lab frame + + qn=bonus[ellipsoid[n]].quat; + MathExtra::q_to_exyz(qn,nx_temp,ny_temp,nz_temp); + + nx[n][0] = nx_temp[0]; + nx[n][1] = nx_temp[1]; + nx[n][2] = nx_temp[2]; + ny[n][0] = ny_temp[0]; + ny[n][1] = ny_temp[1]; + ny[n][2] = ny_temp[2]; + nz[n][0] = nz_temp[0]; + nz[n][1] = nz_temp[1]; + nz[n][2] = nz_temp[2]; + + } + + comm->forward_comm_pair(this); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -154,8 +183,15 @@ void PairOxdnaExcv::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx[a][0]; + ax[1] = nx[a][1]; + ax[2] = nx[a][2]; + ay[0] = ny[a][0]; + ay[1] = ny[a][1]; + ay[2] = ny[a][2]; + az[0] = nz[a][0]; + az[1] = nz[a][1]; + az[2] = nz[a][2]; // vector COM - backbone and base site a compute_interaction_sites(ax,ay,az,ra_cs,ra_cb); @@ -179,8 +215,15 @@ void PairOxdnaExcv::compute(int eflag, int vflag) btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx[b][0]; + bx[1] = nx[b][1]; + bx[2] = nx[b][2]; + by[0] = ny[b][0]; + by[1] = ny[b][1]; + by[2] = ny[b][2]; + bz[0] = nz[b][0]; + bz[1] = nz[b][1]; + bz[2] = nz[b][2]; // vector COM - backbone and base site b compute_interaction_sites(bx,by,bz,rb_cs,rb_cb); @@ -400,6 +443,10 @@ void PairOxdnaExcv::allocate() for (int j = i; j <= n; j++) setflag[i][j] = 0; + memory->create(nx,atom->nmax,3,"pair:nx"); + memory->create(ny,atom->nmax,3,"pair:ny"); + memory->create(nz,atom->nmax,3,"pair:nz"); + memory->create(cutsq,n+1,n+1,"pair:cutsq"); memory->create(epsilon_ss,n+1,n+1,"pair:epsilon_ss"); @@ -806,10 +853,58 @@ void PairOxdnaExcv::write_data_all(FILE *fp) /* ---------------------------------------------------------------------- */ +int PairOxdnaExcv::pack_forward_comm(int n, int *list, double *buf, + int /*pbc_flag*/, int * /*pbc*/) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = nx[j][0]; + buf[m++] = nx[j][1]; + buf[m++] = nx[j][2]; + buf[m++] = ny[j][0]; + buf[m++] = ny[j][1]; + buf[m++] = ny[j][2]; + buf[m++] = nz[j][0]; + buf[m++] = nz[j][1]; + buf[m++] = nz[j][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairOxdnaExcv::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + nx[i][0] = buf[m++]; + nx[i][1] = buf[m++]; + nx[i][2] = buf[m++]; + ny[i][0] = buf[m++]; + ny[i][1] = buf[m++]; + ny[i][2] = buf[m++]; + nz[i][0] = buf[m++]; + nz[i][1] = buf[m++]; + nz[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + void *PairOxdnaExcv::extract(const char *str, int &dim) { dim = 2; + if (strcmp(str,"nx") == 0) return (void *) nx; + if (strcmp(str,"ny") == 0) return (void *) ny; + if (strcmp(str,"nz") == 0) return (void *) nz; + if (strcmp(str,"epsilon_ss") == 0) return (void *) epsilon_ss; if (strcmp(str,"sigma_ss") == 0) return (void *) sigma_ss; if (strcmp(str,"cut_ss_ast") == 0) return (void *) cut_ss_ast; diff --git a/src/CG-DNA/pair_oxdna_excv.h b/src/CG-DNA/pair_oxdna_excv.h index 2e92985e0c..5cf781feaa 100644 --- a/src/CG-DNA/pair_oxdna_excv.h +++ b/src/CG-DNA/pair_oxdna_excv.h @@ -41,6 +41,8 @@ class PairOxdnaExcv : public Pair { void write_data(FILE *) override; void write_data_all(FILE *) override; void *extract(const char *, int &) override; + virtual int pack_forward_comm(int, int *, double *, int, int *); + virtual void unpack_forward_comm(int, int, double *); protected: // s=sugar-phosphate backbone site, b=base site, st=stacking site @@ -52,6 +54,7 @@ class PairOxdnaExcv : public Pair { double **lj1_sb, **lj2_sb, **b_sb, **cut_sb_c, **cutsq_sb_c; double **epsilon_bb, **sigma_bb, **cut_bb_ast, **cutsq_bb_ast; double **lj1_bb, **lj2_bb, **b_bb, **cut_bb_c, **cutsq_bb_c; + double **nx, **ny, **nz; // per-atom arrays for local unit vectors virtual void allocate(); }; diff --git a/src/CG-DNA/pair_oxdna_hbond.cpp b/src/CG-DNA/pair_oxdna_hbond.cpp index 4bf0bc9c56..3d2e803aa8 100644 --- a/src/CG-DNA/pair_oxdna_hbond.cpp +++ b/src/CG-DNA/pair_oxdna_hbond.cpp @@ -148,10 +148,9 @@ void PairOxdnaHbond::compute(int eflag, int vflag) double d_chb=+0.4; // vectors COM-h-bonding site in lab frame double ra_chb[3],rb_chb[3]; - - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -180,6 +179,12 @@ void PairOxdnaHbond::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // n(x/y/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -187,8 +192,9 @@ void PairOxdnaHbond::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; ra_chb[0] = d_chb*ax[0]; ra_chb[1] = d_chb*ax[1]; @@ -205,8 +211,9 @@ void PairOxdnaHbond::compute(int eflag, int vflag) btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; rb_chb[0] = d_chb*bx[0]; rb_chb[1] = d_chb*bx[1]; @@ -265,6 +272,13 @@ void PairOxdnaHbond::compute(int eflag, int vflag) // early rejection criterium if (f4t3) { + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; + cost4 = MathExtra::dot3(az,bz); if (cost4 > 1.0) cost4 = 1.0; if (cost4 < -1.0) cost4 = -1.0; diff --git a/src/CG-DNA/pair_oxdna_hbond.h b/src/CG-DNA/pair_oxdna_hbond.h index 7c6add7c4a..32120a79cf 100644 --- a/src/CG-DNA/pair_oxdna_hbond.h +++ b/src/CG-DNA/pair_oxdna_hbond.h @@ -48,25 +48,19 @@ class PairOxdnaHbond : public Pair { double **epsilon_hb, **a_hb, **cut_hb_0, **cut_hb_c, **cut_hb_lo, **cut_hb_hi; double **cut_hb_lc, **cut_hb_hc, **b_hb_lo, **b_hb_hi, **shift_hb; double **cutsq_hb_hc; - double **a_hb1, **theta_hb1_0, **dtheta_hb1_ast; double **b_hb1, **dtheta_hb1_c; - double **a_hb2, **theta_hb2_0, **dtheta_hb2_ast; double **b_hb2, **dtheta_hb2_c; - double **a_hb3, **theta_hb3_0, **dtheta_hb3_ast; double **b_hb3, **dtheta_hb3_c; - double **a_hb4, **theta_hb4_0, **dtheta_hb4_ast; double **b_hb4, **dtheta_hb4_c; - double **a_hb7, **theta_hb7_0, **dtheta_hb7_ast; double **b_hb7, **dtheta_hb7_c; - double **a_hb8, **theta_hb8_0, **dtheta_hb8_ast; double **b_hb8, **dtheta_hb8_c; - + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors int seqdepflag; virtual void allocate(); diff --git a/src/CG-DNA/pair_oxdna_stk.cpp b/src/CG-DNA/pair_oxdna_stk.cpp index 4980408986..feeb41d78b 100644 --- a/src/CG-DNA/pair_oxdna_stk.cpp +++ b/src/CG-DNA/pair_oxdna_stk.cpp @@ -212,7 +212,6 @@ void PairOxdnaStk::ev_tally_xyz(int i, int j, int nlocal, int newton_bond, void PairOxdnaStk::compute(int eflag, int vflag) { - double delf[3],delta[3],deltb[3]; // force, torque increment; double evdwl,fpair,finc,tpair; double delr_ss[3],delr_ss_norm[3],rsq_ss,r_ss,rinv_ss; @@ -227,10 +226,9 @@ void PairOxdnaStk::compute(int eflag, int vflag) // vectors COM-backbone site, COM-stacking site in lab frame double ra_cs[3],ra_cst[3]; double rb_cs[3],rb_cst[3]; - - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -257,6 +255,12 @@ void PairOxdnaStk::compute(int eflag, int vflag) evdwl = 0.0; ev_init(eflag,vflag); + // n(x/y/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over stacking interaction neighbors using bond topology for (in = 0; in < nbondlist; in++) { @@ -275,10 +279,13 @@ void PairOxdnaStk::compute(int eflag, int vflag) // a now in 3' direction, b in 5' direction - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; + // (a/b)y/z not needed here as oxDNA(1) co-linear // vector COM a - stacking site a ra_cst[0] = d_cst*ax[0]; @@ -336,6 +343,13 @@ void PairOxdnaStk::compute(int eflag, int vflag) // early rejection criterium if (f1) { + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; + // theta4 angle and correction cost4 = MathExtra::dot3(bz,az); if (cost4 > 1.0) cost4 = 1.0; @@ -360,6 +374,13 @@ void PairOxdnaStk::compute(int eflag, int vflag) // early rejection criterium if (f4t5) { + ay[0] = ny_xtrct[a][0]; + ay[1] = ny_xtrct[a][1]; + ay[2] = ny_xtrct[a][2]; + by[0] = ny_xtrct[b][0]; + by[1] = ny_xtrct[b][1]; + by[2] = ny_xtrct[b][2]; + cost6p = MathExtra::dot3(delr_st_norm,az); if (cost6p > 1.0) cost6p = 1.0; if (cost6p < -1.0) cost6p = -1.0; diff --git a/src/CG-DNA/pair_oxdna_stk.h b/src/CG-DNA/pair_oxdna_stk.h index 1e97f8823c..5e9329ea57 100644 --- a/src/CG-DNA/pair_oxdna_stk.h +++ b/src/CG-DNA/pair_oxdna_stk.h @@ -59,7 +59,7 @@ class PairOxdnaStk : public Pair { double **b_st6, **dtheta_st6_c; double **a_st1, **cosphi_st1_ast, **b_st1, **cosphi_st1_c; double **a_st2, **cosphi_st2_ast, **b_st2, **cosphi_st2_c; - + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors int seqdepflag; virtual void allocate(); diff --git a/src/CG-DNA/pair_oxdna_xstk.cpp b/src/CG-DNA/pair_oxdna_xstk.cpp index 447483e413..61dc1a8100 100644 --- a/src/CG-DNA/pair_oxdna_xstk.cpp +++ b/src/CG-DNA/pair_oxdna_xstk.cpp @@ -111,7 +111,6 @@ PairOxdnaXstk::~PairOxdnaXstk() void PairOxdnaXstk::compute(int eflag, int vflag) { - double delf[3],delta[3],deltb[3]; // force, torque increment; double evdwl,fpair,finc,tpair,factor_lj; double delr_hb[3],delr_hb_norm[3],rsq_hb,r_hb,rinv_hb; @@ -126,10 +125,9 @@ void PairOxdnaXstk::compute(int eflag, int vflag) double d_chb=+0.4; // vectors COM-h-bonding site in lab frame double ra_chb[3],rb_chb[3]; - - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -158,6 +156,12 @@ void PairOxdnaXstk::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // n(x/y/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -165,8 +169,10 @@ void PairOxdnaXstk::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; + // a(y/z) not needed here as oxDNA(1) co-linear ra_chb[0] = d_chb*ax[0]; ra_chb[1] = d_chb*ax[1]; @@ -183,8 +189,10 @@ void PairOxdnaXstk::compute(int eflag, int vflag) btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; + // b(y/z) not needed here as oxDNA(1) co-linear rb_chb[0] = d_chb*bx[0]; rb_chb[1] = d_chb*bx[1]; @@ -243,6 +251,13 @@ void PairOxdnaXstk::compute(int eflag, int vflag) // early rejection criterium if (f4t3) { + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; + cost4 = MathExtra::dot3(az,bz); if (cost4 > 1.0) cost4 = 1.0; if (cost4 < -1.0) cost4 = -1.0; diff --git a/src/CG-DNA/pair_oxdna_xstk.h b/src/CG-DNA/pair_oxdna_xstk.h index 28fc7fb2f6..8d0a126943 100644 --- a/src/CG-DNA/pair_oxdna_xstk.h +++ b/src/CG-DNA/pair_oxdna_xstk.h @@ -47,24 +47,19 @@ class PairOxdnaXstk : public Pair { double **k_xst, **cut_xst_0, **cut_xst_c, **cut_xst_lo, **cut_xst_hi; double **cut_xst_lc, **cut_xst_hc, **b_xst_lo, **b_xst_hi; double **cutsq_xst_hc; - double **a_xst1, **theta_xst1_0, **dtheta_xst1_ast; double **b_xst1, **dtheta_xst1_c; - double **a_xst2, **theta_xst2_0, **dtheta_xst2_ast; double **b_xst2, **dtheta_xst2_c; - double **a_xst3, **theta_xst3_0, **dtheta_xst3_ast; double **b_xst3, **dtheta_xst3_c; - double **a_xst4, **theta_xst4_0, **dtheta_xst4_ast; double **b_xst4, **dtheta_xst4_c; - double **a_xst7, **theta_xst7_0, **dtheta_xst7_ast; double **b_xst7, **dtheta_xst7_c; - double **a_xst8, **theta_xst8_0, **dtheta_xst8_ast; double **b_xst8, **dtheta_xst8_c; + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors virtual void allocate(); }; diff --git a/src/CG-DNA/pair_oxrna2_stk.cpp b/src/CG-DNA/pair_oxrna2_stk.cpp index 18cd798fc7..c5fa47e25e 100644 --- a/src/CG-DNA/pair_oxrna2_stk.cpp +++ b/src/CG-DNA/pair_oxrna2_stk.cpp @@ -245,9 +245,9 @@ void PairOxrna2Stk::compute(int eflag, int vflag) double ra_cs[3],ra_cst[3]; double rb_cs[3],rb_cst[3]; - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -274,6 +274,12 @@ void PairOxrna2Stk::compute(int eflag, int vflag) evdwl = 0.0; ev_init(eflag,vflag); + // n(x/y/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + ny_xtrct = (double **) force->pair->extract("ny",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over stacking interaction neighbors using bond topology for (in = 0; in < nbondlist; in++) { @@ -290,12 +296,26 @@ void PairOxrna2Stk::compute(int eflag, int vflag) } - // a now in 3' direction, b in 5' direction + // a now in 3' direction, b in 5' direction - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; + ay[0] = ny_xtrct[a][0]; + ay[1] = ny_xtrct[a][1]; + ay[2] = ny_xtrct[a][2]; + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; + by[0] = ny_xtrct[b][0]; + by[1] = ny_xtrct[b][1]; + by[2] = ny_xtrct[b][2]; + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; // vector COM a - 5'-stacking site a ra_cst[0] = d_cst_x_5p*ax[0] + d_cst_y_5p*ay[0]; diff --git a/src/CG-DNA/pair_oxrna2_stk.h b/src/CG-DNA/pair_oxrna2_stk.h index b8b2102a7a..8530544fdc 100644 --- a/src/CG-DNA/pair_oxrna2_stk.h +++ b/src/CG-DNA/pair_oxrna2_stk.h @@ -60,7 +60,7 @@ class PairOxrna2Stk : public Pair { double **b_st10, **dtheta_st10_c; double **a_st1, **cosphi_st1_ast, **b_st1, **cosphi_st1_c; double **a_st2, **cosphi_st2_ast, **b_st2, **cosphi_st2_c; - + double **nx_xtrct, **ny_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors int seqdepflag; virtual void allocate(); diff --git a/src/CG-DNA/pair_oxrna2_xstk.cpp b/src/CG-DNA/pair_oxrna2_xstk.cpp index 8b44a9bde1..1f069e6b2f 100644 --- a/src/CG-DNA/pair_oxrna2_xstk.cpp +++ b/src/CG-DNA/pair_oxrna2_xstk.cpp @@ -120,9 +120,9 @@ void PairOxrna2Xstk::compute(int eflag, int vflag) // vectors COM-h-bonding site in lab frame double ra_chb[3],rb_chb[3]; - // quaternions and Cartesian unit vectors in lab frame - double *qa,ax[3],ay[3],az[3]; - double *qb,bx[3],by[3],bz[3]; + // Cartesian unit vectors in lab frame + double ax[3],ay[3],az[3]; + double bx[3],by[3],bz[3]; double **x = atom->x; double **f = atom->f; @@ -151,6 +151,11 @@ void PairOxrna2Xstk::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + // n(x/z)_xtrct = extracted local unit vectors from oxdna_excv + int dim; + nx_xtrct = (double **) force->pair->extract("nx",dim); + nz_xtrct = (double **) force->pair->extract("nz",dim); + // loop over pair interaction neighbors of my atoms for (ia = 0; ia < anum; ia++) { @@ -158,8 +163,9 @@ void PairOxrna2Xstk::compute(int eflag, int vflag) a = alist[ia]; atype = type[a]; - qa=bonus[ellipsoid[a]].quat; - MathExtra::q_to_exyz(qa,ax,ay,az); + ax[0] = nx_xtrct[a][0]; + ax[1] = nx_xtrct[a][1]; + ax[2] = nx_xtrct[a][2]; ra_chb[0] = d_chb*ax[0]; ra_chb[1] = d_chb*ax[1]; @@ -176,8 +182,9 @@ void PairOxrna2Xstk::compute(int eflag, int vflag) btype = type[b]; - qb=bonus[ellipsoid[b]].quat; - MathExtra::q_to_exyz(qb,bx,by,bz); + bx[0] = nx_xtrct[b][0]; + bx[1] = nx_xtrct[b][1]; + bx[2] = nx_xtrct[b][2]; rb_chb[0] = d_chb*bx[0]; rb_chb[1] = d_chb*bx[1]; @@ -236,6 +243,10 @@ void PairOxrna2Xstk::compute(int eflag, int vflag) // early rejection criterium if (f4t3) { + az[0] = nz_xtrct[a][0]; + az[1] = nz_xtrct[a][1]; + az[2] = nz_xtrct[a][2]; + cost7 = -1.0*MathExtra::dot3(az,delr_hb_norm); if (cost7 > 1.0) cost7 = 1.0; if (cost7 < -1.0) cost7 = -1.0; @@ -250,6 +261,10 @@ void PairOxrna2Xstk::compute(int eflag, int vflag) // early rejection criterium if (f4t7) { + bz[0] = nz_xtrct[b][0]; + bz[1] = nz_xtrct[b][1]; + bz[2] = nz_xtrct[b][2]; + cost8 = MathExtra::dot3(bz,delr_hb_norm); if (cost8 > 1.0) cost8 = 1.0; if (cost8 < -1.0) cost8 = -1.0; diff --git a/src/CG-DNA/pair_oxrna2_xstk.h b/src/CG-DNA/pair_oxrna2_xstk.h index 6a3f02ee8d..c73839b4a7 100644 --- a/src/CG-DNA/pair_oxrna2_xstk.h +++ b/src/CG-DNA/pair_oxrna2_xstk.h @@ -46,21 +46,17 @@ class PairOxrna2Xstk : public Pair { double **k_xst, **cut_xst_0, **cut_xst_c, **cut_xst_lo, **cut_xst_hi; double **cut_xst_lc, **cut_xst_hc, **b_xst_lo, **b_xst_hi; double **cutsq_xst_hc; - double **a_xst1, **theta_xst1_0, **dtheta_xst1_ast; double **b_xst1, **dtheta_xst1_c; - double **a_xst2, **theta_xst2_0, **dtheta_xst2_ast; double **b_xst2, **dtheta_xst2_c; - double **a_xst3, **theta_xst3_0, **dtheta_xst3_ast; double **b_xst3, **dtheta_xst3_c; - double **a_xst7, **theta_xst7_0, **dtheta_xst7_ast; double **b_xst7, **dtheta_xst7_c; - double **a_xst8, **theta_xst8_0, **dtheta_xst8_ast; double **b_xst8, **dtheta_xst8_c; + double **nx_xtrct, **nz_xtrct; // per-atom arrays for local unit vectors virtual void allocate(); }; diff --git a/src/Depend.sh b/src/Depend.sh index a8e17e0546..5123354b1c 100755 --- a/src/Depend.sh +++ b/src/Depend.sh @@ -135,6 +135,10 @@ if (test $1 = "PYTHON") then depend ML-IAP fi +if (test $1 = "PHONON") then + depend KOKKOS +fi + if (test $1 = "RIGID") then depend KOKKOS depend OPENMP diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 45fa0654a9..6da318c2d5 100755 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -108,6 +108,8 @@ action dihedral_opls_kokkos.cpp dihedral_opls.cpp action dihedral_opls_kokkos.h dihedral_opls.h action domain_kokkos.cpp action domain_kokkos.h +action dynamical_matrix_kokkos.cpp dynamical_matrix.cpp +action dynamical_matrix_kokkos.h dynamical_matrix.h action fftdata_kokkos.h fft3d.h action fft3d_kokkos.cpp fft3d.cpp action fft3d_kokkos.h fft3d.h @@ -312,6 +314,8 @@ action remap_kokkos.cpp remap.cpp action remap_kokkos.h remap.h action sna_kokkos.h sna.h action sna_kokkos_impl.h sna.cpp +action third_order_kokkos.cpp dynamical_matrix.cpp +action third_order_kokkos.h dynamical_matrix.h action verlet_kokkos.cpp action verlet_kokkos.h diff --git a/src/KOKKOS/angle_charmm_kokkos.h b/src/KOKKOS/angle_charmm_kokkos.h index b74b1e2886..10ef9efaa4 100644 --- a/src/KOKKOS/angle_charmm_kokkos.h +++ b/src/KOKKOS/angle_charmm_kokkos.h @@ -65,14 +65,14 @@ class AngleCharmmKokkos : public AngleCharmm { typedef ArrayTypes AT; typename AT::t_x_array_randomread x; - typedef typename KKDevice::value KKDeviceType; + using KKDeviceType = typename KKDevice::value; typename Kokkos::View > f; typename AT::t_int_2d anglelist; Kokkos::DualView k_eatom; Kokkos::DualView k_vatom; - Kokkos::View::value,Kokkos::MemoryTraits > d_eatom; - Kokkos::View::value,Kokkos::MemoryTraits > d_vatom; + Kokkos::View> d_eatom; + Kokkos::View> d_vatom; int nlocal,newton_bond; int eflag,vflag; diff --git a/src/KOKKOS/dynamical_matrix_kokkos.cpp b/src/KOKKOS/dynamical_matrix_kokkos.cpp new file mode 100644 index 0000000000..dc180a1743 --- /dev/null +++ b/src/KOKKOS/dynamical_matrix_kokkos.cpp @@ -0,0 +1,353 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Charlie Sievers (UC Davis), charliesievers at cox.net +------------------------------------------------------------------------- */ + +#include "dynamical_matrix_kokkos.h" + +#include "angle.h" +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "bond.h" +#include "comm.h" +#include "compute.h" +#include "dihedral.h" +#include "domain.h" +#include "error.h" +#include "finish.h" +#include "force.h" +#include "group.h" +#include "improper.h" +#include "kokkos.h" +#include "kspace.h" +#include "memory.h" +#include "modify.h" +#include "neighbor.h" +#include "pair.h" +#include "timer.h" +#include "update.h" + +#include +#include +#include + +using namespace LAMMPS_NS; +enum{REGULAR,ESKM}; + +template +struct ForceAdder { + ViewA a; + ViewB b; + ForceAdder(const ViewA& a_, const ViewB& b_):a(a_),b(b_) {} + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + a(i,0) += b(i,0); + a(i,1) += b(i,1); + a(i,2) += b(i,2); + } +}; + +/* ---------------------------------------------------------------------- */ + +template +struct Zero { + View v; + Zero(const View &v_):v(v_) {} + KOKKOS_INLINE_FUNCTION + void operator()(const int &i) const { + v(i,0) = 0; + v(i,1) = 0; + v(i,2) = 0; + } +}; + +/* ---------------------------------------------------------------------- */ + +DynamicalMatrixKokkos::DynamicalMatrixKokkos(LAMMPS *lmp) : DynamicalMatrix(lmp) +{ + atomKK = (AtomKokkos *) atom; +} + +/* ---------------------------------------------------------------------- */ + +DynamicalMatrixKokkos::~DynamicalMatrixKokkos() +{ + +} + +/* ---------------------------------------------------------------------- */ + +void DynamicalMatrixKokkos::command(int narg, char **arg) +{ + atomKK->sync(Host, X_MASK|RMASS_MASK|TYPE_MASK); + DynamicalMatrix::command(narg, arg); +} + +/* ---------------------------------------------------------------------- + setup without output or one-time post-init setup + flag = 0 = just force calculation + flag = 1 = reneighbor and force calculation +------------------------------------------------------------------------- */ + +void DynamicalMatrixKokkos::setup() +{ + lmp->kokkos->auto_sync = 1; + + // setup domain, communication and neighboring + // acquire ghosts + // build neighbor lists + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + comm->exchange(); + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + domain->image_check(); + domain->box_too_small_check(); + neighbor->build(1); + + // compute all forces + eflag=0; + vflag=0; + if (force->kspace) { + force->kspace->setup(); + } + update_force(); + + if (pair_compute_flag) { + atomKK->sync(force->pair->execution_space,force->pair->datamask_read); + force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); + } + else if (force->pair) force->pair->compute_dummy(eflag,vflag); + update->setupflag = 0; + + lmp->kokkos->auto_sync = 0; + + //if all then skip communication groupmap population + if (gcount == atom->natoms) + for (bigint i=0; inatoms; i++) + groupmap[i] = i; + else + create_groupmap(); +} + +/* ---------------------------------------------------------------------- + evaluate potential energy and forces + may migrate atoms due to reneighboring + return new energy, which should include nextra_global dof + return negative gradient stored in atom->f + return negative gradient for nextra_global dof in fextra +------------------------------------------------------------------------- */ + +void DynamicalMatrixKokkos::update_force() +{ + int n_pre_force = modify->n_pre_force; + int n_pre_reverse = modify->n_pre_reverse; + int n_post_force = modify->n_post_force; + + lmp->kokkos->auto_sync = 0; + + f_merge_copy = DAT::t_f_array("DynamicalMatrixKokkos::f_merge_copy",atomKK->k_f.extent(0)); + + atomKK->modified(Host,X_MASK); + atomKK->sync(Device,X_MASK); + + force_clear(); + + neighbor->ago = 0; + if ((modify->get_fix_by_id("package_intel")) ? true : false) + neighbor->decide(); + + + if (n_pre_force) { + modify->pre_force(vflag); + timer->stamp(Timer::MODIFY); + } + + bool execute_on_host = false; + unsigned int datamask_read_device = 0; + unsigned int datamask_modify_device = 0; + unsigned int datamask_read_host = 0; + + if (pair_compute_flag) { + if (force->pair->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->pair->datamask_read; + datamask_modify_device |= force->pair->datamask_modify; + } else { + datamask_read_device |= force->pair->datamask_read; + datamask_modify_device |= force->pair->datamask_modify; + } + } + if (atomKK->molecular && force->bond) { + if (force->bond->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->bond->datamask_read; + datamask_modify_device |= force->bond->datamask_modify; + } else { + datamask_read_device |= force->bond->datamask_read; + datamask_modify_device |= force->bond->datamask_modify; + } + } + if (atomKK->molecular && force->angle) { + if (force->angle->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->angle->datamask_read; + datamask_modify_device |= force->angle->datamask_modify; + } else { + datamask_read_device |= force->angle->datamask_read; + datamask_modify_device |= force->angle->datamask_modify; + } + } + if (atomKK->molecular && force->dihedral) { + if (force->dihedral->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->dihedral->datamask_read; + datamask_modify_device |= force->dihedral->datamask_modify; + } else { + datamask_read_device |= force->dihedral->datamask_read; + datamask_modify_device |= force->dihedral->datamask_modify; + } + } + if (atomKK->molecular && force->improper) { + if (force->improper->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->improper->datamask_read; + datamask_modify_device |= force->improper->datamask_modify; + } else { + datamask_read_device |= force->improper->datamask_read; + datamask_modify_device |= force->improper->datamask_modify; + } + } + if (kspace_compute_flag) { + if (force->kspace->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->kspace->datamask_read; + datamask_modify_device |= force->kspace->datamask_modify; + } else { + datamask_read_device |= force->kspace->datamask_read; + datamask_modify_device |= force->kspace->datamask_modify; + } + } + + + if (pair_compute_flag) { + atomKK->sync(force->pair->execution_space,force->pair->datamask_read); + atomKK->sync(force->pair->execution_space,~(~force->pair->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + Kokkos::Timer ktimer; + force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); + atomKK->modified(force->pair->execution_space,~(~force->pair->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + timer->stamp(Timer::PAIR); + } + + if (execute_on_host) { + if (pair_compute_flag && force->pair->datamask_modify!=(F_MASK | ENERGY_MASK | VIRIAL_MASK)) + Kokkos::fence(); + atomKK->sync_overlapping_device(Host,~(~datamask_read_host|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + if (pair_compute_flag && force->pair->execution_space!=Host) { + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.h_view,0.0); + } + } + + if (atomKK->molecular) { + if (force->bond) { + atomKK->sync(force->bond->execution_space,~(~force->bond->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->bond->compute(eflag,vflag); + atomKK->modified(force->bond->execution_space,~(~force->bond->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + if (force->angle) { + atomKK->sync(force->angle->execution_space,~(~force->angle->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->angle->compute(eflag,vflag); + atomKK->modified(force->angle->execution_space,~(~force->angle->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + if (force->dihedral) { + atomKK->sync(force->dihedral->execution_space,~(~force->dihedral->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->dihedral->compute(eflag,vflag); + atomKK->modified(force->dihedral->execution_space,~(~force->dihedral->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + if (force->improper) { + atomKK->sync(force->improper->execution_space,~(~force->improper->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->improper->compute(eflag,vflag); + atomKK->modified(force->improper->execution_space,~(~force->improper->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + timer->stamp(Timer::BOND); + } + + if (kspace_compute_flag) { + atomKK->sync(force->kspace->execution_space,~(~force->kspace->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->kspace->compute(eflag,vflag); + atomKK->modified(force->kspace->execution_space,~(~force->kspace->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + timer->stamp(Timer::KSPACE); + } + + if (execute_on_host && !std::is_same::value) { + if (f_merge_copy.extent(0)k_f.extent(0)) { + f_merge_copy = DAT::t_f_array("DynamicalMatrixKokkos::f_merge_copy",atomKK->k_f.extent(0)); + } + f = atomKK->k_f.d_view; + Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.h_view); + Kokkos::parallel_for(atomKK->k_f.extent(0), + ForceAdder(atomKK->k_f.d_view,f_merge_copy)); + atomKK->k_f.clear_sync_state(); // special case + atomKK->k_f.modify(); + } + if (n_pre_reverse) { + modify->pre_reverse(eflag,vflag); + timer->stamp(Timer::MODIFY); + } + if (force->newton) { + comm->reverse_comm(); + timer->stamp(Timer::COMM); + } + // force modifications + + if (n_post_force) { + modify->post_force(vflag); + timer->stamp(Timer::MODIFY); + } + + atomKK->sync(Host,F_MASK); + lmp->kokkos->auto_sync = 1; + + ++ update->nsteps; +} + +/* ---------------------------------------------------------------------- + clear force on own & ghost atoms + clear other arrays as needed +------------------------------------------------------------------------- */ + +void DynamicalMatrixKokkos::force_clear() +{ + if (external_force_clear) return; + + atomKK->k_f.clear_sync_state(); // ignore host forces/torques since device views + + // clear force on all particles + // if either newton flag is set, also include ghosts + // when using threads always clear all forces. + + int nall = atomKK->nlocal; + if (force->newton) nall += atomKK->nghost; + + Kokkos::parallel_for(nall, Zero::t_f_array>(atomKK->k_f.view())); + atomKK->modified(Device,F_MASK); + +} diff --git a/src/KOKKOS/dynamical_matrix_kokkos.h b/src/KOKKOS/dynamical_matrix_kokkos.h new file mode 100644 index 0000000000..02b93e2112 --- /dev/null +++ b/src/KOKKOS/dynamical_matrix_kokkos.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMMAND_CLASS +// clang-format off +CommandStyle(dynamical_matrix/kk,DynamicalMatrixKokkos); +CommandStyle(dynamical_matrix/kk/device,DynamicalMatrixKokkos); +CommandStyle(dynamical_matrix/kk/host,DynamicalMatrixKokkos); +// clang-format on +#else + +#ifndef LMP_DYNAMICAL_MATRIX_KOKKOS_H +#define LMP_DYNAMICAL_MATRIX_KOKKOS_H + +#include "dynamical_matrix.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class DynamicalMatrixKokkos : public DynamicalMatrix { + public: + DynamicalMatrixKokkos(class LAMMPS *); + ~DynamicalMatrixKokkos() override; + void command(int, char **) override; + void setup(); + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + f(i,0) += f_merge_copy(i,0); + f(i,1) += f_merge_copy(i,1); + f(i,2) += f_merge_copy(i,2); + } + + protected: + void update_force(); + void force_clear(); + DAT::t_f_array f_merge_copy,f; + + +}; +} // namespace LAMMPS_NS + +#endif //LMP_DYNAMICAL_MATRIX_KOKKOS_H +#endif diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp index 582e9a39ce..9d228020c3 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp @@ -864,8 +864,8 @@ KOKKOS_INLINE_FUNCTION void FixACKS2ReaxFFKokkos::compute_x_item(int ii, int &m_fill, const bool &final) const { // The X_diag array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_X_diag = ScatterViewHelper::value,decltype(dup_X_diag),decltype(ndup_X_diag)>::get(dup_X_diag,ndup_X_diag); - auto a_X_diag = v_X_diag.template access::value>(); + auto v_X_diag = ScatterViewHelper,decltype(dup_X_diag),decltype(ndup_X_diag)>::get(dup_X_diag,ndup_X_diag); + auto a_X_diag = v_X_diag.template access>(); const int i = d_ilist[ii]; int j,jj,jtype; @@ -942,8 +942,8 @@ void FixACKS2ReaxFFKokkos::compute_x_team( int atoms_per_team, int vector_length) const { // The X_diag array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_X_diag = ScatterViewHelper::value,decltype(dup_X_diag),decltype(ndup_X_diag)>::get(dup_X_diag,ndup_X_diag); - auto a_X_diag = v_X_diag.template access::value>(); + auto v_X_diag = ScatterViewHelper,decltype(dup_X_diag),decltype(ndup_X_diag)>::get(dup_X_diag,ndup_X_diag); + auto a_X_diag = v_X_diag.template access>(); // scratch space setup Kokkos::View, @@ -1460,8 +1460,8 @@ KOKKOS_INLINE_FUNCTION void FixACKS2ReaxFFKokkos::operator() (TagACKS2SparseMatvec3_Half, const int &ii) const { // The bb array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_bb = ScatterViewHelper::value,decltype(dup_bb),decltype(ndup_bb)>::get(dup_bb,ndup_bb); - auto a_bb = v_bb.template access::value>(); + auto v_bb = ScatterViewHelper,decltype(dup_bb),decltype(ndup_bb)>::get(dup_bb,ndup_bb); + auto a_bb = v_bb.template access>(); const int i = d_ilist[ii]; if (mask[i] & groupbit) { diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.h b/src/KOKKOS/fix_acks2_reaxff_kokkos.h index bce90e97a3..735b478f1b 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.h +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.h @@ -183,16 +183,16 @@ class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF { Kokkos::DualView k_params; typename Kokkos::DualView::t_dev_const params; - typename ArrayTypes::t_x_array x; - typename ArrayTypes::t_v_array v; - typename ArrayTypes::t_f_array_const f; - typename ArrayTypes::t_ffloat_1d_randomread mass; - typename ArrayTypes::t_ffloat_1d q; - typename ArrayTypes::t_int_1d type, mask; - typename ArrayTypes::t_tagint_1d tag; + typename AT::t_x_array x; + typename AT::t_v_array v; + typename AT::t_f_array_const f; + typename AT::t_ffloat_1d_randomread mass; + typename AT::t_ffloat_1d q; + typename AT::t_int_1d type, mask; + typename AT::t_tagint_1d tag; - typename ArrayTypes::t_neighbors_2d d_neighbors; - typename ArrayTypes::t_int_1d_randomread d_ilist, d_numneigh; + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist, d_numneigh; DAT::tdual_ffloat_1d k_tap; typename AT::t_ffloat_1d d_tap; @@ -222,11 +222,19 @@ class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF { typename AT::t_ffloat_2d d_shield, d_s_hist, d_s_hist_X, d_s_hist_last; typename AT::t_ffloat_2d_randomread r_s_hist, r_s_hist_X, r_s_hist_last; - Kokkos::Experimental::ScatterView::value, Kokkos::Experimental::ScatterSum, Kokkos::Experimental::ScatterDuplicated> dup_X_diag; - Kokkos::Experimental::ScatterView::value, Kokkos::Experimental::ScatterSum, Kokkos::Experimental::ScatterNonDuplicated> ndup_X_diag; + using KKDeviceType = typename KKDevice::value; - Kokkos::Experimental::ScatterView::value, Kokkos::Experimental::ScatterSum, Kokkos::Experimental::ScatterDuplicated> dup_bb; - Kokkos::Experimental::ScatterView::value, Kokkos::Experimental::ScatterSum, Kokkos::Experimental::ScatterNonDuplicated> ndup_bb; + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_X_diag; + NonDupScatterView ndup_X_diag; + + DupScatterView dup_bb; + NonDupScatterView ndup_bb; void init_shielding_k(); void init_hist(); diff --git a/src/KOKKOS/fix_deform_kokkos.cpp b/src/KOKKOS/fix_deform_kokkos.cpp index 576e34503c..104ac41188 100644 --- a/src/KOKKOS/fix_deform_kokkos.cpp +++ b/src/KOKKOS/fix_deform_kokkos.cpp @@ -319,7 +319,7 @@ void FixDeformKokkos::end_of_step() // if (mask[i] & groupbit) // domain->x2lamda(x[i],x[i]); - if (nrigid) + if (rfix.size() > 0) error->all(FLERR,"Cannot (yet) use rigid bodies with fix deform and Kokkos"); //for (i = 0; i < nrigid; i++) // modify->fix[rfix[i]]->deform(0); diff --git a/src/KOKKOS/fix_langevin_kokkos.h b/src/KOKKOS/fix_langevin_kokkos.h index 3bb076b561..96b61532e6 100644 --- a/src/KOKKOS/fix_langevin_kokkos.h +++ b/src/KOKKOS/fix_langevin_kokkos.h @@ -45,11 +45,10 @@ namespace LAMMPS_NS { } KOKKOS_INLINE_FUNCTION - volatile s_FSUM& operator+=(const volatile s_FSUM &rhs) volatile { + void operator+=(const volatile s_FSUM &rhs) volatile { fx += rhs.fx; fy += rhs.fy; fz += rhs.fz; - return *this; } }; typedef s_FSUM FSUM; diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp index b35bbc46ee..52212c09ed 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp @@ -1041,8 +1041,8 @@ KOKKOS_INLINE_FUNCTION void FixQEqReaxFFKokkos::sparse13_item(int ii) const { // The q array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_o = ScatterViewHelper::value,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); - auto a_o = v_o.template access::value>(); + auto v_o = ScatterViewHelper,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); + auto a_o = v_o.template access>(); const int i = d_ilist[ii]; if (mask[i] & groupbit) { @@ -1094,8 +1094,8 @@ KOKKOS_INLINE_FUNCTION void FixQEqReaxFFKokkos::sparse23_item(int ii) const { // The q array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_o = ScatterViewHelper::value,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); - auto a_o = v_o.template access::value>(); + auto v_o = ScatterViewHelper,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); + auto a_o = v_o.template access>(); const int i = d_ilist[ii]; if (mask[i] & groupbit) { @@ -1154,8 +1154,8 @@ KOKKOS_INLINE_FUNCTION void FixQEqReaxFFKokkos::sparse33_item(int ii) const { // The q array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_o = ScatterViewHelper::value,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); - auto a_o = v_o.template access::value>(); + auto v_o = ScatterViewHelper,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); + auto a_o = v_o.template access>(); const int i = d_ilist[ii]; if (mask[i] & groupbit) { diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.h b/src/KOKKOS/fix_qeq_reaxff_kokkos.h index 85cc14d617..28ffc34a3d 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.h +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.h @@ -177,21 +177,21 @@ class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase { Kokkos::DualView k_params; typename Kokkos::DualView::t_dev_const params; - typename ArrayTypes::t_x_array x; - typename ArrayTypes::t_v_array v; - typename ArrayTypes::t_f_array_const f; - //typename ArrayTypes::t_float_1d_randomread mass, q; - typename ArrayTypes::t_float_1d_randomread mass; - typename ArrayTypes::t_float_1d q; - typename ArrayTypes::t_int_1d type, mask; - typename ArrayTypes::t_tagint_1d tag; + typename AT::t_x_array x; + typename AT::t_v_array v; + typename AT::t_f_array_const f; + //typename AT::t_float_1d_randomread mass, q; + typename AT::t_float_1d_randomread mass; + typename AT::t_float_1d q; + typename AT::t_int_1d type, mask; + typename AT::t_tagint_1d tag; DAT::tdual_float_1d k_q; typename AT::t_float_1d d_q; HAT::t_float_1d h_q; - typename ArrayTypes::t_neighbors_2d d_neighbors; - typename ArrayTypes::t_int_1d_randomread d_ilist, d_numneigh; + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist, d_numneigh; DAT::tdual_ffloat_1d k_tap; typename AT::t_ffloat_1d d_tap; @@ -216,8 +216,16 @@ class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase { HAT::t_ffloat_2d h_s_hist, h_t_hist; typename AT::t_ffloat_2d_randomread r_s_hist, r_t_hist; - Kokkos::Experimental::ScatterView::value, Kokkos::Experimental::ScatterSum, Kokkos::Experimental::ScatterDuplicated> dup_o; - Kokkos::Experimental::ScatterView::value, Kokkos::Experimental::ScatterSum, Kokkos::Experimental::ScatterNonDuplicated> ndup_o; + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_o; + NonDupScatterView ndup_o; int iswap; int first; diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 602cb67dbc..3440de9885 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -61,13 +61,12 @@ struct s_CounterType } KOKKOS_INLINE_FUNCTION - volatile s_CounterType& operator+=(const volatile s_CounterType &rhs) volatile + void operator+=(const volatile s_CounterType &rhs) volatile { nSteps += rhs.nSteps; nIters += rhs.nIters; nFuncs += rhs.nFuncs; nFails += rhs.nFails; - return *this; } }; typedef struct s_CounterType CounterType; @@ -239,22 +238,22 @@ class FixRxKokkos : public FixRX { typename AT::t_efloat_1d d_dpdThetaLocal, d_sumWeights; HAT::t_efloat_1d h_dpdThetaLocal, h_sumWeights; - typename ArrayTypes::t_x_array_randomread d_x ; - typename ArrayTypes::t_int_1d_randomread d_type ; - typename ArrayTypes::t_efloat_1d d_dpdTheta; + typename AT::t_x_array_randomread d_x; + typename AT::t_int_1d_randomread d_type; + typename AT::t_efloat_1d d_dpdTheta; - typename ArrayTypes::tdual_ffloat_2d k_cutsq; - typename ArrayTypes::t_ffloat_2d d_cutsq; + typename AT::tdual_ffloat_2d k_cutsq; + typename AT::t_ffloat_2d d_cutsq; //double **h_cutsq; - typename ArrayTypes::t_neighbors_2d d_neighbors; - typename ArrayTypes::t_int_1d d_ilist ; - typename ArrayTypes::t_int_1d d_numneigh ; + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d d_ilist; + typename AT::t_int_1d d_numneigh; - typename ArrayTypes::t_float_2d d_dvector; - typename ArrayTypes::t_int_1d d_mask ; + typename AT::t_float_2d d_dvector; + typename AT::t_int_1d d_mask; - typename ArrayTypes::t_double_1d d_scratchSpace; + typename AT::t_double_1d d_scratchSpace; size_t scratchSpaceSize; // Error flag for any failures. diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index 91d8458d21..3fef8030a1 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -590,8 +590,8 @@ void FixShakeKokkos::shake(int m, EV_FLOAT& ev) const // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); int nlist,list[2]; double v[6]; @@ -701,8 +701,8 @@ void FixShakeKokkos::shake3(int m, EV_FLOAT& ev) const // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); int nlist,list[3]; double v[6]; @@ -884,8 +884,8 @@ void FixShakeKokkos::shake4(int m, EV_FLOAT& ev) const // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); int nlist,list[4]; double v[6]; @@ -1146,8 +1146,8 @@ void FixShakeKokkos::shake3angle(int m, EV_FLOAT& ev) const // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); int nlist,list[3]; double v[6]; @@ -1744,8 +1744,8 @@ void FixShakeKokkos::v_tally(EV_FLOAT &ev, int n, int *list, double if (vflag_atom) { double fraction = 1.0/total; for (int i = 0; i < n; i++) { - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); m = list[i]; a_vatom(m,0) += fraction*v[0]; a_vatom(m,1) += fraction*v[1]; diff --git a/src/KOKKOS/fix_shake_kokkos.h b/src/KOKKOS/fix_shake_kokkos.h index 8adae5f0a3..11a94f0d2c 100644 --- a/src/KOKKOS/fix_shake_kokkos.h +++ b/src/KOKKOS/fix_shake_kokkos.h @@ -151,14 +151,21 @@ class FixShakeKokkos : public FixShake, public KokkosBase { KOKKOS_INLINE_FUNCTION void shake3angle(int, EV_FLOAT&) const; - typedef typename KKDevice::value KKDeviceType; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; + using KKDeviceType = typename KKDevice::value; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; int neighflag,need_dup; diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index f0dc026df8..23145cb7fd 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -197,6 +197,15 @@ public: #endif }; +// Helpers for readability + +using KKScatterSum = Kokkos::Experimental::ScatterSum; +using KKScatterDuplicated = Kokkos::Experimental::ScatterDuplicated; +using KKScatterNonDuplicated = Kokkos::Experimental::ScatterNonDuplicated; + +template +using KKScatterView = Kokkos::Experimental::ScatterView; + // set ExecutionSpace stuct with variable "space" @@ -274,6 +283,9 @@ struct AtomicDup { using value = Kokkos::Experimental::ScatterNonAtomic; }; +template +using AtomicDup_v = typename AtomicDup::value; + #ifdef KOKKOS_ENABLE_CUDA template<> struct AtomicDup { @@ -322,6 +334,9 @@ struct NeedDup { using value = Kokkos::Experimental::ScatterNonDuplicated; }; +template +using NeedDup_v = typename NeedDup::value; + #ifndef LMP_KOKKOS_USE_ATOMICS #ifdef KOKKOS_ENABLE_OPENMP diff --git a/src/KOKKOS/memory_kokkos.h b/src/KOKKOS/memory_kokkos.h index 58c3c08e2a..1134e627ca 100644 --- a/src/KOKKOS/memory_kokkos.h +++ b/src/KOKKOS/memory_kokkos.h @@ -172,13 +172,11 @@ TYPE create_kokkos(TYPE &data, typename TYPE::value_type **&array, bigint nbytes = ((bigint) sizeof(typename TYPE::value_type *)) * n1; array = (typename TYPE::value_type **) smalloc(nbytes,name); - bigint n = 0; for (int i = 0; i < n1; i++) { if (n2==0) array[i] = nullptr; else array[i] = &data.h_view(i,0); - n += n2; } return data; } @@ -193,13 +191,11 @@ template bigint nbytes = ((bigint) sizeof(typename TYPE::value_type *)) * n1; array = (typename TYPE::value_type **) smalloc(nbytes,name); - bigint n = 0; for (int i = 0; i < n1; i++) { if (n2==0) array[i] = nullptr; else array[i] = &h_data(i,0); - n += n2; } return data; } diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index b91ff7bd41..d6ad5ade0c 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -142,7 +142,7 @@ void NBinSSAKokkos::bin_atoms() k_gbincount.sync(); ghosts_per_gbin = 0; NPairSSAKokkosBinIDGhostsFunctor f(*this); - Kokkos::parallel_reduce(Kokkos::RangePolicy(nlocal,nall), f, ghosts_per_gbin); + Kokkos::parallel_reduce(Kokkos::RangePolicy(nlocal,nall), f, ghosts_per_gbin); } // actually bin the ghost atoms diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index 9421946c3e..4b253793c8 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -553,8 +553,8 @@ void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelA::value,decltype(dup_rho),decltype(ndup_rho)>::get(dup_rho,ndup_rho); - auto a_rho = v_rho.template access::value>(); + auto v_rho = ScatterViewHelper,decltype(dup_rho),decltype(ndup_rho)>::get(dup_rho,ndup_rho); + auto a_rho = v_rho.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -718,8 +718,8 @@ void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelC::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -832,11 +832,11 @@ void PairEAMAlloyKokkos::ev_tally(EV_FLOAT &ev, const int &i, const // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (EFLAG) { if (eflag_atom) { diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.h b/src/KOKKOS/pair_eam_alloy_kokkos.h index a94368f509..0015a71448 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.h +++ b/src/KOKKOS/pair_eam_alloy_kokkos.h @@ -123,18 +123,28 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_rho; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_rho; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_rho; + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + + NonDupScatterView ndup_rho; + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; DAT::tdual_ffloat_1d k_rho; DAT::tdual_ffloat_1d k_fp; diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index 5fbd14d8b3..f9ae3b420c 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -553,8 +553,8 @@ void PairEAMFSKokkos::operator()(TagPairEAMFSKernelA::value,decltype(dup_rho),decltype(ndup_rho)>::get(dup_rho,ndup_rho); - auto a_rho = v_rho.template access::value>(); + auto v_rho = ScatterViewHelper,decltype(dup_rho),decltype(ndup_rho)>::get(dup_rho,ndup_rho); + auto a_rho = v_rho.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -719,8 +719,8 @@ void PairEAMFSKokkos::operator()(TagPairEAMFSKernelC::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -833,11 +833,11 @@ void PairEAMFSKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (EFLAG) { if (eflag_atom) { diff --git a/src/KOKKOS/pair_eam_fs_kokkos.h b/src/KOKKOS/pair_eam_fs_kokkos.h index d2c41d345e..1edbbb91dd 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.h +++ b/src/KOKKOS/pair_eam_fs_kokkos.h @@ -123,18 +123,28 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_rho; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_rho; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_rho; + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + + NonDupScatterView ndup_rho; + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; DAT::tdual_ffloat_1d k_rho; DAT::tdual_ffloat_1d k_fp; diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 417efc3f7d..5aa36299d7 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -548,8 +548,8 @@ void PairEAMKokkos::operator()(TagPairEAMKernelA::value,decltype(dup_rho),decltype(ndup_rho)>::get(dup_rho,ndup_rho); - auto a_rho = v_rho.template access::value>(); + auto v_rho = ScatterViewHelper,decltype(dup_rho),decltype(ndup_rho)>::get(dup_rho,ndup_rho); + auto a_rho = v_rho.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -713,8 +713,8 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -827,11 +827,11 @@ void PairEAMKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int & // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (EFLAG) { if (eflag_atom) { diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 08de102a6c..9949c3071c 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -120,18 +120,27 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_rho; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_rho; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_rho; + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + NonDupScatterView ndup_rho; + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; DAT::tdual_ffloat_1d k_rho; DAT::tdual_ffloat_1d k_fp; diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 65fffd58ad..af959ad63a 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -65,19 +65,22 @@ struct PairComputeFunctor { typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; + using KKDeviceType = typename KKDevice::value; + using DUP = typename NeedDup::value; + // The force array is atomic for Half/Thread neighbor style //Kokkos::View::value,Kokkos::MemoryTraits::value> > f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,typename NeedDup::value > dup_f; + KKScatterView dup_f; // The eatom and vatom arrays are atomic for Half/Thread neighbor style //Kokkos::View::value,Kokkos::MemoryTraits::value> > eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,typename NeedDup::value > dup_eatom; + KKScatterView dup_eatom; //Kokkos::View::value,Kokkos::MemoryTraits::value> > vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,typename NeedDup::value > dup_vatom; + KKScatterView dup_vatom; @@ -90,9 +93,9 @@ struct PairComputeFunctor { f = c.f; d_eatom = c.d_eatom; d_vatom = c.d_vatom; - dup_f = Kokkos::Experimental::create_scatter_view::value >(c.f); - dup_eatom = Kokkos::Experimental::create_scatter_view::value >(c.d_eatom); - dup_vatom = Kokkos::Experimental::create_scatter_view::value >(c.d_vatom); + dup_f = Kokkos::Experimental::create_scatter_view(c.f); + dup_eatom = Kokkos::Experimental::create_scatter_view(c.d_eatom); + dup_vatom = Kokkos::Experimental::create_scatter_view(c.d_vatom); }; // Set copymode = 1 so parent allocations aren't destructed by copies of the style @@ -263,7 +266,7 @@ struct PairComputeFunctor { // Loop over neighbors of one atom without coulomb interaction // This function is called in parallel KOKKOS_FUNCTION - void compute_item_team(Kokkos::TeamPolicy<>::member_type team, + void compute_item_team(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const NoCoulTag&) const { const int inum = team.league_size(); @@ -319,7 +322,7 @@ struct PairComputeFunctor { // Loop over neighbors of one atom with coulomb interaction // This function is called in parallel KOKKOS_FUNCTION - void compute_item_team(Kokkos::TeamPolicy<>::member_type team, + void compute_item_team(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const CoulTag& ) const { const int inum = team.league_size(); @@ -380,7 +383,7 @@ struct PairComputeFunctor { // Loop over neighbors of one atom without coulomb interaction // This function is called in parallel KOKKOS_FUNCTION - EV_FLOAT compute_item_team_ev(Kokkos::TeamPolicy<>::member_type team, + EV_FLOAT compute_item_team_ev(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const NoCoulTag&) const { EV_FLOAT ev; @@ -475,7 +478,7 @@ struct PairComputeFunctor { // Loop over neighbors of one atom with coulomb interaction // This function is called in parallel KOKKOS_FUNCTION - EV_FLOAT compute_item_team_ev(Kokkos::TeamPolicy<>::member_type team, + EV_FLOAT compute_item_team_ev(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const CoulTag& ) const { EV_FLOAT ev; @@ -684,12 +687,12 @@ struct PairComputeFunctor { } KOKKOS_INLINE_FUNCTION - void operator()(const typename Kokkos::TeamPolicy<>::member_type& team) const { + void operator()(const typename Kokkos::TeamPolicy::member_type& team) const { compute_item_team(team,list,typename DoCoul::type()); } KOKKOS_INLINE_FUNCTION - void operator()(const typename Kokkos::TeamPolicy<>::member_type& team, value_type &energy_virial) const { + void operator()(const typename Kokkos::TeamPolicy::member_type& team, value_type &energy_virial) const { energy_virial += compute_item_team_ev(team,list,typename DoCoul::type()); } }; @@ -711,7 +714,7 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename std::enable_if +template int GetTeamSize(FunctorStyle& KOKKOS_GPU_ARG(functor), int KOKKOS_GPU_ARG(inum), int KOKKOS_GPU_ARG(reduce_flag), int team_size, int KOKKOS_GPU_ARG(vector_length)) { @@ -719,9 +722,9 @@ int GetTeamSize(FunctorStyle& KOKKOS_GPU_ARG(functor), int KOKKOS_GPU_ARG(inum), int team_size_max; if (reduce_flag) - team_size_max = Kokkos::TeamPolicy<>(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelReduceTag()); + team_size_max = Kokkos::TeamPolicy(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelReduceTag()); else - team_size_max = Kokkos::TeamPolicy<>(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelForTag()); + team_size_max = Kokkos::TeamPolicy(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelForTag()); if (team_size*vector_length > team_size_max) team_size = team_size_max/vector_length; @@ -746,14 +749,14 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename std::enable_if<(NEIG if (fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { PairComputeFunctor ff(fpair,list); - atoms_per_team = GetTeamSize(ff, list->inum, (fpair->eflag || fpair->vflag), atoms_per_team, vector_length); - Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); + atoms_per_team = GetTeamSize(ff, list->inum, (fpair->eflag || fpair->vflag), atoms_per_team, vector_length); + Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); else Kokkos::parallel_for(policy,ff); } else { PairComputeFunctor ff(fpair,list); - atoms_per_team = GetTeamSize(ff, list->inum, (fpair->eflag || fpair->vflag), atoms_per_team, vector_length); - Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); + atoms_per_team = GetTeamSize(ff, list->inum, (fpair->eflag || fpair->vflag), atoms_per_team, vector_length); + Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); else Kokkos::parallel_for(policy,ff); } diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 1107d39fe9..820e0e4924 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -669,7 +669,7 @@ int PairMultiLucyRXKokkos::pack_forward_comm_kokkos(int n, DAT::tdua d_sendlist = k_sendlist.view(); iswap = iswap_in; v_buf = buf.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); return n; } @@ -687,7 +687,7 @@ void PairMultiLucyRXKokkos::unpack_forward_comm_kokkos(int n, int fi { first = first_in; v_buf = buf.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); atomKK->modified(execution_space,DPDRHO_MASK); // needed for auto_sync } diff --git a/src/KOKKOS/pair_reaxff_kokkos.cpp b/src/KOKKOS/pair_reaxff_kokkos.cpp index 8d9c498005..3a19a3825d 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.cpp +++ b/src/KOKKOS/pair_reaxff_kokkos.cpp @@ -843,12 +843,12 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) k_resize_bo.modify(); k_resize_bo.sync(); int resize_bo = k_resize_bo.h_view(); - if (resize_bo) maxbo++; + if (resize_bo) maxbo = MAX(maxbo+MAX(1,maxbo*0.1),resize_bo); k_resize_hb.modify(); k_resize_hb.sync(); int resize_hb = k_resize_hb.h_view(); - if (resize_hb) maxhb++; + if (resize_hb) maxhb = MAX(maxhb+MAX(1,maxhb*0.1),resize_hb); resize = resize_bo || resize_hb; if (resize) { @@ -1122,8 +1122,8 @@ void PairReaxFFKokkos::operator()(PairReaxFFComputeLJCoulomb::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); F_FLOAT powr_vdw, powgi_vdw, fn13, dfn13, exp1, exp2, etmp; F_FLOAT evdwl, fvdwl; @@ -1313,8 +1313,8 @@ void PairReaxFFKokkos::operator()(PairReaxFFComputeTabulatedLJCoulom // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -1711,14 +1711,11 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxBuildListsHalf, const int &ii) const { - if (d_resize_bo() || d_resize_hb()) - return; + auto v_dDeltap_self = ScatterViewHelper,decltype(dup_dDeltap_self),decltype(ndup_dDeltap_self)>::get(dup_dDeltap_self,ndup_dDeltap_self); + auto a_dDeltap_self = v_dDeltap_self.template access>(); - auto v_dDeltap_self = ScatterViewHelper::value,decltype(dup_dDeltap_self),decltype(ndup_dDeltap_self)>::get(dup_dDeltap_self,ndup_dDeltap_self); - auto a_dDeltap_self = v_dDeltap_self.template access::value>(); - - auto v_total_bo = ScatterViewHelper::value,decltype(dup_total_bo),decltype(ndup_total_bo)>::get(dup_total_bo,ndup_total_bo); - auto a_total_bo = v_total_bo.template access::value>(); + auto v_total_bo = ScatterViewHelper,decltype(dup_total_bo),decltype(ndup_total_bo)>::get(dup_total_bo,ndup_total_bo); + auto a_total_bo = v_total_bo.template access>(); const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -1777,12 +1774,10 @@ void PairReaxFFKokkos::operator()(PairReaxBuildListsHalf, const int jj_index = j_index - hb_first_i; - if (jj_index >= maxhb) { - d_resize_hb() = 1; - return; - } - - d_hb_list[j_index] = j; + if (jj_index >= maxhb) + d_resize_hb() = MAX(d_resize_hb(),jj_index+1); + else + d_hb_list[j_index] = j; } else if (j < nlocal && ihb == 2 && jhb == 1) { if (NEIGHFLAG == HALF) { i_index = d_hb_first[j] + d_hb_num[j]; @@ -1793,12 +1788,10 @@ void PairReaxFFKokkos::operator()(PairReaxBuildListsHalf, const int ii_index = i_index - d_hb_first[j]; - if (ii_index >= maxhb) { - d_resize_hb() = 1; - return; - } - - d_hb_list[i_index] = i; + if (ii_index >= maxhb) + d_resize_hb() = MAX(d_resize_hb(),ii_index+1); + else + d_hb_list[i_index] = i; } } @@ -1851,68 +1844,68 @@ void PairReaxFFKokkos::operator()(PairReaxBuildListsHalf, const int ii_index = i_index - d_bo_first[j]; if (jj_index >= maxbo || ii_index >= maxbo) { - d_resize_bo() = 1; - return; + const int max_val = MAX(ii_index+1,jj_index+1); + d_resize_bo() = MAX(d_resize_bo(),max_val); + } else { + d_bo_list[j_index] = j; + d_bo_list[i_index] = i; + + // from BondOrder1 + + d_BO(i,jj_index) = BO; + d_BO_s(i,jj_index) = BO_s; + d_BO_pi(i,jj_index) = BO_pi; + d_BO_pi2(i,jj_index) = BO_pi2; + + d_BO(j,ii_index) = BO; + d_BO_s(j,ii_index) = BO_s; + d_BO_pi(j,ii_index) = BO_pi; + d_BO_pi2(j,ii_index) = BO_pi2; + + F_FLOAT Cln_BOp_s = p_bo2 * C12 / rij / rij; + F_FLOAT Cln_BOp_pi = p_bo4 * C34 / rij / rij; + F_FLOAT Cln_BOp_pi2 = p_bo6 * C56 / rij / rij; + + if (nlocal == 0) + Cln_BOp_s = Cln_BOp_pi = Cln_BOp_pi2 = 0.0; + + for (int d = 0; d < 3; d++) dln_BOp_pi_i[d] = -(BO_pi*Cln_BOp_pi)*delij[d]; + for (int d = 0; d < 3; d++) dln_BOp_pi2_i[d] = -(BO_pi2*Cln_BOp_pi2)*delij[d]; + for (int d = 0; d < 3; d++) dBOp_i[d] = -(BO_s*Cln_BOp_s+BO_pi*Cln_BOp_pi+BO_pi2*Cln_BOp_pi2)*delij[d]; + for (int d = 0; d < 3; d++) a_dDeltap_self(i,d) += dBOp_i[d]; + for (int d = 0; d < 3; d++) a_dDeltap_self(j,d) += -dBOp_i[d]; + + d_dln_BOp_pix(i,jj_index) = dln_BOp_pi_i[0]; + d_dln_BOp_piy(i,jj_index) = dln_BOp_pi_i[1]; + d_dln_BOp_piz(i,jj_index) = dln_BOp_pi_i[2]; + + d_dln_BOp_pix(j,ii_index) = -dln_BOp_pi_i[0]; + d_dln_BOp_piy(j,ii_index) = -dln_BOp_pi_i[1]; + d_dln_BOp_piz(j,ii_index) = -dln_BOp_pi_i[2]; + + d_dln_BOp_pi2x(i,jj_index) = dln_BOp_pi2_i[0]; + d_dln_BOp_pi2y(i,jj_index) = dln_BOp_pi2_i[1]; + d_dln_BOp_pi2z(i,jj_index) = dln_BOp_pi2_i[2]; + + d_dln_BOp_pi2x(j,ii_index) = -dln_BOp_pi2_i[0]; + d_dln_BOp_pi2y(j,ii_index) = -dln_BOp_pi2_i[1]; + d_dln_BOp_pi2z(j,ii_index) = -dln_BOp_pi2_i[2]; + + d_dBOpx(i,jj_index) = dBOp_i[0]; + d_dBOpy(i,jj_index) = dBOp_i[1]; + d_dBOpz(i,jj_index) = dBOp_i[2]; + + d_dBOpx(j,ii_index) = -dBOp_i[0]; + d_dBOpy(j,ii_index) = -dBOp_i[1]; + d_dBOpz(j,ii_index) = -dBOp_i[2]; + + d_BO(i,jj_index) -= bo_cut; + d_BO(j,ii_index) -= bo_cut; + d_BO_s(i,jj_index) -= bo_cut; + d_BO_s(j,ii_index) -= bo_cut; + total_bo += d_BO(i,jj_index); + a_total_bo[j] += d_BO(j,ii_index); } - - d_bo_list[j_index] = j; - d_bo_list[i_index] = i; - - // from BondOrder1 - - d_BO(i,jj_index) = BO; - d_BO_s(i,jj_index) = BO_s; - d_BO_pi(i,jj_index) = BO_pi; - d_BO_pi2(i,jj_index) = BO_pi2; - - d_BO(j,ii_index) = BO; - d_BO_s(j,ii_index) = BO_s; - d_BO_pi(j,ii_index) = BO_pi; - d_BO_pi2(j,ii_index) = BO_pi2; - - F_FLOAT Cln_BOp_s = p_bo2 * C12 / rij / rij; - F_FLOAT Cln_BOp_pi = p_bo4 * C34 / rij / rij; - F_FLOAT Cln_BOp_pi2 = p_bo6 * C56 / rij / rij; - - if (nlocal == 0) - Cln_BOp_s = Cln_BOp_pi = Cln_BOp_pi2 = 0.0; - - for (int d = 0; d < 3; d++) dln_BOp_pi_i[d] = -(BO_pi*Cln_BOp_pi)*delij[d]; - for (int d = 0; d < 3; d++) dln_BOp_pi2_i[d] = -(BO_pi2*Cln_BOp_pi2)*delij[d]; - for (int d = 0; d < 3; d++) dBOp_i[d] = -(BO_s*Cln_BOp_s+BO_pi*Cln_BOp_pi+BO_pi2*Cln_BOp_pi2)*delij[d]; - for (int d = 0; d < 3; d++) a_dDeltap_self(i,d) += dBOp_i[d]; - for (int d = 0; d < 3; d++) a_dDeltap_self(j,d) += -dBOp_i[d]; - - d_dln_BOp_pix(i,jj_index) = dln_BOp_pi_i[0]; - d_dln_BOp_piy(i,jj_index) = dln_BOp_pi_i[1]; - d_dln_BOp_piz(i,jj_index) = dln_BOp_pi_i[2]; - - d_dln_BOp_pix(j,ii_index) = -dln_BOp_pi_i[0]; - d_dln_BOp_piy(j,ii_index) = -dln_BOp_pi_i[1]; - d_dln_BOp_piz(j,ii_index) = -dln_BOp_pi_i[2]; - - d_dln_BOp_pi2x(i,jj_index) = dln_BOp_pi2_i[0]; - d_dln_BOp_pi2y(i,jj_index) = dln_BOp_pi2_i[1]; - d_dln_BOp_pi2z(i,jj_index) = dln_BOp_pi2_i[2]; - - d_dln_BOp_pi2x(j,ii_index) = -dln_BOp_pi2_i[0]; - d_dln_BOp_pi2y(j,ii_index) = -dln_BOp_pi2_i[1]; - d_dln_BOp_pi2z(j,ii_index) = -dln_BOp_pi2_i[2]; - - d_dBOpx(i,jj_index) = dBOp_i[0]; - d_dBOpy(i,jj_index) = dBOp_i[1]; - d_dBOpz(i,jj_index) = dBOp_i[2]; - - d_dBOpx(j,ii_index) = -dBOp_i[0]; - d_dBOpy(j,ii_index) = -dBOp_i[1]; - d_dBOpz(j,ii_index) = -dBOp_i[2]; - - d_BO(i,jj_index) -= bo_cut; - d_BO(j,ii_index) -= bo_cut; - d_BO_s(i,jj_index) -= bo_cut; - d_BO_s(j,ii_index) -= bo_cut; - total_bo += d_BO(i,jj_index); - a_total_bo[j] += d_BO(j,ii_index); } a_total_bo[i] += total_bo; @@ -2142,8 +2135,8 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxFFComputeMulti2, const int &ii, EV_FLOAT_REAX& ev) const { - auto v_CdDelta = ScatterViewHelper::value,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); - auto a_CdDelta = v_CdDelta.template access::value>(); + auto v_CdDelta = ScatterViewHelper,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); + auto a_CdDelta = v_CdDelta.template access>(); const int i = d_ilist[ii]; const int itype = type(i); @@ -2294,12 +2287,12 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxFFComputeAngular, const int &ii, EV_FLOAT_REAX& ev) const { - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); Kokkos::View::value,Kokkos::MemoryTraits::value> > a_Cdbo = d_Cdbo; - auto v_CdDelta = ScatterViewHelper::value,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); - auto a_CdDelta = v_CdDelta.template access::value>(); + auto v_CdDelta = ScatterViewHelper,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); + auto a_CdDelta = v_CdDelta.template access>(); const int i = d_ilist[ii]; const int itype = type(i); @@ -2606,13 +2599,13 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxFFComputeTorsion, const int &ii, EV_FLOAT_REAX& ev) const { - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); - auto v_CdDelta = ScatterViewHelper::value,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); - auto a_CdDelta = v_CdDelta.template access::value>(); + auto v_CdDelta = ScatterViewHelper,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); + auto a_CdDelta = v_CdDelta.template access>(); Kokkos::View::value,Kokkos::MemoryTraits::value> > a_Cdbo = d_Cdbo; - //auto a_Cdbo = dup_Cdbo.template access::value>(); + //auto a_Cdbo = dup_Cdbo.template access>(); // in reaxff_torsion_angles: j = i, k = j, i = k; @@ -2981,8 +2974,8 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxFFComputeHydrogen, const int &ii, EV_FLOAT_REAX& ev) const { - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); int hblist[MAX_BONDS]; F_FLOAT theta, cos_theta, sin_xhz4, cos_xhz1, sin_theta2; @@ -3131,9 +3124,9 @@ void PairReaxFFKokkos::operator()(PairReaxUpdateBond, con Kokkos::View::value,Kokkos::MemoryTraits::value> > a_Cdbo = d_Cdbo; Kokkos::View::value,Kokkos::MemoryTraits::value> > a_Cdbopi = d_Cdbopi; Kokkos::View::value,Kokkos::MemoryTraits::value> > a_Cdbopi2 = d_Cdbopi2; - //auto a_Cdbo = dup_Cdbo.template access::value>(); - //auto a_Cdbopi = dup_Cdbopi.template access::value>(); - //auto a_Cdbopi2 = dup_Cdbopi2.template access::value>(); + //auto a_Cdbo = dup_Cdbo.template access>(); + //auto a_Cdbopi = dup_Cdbopi.template access>(); + //auto a_Cdbopi2 = dup_Cdbopi2.template access>(); const int i = d_ilist[ii]; const tagint itag = tag(i); @@ -3180,10 +3173,10 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxFFComputeBond1, const int &ii, EV_FLOAT_REAX& ev) const { - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto v_CdDelta = ScatterViewHelper::value,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); - auto a_CdDelta = v_CdDelta.template access::value>(); + auto v_CdDelta = ScatterViewHelper,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); + auto a_CdDelta = v_CdDelta.template access>(); F_FLOAT p_be1, p_be2, De_s, De_p, De_pp, pow_BOs_be2, exp_be12, CEbo, ebond; @@ -3298,8 +3291,8 @@ template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(PairReaxFFComputeBond2, const int &ii, EV_FLOAT_REAX& ev) const { - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); F_FLOAT delij[3], delik[3], deljk[3], tmpvec[3]; F_FLOAT dBOp_i[3], dBOp_k[3], dln_BOp_pi[3], dln_BOp_pi2[3]; @@ -3505,11 +3498,11 @@ void PairReaxFFKokkos::ev_tally(EV_FLOAT_REAX &ev, const int &i, con // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (eflag_atom) { const E_FLOAT epairhalf = 0.5 * epair; @@ -3564,8 +3557,8 @@ void PairReaxFFKokkos::e_tally(EV_FLOAT_REAX & /*ev*/, const int &i, if (eflag_atom) { - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); const E_FLOAT epairhalf = 0.5 * epair; a_eatom[i] += epairhalf; @@ -3582,8 +3575,8 @@ void PairReaxFFKokkos::e_tally_single(EV_FLOAT_REAX & /*ev*/, const const F_FLOAT &epair) const { // The eatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); a_eatom[i] += epair; } @@ -3616,8 +3609,8 @@ void PairReaxFFKokkos::v_tally(EV_FLOAT_REAX &ev, const int &i, } if (vflag_atom) { - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); a_vatom(i,0) += v[0]; a_vatom(i,1) += v[1]; a_vatom(i,2) += v[2]; a_vatom(i,3) += v[3]; a_vatom(i,4) += v[4]; a_vatom(i,5) += v[5]; @@ -3634,8 +3627,8 @@ void PairReaxFFKokkos::v_tally3(EV_FLOAT_REAX &ev, const int &i, con { // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); F_FLOAT v[6]; @@ -3696,8 +3689,8 @@ void PairReaxFFKokkos::v_tally4(EV_FLOAT_REAX &ev, const int &i, con } if (vflag_atom) { - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); a_vatom(i,0) += 0.25 * v[0]; a_vatom(i,1) += 0.25 * v[1]; a_vatom(i,2) += 0.25 * v[2]; a_vatom(i,3) += 0.25 * v[3]; a_vatom(i,4) += 0.25 * v[4]; a_vatom(i,5) += 0.25 * v[5]; diff --git a/src/KOKKOS/pair_reaxff_kokkos.h b/src/KOKKOS/pair_reaxff_kokkos.h index a88248a717..c74a35fab9 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.h +++ b/src/KOKKOS/pair_reaxff_kokkos.h @@ -387,25 +387,33 @@ class PairReaxFFKokkos : public PairReaxFF { typename AT::t_ffloat_2d_dl d_C1dbopi2, d_C2dbopi2, d_C3dbopi2, d_C4dbopi2; typename AT::t_ffloat_2d_dl d_Cdbo, d_Cdbopi, d_Cdbopi2, d_dDeltap_self; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_total_bo; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_CdDelta; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_dDeltap_self; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_Cdbo; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_Cdbopi; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_Cdbopi2; + using KKDeviceType = typename KKDevice::value; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_total_bo; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_CdDelta; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_dDeltap_self; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_Cdbo; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_Cdbopi; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_Cdbopi2; + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_total_bo; + DupScatterView dup_CdDelta; + DupScatterView dup_eatom; + DupScatterView dup_f; + DupScatterView dup_vatom; + DupScatterView dup_dDeltap_self; + DupScatterView dup_Cdbo; + DupScatterView dup_Cdbopi; + DupScatterView dup_Cdbopi2; + + NonDupScatterView ndup_total_bo; + NonDupScatterView ndup_CdDelta; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_f; + NonDupScatterView ndup_vatom; + NonDupScatterView ndup_dDeltap_self; + NonDupScatterView ndup_Cdbo; + NonDupScatterView ndup_Cdbopi; + NonDupScatterView ndup_Cdbopi2; int need_dup; diff --git a/src/KOKKOS/pair_snap_kokkos.h b/src/KOKKOS/pair_snap_kokkos.h index b728d92f96..bdad113c18 100644 --- a/src/KOKKOS/pair_snap_kokkos.h +++ b/src/KOKKOS/pair_snap_kokkos.h @@ -297,10 +297,20 @@ inline double dist2(double* x,double* y); typename AT::t_int_1d_randomread type; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_f; + DupScatterView dup_vatom; + + NonDupScatterView ndup_f; + NonDupScatterView ndup_vatom; friend void pair_virial_fdotr_compute(PairSNAPKokkos*); diff --git a/src/KOKKOS/pair_snap_kokkos_impl.h b/src/KOKKOS/pair_snap_kokkos_impl.h index e66f490f8a..49c022105d 100644 --- a/src/KOKKOS/pair_snap_kokkos_impl.h +++ b/src/KOKKOS/pair_snap_kokkos_impl.h @@ -1257,8 +1257,8 @@ KOKKOS_INLINE_FUNCTION void PairSNAPKokkos::operator() (TagPairSNAPComputeForce, const int& ii, EV_FLOAT& ev) const { // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii + chunk_offset]; @@ -1358,8 +1358,8 @@ void PairSNAPKokkos::v_tally_xyz(EV_FLOAT { // The vatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); const E_FLOAT v0 = delx*fx; const E_FLOAT v1 = dely*fy; diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index 59949551f6..dec7d12ebb 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -246,8 +246,8 @@ void PairSWKokkos::operator()(TagPairSWComputeHalf // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_f = ScatterViewHelper::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); F_FLOAT delr1[3],delr2[3],fj[3],fk[3]; F_FLOAT evdwl = 0.0; @@ -339,7 +339,7 @@ void PairSWKokkos::operator()(TagPairSWComputeHalf if (rsq2 >= d_params[ikparam].cutsq) continue; - threebody(d_params[ijparam],d_params[ikparam],d_params[ijkparam], + threebody_kk(d_params[ijparam],d_params[ikparam],d_params[ijkparam], rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl); fxtmpi -= fj[0] + fk[0]; @@ -457,7 +457,7 @@ void PairSWKokkos::operator()(TagPairSWComputeFullA= d_params[ikparam].cutsq) continue; - threebody(d_params[ijparam],d_params[ikparam],d_params[ijkparam], + threebody_kk(d_params[ijparam],d_params[ikparam],d_params[ijkparam], rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl); fxtmpi -= fj[0] + fk[0]; @@ -542,7 +542,7 @@ void PairSWKokkos::operator()(TagPairSWComputeFullB= d_params[jkparam].cutsq) continue; if (vflag_atom) - threebody(d_params[jiparam],d_params[jkparam],d_params[jikparam], + threebody_kk(d_params[jiparam],d_params[jkparam],d_params[jikparam], rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl); else threebodyj(d_params[jiparam],d_params[jkparam],d_params[jikparam], @@ -686,7 +686,7 @@ void PairSWKokkos::twobody(const Param& param, const F_FLOAT& rsq, F template KOKKOS_INLINE_FUNCTION -void PairSWKokkos::threebody(const Param& paramij, const Param& paramik, const Param& paramijk, +void PairSWKokkos::threebody_kk(const Param& paramij, const Param& paramik, const Param& paramijk, const F_FLOAT& rsq1, const F_FLOAT& rsq2, F_FLOAT *delr1, F_FLOAT *delr2, F_FLOAT *fj, F_FLOAT *fk, const int& eflag, F_FLOAT& eng) const @@ -800,11 +800,11 @@ void PairSWKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (eflag_atom) { const E_FLOAT epairhalf = 0.5 * epair; @@ -878,11 +878,11 @@ void PairSWKokkos::ev_tally3(EV_FLOAT &ev, const int &i, const int & // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (eflag_atom) { epairthird = THIRD * (evdwl + ecoul); diff --git a/src/KOKKOS/pair_sw_kokkos.h b/src/KOKKOS/pair_sw_kokkos.h index 3513a8d621..1259ddf71e 100644 --- a/src/KOKKOS/pair_sw_kokkos.h +++ b/src/KOKKOS/pair_sw_kokkos.h @@ -118,8 +118,8 @@ class PairSWKokkos : public PairSW { void twobody(const Param&, const F_FLOAT&, F_FLOAT&, const int&, F_FLOAT&) const; KOKKOS_INLINE_FUNCTION - void threebody(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, - F_FLOAT *, F_FLOAT *, const int&, F_FLOAT&) const; + void threebody_kk(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, + F_FLOAT *, F_FLOAT *, const int&, F_FLOAT&) const; KOKKOS_INLINE_FUNCTION void threebodyj(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, @@ -136,12 +136,22 @@ class PairSWKokkos : public PairSW { typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; typename AT::t_int_1d_randomread d_type2frho; typename AT::t_int_2d_randomread d_type2rhor; diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 8700bd356f..d98b690c9c 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -328,8 +328,8 @@ void PairTersoffKokkos::operator()(TagPairTersoffComputeHalf::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; if (i >= nlocal) return; @@ -1143,11 +1143,11 @@ void PairTersoffKokkos::ev_tally(EV_FLOAT &ev, const int &i, const i // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (eflag_atom) { const E_FLOAT epairhalf = 0.5 * epair; @@ -1211,8 +1211,8 @@ void PairTersoffKokkos::v_tally3(EV_FLOAT &ev, const int &i, const i { // The vatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); F_FLOAT v[6]; diff --git a/src/KOKKOS/pair_tersoff_kokkos.h b/src/KOKKOS/pair_tersoff_kokkos.h index 77da7bad4b..2df74721d0 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.h +++ b/src/KOKKOS/pair_tersoff_kokkos.h @@ -196,16 +196,26 @@ class PairTersoffKokkos : public PairTersoff { DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 51800cd1a1..388e216a41 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -328,8 +328,8 @@ void PairTersoffMODKokkos::operator()(TagPairTersoffMODComputeHalf::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; if (i >= nlocal) return; @@ -1146,11 +1146,11 @@ void PairTersoffMODKokkos::ev_tally(EV_FLOAT &ev, const int &i, cons // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (eflag_atom) { const E_FLOAT epairhalf = 0.5 * epair; @@ -1214,8 +1214,8 @@ void PairTersoffMODKokkos::v_tally3(EV_FLOAT &ev, const int &i, cons { // The vatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); F_FLOAT v[6]; diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.h b/src/KOKKOS/pair_tersoff_mod_kokkos.h index ffc8e24ed3..dc5204bdbe 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.h +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.h @@ -181,6 +181,8 @@ class PairTersoffMODKokkos : public PairTersoffMOD { void setup_params() override; protected: + using KKDeviceType = typename KKDevice::value; + typedef Kokkos::DualView tdual_int_3d; Kokkos::DualView k_params; typename Kokkos::DualView::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index 3f9beb6041..d718e2a785 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -344,8 +344,8 @@ void PairTersoffZBLKokkos::operator()(TagPairTersoffZBLComputeHalf::value,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); - auto a_f = v_f.template access::value>(); + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); const int i = d_ilist[ii]; if (i >= nlocal) return; @@ -1242,11 +1242,11 @@ void PairTersoffZBLKokkos::ev_tally(EV_FLOAT &ev, const int &i, cons // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_eatom = ScatterViewHelper::value,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access::value>(); + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); if (eflag_atom) { const E_FLOAT epairhalf = 0.5 * epair; @@ -1310,8 +1310,8 @@ void PairTersoffZBLKokkos::v_tally3(EV_FLOAT &ev, const int &i, cons { // The vatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_vatom = ScatterViewHelper::value,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); - auto a_vatom = v_vatom.template access::value>(); + auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); + auto a_vatom = v_vatom.template access>(); F_FLOAT v[6]; diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.h b/src/KOKKOS/pair_tersoff_zbl_kokkos.h index 9c52c1b2f9..57402fe683 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.h +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.h @@ -201,24 +201,34 @@ class PairTersoffZBLKokkos : public PairTersoffZBL { DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; int need_dup; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterDuplicated> dup_vatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_f; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_eatom; - Kokkos::Experimental::ScatterView::value,typename Kokkos::Experimental::ScatterSum,Kokkos::Experimental::ScatterNonDuplicated> ndup_vatom; + + using KKDeviceType = typename KKDevice::value; + + template + using DupScatterView = KKScatterView; + + template + using NonDupScatterView = KKScatterView; + + DupScatterView dup_f; + DupScatterView dup_eatom; + DupScatterView dup_vatom; + + NonDupScatterView ndup_f; + NonDupScatterView ndup_eatom; + NonDupScatterView ndup_vatom; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; typedef typename tdual_ffloat_2d_n7::t_host t_host_ffloat_2d_n7; - typename ArrayTypes::t_neighbors_2d d_neighbors; - typename ArrayTypes::t_int_1d_randomread d_ilist; - typename ArrayTypes::t_int_1d_randomread d_numneigh; + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist; + typename AT::t_int_1d_randomread d_numneigh; //NeighListKokkos k_list; int neighflag,newton_pair; diff --git a/src/KOKKOS/sna_kokkos.h b/src/KOKKOS/sna_kokkos.h index 0bcb07285c..c33f5e486e 100644 --- a/src/KOKKOS/sna_kokkos.h +++ b/src/KOKKOS/sna_kokkos.h @@ -69,9 +69,11 @@ public: using complex = SNAComplex; static constexpr int vector_length = vector_length_; + using KKDeviceType = typename KKDevice::value; + typedef Kokkos::View t_sna_1i; typedef Kokkos::View t_sna_1d; - typedef Kokkos::View::value, Kokkos::MemoryTraits > t_sna_1d_atomic; + typedef Kokkos::View> t_sna_1d_atomic; typedef Kokkos::View t_sna_2i; typedef Kokkos::View t_sna_2d; typedef Kokkos::View t_sna_2d_ll; @@ -83,7 +85,7 @@ public: typedef Kokkos::View t_sna_5d; typedef Kokkos::View t_sna_1c; - typedef Kokkos::View::value, Kokkos::MemoryTraits > t_sna_1c_atomic; + typedef Kokkos::View> t_sna_1c_atomic; typedef Kokkos::View t_sna_2c; typedef Kokkos::View t_sna_2c_ll; typedef Kokkos::View t_sna_2c_lr; diff --git a/src/KOKKOS/third_order_kokkos.cpp b/src/KOKKOS/third_order_kokkos.cpp new file mode 100644 index 0000000000..2aeb9152a1 --- /dev/null +++ b/src/KOKKOS/third_order_kokkos.cpp @@ -0,0 +1,353 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Charlie Sievers (UC Davis), charliesievers at cox.net +------------------------------------------------------------------------- */ + +#include "third_order_kokkos.h" + +#include "angle.h" +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "bond.h" +#include "comm.h" +#include "compute.h" +#include "dihedral.h" +#include "domain.h" +#include "error.h" +#include "finish.h" +#include "force.h" +#include "group.h" +#include "improper.h" +#include "kokkos.h" +#include "kspace.h" +#include "memory.h" +#include "modify.h" +#include "neighbor.h" +#include "pair.h" +#include "timer.h" +#include "update.h" + +#include +#include +#include + +using namespace LAMMPS_NS; +enum{REGULAR,ESKM}; + +template +struct ForceAdder { + ViewA a; + ViewB b; + ForceAdder(const ViewA& a_, const ViewB& b_):a(a_),b(b_) {} + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + a(i,0) += b(i,0); + a(i,1) += b(i,1); + a(i,2) += b(i,2); + } +}; + +/* ---------------------------------------------------------------------- */ + +template +struct Zero { + View v; + Zero(const View &v_):v(v_) {} + KOKKOS_INLINE_FUNCTION + void operator()(const int &i) const { + v(i,0) = 0; + v(i,1) = 0; + v(i,2) = 0; + } +}; + +/* ---------------------------------------------------------------------- */ + +ThirdOrderKokkos::ThirdOrderKokkos(LAMMPS *lmp) : ThirdOrder(lmp) +{ + atomKK = (AtomKokkos *) atom; +} + +/* ---------------------------------------------------------------------- */ + +ThirdOrderKokkos::~ThirdOrderKokkos() +{ + +} + +/* ---------------------------------------------------------------------- */ + +void ThirdOrderKokkos::command(int narg, char **arg) +{ + atomKK->sync(Host, X_MASK|RMASS_MASK|TYPE_MASK); + ThirdOrder::command(narg, arg); +} + +/* ---------------------------------------------------------------------- + setup without output or one-time post-init setup + flag = 0 = just force calculation + flag = 1 = reneighbor and force calculation +------------------------------------------------------------------------- */ + +void ThirdOrderKokkos::setup() +{ + lmp->kokkos->auto_sync = 1; + + // setup domain, communication and neighboring + // acquire ghosts + // build neighbor lists + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + comm->exchange(); + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + domain->image_check(); + domain->box_too_small_check(); + neighbor->build(1); + + // compute all forces + eflag=0; + vflag=0; + if (force->kspace) { + force->kspace->setup(); + } + update_force(); + + if (pair_compute_flag) { + atomKK->sync(force->pair->execution_space,force->pair->datamask_read); + force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); + } + else if (force->pair) force->pair->compute_dummy(eflag,vflag); + update->setupflag = 0; + + lmp->kokkos->auto_sync = 0; + + //if all then skip communication groupmap population + if (gcount == atom->natoms) + for (bigint i=0; inatoms; i++) + groupmap[i] = i; + else + create_groupmap(); + +} + +/* ---------------------------------------------------------------------- + evaluate potential energy and forces + may migrate atoms due to reneighboring + return new energy, which should include nextra_global dof + return negative gradient stored in atom->f + return negative gradient for nextra_global dof in fextra +------------------------------------------------------------------------- */ + +void ThirdOrderKokkos::update_force() +{ + int n_pre_force = modify->n_pre_force; + int n_pre_reverse = modify->n_pre_reverse; + int n_post_force = modify->n_post_force; + + lmp->kokkos->auto_sync = 0; + + f_merge_copy = DAT::t_f_array("ThirdOrderKokkos::f_merge_copy",atomKK->k_f.extent(0)); + + atomKK->modified(Host,X_MASK); + atomKK->sync(Device,X_MASK); + + force_clear(); + + neighbor->ago = 0; + if ((modify->get_fix_by_id("package_intel")) ? true : false) + neighbor->decide(); + + if (n_pre_force) { + modify->pre_force(vflag); + timer->stamp(Timer::MODIFY); + } + + bool execute_on_host = false; + unsigned int datamask_read_device = 0; + unsigned int datamask_modify_device = 0; + unsigned int datamask_read_host = 0; + + if (pair_compute_flag) { + if (force->pair->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->pair->datamask_read; + datamask_modify_device |= force->pair->datamask_modify; + } else { + datamask_read_device |= force->pair->datamask_read; + datamask_modify_device |= force->pair->datamask_modify; + } + } + if (atomKK->molecular && force->bond) { + if (force->bond->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->bond->datamask_read; + datamask_modify_device |= force->bond->datamask_modify; + } else { + datamask_read_device |= force->bond->datamask_read; + datamask_modify_device |= force->bond->datamask_modify; + } + } + if (atomKK->molecular && force->angle) { + if (force->angle->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->angle->datamask_read; + datamask_modify_device |= force->angle->datamask_modify; + } else { + datamask_read_device |= force->angle->datamask_read; + datamask_modify_device |= force->angle->datamask_modify; + } + } + if (atomKK->molecular && force->dihedral) { + if (force->dihedral->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->dihedral->datamask_read; + datamask_modify_device |= force->dihedral->datamask_modify; + } else { + datamask_read_device |= force->dihedral->datamask_read; + datamask_modify_device |= force->dihedral->datamask_modify; + } + } + if (atomKK->molecular && force->improper) { + if (force->improper->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->improper->datamask_read; + datamask_modify_device |= force->improper->datamask_modify; + } else { + datamask_read_device |= force->improper->datamask_read; + datamask_modify_device |= force->improper->datamask_modify; + } + } + if (kspace_compute_flag) { + if (force->kspace->execution_space==Host) { + execute_on_host = true; + datamask_read_host |= force->kspace->datamask_read; + datamask_modify_device |= force->kspace->datamask_modify; + } else { + datamask_read_device |= force->kspace->datamask_read; + datamask_modify_device |= force->kspace->datamask_modify; + } + } + + + if (pair_compute_flag) { + atomKK->sync(force->pair->execution_space,force->pair->datamask_read); + atomKK->sync(force->pair->execution_space,~(~force->pair->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + Kokkos::Timer ktimer; + force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); + atomKK->modified(force->pair->execution_space,~(~force->pair->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + timer->stamp(Timer::PAIR); + } + + if (execute_on_host) { + if (pair_compute_flag && force->pair->datamask_modify!=(F_MASK | ENERGY_MASK | VIRIAL_MASK)) + Kokkos::fence(); + atomKK->sync_overlapping_device(Host,~(~datamask_read_host|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + if (pair_compute_flag && force->pair->execution_space!=Host) { + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.h_view,0.0); + } + } + + if (atomKK->molecular) { + if (force->bond) { + atomKK->sync(force->bond->execution_space,~(~force->bond->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->bond->compute(eflag,vflag); + atomKK->modified(force->bond->execution_space,~(~force->bond->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + if (force->angle) { + atomKK->sync(force->angle->execution_space,~(~force->angle->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->angle->compute(eflag,vflag); + atomKK->modified(force->angle->execution_space,~(~force->angle->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + if (force->dihedral) { + atomKK->sync(force->dihedral->execution_space,~(~force->dihedral->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->dihedral->compute(eflag,vflag); + atomKK->modified(force->dihedral->execution_space,~(~force->dihedral->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + if (force->improper) { + atomKK->sync(force->improper->execution_space,~(~force->improper->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->improper->compute(eflag,vflag); + atomKK->modified(force->improper->execution_space,~(~force->improper->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + } + timer->stamp(Timer::BOND); + } + + if (kspace_compute_flag) { + atomKK->sync(force->kspace->execution_space,~(~force->kspace->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + force->kspace->compute(eflag,vflag); + atomKK->modified(force->kspace->execution_space,~(~force->kspace->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); + timer->stamp(Timer::KSPACE); + } + + if (execute_on_host && !std::is_same::value) { + if (f_merge_copy.extent(0)k_f.extent(0)) { + f_merge_copy = DAT::t_f_array("ThirdOrderKokkos::f_merge_copy",atomKK->k_f.extent(0)); + } + f = atomKK->k_f.d_view; + Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.h_view); + Kokkos::parallel_for(atomKK->k_f.extent(0), + ForceAdder(atomKK->k_f.d_view,f_merge_copy)); + atomKK->k_f.clear_sync_state(); // special case + atomKK->k_f.modify(); + } + if (n_pre_reverse) { + modify->pre_reverse(eflag,vflag); + timer->stamp(Timer::MODIFY); + } + if (force->newton) { + comm->reverse_comm(); + timer->stamp(Timer::COMM); + } + // force modifications + + if (n_post_force) { + modify->post_force(vflag); + timer->stamp(Timer::MODIFY); + } + + atomKK->sync(Host,F_MASK); + lmp->kokkos->auto_sync = 1; + + ++ update->nsteps; +} + +/* ---------------------------------------------------------------------- + clear force on own & ghost atoms + clear other arrays as needed +------------------------------------------------------------------------- */ + +void ThirdOrderKokkos::force_clear() +{ + if (external_force_clear) return; + + atomKK->k_f.clear_sync_state(); // ignore host forces/torques since device views + + // clear force on all particles + // if either newton flag is set, also include ghosts + // when using threads always clear all forces. + + int nall = atomKK->nlocal; + if (force->newton) nall += atomKK->nghost; + + Kokkos::parallel_for(nall, Zero::t_f_array>(atomKK->k_f.view())); + atomKK->modified(Device,F_MASK); + +} diff --git a/src/KOKKOS/third_order_kokkos.h b/src/KOKKOS/third_order_kokkos.h new file mode 100644 index 0000000000..5392c825c5 --- /dev/null +++ b/src/KOKKOS/third_order_kokkos.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMMAND_CLASS +// clang-format off +CommandStyle(third_order/kk,ThirdOrderKokkos); +CommandStyle(third_order/kk/device,ThirdOrderKokkos); +CommandStyle(third_order/kk/host,ThirdOrderKokkos); +// clang-format on +#else + +#ifndef LMP_THIRD_ORDER_KOKKOS_H +#define LMP_THIRD_ORDER_KOKKOS_H + +#include "third_order.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class ThirdOrderKokkos : public ThirdOrder { + public: + ThirdOrderKokkos(class LAMMPS *); + ~ThirdOrderKokkos() override; + void command(int, char **) override; + void setup(); + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + f(i,0) += f_merge_copy(i,0); + f(i,1) += f_merge_copy(i,1); + f(i,2) += f_merge_copy(i,2); + } + + protected: + void update_force(); + void force_clear(); + DAT::t_f_array f_merge_copy,f; + + +}; +} // namespace LAMMPS_NS + +#endif //LMP_THIRD_ORDER_KOKKOS_H +#endif diff --git a/src/MANYBODY/pair_eam_cd.cpp b/src/MANYBODY/pair_eam_cd.cpp index dc1ec360c6..376469e238 100644 --- a/src/MANYBODY/pair_eam_cd.cpp +++ b/src/MANYBODY/pair_eam_cd.cpp @@ -505,8 +505,10 @@ void PairEAMCD::read_h_coeff(char *filename) utils::getsyserror()); char *buf = new char[MAXLINE+1]; - utils::sfread(FLERR, buf, 1, MAXLINE, fptr, filename, error); - buf[MAXLINE] = '\0'; // must 0-terminate buffer for string processing + auto rv = fread(buf,1,MAXLINE,fptr); + if (rv == 0) error->one(FLERR,"Failure to read h(x) coeffs: {}", utils::getsyserror()); + buf[rv] = '\0'; // must 0-terminate buffer for string processing + Tokenizer lines(buf, "\n"); delete[] buf; diff --git a/src/Makefile b/src/Makefile index d23058447a..eeccc19ae0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -356,10 +356,10 @@ gitversion: branch='(unknown)' ; \ describe='(unknown)' ; \ fi ; \ - echo "const bool LAMMPS_NS::LAMMPS::has_git_info = $${git};" >> ${TMPNAME}.lmpgitversion ; \ - echo "const char LAMMPS_NS::LAMMPS::git_commit[] = \"$${commit}\";" >> ${TMPNAME}.lmpgitversion ; \ - echo "const char LAMMPS_NS::LAMMPS::git_branch[] = \"$${branch}\";" >> ${TMPNAME}.lmpgitversion ; \ - echo "const char LAMMPS_NS::LAMMPS::git_descriptor[] = \"$${describe}\";" >> ${TMPNAME}.lmpgitversion + echo "bool LAMMPS_NS::LAMMPS::has_git_info() { return $${git}; }" >> ${TMPNAME}.lmpgitversion ; \ + echo "const char *LAMMPS_NS::LAMMPS::git_commit() { return \"$${commit}\"; }" >> ${TMPNAME}.lmpgitversion ; \ + echo "const char *LAMMPS_NS::LAMMPS::git_branch() { return \"$${branch}\"; }" >> ${TMPNAME}.lmpgitversion ; \ + echo "const char *LAMMPS_NS::LAMMPS::git_descriptor() { return \"$${describe}\"; }" >> ${TMPNAME}.lmpgitversion @echo '#endif' >> ${TMPNAME}.lmpgitversion @if [ -f lmpgitversion.h ]; \ then test "`diff --brief ${TMPNAME}.lmpgitversion lmpgitversion.h`" != "" && \ diff --git a/src/PHONON/dynamical_matrix.cpp b/src/PHONON/dynamical_matrix.cpp index e236e24a15..3a596bfd05 100644 --- a/src/PHONON/dynamical_matrix.cpp +++ b/src/PHONON/dynamical_matrix.cpp @@ -10,11 +10,11 @@ the GNU General Public License. See the README file in the top-level LAMMPS directory. - ----------------------------------------------------------------------- */ +------------------------------------------------------------------------- */ -// -// Created by charlie sievers on 6/21/18. -// +/* ---------------------------------------------------------------------- + Contributing author: Charlie Sievers (UC Davis), charliesievers at cox.net +------------------------------------------------------------------------- */ #include "dynamical_matrix.h" @@ -22,6 +22,7 @@ #include "atom.h" #include "bond.h" #include "comm.h" +#include "compute.h" #include "dihedral.h" #include "domain.h" #include "error.h" @@ -48,14 +49,14 @@ enum{REGULAR,ESKM}; DynamicalMatrix::DynamicalMatrix(LAMMPS *lmp) : Command(lmp), fp(nullptr) { - external_force_clear = 1; + external_force_clear = 0; } /* ---------------------------------------------------------------------- */ DynamicalMatrix::~DynamicalMatrix() { - if (fp && me == 0) { + if (fp && comm->me == 0) { if (compressed) platform::pclose(fp); else fclose(fp); memory->destroy(groupmap); @@ -71,111 +72,120 @@ DynamicalMatrix::~DynamicalMatrix() void DynamicalMatrix::setup() { - // setup domain, communication and neighboring - // acquire ghosts - // build neighbor lists - if (triclinic) domain->x2lamda(atom->nlocal); - domain->pbc(); - domain->reset_box(); - comm->setup(); - if (neighbor->style) neighbor->setup_bins(); - comm->exchange(); - comm->borders(); - if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); - domain->image_check(); - domain->box_too_small_check(); - neighbor->build(1); + // setup domain, communication and neighboring + // acquire ghosts + // build neighbor lists + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + comm->exchange(); + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + domain->image_check(); + domain->box_too_small_check(); + neighbor->build(1); - // compute all forces - external_force_clear = 0; - eflag=0; - vflag=0; - update_force(); + // compute all forces + eflag=0; + vflag=0; + if (force->kspace) { + force->kspace->setup(); + } + update_force(); - //if all then skip communication groupmap population - if (gcount == atom->natoms) - for (bigint i=0; inatoms; i++) - groupmap[i] = i; - else - create_groupmap(); + + update->setupflag = 0; + + //if all then skip communication groupmap population + if (gcount == atom->natoms) + for (bigint i=0; inatoms; i++) + groupmap[i] = i; + else + create_groupmap(); } /* ---------------------------------------------------------------------- */ void DynamicalMatrix::command(int narg, char **arg) { - MPI_Comm_rank(world,&me); + MPI_Comm_rank(world,&me); - if (domain->box_exist == 0) - error->all(FLERR,"Dynamical_matrix command before simulation box is defined"); - if (narg < 2) error->all(FLERR,"Illegal dynamical_matrix command"); + if (domain->box_exist == 0) + error->all(FLERR,"Dynamical_matrix command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal dynamical_matrix command"); - lmp->init(); + lmp->init(); - // orthogonal vs triclinic simulation box + // orthogonal vs triclinic simulation box - triclinic = domain->triclinic; + triclinic = domain->triclinic; - if (force->pair && force->pair->compute_flag) pair_compute_flag = 1; - else pair_compute_flag = 0; - if (force->kspace && force->kspace->compute_flag) kspace_compute_flag = 1; - else kspace_compute_flag = 0; + if (force->pair && force->pair->compute_flag) pair_compute_flag = 1; + else pair_compute_flag = 0; + if (force->kspace && force->kspace->compute_flag) kspace_compute_flag = 1; + else kspace_compute_flag = 0; - // group and style + // group and style - igroup = group->find(arg[0]); - if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); - groupbit = group->bitmask[igroup]; - gcount = group->count(igroup); - dynlen = (gcount)*3; - memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); - update->setupflag = 1; + igroup = group->find(arg[0]); + if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); + groupbit = group->bitmask[igroup]; + gcount = group->count(igroup); + dynlen = (gcount)*3; + memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); + update->setupflag = 1; - int style = -1; - if (strcmp(arg[1],"regular") == 0) style = REGULAR; - else if (strcmp(arg[1],"eskm") == 0) style = ESKM; - else error->all(FLERR,"Illegal Dynamical Matrix command"); - del = utils::numeric(FLERR, arg[2],false,lmp); + int style = -1; + if (strcmp(arg[1],"regular") == 0) style = REGULAR; + else if (strcmp(arg[1],"eskm") == 0) style = ESKM; + else error->all(FLERR,"Illegal Dynamical_matrix command"); + del = utils::numeric(FLERR, arg[2],false,lmp); - // set option defaults + // set option defaults - binaryflag = 0; - scaleflag = 0; - compressed = 0; - file_flag = 0; - file_opened = 0; - conversion = 1; + binaryflag = 0; + scaleflag = 0; + compressed = 0; + file_flag = 0; + file_opened = 0; + folded = 0; + conversion = 1; - // read options from end of input line - if (style == REGULAR) options(narg-3,&arg[3]); //COME BACK - else if (style == ESKM) options(narg-3,&arg[3]); //COME BACK - else if (comm->me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); + // read options from end of input line + if (style == REGULAR) options(narg-3,&arg[3]); + else if (style == ESKM) options(narg-3,&arg[3]); + else if (me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); - if (atom->map_style == Atom::MAP_NONE) - error->all(FLERR,"Dynamical_matrix command requires an atom map, see atom_modify"); + if (!folded) dynlenb = dynlen; + else dynlenb = (atom->natoms)*3; - // move atoms by 3-vector or specified variable(s) + if (atom->map_style == Atom::MAP_NONE) + error->all(FLERR,"Dynamical_matrix command requires an atom map"); - if (style == REGULAR) { - setup(); - timer->init(); - timer->barrier_start(); - calculateMatrix(); - timer->barrier_stop(); - } + // move atoms by 3-vector or specified variable(s) - if (style == ESKM) { - setup(); - convert_units(update->unit_style); - conversion = conv_energy/conv_distance/conv_mass; - timer->init(); - timer->barrier_start(); - calculateMatrix(); - timer->barrier_stop(); - } + if (style == REGULAR) { + setup(); + timer->init(); + timer->barrier_start(); + calculateMatrix(); + timer->barrier_stop(); + } - Finish finish(lmp); - finish.end(1); + if (style == ESKM) { + setup(); + convert_units(update->unit_style); + conversion = conv_energy/conv_distance/conv_mass; + timer->init(); + timer->barrier_start(); + calculateMatrix(); + timer->barrier_stop(); + } + + Finish finish(lmp); + finish.end(1); } /* ---------------------------------------------------------------------- @@ -192,9 +202,9 @@ void DynamicalMatrix::options(int narg, char **arg) if (strcmp(arg[iarg],"binary") == 0) { if (iarg + 2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); if (strcmp(arg[iarg+1],"gzip") == 0) { - compressed = 1; + compressed = 1; } else { - binaryflag = utils::logical(FLERR,arg[iarg+1],false,lmp); + binaryflag = utils::logical(FLERR,arg[iarg+1],false,lmp); } iarg += 2; } else if (strcmp(arg[iarg],"file") == 0) { @@ -202,6 +212,14 @@ void DynamicalMatrix::options(int narg, char **arg) filename = arg[iarg + 1]; file_flag = 1; iarg += 2; + } else if (strcmp(arg[iarg],"fold") == 0) { + if (iarg+2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); + if (strcmp(arg[iarg+1],"yes") == 0) { + folded = 1; + } else if (strcmp(arg[iarg+1],"no") == 0) { + folded = 0; + } else error->all(FLERR,"Illegal input for dynamical_matrix fold option"); + iarg += 2; } else error->all(FLERR,"Illegal dynamical_matrix command"); } if (file_flag == 1) { @@ -217,23 +235,23 @@ void DynamicalMatrix::options(int narg, char **arg) void DynamicalMatrix::openfile(const char *filename) { - // if file already opened, return - if (file_opened) return; - fp = nullptr; + // if file already opened, return + if (file_opened) return; + fp = nullptr; - if (me == 0) { - if (compressed) { - fp = platform::compressed_write(std::string(filename)+".gz"); - if (!fp) error->one(FLERR,"Cannot open compressed file"); - } else if (binaryflag) { - fp = fopen(filename,"wb"); - } else { - fp = fopen(filename,"w"); - } - if (!fp) error->one(FLERR,"Cannot open dynmat file: {}", utils::getsyserror()); + if (me == 0) { + if (compressed) { + fp = platform::compressed_write(std::string(filename)+".gz"); + if (!fp) error->one(FLERR,"Cannot open compressed file"); + } else if (binaryflag) { + fp = fopen(filename,"wb"); + } else { + fp = fopen(filename,"w"); } + if (!fp) error->one(FLERR,"Cannot open dynmat file: {}", utils::getsyserror()); + } - file_opened = 1; + file_opened = 1; } /* ---------------------------------------------------------------------- @@ -242,98 +260,112 @@ void DynamicalMatrix::openfile(const char *filename) void DynamicalMatrix::calculateMatrix() { - int local_idx; // local index - int local_jdx; // second local index - int nlocal = atom->nlocal; - bigint natoms = atom->natoms; - int *type = atom->type; - bigint *gm = groupmap; - double imass; // dynamical matrix element - double *m = atom->mass; - double **f = atom->f; + int local_idx; // local index + int local_jdx; // second local index + int nlocal = atom->nlocal; + bigint natoms = atom->natoms; + int *type = atom->type; + bigint *gm = groupmap; + double imass; // dynamical matrix element + double *m = atom->mass; + double **f = atom->f; - double **dynmat = new double*[3]; - for (int i=0; i<3; i++) - dynmat[i] = new double[dynlen]; + double **dynmat = new double*[3]; + for (int i=0; i<3; i++) + dynmat[i] = new double[dynlenb]; - double **fdynmat = new double*[3]; - for (int i=0; i<3; i++) - fdynmat[i] = new double[dynlen]; + double **fdynmat = new double*[3]; + for (int i=0; i<3; i++) + fdynmat[i] = new double[dynlenb]; - //initialize dynmat to all zeros + //initialize dynmat to all zeros + dynmat_clear(dynmat); + + if (me == 0 && screen) { + fprintf(screen,"Calculating Dynamical Matrix ...\n"); + fprintf(screen," Total # of atoms = " BIGINT_FORMAT "\n", natoms); + fprintf(screen," Atoms in group = " BIGINT_FORMAT "\n", gcount); + fprintf(screen," Total dynamical matrix elements = " BIGINT_FORMAT "\n", (dynlen*dynlen) ); + } + + // emit dynlen rows of dimalpha*dynlen*dimbeta elements + + update->nsteps = 0; + int prog = 0; + for (bigint i=1; i<=natoms; i++) { + local_idx = atom->map(i); + if (gm[i-1] < 0) + continue; + for (int alpha=0; alpha<3; alpha++) { + displace_atom(local_idx, alpha, 1); + update_force(); + for (bigint j=1; j<=natoms; j++) { + local_jdx = atom->map(j); + if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal + && (gm[j-1] >= 0 || folded)){ + if (folded) { + for (int beta=0; beta<3; beta++){ + dynmat[alpha][(j-1)*3+beta] -= f[local_jdx][beta]; + } + } else { + for (int beta=0; beta<3; beta++){ + dynmat[alpha][gm[j-1]*3+beta] -= f[local_jdx][beta]; + } + } + } + } + displace_atom(local_idx,alpha,-2); + update_force(); + for (bigint j=1; j<=natoms; j++) { + local_jdx = atom->map(j); + if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal + && (gm[j-1] >= 0 || folded)){ + if (atom->rmass_flag == 1) + imass = sqrt(m[local_idx] * m[local_jdx]); + else + imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); + if (folded){ + for (int beta=0; beta<3; beta++){ + dynmat[alpha][(j-1)*3+beta] -= -f[local_jdx][beta]; + dynmat[alpha][(j-1)*3+beta] /= (2 * del * imass); + dynmat[alpha][(j-1)*3+beta] *= conversion; + } + } else { + for (int beta=0; beta<3; beta++){ + dynmat[alpha][gm[j-1]*3+beta] -= -f[local_jdx][beta]; + dynmat[alpha][gm[j-1]*3+beta] /= (2 * del * imass); + dynmat[alpha][gm[j-1]*3+beta] *= conversion; + } + } + } + } + displace_atom(local_idx,alpha,1); + } + for (int k=0; k<3; k++) + MPI_Reduce(dynmat[k],fdynmat[k],dynlenb,MPI_DOUBLE,MPI_SUM,0,world); + if (me == 0) + writeMatrix(fdynmat); dynmat_clear(dynmat); - - if (comm->me == 0 && screen) { - fprintf(screen,"Calculating Dynamical Matrix ...\n"); - fprintf(screen," Total # of atoms = " BIGINT_FORMAT "\n", natoms); - fprintf(screen," Atoms in group = " BIGINT_FORMAT "\n", gcount); - fprintf(screen," Total dynamical matrix elements = " BIGINT_FORMAT "\n", (dynlen*dynlen) ); + if (me == 0 && screen) { + int p = 10 * gm[i-1] / gcount; + if (p > prog) { + prog = p; + fprintf(screen," %d%%",p*10); + fflush(screen); + } } + } + if (me == 0 && screen) fprintf(screen,"\n"); - // emit dynlen rows of dimalpha*dynlen*dimbeta elements + for (int i=0; i < 3; i++) + delete [] dynmat[i]; + delete [] dynmat; - update->nsteps = 0; - int prog = 0; - for (bigint i=1; i<=natoms; i++) { - local_idx = atom->map(i); - if (gm[i-1] < 0) - continue; - for (int alpha=0; alpha<3; alpha++) { - displace_atom(local_idx, alpha, 1); - update_force(); - for (bigint j=1; j<=natoms; j++) { - local_jdx = atom->map(j); - if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal - && gm[j-1] >= 0) { - for (int beta=0; beta<3; beta++) { - dynmat[alpha][gm[j-1]*3+beta] -= f[local_jdx][beta]; - } - } - } - displace_atom(local_idx,alpha,-2); - update_force(); - for (bigint j=1; j<=natoms; j++) { - local_jdx = atom->map(j); - if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal - && gm[j-1] >= 0) { - for (int beta=0; beta<3; beta++) { - if (atom->rmass_flag == 1) - imass = sqrt(m[local_idx] * m[local_jdx]); - else - imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); - dynmat[alpha][gm[j-1]*3+beta] -= -f[local_jdx][beta]; - dynmat[alpha][gm[j-1]*3+beta] /= (2 * del * imass); - dynmat[alpha][gm[j-1]*3+beta] *= conversion; - } - } - } - displace_atom(local_idx,alpha,1); - } - for (int k=0; k<3; k++) - MPI_Reduce(dynmat[k],fdynmat[k],dynlen,MPI_DOUBLE,MPI_SUM,0,world); - if (me == 0) - writeMatrix(fdynmat); - dynmat_clear(dynmat); - if (comm->me == 0 && screen) { - int p = 10 * gm[i-1] / gcount; - if (p > prog) { - prog = p; - fprintf(screen," %d%%",p*10); - fflush(screen); - } - } - } - if (comm->me == 0 && screen) fprintf(screen,"\n"); + for (int i=0; i < 3; i++) + delete [] fdynmat[i]; + delete [] fdynmat; - for (int i=0; i < 3; i++) - delete [] dynmat[i]; - delete [] dynmat; - - for (int i=0; i < 3; i++) - delete [] fdynmat[i]; - delete [] fdynmat; - - if (screen && me ==0 ) fprintf(screen,"Finished Calculating Dynamical Matrix\n"); + if (screen && me ==0 ) fprintf(screen,"Finished Calculating Dynamical Matrix\n"); } /* ---------------------------------------------------------------------- @@ -342,25 +374,25 @@ void DynamicalMatrix::calculateMatrix() void DynamicalMatrix::writeMatrix(double **dynmat) { - if (me != 0 || !fp) - return; + if (me != 0 || !fp) + return; - clearerr(fp); - if (binaryflag) { - for (int i=0; i<3; i++) - fwrite(dynmat[i], sizeof(double), dynlen, fp); - if (ferror(fp)) - error->one(FLERR, "Error writing to binary file"); - } else { - for (int i = 0; i < 3; i++) { - for (bigint j = 0; j < dynlen; j++) { - if ((j+1)%3==0) fprintf(fp, "%4.8f\n", dynmat[i][j]); - else fprintf(fp, "%4.8f ",dynmat[i][j]); - } - } - if (ferror(fp)) - error->one(FLERR,"Error writing to file"); + clearerr(fp); + if (binaryflag) { + for (int i=0; i<3; i++) + fwrite(dynmat[i], sizeof(double), dynlenb, fp); + if (ferror(fp)) + error->one(FLERR, "Error writing to binary file"); + } else { + for (int i = 0; i < 3; i++) { + for (bigint j = 0; j < dynlenb; j++) { + if ((j+1)%3==0) fprintf(fp, "%4.8f\n", dynmat[i][j]); + else fprintf(fp, "%4.8f ",dynmat[i][j]); + } } + if (ferror(fp)) + error->one(FLERR,"Error writing to file"); + } } /* ---------------------------------------------------------------------- @@ -369,18 +401,18 @@ void DynamicalMatrix::writeMatrix(double **dynmat) void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) { - if (local_idx < 0) return; + if (local_idx < 0) return; - double **x = atom->x; - int *sametag = atom->sametag; - int j = local_idx; + double **x = atom->x; + int *sametag = atom->sametag; + int j = local_idx; - x[local_idx][direction] += del*magnitude; + x[local_idx][direction] += del*magnitude; - while (sametag[j] >= 0) { - j = sametag[j]; - x[j][direction] += del*magnitude; - } + while (sametag[j] >= 0) { + j = sametag[j]; + x[j][direction] += del*magnitude; + } } @@ -394,35 +426,50 @@ void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) void DynamicalMatrix::update_force() { - force_clear(); - int n_post_force = modify->n_post_force; + neighbor->ago = 0; + if ((modify->get_fix_by_id("package_intel")) ? true : false) + neighbor->decide(); + force_clear(); + int n_pre_force = modify->n_pre_force; + int n_pre_reverse = modify->n_pre_reverse; + int n_post_force = modify->n_post_force; - if (pair_compute_flag) { - force->pair->compute(eflag,vflag); - timer->stamp(Timer::PAIR); - } - if (atom->molecular != Atom::ATOMIC) { - if (force->bond) force->bond->compute(eflag,vflag); - if (force->angle) force->angle->compute(eflag,vflag); - if (force->dihedral) force->dihedral->compute(eflag,vflag); - if (force->improper) force->improper->compute(eflag,vflag); - timer->stamp(Timer::BOND); - } - if (kspace_compute_flag) { - force->kspace->compute(eflag,vflag); - timer->stamp(Timer::KSPACE); - } - if (force->newton) { - comm->reverse_comm(); - timer->stamp(Timer::COMM); - } - - // force modifications - - if (n_post_force) modify->post_force(vflag); + if (n_pre_force) { + modify->pre_force(vflag); timer->stamp(Timer::MODIFY); + } - ++ update->nsteps; + if (pair_compute_flag) { + force->pair->compute(eflag,vflag); + timer->stamp(Timer::PAIR); + } + if (atom->molecular != Atom::ATOMIC) { + if (force->bond) force->bond->compute(eflag,vflag); + if (force->angle) force->angle->compute(eflag,vflag); + if (force->dihedral) force->dihedral->compute(eflag,vflag); + if (force->improper) force->improper->compute(eflag,vflag); + timer->stamp(Timer::BOND); + } + if (kspace_compute_flag) { + force->kspace->compute(eflag,vflag); + timer->stamp(Timer::KSPACE); + } + if (n_pre_reverse) { + modify->pre_reverse(eflag,vflag); + timer->stamp(Timer::MODIFY); + } + if (force->newton) { + comm->reverse_comm(); + timer->stamp(Timer::COMM); + } + // force modifications + + if (n_post_force) { + modify->post_force(vflag); + timer->stamp(Timer::MODIFY); + } + + ++ update->nsteps; } /* ---------------------------------------------------------------------- @@ -432,17 +479,17 @@ void DynamicalMatrix::update_force() void DynamicalMatrix::force_clear() { - if (external_force_clear) return; + if (external_force_clear) return; - // clear global force array - // if either newton flag is set, also include ghosts + // clear global force array + // if either newton flag is set, also include ghosts - size_t nbytes = sizeof(double) * atom->nlocal; - if (force->newton) nbytes += sizeof(double) * atom->nghost; + size_t nbytes = sizeof(double) * atom->nlocal; + if (force->newton) nbytes += sizeof(double) * atom->nghost; - if (nbytes) { - memset(&atom->f[0][0],0,3*nbytes); - } + if (nbytes) { + memset(&atom->f[0][0],0,3*nbytes); + } } /* ---------------------------------------------------------------------- @@ -451,67 +498,66 @@ void DynamicalMatrix::force_clear() void DynamicalMatrix::dynmat_clear(double **dynmat) { + size_t nbytes = sizeof(double) * dynlenb; - size_t nbytes = sizeof(double) * dynlen; - - if (nbytes) { - for (int i=0; i<3; i++) - memset(&dynmat[i][0],0,nbytes); - } + if (nbytes) { + for (int i=0; i<3; i++) + memset(&dynmat[i][0],0,nbytes); + } } /* ---------------------------------------------------------------------- */ void DynamicalMatrix::convert_units(const char *style) { - // physical constants from: - // https://physics.nist.gov/cuu/Constants/Table/allascii.txt - // using thermochemical calorie = 4.184 J + // physical constants from: + // https://physics.nist.gov/cuu/Constants/Table/allascii.txt + // using thermochemical calorie = 4.184 J - if (strcmp(style,"lj") == 0) { - error->all(FLERR,"Conversion Not Set"); - //conversion = 1; // lj -> 10 J/mol + if (strcmp(style,"lj") == 0) { + error->all(FLERR,"Conversion Not Set"); + //conversion = 1; // lj -> 10 J/mol - } else if (strcmp(style,"real") == 0) { - conv_energy = 418.4; // kcal/mol -> 10 J/mol - conv_mass = 1; // g/mol -> g/mol - conv_distance = 1; // angstrom -> angstrom + } else if (strcmp(style,"real") == 0) { + conv_energy = 418.4; // kcal/mol -> 10 J/mol + conv_mass = 1; // g/mol -> g/mol + conv_distance = 1; // angstrom -> angstrom - } else if (strcmp(style,"metal") == 0) { - conv_energy = 9648.5; // eV -> 10 J/mol - conv_mass = 1; // g/mol -> g/mol - conv_distance = 1; // angstrom -> angstrom + } else if (strcmp(style,"metal") == 0) { + conv_energy = 9648.5; // eV -> 10 J/mol + conv_mass = 1; // g/mol -> g/mol + conv_distance = 1; // angstrom -> angstrom - } else if (strcmp(style,"si") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); - conv_energy = 6.022E22; // J -> 10 J/mol - conv_mass = 6.022E26; // kg -> g/mol - conv_distance = 1E-10; // meter -> angstrom + } else if (strcmp(style,"si") == 0) { + if (me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + conv_energy = 6.022E22; // J -> 10 J/mol + conv_mass = 6.022E26; // kg -> g/mol + conv_distance = 1E-10; // meter -> angstrom - } else if (strcmp(style,"cgs") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); - conv_energy = 6.022E12; // Erg -> 10 J/mol - conv_mass = 6.022E23; // g -> g/mol - conv_distance = 1E-7; // centimeter -> angstrom + } else if (strcmp(style,"cgs") == 0) { + if (me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + conv_energy = 6.022E12; // Erg -> 10 J/mol + conv_mass = 6.022E23; // g -> g/mol + conv_distance = 1E-7; // centimeter -> angstrom - } else if (strcmp(style,"electron") == 0) { - conv_energy = 262550; // Hartree -> 10 J/mol - conv_mass = 1; // amu -> g/mol - conv_distance = 0.529177249; // bohr -> angstrom + } else if (strcmp(style,"electron") == 0) { + conv_energy = 262550; // Hartree -> 10 J/mol + conv_mass = 1; // amu -> g/mol + conv_distance = 0.529177249; // bohr -> angstrom - } else if (strcmp(style,"micro") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); - conv_energy = 6.022E10; // picogram-micrometer^2/microsecond^2 -> 10 J/mol - conv_mass = 6.022E11; // pg -> g/mol - conv_distance = 1E-4; // micrometer -> angstrom + } else if (strcmp(style,"micro") == 0) { + if (me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + conv_energy = 6.022E10; // picogram-micrometer^2/microsecond^2 -> 10 J/mol + conv_mass = 6.022E11; // pg -> g/mol + conv_distance = 1E-4; // micrometer -> angstrom - } else if (strcmp(style,"nano") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); - conv_energy = 6.022E4; // attogram-nanometer^2/nanosecond^2 -> 10 J/mol - conv_mass = 6.022E5; // ag -> g/mol - conv_distance = 0.1; // angstrom -> angstrom + } else if (strcmp(style,"nano") == 0) { + if (me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + conv_energy = 6.022E4; // attogram-nanometer^2/nanosecond^2 -> 10 J/mol + conv_mass = 6.022E5; // ag -> g/mol + conv_distance = 0.1; // angstrom -> angstrom - } else error->all(FLERR,"Units Type Conversion Not Found"); + } else error->all(FLERR,"Units Type Conversion Not Found"); } @@ -519,66 +565,66 @@ void DynamicalMatrix::convert_units(const char *style) void DynamicalMatrix::create_groupmap() { - //Create a group map which maps atom order onto group - // groupmap[global atom index-1] = output column/row + //Create a group map which maps atom order onto group + // groupmap[global atom index-1] = output column/row - int local_idx; // local index - int gid = 0; //group index - int nlocal = atom->nlocal; - int *mask = atom->mask; - bigint natoms = atom->natoms; - int *recv = new int[comm->nprocs]; - int *displs = new int[comm->nprocs]; - bigint *temp_groupmap = new bigint[natoms]; + int local_idx; // local index + int gid = 0; //group index + int nlocal = atom->nlocal; + int *mask = atom->mask; + bigint natoms = atom->natoms; + int *recv = new int[comm->nprocs]; + int *displs = new int[comm->nprocs]; + bigint *temp_groupmap = new bigint[natoms]; - //find number of local atoms in the group (final_gid) - for (bigint i=1; i<=natoms; i++) { - local_idx = atom->map(i); - if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) - gid += 1; // gid at the end of loop is final_Gid + //find number of local atoms in the group (final_gid) + for (bigint i=1; i<=natoms; i++) { + local_idx = atom->map(i); + if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) + gid += 1; // gid at the end of loop is final_Gid + } + //create an array of length final_gid + bigint *sub_groupmap = new bigint[gid]; + + gid = 0; + //create a map between global atom id and group atom id for each proc + for (bigint i=1; i<=natoms; i++) { + local_idx = atom->map(i); + if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) { + sub_groupmap[gid] = i; + gid += 1; } - //create an array of length final_gid - bigint *sub_groupmap = new bigint[gid]; + } - gid = 0; - //create a map between global atom id and group atom id for each proc - for (bigint i=1; i<=natoms; i++) { - local_idx = atom->map(i); - if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) { - sub_groupmap[gid] = i; - gid += 1; - } - } + //populate arrays for Allgatherv + for (int i=0; i < comm->nprocs; i++) { + recv[i] = 0; + } + recv[me] = gid; + MPI_Allreduce(recv,displs,comm->nprocs,MPI_INT,MPI_SUM,world); + for (int i=0; inprocs; i++) { + recv[i]=displs[i]; + if (i>0) displs[i] = displs[i-1]+recv[i-1]; + else displs[i] = 0; + } - //populate arrays for Allgatherv - for (int i=0; inprocs; i++) { - recv[i] = 0; - } - recv[comm->me] = gid; - MPI_Allreduce(recv,displs,comm->nprocs,MPI_INT,MPI_SUM,world); - for (int i=0; inprocs; i++) { - recv[i]=displs[i]; - if (i>0) displs[i] = displs[i-1]+recv[i-1]; - else displs[i] = 0; - } + //combine subgroup maps into total temporary groupmap + MPI_Allgatherv(sub_groupmap,gid,MPI_LMP_BIGINT,temp_groupmap,recv,displs,MPI_LMP_BIGINT,world); + std::sort(temp_groupmap,temp_groupmap+gcount); - //combine subgroup maps into total temporary groupmap - MPI_Allgatherv(sub_groupmap,gid,MPI_LMP_BIGINT,temp_groupmap,recv,displs,MPI_LMP_BIGINT,world); - std::sort(temp_groupmap,temp_groupmap+gcount); + //populate member groupmap based on temp groupmap + bigint j = 0; + for (bigint i=1; i<=natoms; i++) { + // flag groupmap contents that are in temp_groupmap + if (j < gcount && i == temp_groupmap[j]) + groupmap[i-1] = j++; + else + groupmap[i-1] = -1; + } - //populate member groupmap based on temp groupmap - bigint j = 0; - for (bigint i=1; i<=natoms; i++) { - // flag groupmap contents that are in temp_groupmap - if (j < gcount && i == temp_groupmap[j]) - groupmap[i-1] = j++; - else - groupmap[i-1] = -1; - } - - //free that memory! - delete[] recv; - delete[] displs; - delete[] sub_groupmap; - delete[] temp_groupmap; + //free that memory! + delete[] recv; + delete[] displs; + delete[] sub_groupmap; + delete[] temp_groupmap; } diff --git a/src/PHONON/dynamical_matrix.h b/src/PHONON/dynamical_matrix.h index 122d158d55..4a08420381 100644 --- a/src/PHONON/dynamical_matrix.h +++ b/src/PHONON/dynamical_matrix.h @@ -34,11 +34,10 @@ class DynamicalMatrix : public Command { int nvec; // local atomic dof = length of xvec - void update_force(); - void force_clear(); + virtual void update_force(); + virtual void force_clear(); virtual void openfile(const char *filename); - private: void options(int, char **); void calculateMatrix(); void dynmat_clear(double **dynmat); @@ -55,6 +54,7 @@ class DynamicalMatrix : public Command { int igroup, groupbit; bigint gcount; // number of atoms in group bigint dynlen; // rank of dynamical matrix + bigint dynlenb; // new dynlen if folded int scaleflag; int me; bigint *groupmap; @@ -63,6 +63,7 @@ class DynamicalMatrix : public Command { int binaryflag; // 1 if dump file is written binary, 0 no int file_opened; // 1 if openfile method has been called, 0 no int file_flag; // 1 custom file name, 0 dynmat.dat + int folded; // 1 folded, 0 nonfolded FILE *fp; }; diff --git a/src/PHONON/third_order.cpp b/src/PHONON/third_order.cpp index 3206882a4a..7bc03aaf6f 100644 --- a/src/PHONON/third_order.cpp +++ b/src/PHONON/third_order.cpp @@ -10,11 +10,11 @@ the GNU General Public License. See the README file in the top-level LAMMPS directory. - ----------------------------------------------------------------------- */ +------------------------------------------------------------------------- */ -// -// Created by charlie sievers on 7/5/18. -// +/* ---------------------------------------------------------------------- + Contributing author: Charlie Sievers (UC Davis), charliesievers at cox.net +------------------------------------------------------------------------- */ #include "third_order.h" @@ -32,6 +32,9 @@ #include "kspace.h" #include "math_special.h" #include "memory.h" +#include "modify.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "neighbor.h" #include "pair.h" #include "timer.h" @@ -42,7 +45,7 @@ using namespace LAMMPS_NS; using namespace MathSpecial; -enum{REGULAR,BALLISTICO}; +enum{REGULAR,ESKM}; /* ---------------------------------------------------------------------- */ @@ -86,12 +89,22 @@ void ThirdOrder::setup() domain->box_too_small_check(); neighbor->build(1); + // build neighbor list this command needs based on earlier request + + neighbor->build_one(list); + // compute all forces external_force_clear = 0; eflag=0; vflag=0; + if (force->kspace) { + force->kspace->setup(); + } update_force(); + modify->setup(vflag); + update->setupflag = 0; + if (gcount == atom->natoms) for (bigint i=0; inatoms; i++) groupmap[i] = i; @@ -109,7 +122,18 @@ void ThirdOrder::command(int narg, char **arg) error->all(FLERR,"third_order command before simulation box is defined"); if (narg < 2) error->all(FLERR,"Illegal third_order command"); + // request a full neighbor list for use by this command + + int irequest = neighbor->request(this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->command = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->occasional = 1; + neighbor->requests[irequest]->command_style = "third_order"; + lmp->init(); + list = neighbor->lists[irequest]; // orthogonal vs triclinic simulation box @@ -123,7 +147,7 @@ void ThirdOrder::command(int narg, char **arg) // group and style igroup = group->find(arg[0]); - if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); + if (igroup == -1) error->all(FLERR,"Could not find third_order group ID"); groupbit = group->bitmask[igroup]; gcount = group->count(igroup); dynlen = (gcount)*3; @@ -132,7 +156,7 @@ void ThirdOrder::command(int narg, char **arg) int style = -1; if (strcmp(arg[1],"regular") == 0) style = REGULAR; - else if (strcmp(arg[1],"eskm") == 0) style = BALLISTICO; + else if (strcmp(arg[1],"eskm") == 0) style = ESKM; else error->all(FLERR,"Illegal Dynamical Matrix command"); // set option defaults @@ -143,15 +167,23 @@ void ThirdOrder::command(int narg, char **arg) file_flag = 0; file_opened = 0; conversion = 1; + folded = 0; + + // set Neigborlist attributes to NULL + ijnum = NULL; + neighbortags = NULL; // read options from end of input line - if (style == REGULAR) options(narg-3,&arg[3]); //COME BACK - else if (style == BALLISTICO) options(narg-3,&arg[3]); //COME BACK - else if (comm->me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); + if (style == REGULAR) options(narg-3,&arg[3]); + else if (style == ESKM) options(narg-3,&arg[3]); + else error->all(FLERR,"Illegal Third Order command"); del = utils::numeric(FLERR, arg[2],false,lmp); + if (!folded) dynlenb = dynlen; + else dynlenb = (atom->natoms)*3; + if (atom->map_style == Atom::MAP_NONE) - error->all(FLERR,"third_order command requires an atom map, see atom_modify"); + error->all(FLERR,"Third Order command requires an atom map, see atom_modify"); // move atoms by 3-vector or specified variable(s) @@ -163,7 +195,7 @@ void ThirdOrder::command(int narg, char **arg) timer->barrier_stop(); } - if (style == BALLISTICO) { + if (style == ESKM) { setup(); convert_units(update->unit_style); conversion = conv_energy/conv_distance/conv_distance; @@ -183,13 +215,13 @@ void ThirdOrder::command(int narg, char **arg) void ThirdOrder::options(int narg, char **arg) { - if (narg < 0) error->all(FLERR,"Illegal third_order command"); + if (narg < 0) error->all(FLERR,"Illegal Third Order command"); int iarg = 0; - const char *filename = "third_order.dat"; + const char *filename = "Third Order.dat"; while (iarg < narg) { if (strcmp(arg[iarg],"binary") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Illegal third_order command"); + if (iarg + 2 > narg) error->all(FLERR, "Illegal Third Order command"); if (strcmp(arg[iarg+1],"gzip") == 0) { compressed = 1; } else { @@ -200,8 +232,15 @@ void ThirdOrder::options(int narg, char **arg) if (iarg+2 > narg) error->all(FLERR, "Illegal third_order command"); filename = arg[iarg + 1]; file_flag = 1; + } else if (strcmp(arg[iarg],"fold") == 0) { + if (iarg+2 > narg) error->all(FLERR, "Illegal Third Order command"); + if (strcmp(arg[iarg+1],"yes") == 0) { + folded = 1; + } else if (strcmp(arg[iarg+1],"no") == 0) { + folded = 0; + } else error->all(FLERR,"Illegal input for Third Order fold option"); iarg += 2; - } else error->all(FLERR,"Illegal third_order command"); + } else error->all(FLERR,"Illegal Third Order command"); } if (file_flag == 1 && me == 0) { openfile(filename); @@ -231,11 +270,13 @@ void ThirdOrder::openfile(const char* filename) } if (!fp) error->one(FLERR,"Cannot open third_order file: {}", utils::getsyserror()); } + + file_opened = 1; } /* ---------------------------------------------------------------------- - create dynamical matrix + create third order tensor ------------------------------------------------------------------------- */ void ThirdOrder::calculateMatrix() @@ -247,28 +288,40 @@ void ThirdOrder::calculateMatrix() bigint natoms = atom->natoms; bigint *gm = groupmap; double **f = atom->f; + int inum; + bigint j; + bigint *firstneigh; - double *dynmat = new double[3*dynlen]; - double *fdynmat = new double[3*dynlen]; - memset(&dynmat[0],0,dynlen*sizeof(double)); - memset(&fdynmat[0],0,dynlen*sizeof(double)); + double *dynmat = new double[dynlenb]; + double *fdynmat = new double[dynlenb]; + memset(&dynmat[0],0,dynlenb*sizeof(double)); + memset(&fdynmat[0],0,dynlenb*sizeof(double)); + + getNeighbortags(); if (comm->me == 0 && screen) { - fprintf(screen,"Calculating Third Order ...\n"); - fprintf(screen," Total # of atoms = " BIGINT_FORMAT "\n", natoms); - fprintf(screen," Atoms in group = " BIGINT_FORMAT "\n", gcount); - fprintf(screen," Total third order elements = " - BIGINT_FORMAT "\n", (dynlen*dynlen*dynlen) ); + fprintf(screen, "Calculating Third Order ...\n"); + fprintf(screen, " Total # of atoms = " BIGINT_FORMAT "\n", natoms); + fprintf(screen, " Atoms in group = " BIGINT_FORMAT "\n", gcount); + fprintf(screen, " Total third order elements = " + BIGINT_FORMAT "\n", (dynlen * dynlen * dynlen)); } update->nsteps = 0; int prog = 0; - for (bigint i=1; i<=natoms; i++) { + for (bigint i=1; i<=natoms; i++){ + if (gm[i-1] < 0) + continue; + inum = ijnum[i-1]; + firstneigh = neighbortags[i-1]; local_idx = atom->map(i); - for (int alpha=0; alpha<3; alpha++) { - for (bigint j=1; j<=natoms; j++) { - local_jdx = atom->map(j); - for (int beta=0; beta<3; beta++) { + for (int alpha=0; alpha<3; alpha++){ + for (int jj=0; jjmap(j+1); + for (int beta=0; beta<3; beta++){ displace_atom(local_idx, alpha, 1); displace_atom(local_jdx, beta, 1); update_force(); @@ -276,9 +329,13 @@ void ThirdOrder::calculateMatrix() local_kdx = atom->map(k); for (int gamma=0; gamma<3; gamma++) { if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && ((gm[j] >= 0 && gm[k-1] >= 0) || folded) && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; + if (folded) { + dynmat[(k-1)*3+gamma] += f[local_kdx][gamma]; + } else { + dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; + } } } } @@ -288,9 +345,13 @@ void ThirdOrder::calculateMatrix() local_kdx = atom->map(k); for (int gamma=0; gamma<3; gamma++) { if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && ((gm[j] >= 0 && gm[k-1] >= 0) || folded) && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; + if (folded) { + dynmat[(k-1)*3+gamma] -= f[local_kdx][gamma]; + } else { + dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; + } } } } @@ -302,9 +363,13 @@ void ThirdOrder::calculateMatrix() local_kdx = atom->map(k); for (int gamma=0; gamma<3; gamma++) { if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && ((gm[j] >= 0 && gm[k-1] >= 0) || folded) && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; + if (folded) { + dynmat[(k-1)*3+gamma] -= f[local_kdx][gamma]; + } else { + dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; + } } } } @@ -314,24 +379,33 @@ void ThirdOrder::calculateMatrix() local_kdx = atom->map(k); for (int gamma=0; gamma<3; gamma++) { if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && ((gm[j] >= 0 && gm[k-1] >= 0) || folded) && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; - dynmat[gm[k-1]*3+gamma] /= (4 * del * del); + if (folded) { + dynmat[(k-1)*3+gamma] += f[local_kdx][gamma]; + dynmat[(k-1)*3+gamma] /= (4 * del * del); + } else { + dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; + dynmat[gm[k-1]*3+gamma] /= (4 * del * del); + } } } } displace_atom(local_jdx, beta, 1); displace_atom(local_idx, alpha, 1); - MPI_Reduce(dynmat,fdynmat,3*dynlen,MPI_DOUBLE,MPI_SUM,0,world); - if (me == 0) { - writeMatrix(fdynmat, gm[i-1], alpha, gm[j-1], beta); + MPI_Reduce(dynmat,fdynmat,dynlenb,MPI_DOUBLE,MPI_SUM,0,world); + if (me == 0){ + if (folded) { + writeMatrix(fdynmat, gm[i-1], alpha, j, beta); + } else { + writeMatrix(fdynmat, gm[i-1], alpha, gm[j], beta); + } } - memset(&dynmat[0],0,dynlen*sizeof(double)); + memset(&dynmat[0],0,dynlenb*sizeof(double)); } } } - if (comm->me == 0 && screen) { + if (me == 0 && screen) { int p = 10 * gm[i-1] / gcount; if (p > prog) { prog = p; @@ -344,12 +418,12 @@ void ThirdOrder::calculateMatrix() delete [] dynmat; delete [] fdynmat; - if (screen && me ==0 ) + if (screen && me ==0) fprintf(screen,"Finished Calculating Third Order Tensor\n"); } /* ---------------------------------------------------------------------- - write dynamical matrix + write third order tensor ------------------------------------------------------------------------- */ void ThirdOrder::writeMatrix(double *dynmat, bigint i, int a, bigint j, int b) @@ -360,18 +434,34 @@ void ThirdOrder::writeMatrix(double *dynmat, bigint i, int a, bigint j, int b) double norm; if (!binaryflag && fp) { clearerr(fp); - for (int k = 0; k < gcount; k++) { - norm = square(dynmat[k*3])+ - square(dynmat[k*3+1])+ - square(dynmat[k*3+2]); - if (norm > 1.0e-16) - fprintf(fp, - BIGINT_FORMAT " %d " BIGINT_FORMAT " %d " BIGINT_FORMAT - " %7.8f %7.8f %7.8f\n", - i+1, a + 1, j+1, b + 1, groupmap[k]+1, - dynmat[k*3] * conversion, - dynmat[k*3+1] * conversion, - dynmat[k*3+2] * conversion); + if (folded){ + for (int k = 0; k < atom->natoms; k++){ + norm = square(dynmat[k*3])+ + square(dynmat[k*3+1])+ + square(dynmat[k*3+2]); + if (norm > 1.0e-16) + fprintf(fp, + BIGINT_FORMAT " %d " BIGINT_FORMAT " %d " BIGINT_FORMAT + " %7.8f %7.8f %7.8f\n", + i+1, a + 1, j+1, b + 1, k+1, + dynmat[k*3] * conversion, + dynmat[k*3+1] * conversion, + dynmat[k*3+2] * conversion); + } + } else { + for (int k = 0; k < gcount; k++){ + norm = square(dynmat[k*3])+ + square(dynmat[k*3+1])+ + square(dynmat[k*3+2]); + if (norm > 1.0e-16) + fprintf(fp, + BIGINT_FORMAT " %d " BIGINT_FORMAT " %d " BIGINT_FORMAT + " %7.8f %7.8f %7.8f\n", + i+1, a + 1, j+1, b + 1, groupmap[k]+1, + dynmat[k*3] * conversion, + dynmat[k*3+1] * conversion, + dynmat[k*3+2] * conversion); + } } } else if (binaryflag && fp) { clearerr(fp); @@ -411,7 +501,18 @@ void ThirdOrder::displace_atom(int local_idx, int direction, int magnitude) void ThirdOrder::update_force() { + neighbor->ago = 0; + if ((modify->get_fix_by_id("package_intel")) ? true : false) + neighbor->decide(); force_clear(); + int n_post_force = modify->n_post_force; + int n_pre_force = modify->n_pre_force; + int n_pre_reverse = modify->n_pre_reverse; + + if (n_pre_force) { + modify->pre_force(vflag); + timer->stamp(Timer::MODIFY); + } if (pair_compute_flag) { force->pair->compute(eflag,vflag); @@ -428,10 +529,22 @@ void ThirdOrder::update_force() force->kspace->compute(eflag,vflag); timer->stamp(Timer::KSPACE); } + if (n_pre_reverse) { + modify->pre_reverse(eflag,vflag); + timer->stamp(Timer::MODIFY); + } if (force->newton) { comm->reverse_comm(); timer->stamp(Timer::COMM); } + + // force modifications + + if (n_post_force) { + modify->post_force(vflag); + timer->stamp(Timer::MODIFY); + } + ++ update->nsteps; } @@ -478,13 +591,13 @@ void ThirdOrder::convert_units(const char *style) conv_distance = 1; // angstrom -> angstrom } else if (strcmp(style,"si") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + if (me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); conv_energy = 6.022E22; // J -> 10 J/mol conv_mass = 6.022E26; // kg -> g/mol conv_distance = 1E-10; // meter -> angstrom } else if (strcmp(style,"cgs") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + if (me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); conv_energy = 6.022E12; // Erg -> 10 J/mol conv_mass = 6.022E23; // g -> g/mol conv_distance = 1E-7; // centimeter -> angstrom @@ -495,13 +608,13 @@ void ThirdOrder::convert_units(const char *style) conv_distance = 0.529177249; // bohr -> angstrom } else if (strcmp(style,"micro") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + if (me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); conv_energy = 6.022E10; // picogram-micrometer^2/microsecond^2 -> 10 J/mol conv_mass = 6.022E11; // pg -> g/mol conv_distance = 1E-4; // micrometer -> angstrom } else if (strcmp(style,"nano") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + if (me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); conv_energy = 6.022E4; // attogram-nanometer^2/nanosecond^2 -> 10 J/mol conv_mass = 6.022E5; // ag -> g/mol conv_distance = 0.1; // angstrom -> angstrom @@ -550,7 +663,7 @@ void ThirdOrder::create_groupmap() for (int i=0; inprocs; i++) { recv[i] = 0; } - recv[comm->me] = gid; + recv[me] = gid; MPI_Allreduce(recv,displs,comm->nprocs,MPI_INT,MPI_SUM,world); for (int i=0; inprocs; i++) { recv[i]=displs[i]; @@ -579,3 +692,144 @@ void ThirdOrder::create_groupmap() delete[] sub_groupmap; delete[] temp_groupmap; } + +/* ---------------------------------------------------------------------- */ + +void ThirdOrder::getNeighbortags() { + // Create an extended neighbor list which is indexed by atom tag and yields atom tags + // groupmap[global atom index-1] = global atom indices (-1) of extended neighbors + + bigint natoms = atom->natoms; + int *ilist,*jlist,*numneigh,**firstneigh; + bigint *Jlist,*klist; + int ii,jj,kk,inum,jnum,knum,sum; + int *temptags = (int*) malloc(natoms*sizeof(int)); + int *ijnumproc = (int*) malloc(natoms*sizeof(int)); + memory->create(ijnum, natoms, "thirdorder:ijnum"); + bigint **firsttags; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + memset(&ijnum[0],0,natoms*sizeof(int)); + for (ii = 0; ii < inum; ii++) { + sum = 0; + memset(&temptags[0],0,natoms*sizeof(int)); + jnum = numneigh[ii]; + jlist = firstneigh[ii]; + temptags[atom->tag[ilist[ii] & NEIGHMASK]-1] = 1; + for (jj = 0; jj < jnum; jj++) { + temptags[atom->tag[jlist[jj] & NEIGHMASK]-1] = 1; + } + for (bigint i=0; i<=natoms-1; i++) { + sum += temptags[i]; + } + ijnum[atom->tag[ilist[ii] & NEIGHMASK]-1] = sum; + } + MPI_Allreduce(ijnum,ijnumproc,natoms,MPI_INT,MPI_SUM,world); + memset(&ijnum[0],0,natoms*sizeof(int)); + sum = 0; + for (bigint i=0; i<=natoms-1; i++) { + sum += ijnumproc[i]; + } + + bigint nbytes = ((bigint) sizeof(bigint)) * sum; + bigint *data = (bigint *) memory->smalloc(nbytes, "thirdorder:firsttags"); + bigint *datarecv = (bigint *) memory->smalloc(nbytes, "thirdorder:neighbortags"); + nbytes = ((bigint) sizeof(bigint *)) * natoms; + firsttags = (bigint **) memory->smalloc(nbytes, "thirdorder:firsttags"); + neighbortags = (bigint **) memory->smalloc(nbytes, "thirdorder:neighbortags"); + memset(&data[0],0,sum*sizeof(bigint)); + memset(&datarecv[0],0,sum*sizeof(bigint)); + + bigint n = 0; + for (bigint i = 0; i < natoms; i++) { + firsttags[i] = &data[n]; + neighbortags[i] = &datarecv[n]; + n += ijnumproc[i]; + } + + for (ii = 0; ii < inum; ii++) { + int m = 0; + memset(&temptags[0],0,natoms*sizeof(int)); + jnum = numneigh[ii]; + jlist = firstneigh[ii]; + temptags[atom->tag[ilist[ii] & NEIGHMASK]-1] = 1; + for (jj = 0; jj < jnum; jj++) { + temptags[atom->tag[jlist[jj] & NEIGHMASK]-1] = 1; + } + for (int j=0; j < natoms; j++) { + if (temptags[j] == 1) { + neighbortags[atom->tag[ilist[ii] & NEIGHMASK]-1][m] = j; + m += 1; + } + } + } + MPI_Allreduce(datarecv,data,sum,MPI_LMP_BIGINT,MPI_SUM,world); + + for (bigint i = 0; i < natoms; i++) { + ijnum[i] = 0; + sum = 0; + memset(&temptags[0],0,natoms*sizeof(int)); + jnum = ijnumproc[i]; + Jlist = firsttags[i]; + temptags[i] = 1; + for (jj = 0; jj < jnum; jj++) { + temptags[Jlist[jj]] = 1; + klist = firsttags[Jlist[jj]]; + knum = ijnumproc[Jlist[jj]]; + for (kk = 0; kk < knum; kk++) { + temptags[klist[kk]] = 1; + } + } + for (bigint j=0; jsmalloc(nbytes, "thirdorder:firsttags"); + nbytes = ((bigint) sizeof(bigint *)) * natoms; + neighbortags = (bigint **) memory->smalloc(nbytes, "thirdorder:neighbortags"); + memset(&datarecv[0],0,sum*sizeof(bigint)); + + n = 0; + for (bigint i = 0; i < natoms; i++) { + neighbortags[i] = &datarecv[n]; + n += ijnum[i]; + } + + for (bigint i = 0; i < natoms; i++) { + int m = 0; + memset(&temptags[0],0,natoms*sizeof(int)); + jnum = ijnumproc[i]; + Jlist = firsttags[i]; + temptags[i] = 1; + for (int j = 0; j < jnum; j++) { + temptags[Jlist[j]] = 1; + klist = firsttags[Jlist[j]]; + knum = ijnumproc[Jlist[j]]; + for (kk = 0; kk < knum; kk++) { + temptags[klist[kk]] = 1; + } + } + for (bigint j=0; j < natoms; j++) { + if (temptags[j] == 1) { + neighbortags[i][m] = j; + m += 1; + } + } + } + + free (firsttags); + free (ijnumproc); + free (temptags); +} diff --git a/src/PHONON/third_order.h b/src/PHONON/third_order.h index 1961d52355..e3d2cdc16e 100644 --- a/src/PHONON/third_order.h +++ b/src/PHONON/third_order.h @@ -23,8 +23,9 @@ class ThirdOrder : public Command { void setup(); protected: - int eflag, vflag; // flags for energy/virial computation - int external_force_clear; // clear forces locally or externally + int eflag,vflag; // flags for energy/virial computation + int external_force_clear; // clear forces locally or externally + int triclinic; // 0 if domain is orthog, 1 if triclinic int pairflag; @@ -34,25 +35,28 @@ class ThirdOrder : public Command { int nvec; // local atomic dof = length of xvec - void update_force(); - void force_clear(); - virtual void openfile(const char *filename); + virtual void update_force(); + virtual void force_clear(); + virtual void openfile(const char* filename); - private: + + protected: void options(int, char **); void create_groupmap(); void calculateMatrix(); void convert_units(const char *style); void displace_atom(int local_idx, int direction, int magnitude); void writeMatrix(double *, bigint, int, bigint, int); + void getNeighbortags(); double conversion; double conv_energy; double conv_distance; double conv_mass; double del; - int igroup, groupbit; + int igroup,groupbit; bigint dynlen; + bigint dynlenb; int scaleflag; int me; bigint gcount; // number of atoms in group @@ -62,6 +66,11 @@ class ThirdOrder : public Command { int binaryflag; // 1 if dump file is written binary, 0 no int file_opened; // 1 if openfile method has been called, 0 no int file_flag; // 1 custom file name, 0 dynmat.dat + int folded; // 1 if system is folded, 0 no + + class NeighList *list; + int *ijnum; + bigint **neighbortags; FILE *fp; }; diff --git a/src/PYTHON/python_impl.cpp b/src/PYTHON/python_impl.cpp index 983aafb16b..bc593d5b8a 100644 --- a/src/PYTHON/python_impl.cpp +++ b/src/PYTHON/python_impl.cpp @@ -329,9 +329,11 @@ void PythonImpl::invoke_function(int ifunc, char *result) if (pfuncs[ifunc].noutput) { int otype = pfuncs[ifunc].otype; if (otype == INT) { - sprintf(result, "%ld", PY_INT_AS_LONG(pValue)); + auto value = fmt::format("{}", PY_INT_AS_LONG(pValue)); + strncpy(result, value.c_str(), Variable::VALUELENGTH - 1); } else if (otype == DOUBLE) { - sprintf(result, "%.15g", PyFloat_AsDouble(pValue)); + auto value = fmt::format("{:.15g}", PyFloat_AsDouble(pValue)); + strncpy(result, value.c_str(), Variable::VALUELENGTH - 1); } else if (otype == STRING) { const char *pystr = PY_STRING_AS_STRING(pValue); if (pfuncs[ifunc].longstr) diff --git a/src/atom.cpp b/src/atom.cpp index aece451b9b..0b448a5433 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -1052,7 +1052,7 @@ void Atom::deallocate_topology() void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset, int type_offset, int shiftflag, double *shift) { - int m,xptr,iptr; + int xptr,iptr; imageint imagedata; double xdata[3],lamda[3]; double *coord; @@ -1197,7 +1197,7 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset, void Atom::data_vels(int n, char *buf, tagint id_offset) { - int j,m; + int m; char *next; next = strchr(buf,'\n'); @@ -1576,7 +1576,7 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset, void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus, tagint id_offset) { - int j,m; + int m; char *next; next = strchr(buf,'\n'); diff --git a/src/compute_pair_local.cpp b/src/compute_pair_local.cpp index b98f6eec33..3dc37707c6 100644 --- a/src/compute_pair_local.cpp +++ b/src/compute_pair_local.cpp @@ -226,13 +226,13 @@ int ComputePairLocal::compute_pairs(int flag) factor_lj = special_lj[sbmask(j)]; factor_coul = special_coul[sbmask(j)]; j &= NEIGHMASK; + jtag = tag[j]; if (!(mask[j] & groupbit)) continue; // itag = jtag is possible for long cutoffs that include images of self if (newton_pair == 0 && j >= nlocal) { - jtag = tag[j]; if (itag > jtag) { if ((itag+jtag) % 2 == 0) continue; } else if (itag < jtag) { diff --git a/src/dump.cpp b/src/dump.cpp index 181a56ff46..f11f21f71e 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -952,76 +952,67 @@ void Dump::balance() int nswap = 0; MPI_Request *request = new MPI_Request[nprocs]; - int procstart = 0; - int iproc = me; - int iproc_prev; - for (int i = 0; i < nme_balance; i++) { + // find which proc starting atom belongs to - // find which proc this atom belongs to + int startproc = me; + while (proc_new_offsets[me] < proc_offsets[startproc]) startproc--; + while (proc_new_offsets[me] > proc_offsets[startproc+1]-1) startproc++; - while (proc_new_offsets[me] + i < proc_offsets[iproc]) iproc--; - while (proc_new_offsets[me] + i > proc_offsets[iproc+1]-1) iproc++; + // find which proc ending atom belongs to - if (i != 0 && (iproc != iproc_prev || i == nme_balance - 1)) { + int endproc = me; + while (proc_new_offsets[me] + nme_balance-1 < proc_offsets[endproc]) endproc--; + while (proc_new_offsets[me] + nme_balance-1 > proc_offsets[endproc+1]-1) endproc++; - // finished with proc + // loop over procs - int procrecv = iproc; - if (iproc != iproc_prev) procrecv = iproc_prev; + for (int iproc = startproc; iproc <= endproc; iproc++) { + int istart = MAX(0, proc_offsets[iproc] - proc_new_offsets[me]); + int iend = MIN(nme_balance-1, proc_offsets[iproc+1]-1 - proc_new_offsets[me]); + int nrecv = iend - istart + 1; + if (nrecv == 0) continue; - int procnrecv = i - procstart + 1; - if (iproc != iproc_prev) procnrecv--; + // post receive for this proc - // post receive for this proc - - if (iproc_prev != me) - MPI_Irecv(&buf_balance[procstart*size_one],procnrecv*size_one,MPI_DOUBLE, - procrecv,0,world,&request[nswap++]); - - procstart = i; - } - - iproc_prev = iproc; + if (iproc != me) + MPI_Irecv(&buf_balance[istart*size_one],nrecv*size_one,MPI_DOUBLE, + iproc,0,world,&request[nswap++]); } // compute which atoms I am sending and to which procs - procstart = 0; - iproc = me; - for (int i = 0; i < nme; i++) { + // find which proc starting atom belongs to - // find which proc this atom should belong to + startproc = me; + while (proc_offsets[me] < proc_new_offsets[startproc]) startproc--; + while (proc_offsets[me] > proc_new_offsets[startproc+1]-1) startproc++; - while (proc_offsets[me] + i < proc_new_offsets[iproc]) iproc--; - while (proc_offsets[me] + i > proc_new_offsets[iproc+1] - 1) iproc++; + // find which proc ending atom belongs to - if (i != 0 && (iproc != iproc_prev || i == nme - 1)) { + endproc = me; + while (proc_offsets[me] + nme-1 < proc_new_offsets[endproc]) endproc--; + while (proc_offsets[me] + nme-1 > proc_new_offsets[endproc+1]-1) endproc++; - // finished with proc + // loop over procs - int procsend = iproc; - if (iproc != iproc_prev) procsend = iproc_prev; + for (int iproc = startproc; iproc <= endproc; iproc++) { + int istart = MAX(0,proc_new_offsets[iproc] - proc_offsets[me]); + int iend = MIN(nme-1,proc_new_offsets[iproc+1]-1 - proc_offsets[me]); + int nsend = iend - istart + 1; + if (nsend == 0) continue; - int procnsend = i - procstart + 1; - if (iproc != iproc_prev) procnsend--; + // send for this proc - // send for this proc + if (iproc != me) { + MPI_Send(&buf[istart*size_one],nsend*size_one,MPI_DOUBLE,iproc,0,world); + } else { - if (iproc_prev != me) { - MPI_Send(&buf[procstart*size_one],procnsend*size_one,MPI_DOUBLE,procsend,0,world); - } else { + // sending to self, copy buffers - // sending to self, copy buffers - - int offset_me = proc_offsets[me] - proc_new_offsets[me]; - memcpy(&buf_balance[(offset_me + procstart)*size_one],&buf[procstart*size_one],procnsend*size_one*sizeof(double)); - } - - procstart = i; + int offset_me = proc_offsets[me] - proc_new_offsets[me]; + memcpy(&buf_balance[(offset_me + istart)*size_one],&buf[istart*size_one],sizeof(double)*nsend*size_one); } - - iproc_prev = iproc; } // wait for all recvs diff --git a/src/dump_cfg.cpp b/src/dump_cfg.cpp index 8e87f4104e..d52dac745f 100644 --- a/src/dump_cfg.cpp +++ b/src/dump_cfg.cpp @@ -167,16 +167,13 @@ int DumpCFG::convert_string(int n, double *mybuf) offset += sprintf(&sbuf[offset],"%s \n",typenames[(int) mybuf[m]]); } else if (j >= 2) { if (vtype[j] == Dump::INT) - offset += - sprintf(&sbuf[offset],vformat[j],static_cast (mybuf[m])); + offset += sprintf(&sbuf[offset],vformat[j],static_cast (mybuf[m])); else if (vtype[j] == Dump::DOUBLE) offset += sprintf(&sbuf[offset],vformat[j],mybuf[m]); else if (vtype[j] == Dump::STRING) - offset += - sprintf(&sbuf[offset],vformat[j],typenames[(int) mybuf[m]]); + offset += sprintf(&sbuf[offset],vformat[j],typenames[(int) mybuf[m]]); else if (vtype[j] == Dump::BIGINT) - offset += - sprintf(&sbuf[offset],vformat[j],static_cast (mybuf[m])); + offset += sprintf(&sbuf[offset],vformat[j],static_cast (mybuf[m])); } m++; } diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp index 71429ac0f8..68893701a0 100644 --- a/src/fix_deform.cpp +++ b/src/fix_deform.cpp @@ -45,7 +45,7 @@ enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE}; /* ---------------------------------------------------------------------- */ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), -rfix(nullptr), irregular(nullptr), set(nullptr) +irregular(nullptr), set(nullptr) { if (narg < 4) error->all(FLERR,"Illegal fix deform command"); @@ -127,8 +127,8 @@ rfix(nullptr), irregular(nullptr), set(nullptr) error->all(FLERR,"Illegal fix deform command"); if (strstr(arg[iarg+3],"v_") != arg[iarg+3]) error->all(FLERR,"Illegal fix deform command"); - delete [] set[index].hstr; - delete [] set[index].hratestr; + delete[] set[index].hstr; + delete[] set[index].hratestr; set[index].hstr = utils::strdup(&arg[iarg+2][2]); set[index].hratestr = utils::strdup(&arg[iarg+3][2]); iarg += 4; @@ -185,8 +185,8 @@ rfix(nullptr), irregular(nullptr), set(nullptr) error->all(FLERR,"Illegal fix deform command"); if (strstr(arg[iarg+3],"v_") != arg[iarg+3]) error->all(FLERR,"Illegal fix deform command"); - delete [] set[index].hstr; - delete [] set[index].hratestr; + delete[] set[index].hstr; + delete[] set[index].hratestr; set[index].hstr = utils::strdup(&arg[iarg+2][2]); set[index].hratestr = utils::strdup(&arg[iarg+3][2]); iarg += 4; @@ -344,7 +344,6 @@ rfix(nullptr), irregular(nullptr), set(nullptr) force_reneighbor = 1; next_reneighbor = -1; - nrigid = 0; flip = 0; if (force_reneighbor) irregular = new Irregular(lmp); @@ -359,12 +358,11 @@ FixDeform::~FixDeform() { if (set) { for (int i = 0; i < 6; i++) { - delete [] set[i].hstr; - delete [] set[i].hratestr; + delete[] set[i].hstr; + delete[] set[i].hratestr; } } - delete [] set; - delete [] rfix; + delete[] set; delete irregular; @@ -396,9 +394,8 @@ void FixDeform::init() // domain, fix nvt/sllod, compute temp/deform only work on single h_rate int count = 0; - for (int i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"deform") == 0) count++; - if (count > 1) error->all(FLERR,"More than one fix deform"); + if (modify->get_fix_by_style("deform").size() > 1) + error->all(FLERR,"More than one fix deform"); // Kspace setting @@ -609,20 +606,12 @@ void FixDeform::init() } // detect if any rigid fixes exist so rigid bodies can be rescaled - // rfix[] = indices to each fix rigid + // rfix[] = vector with pointers to each fix rigid - delete [] rfix; - nrigid = 0; - rfix = nullptr; + rfix.clear(); - for (int i = 0; i < modify->nfix; i++) - if (modify->fix[i]->rigid_flag) nrigid++; - if (nrigid) { - rfix = new int[nrigid]; - nrigid = 0; - for (int i = 0; i < modify->nfix; i++) - if (modify->fix[i]->rigid_flag) rfix[nrigid++] = i; - } + for (auto ifix : modify->get_fix_list()) + if (ifix->rigid_flag) rfix.push_back(ifix); } /* ---------------------------------------------------------------------- @@ -894,9 +883,8 @@ void FixDeform::end_of_step() if (mask[i] & groupbit) domain->x2lamda(x[i],x[i]); - if (nrigid) - for (i = 0; i < nrigid; i++) - modify->fix[rfix[i]]->deform(0); + for (auto ifix : rfix) + ifix->deform(0); } // reset global and local box to new size/shape @@ -934,9 +922,8 @@ void FixDeform::end_of_step() if (mask[i] & groupbit) domain->lamda2x(x[i],x[i]); - if (nrigid) - for (i = 0; i < nrigid; i++) - modify->fix[rfix[i]]->deform(1); + for (auto ifix : rfix) + ifix->deform(1); } // redo KSpace coeffs since box has changed diff --git a/src/fix_deform.h b/src/fix_deform.h index e090490eca..9d7ddc4683 100644 --- a/src/fix_deform.h +++ b/src/fix_deform.h @@ -45,8 +45,7 @@ class FixDeform : public Fix { double *h_rate, *h_ratelo; int varflag; // 1 if VARIABLE option is used, 0 if not int kspace_flag; // 1 if KSpace invoked, 0 if not - int nrigid; // number of rigid fixes - int *rfix; // indices of rigid fixes + std::vector rfix; // pointers to rigid fixes class Irregular *irregular; // for migrating atoms after box flips double TWOPI; diff --git a/src/info.cpp b/src/info.cpp index 297633cd9d..66430c6f4b 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -278,9 +278,9 @@ void Info::command(int narg, char **arg) fmt::print(out,"\nLAMMPS version: {} / {}\n", lmp->version, lmp->num_ver); - if (lmp->has_git_info) + if (lmp->has_git_info()) fmt::print(out,"Git info: {} / {} / {}\n", - lmp->git_branch, lmp->git_descriptor,lmp->git_commit); + lmp->git_branch(), lmp->git_descriptor(),lmp->git_commit()); fmt::print(out,"\nOS information: {}\n\n",platform::os_info()); diff --git a/src/input.cpp b/src/input.cpp index 30424ad5cb..4107f5d163 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -784,9 +784,21 @@ int Input::execute_command() if (flag) return 0; // invoke commands added via style_command.h + // try suffixed version first - if (command_map->find(command) != command_map->end()) { - CommandCreator &command_creator = (*command_map)[command]; + std::string mycmd = command; + if (lmp->suffix_enable) { + mycmd = command + std::string("/") + lmp->suffix; + if (command_map->find(mycmd) == command_map->end()) { + if (lmp->suffix2) { + mycmd = command + std::string("/") + lmp->suffix2; + if (command_map->find(mycmd) == command_map->end()) + mycmd = command; + } else mycmd = command; + } + } + if (command_map->find(mycmd) != command_map->end()) { + CommandCreator &command_creator = (*command_map)[mycmd]; Command *cmd = command_creator(lmp); cmd->command(narg,arg); delete cmd; @@ -966,10 +978,15 @@ void Input::include() if (nfile == maxfile) error->one(FLERR,"Too many nested levels of input scripts"); - infile = fopen(arg[0],"r"); + // expand variables + int n = strlen(arg[0]) + 1; + if (n > maxline) reallocate(line,maxline,n); + strcpy(line,arg[0]); + substitute(line,work,maxline,maxwork,0); + + infile = fopen(line,"r"); if (infile == nullptr) - error->one(FLERR,"Cannot open input script {}: {}", - arg[0], utils::getsyserror()); + error->one(FLERR,"Cannot open input script {}: {}", line, utils::getsyserror()); infiles[nfile++] = infile; } diff --git a/src/lammps.cpp b/src/lammps.cpp index 55b7755c83..e6ff6efb23 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -1149,9 +1149,9 @@ void _noopt LAMMPS::help() // general help message about command line and flags - if (has_git_info) { + if (has_git_info()) { fprintf(fp,"\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " - LAMMPS_VERSION UPDATE_STRING "\nGit info (%s / %s)\n\n",git_branch, git_descriptor); + LAMMPS_VERSION UPDATE_STRING "\nGit info (%s / %s)\n\n",git_branch(), git_descriptor()); } else { fprintf(fp,"\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " LAMMPS_VERSION UPDATE_STRING "\n\n"); diff --git a/src/lammps.h b/src/lammps.h index 71b731204c..5ccc1a90a9 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -73,10 +73,10 @@ class LAMMPS { static const char *installed_packages[]; static bool is_installed_pkg(const char *pkg); - static const bool has_git_info; - static const char git_commit[]; - static const char git_branch[]; - static const char git_descriptor[]; + static bool has_git_info(); + static const char *git_commit(); + static const char *git_branch(); + static const char *git_descriptor(); LAMMPS(int, char **, MPI_Comm); ~LAMMPS(); diff --git a/src/utils.cpp b/src/utils.cpp index eabe86adbc..ca2a0c4f5b 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1028,7 +1028,7 @@ std::vector utils::split_words(const std::string &text) ------------------------------------------------------------------------- */ std::vector utils::split_lines(const std::string &text) { - return Tokenizer(text, "\n").as_vector(); + return Tokenizer(text, "\r\n").as_vector(); } /* ---------------------------------------------------------------------- diff --git a/src/write_dump.cpp b/src/write_dump.cpp index 53ab80149a..19826eba1b 100644 --- a/src/write_dump.cpp +++ b/src/write_dump.cpp @@ -68,6 +68,7 @@ void WriteDump::command(int narg, char **arg) #undef DUMP_CLASS } else error->all(FLERR,utils::check_packages_for_style("dump",arg[1],lmp)); + delete[] dumpargs; if (modindex < narg) dump->modify_params(narg-modindex-1,&arg[modindex+1]); @@ -89,5 +90,4 @@ void WriteDump::command(int narg, char **arg) // delete the Dump instance and local storage delete dump; - delete [] dumpargs; } diff --git a/tools/msi2lmp/src/GetParameters.c b/tools/msi2lmp/src/GetParameters.c index 192b4d296c..921e37491f 100644 --- a/tools/msi2lmp/src/GetParameters.c +++ b/tools/msi2lmp/src/GetParameters.c @@ -9,14 +9,14 @@ static int find_improper_body_data(char [][5],struct FrcFieldItem,int *); static void rearrange_improper(int,int); static int find_trigonal_body_data(char [][5],struct FrcFieldItem); -static int find_angleangle_data(char [][5],struct FrcFieldItem,int[]); +static int find_angleangle_data(char [][5],struct FrcFieldItem,int[3]); static int find_match(int, char [][5],struct FrcFieldItem,int *); static int match_types(int,int,char [][5],char [][5],int *); static double get_r0(int,int); static double get_t0(int,int,int); static int quo_cp(); static void get_equivs(int,char [][5],char[][5]); -static int find_equiv_type(char[]); +static int find_equiv_type(char[5]); /**********************************************************************/ /* */ diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 6489287097..a310b82c07 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -26,24 +26,21 @@ add_library(GTest::GMockMain ALIAS gmock_main) # the LAMMPS version header in the output for an empty input file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/in.empty "") add_test(NAME RunLammps - COMMAND $ -log none -echo none -in in.empty - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + COMMAND $ -log none -echo none -in in.empty) set_tests_properties(RunLammps PROPERTIES 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 add_test(NAME HelpMessage - COMMAND $ -h - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + COMMAND $ -h) set_tests_properties(HelpMessage PROPERTIES 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 add_test(NAME InvalidFlag - COMMAND $ -xxx - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + COMMAND $ -xxx) set_tests_properties(InvalidFlag PROPERTIES ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=1" PASS_REGULAR_EXPRESSION "ERROR: Invalid command-line argument.*") diff --git a/unittest/c-library/CMakeLists.txt b/unittest/c-library/CMakeLists.txt index 3d57dbbc90..e9409be0cc 100644 --- a/unittest/c-library/CMakeLists.txt +++ b/unittest/c-library/CMakeLists.txt @@ -1,26 +1,26 @@ add_executable(test_library_open test_library_open.cpp test_main.cpp) target_link_libraries(test_library_open PRIVATE lammps GTest::GMock) -add_test(LibraryOpen test_library_open) +add_test(NAME LibraryOpen COMMAND test_library_open) add_executable(test_library_commands test_library_commands.cpp test_main.cpp) target_link_libraries(test_library_commands PRIVATE lammps GTest::GMock) -add_test(LibraryCommands test_library_commands) +add_test(NAME LibraryCommands COMMAND test_library_commands) add_executable(test_library_external test_library_external.cpp test_main.cpp) target_link_libraries(test_library_external PRIVATE lammps GTest::GMock) -add_test(LibraryExternal test_library_external) +add_test(NAME LibraryExternal COMMAND test_library_external) add_executable(test_library_properties test_library_properties.cpp test_main.cpp) 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) +add_test(NAME LibraryProperties COMMAND 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::GMock) target_compile_definitions(test_library_scatter_gather PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) -add_test(LibraryScatterGather test_library_scatter_gather) +add_test(NAME LibraryScatterGather COMMAND test_library_scatter_gather) set_tests_properties(LibraryScatterGather PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") set(TEST_CONFIG_DEFS "-DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR};-DLAMMPS_${LAMMPS_SIZES}") @@ -65,7 +65,7 @@ endforeach() add_executable(test_library_config test_library_config.cpp test_main.cpp) 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) +add_test(NAME LibraryConfig COMMAND test_library_config) add_executable(test_library_mpi test_library_mpi.cpp) target_link_libraries(test_library_mpi PRIVATE lammps GTest::GMock) diff --git a/unittest/c-library/test_library_commands.cpp b/unittest/c-library/test_library_commands.cpp index 203862c696..f1cc51d8d9 100644 --- a/unittest/c-library/test_library_commands.cpp +++ b/unittest/c-library/test_library_commands.cpp @@ -20,7 +20,7 @@ const char *cont_input[] = {"create_atoms 1 single &", "0.2 0.1 0.1"}; class LibraryCommands : public ::testing::Test { protected: void *lmp; - LibraryCommands() = default; + LibraryCommands() = default; ~LibraryCommands() override = default; void SetUp() override @@ -55,13 +55,13 @@ TEST_F(LibraryCommands, from_file) const char cont_file[] = "in.cont"; fp = fopen(demo_file, "w"); - for (auto & inp : demo_input) { + for (auto &inp : demo_input) { fputs(inp, fp); fputc('\n', fp); } fclose(fp); fp = fopen(cont_file, "w"); - for (auto & inp : cont_input) { + for (auto &inp : cont_input) { fputs(inp, fp); fputc('\n', fp); } @@ -85,7 +85,7 @@ TEST_F(LibraryCommands, from_line) { EXPECT_EQ(lammps_get_natoms(lmp), 0); if (!verbose) ::testing::internal::CaptureStdout(); - for (auto & inp : demo_input) { + for (auto &inp : demo_input) { lammps_command(lmp, inp); } if (!verbose) ::testing::internal::GetCapturedStdout(); @@ -106,11 +106,11 @@ TEST_F(LibraryCommands, from_string) { std::string cmds(""); - for (auto & inp : demo_input) { + for (auto &inp : demo_input) { cmds += inp; cmds += "\n"; } - for (auto & inp : cont_input) { + for (auto &inp : cont_input) { cmds += inp; cmds += "\n"; } @@ -126,11 +126,11 @@ TEST_F(LibraryCommands, from_string) if (!verbose) ::testing::internal::GetCapturedStdout(); cmds.clear(); - for (auto & inp : demo_input) { + for (auto &inp : demo_input) { cmds += inp; cmds += "\r\n"; } - for (auto & inp : cont_input) { + for (auto &inp : cont_input) { cmds += inp; cmds += "\r\n"; } diff --git a/unittest/c-library/test_library_config.cpp b/unittest/c-library/test_library_config.cpp index 456faff06f..f402ffc2e9 100644 --- a/unittest/c-library/test_library_config.cpp +++ b/unittest/c-library/test_library_config.cpp @@ -22,7 +22,7 @@ protected: void *lmp; std::string INPUT_DIR = STRINGIFY(TEST_INPUT_FOLDER); - LibraryConfig() = default; + LibraryConfig() = default; ~LibraryConfig() override = default; void SetUp() override diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index 192c6897e9..9bfea75d40 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -25,7 +25,7 @@ protected: void *lmp; std::string INPUT_DIR = STRINGIFY(TEST_INPUT_FOLDER); - LibraryProperties() = default; + LibraryProperties() = default; ~LibraryProperties() override = default; void SetUp() override @@ -438,8 +438,10 @@ class AtomProperties : public ::testing::Test { protected: void *lmp; - AtomProperties()= default;; - ~AtomProperties() override= default;; + AtomProperties() = default; + ; + ~AtomProperties() override = default; + ; void SetUp() override { diff --git a/unittest/c-library/test_library_scatter_gather.cpp b/unittest/c-library/test_library_scatter_gather.cpp index 6144516ac2..25e3dde787 100644 --- a/unittest/c-library/test_library_scatter_gather.cpp +++ b/unittest/c-library/test_library_scatter_gather.cpp @@ -25,7 +25,7 @@ protected: void *lmp; std::string INPUT_DIR = STRINGIFY(TEST_INPUT_FOLDER); - GatherProperties() = default; + GatherProperties() = default; ~GatherProperties() override = default; void SetUp() override diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index 49603a8b22..d4f437dc4c 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -9,21 +9,21 @@ if((NOT (CMAKE_SYSTEM_NAME STREQUAL "Windows")) AND PKG_PLUGIN) endif() target_link_libraries(test_simple_commands PRIVATE lammps GTest::GMock) -add_test(NAME SimpleCommands COMMAND test_simple_commands WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME SimpleCommands COMMAND test_simple_commands) set_tests_properties(SimpleCommands PROPERTIES - ENVIRONMENT "LAMMPS_PLUGIN_BIN_DIR=${CMAKE_BINARY_DIR}/build-plugins") + ENVIRONMENT "LAMMPS_PLUGIN_BIN_DIR=${CMAKE_BINARY_DIR}") add_executable(test_lattice_region test_lattice_region.cpp) 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_test(NAME LatticeRegion COMMAND test_lattice_region) add_executable(test_groups test_groups.cpp) target_link_libraries(test_groups PRIVATE lammps GTest::GMock) -add_test(NAME Groups COMMAND test_groups WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME Groups COMMAND test_groups) add_executable(test_variables test_variables.cpp) target_link_libraries(test_variables PRIVATE lammps GTest::GMock) -add_test(NAME Variables COMMAND test_variables WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME Variables COMMAND test_variables) add_executable(test_kim_commands test_kim_commands.cpp) if(KIM_EXTRA_UNITTESTS) @@ -34,12 +34,12 @@ if(KIM_EXTRA_UNITTESTS) endif() endif() 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_test(NAME KimCommands COMMAND test_kim_commands) add_executable(test_reset_ids test_reset_ids.cpp) target_compile_definitions(test_reset_ids PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_reset_ids PRIVATE lammps GTest::GMock) -add_test(NAME ResetIDs COMMAND test_reset_ids WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME ResetIDs COMMAND test_reset_ids) add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) target_link_libraries(test_mpi_load_balancing PRIVATE lammps GTest::GMock) diff --git a/unittest/commands/data.fourmol b/unittest/commands/data.fourmol deleted file mode 120000 index ebbe325d24..0000000000 --- a/unittest/commands/data.fourmol +++ /dev/null @@ -1 +0,0 @@ -../force-styles/tests/data.fourmol \ No newline at end of file diff --git a/unittest/commands/data.fourmol b/unittest/commands/data.fourmol new file mode 100644 index 0000000000..70dc685895 --- /dev/null +++ b/unittest/commands/data.fourmol @@ -0,0 +1,223 @@ +LAMMPS data file via write_data, version 5 May 2020, timestep = 0 + +29 atoms +5 atom types +24 bonds +5 bond types +30 angles +4 angle types +31 dihedrals +5 dihedral types +2 impropers +2 improper types + + -6.024572 8.975428 xlo xhi + -7.692866 7.307134 ylo yhi + -8.086924 6.913076 zlo zhi + +Masses + +1 12.0107 +2 4.00794 +3 14.0067 +4 15.9994 +5 15.9994 + +Pair Coeffs # zero + +1 +2 +3 +4 +5 + +Bond Coeffs # zero + +1 1.5 +2 1.1 +3 1.3 +4 1.2 +5 1 + +Angle Coeffs # zero + +1 110.1 +2 111 +3 120 +4 108.5 + +Dihedral Coeffs # zero + +1 +2 +3 +4 +5 + +Improper Coeffs # zero + +1 +2 + +Atoms # full + +10 2 1 7.0000000000000007e-02 2.0185283555536988e+00 -1.4283966846517357e+00 -9.6733527271133024e-01 0 0 0 +11 2 2 8.9999999999999997e-02 1.7929780509347666e+00 -1.9871047540768743e+00 -1.8840626643185674e+00 0 0 0 +12 2 1 -2.7000000000000002e-01 3.0030247876861225e+00 -4.8923319967572748e-01 -1.6188658531537248e+00 0 0 0 +13 2 2 8.9999999999999997e-02 4.0447273787895934e+00 -9.0131998547446246e-01 -1.6384447268320836e+00 0 0 0 +14 2 2 8.9999999999999997e-02 2.6033152817257075e+00 -4.0789761505963579e-01 -2.6554413538823063e+00 0 0 0 + 2 1 2 3.1000000000000000e-01 3.0197083955402204e-01 2.9515239068888608e+00 -8.5689735572907566e-01 0 0 0 + 3 1 1 -2.0000000000000000e-02 -6.9435377880558602e-01 1.2440473127136711e+00 -6.2233801468892025e-01 0 0 0 + 4 1 2 8.9999999999999997e-02 -1.5771614164685133e+00 1.4915333140468066e+00 -1.2487126845040522e+00 0 0 0 + 6 1 1 5.1000000000000001e-01 2.9412607937706009e-01 2.2719282656652909e-01 -1.2843094067857870e+00 0 0 0 + 7 1 4 -5.1000000000000001e-01 3.4019871062879609e-01 -9.1277350075786561e-03 -2.4633113224304561e+00 0 0 0 +19 3 2 4.2359999999999998e-01 1.5349125211132961e+00 2.6315969880333707e+00 -4.2472859440220647e+00 0 0 0 +15 2 2 8.9999999999999997e-02 2.9756315249791303e+00 5.6334269722969288e-01 -1.2437650754599008e+00 0 0 0 +18 3 4 -8.4719999999999995e-01 2.1384791188033843e+00 3.0177261773770208e+00 -3.5160827596876225e+00 0 0 0 +20 3 2 4.2359999999999998e-01 2.7641167828863153e+00 3.6833419064000221e+00 -3.9380850623312638e+00 0 0 0 + 8 2 3 -4.6999999999999997e-01 1.1641187171852805e+00 -4.8375305955385234e-01 -6.7659823767368688e-01 0 0 0 + 9 2 2 3.1000000000000000e-01 1.3777459838125838e+00 -2.5366338669522998e-01 2.6877644730326306e-01 0 0 0 +16 2 1 5.1000000000000001e-01 2.6517554244980306e+00 -2.3957110424978438e+00 3.2908335999178327e-02 0 0 0 +17 2 4 -5.1000000000000001e-01 2.2309964792710639e+00 -2.1022918943319384e+00 1.1491948328949437e+00 0 0 0 + 1 1 3 -4.6999999999999997e-01 -2.7993683669226832e-01 2.4726588069312840e+00 -1.7200860244148433e-01 0 0 0 + 5 1 2 8.9999999999999997e-02 -8.9501761359359255e-01 9.3568128743071344e-01 4.0227731871484346e-01 0 0 0 +21 4 5 -8.4719999999999995e-01 4.9064454390208301e+00 -4.0751205255383196e+00 -3.6215576073601046e+00 0 0 0 +22 4 2 4.2359999999999998e-01 4.3687453488627543e+00 -4.2054270536772504e+00 -4.4651491269372565e+00 0 0 0 +23 4 2 4.2359999999999998e-01 5.7374928154769504e+00 -3.5763355905184966e+00 -3.8820297194230728e+00 0 0 0 +24 5 5 -8.4719999999999995e-01 2.0684115301174013e+00 3.1518221747664397e+00 3.1554242678474576e+00 0 0 0 +25 5 2 4.2359999999999998e-01 1.2998381073113014e+00 3.2755513587518097e+00 2.5092990173114837e+00 0 0 0 +26 5 2 4.2359999999999998e-01 2.5807438597688113e+00 4.0120175892854135e+00 3.2133398379059099e+00 0 0 0 +27 6 5 -8.4719999999999995e-01 -1.9613581876744359e+00 -4.3556300596085160e+00 2.1101467673534788e+00 0 0 0 +28 6 2 4.2359999999999998e-01 -2.7406520384725965e+00 -4.0207251278130975e+00 1.5828689861678511e+00 0 0 0 +29 6 2 4.2359999999999998e-01 -1.3108232656499081e+00 -3.5992986322410760e+00 2.2680459788743503e+00 0 0 0 + +Velocities + +1 7.7867804888392077e-04 5.8970331623292821e-04 -2.2179517633030531e-04 +2 2.7129529964126462e-03 4.6286427111164284e-03 3.5805549693846352e-03 +3 -1.2736791029204805e-03 1.6108674226414498e-03 -3.3618185901550799e-04 +4 -9.2828595122009308e-04 -1.2537885319521818e-03 -4.1204974953432108e-03 +5 -1.1800848061603740e-03 7.5424401975844038e-04 6.9023177964912290e-05 +6 -3.0914004879905335e-04 1.2755385764678133e-03 7.9574303350202582e-04 +7 -1.1037894966874103e-04 -7.6764845099077425e-04 -7.7217630460203659e-04 +8 3.9060281273221989e-04 -8.1444231918053418e-04 1.5134641148324972e-04 +9 1.2475530960659720e-03 -2.6608454451432528e-03 1.1117602907112732e-03 +10 4.5008983776042893e-04 4.9530197647538077e-04 -2.3336234361093645e-04 +11 -3.6977669078869707e-04 -1.5289071951960539e-03 -2.9176389881837113e-03 +12 1.0850834530183159e-03 -6.4965897903201833e-04 -1.2971152622619948e-03 +13 4.0754559196230639e-03 3.5043502394946119e-03 -7.8324487687854666e-04 +14 -1.3837220448746613e-04 -4.0656048637594394e-03 -3.9333461173944500e-03 +15 -4.3301707382721859e-03 -3.1802661664634938e-03 3.2037919043360571e-03 +16 -9.6715751018414326e-05 -5.0016572678960377e-04 1.4945658875149626e-03 +17 6.5692180538157174e-04 3.6635779995305095e-04 8.3495414466050911e-04 +18 -6.0936815808025862e-04 -9.3774557532468582e-04 -3.3558072507805731e-04 +19 -6.9919768291957119e-04 -3.6060777270430031e-03 4.2833405289822791e-03 +20 4.7777805013736515e-03 5.1003745845520452e-03 1.8002873923729241e-03 +21 -9.5568188553430398e-04 1.6594630943762931e-04 -1.8199788009966615e-04 +22 -3.3137518957653462e-03 -2.8683968287936054e-03 3.6384389958326871e-03 +23 2.4209481134686401e-04 -4.5457709985051130e-03 2.7663581642115042e-03 +24 2.5447450568861086e-04 4.8412447786110117e-04 -4.8021914527341357e-04 +25 4.3722771097312743e-03 -4.5184411669545515e-03 2.5200952006556795e-03 +26 -1.9250110555001179e-03 -3.0342169883610837e-03 3.5062814567984532e-03 +27 -2.6510179146429716e-04 3.6306203629019116e-04 -5.6235585400647747e-04 +28 -2.3068708109787484e-04 -8.5663070212203200e-04 2.1302563179109169e-03 +29 -2.5054744388303732e-03 -1.6773997805290820e-04 2.8436699761004796e-03 + +Bonds + +1 5 1 2 +2 3 1 3 +3 2 3 4 +4 2 3 5 +5 1 3 6 +6 3 6 8 +7 4 6 7 +8 5 8 9 +9 3 8 10 +10 2 10 11 +11 1 10 12 +12 1 10 16 +13 2 12 13 +14 2 12 14 +15 2 12 15 +16 4 16 17 +17 5 18 19 +18 5 18 20 +19 5 21 22 +20 5 21 23 +21 5 24 25 +22 5 24 26 +23 5 27 28 +24 5 27 29 + +Angles + +1 4 2 1 3 +2 4 1 3 5 +3 4 1 3 4 +4 4 1 3 6 +5 4 4 3 5 +6 2 5 3 6 +7 2 4 3 6 +8 3 3 6 7 +9 3 3 6 8 +10 3 7 6 8 +11 2 6 8 9 +12 2 9 8 10 +13 3 6 8 10 +14 2 8 10 11 +15 3 8 10 16 +16 2 11 10 12 +17 1 12 10 16 +18 1 8 10 12 +19 2 11 10 16 +20 2 10 12 15 +21 2 10 12 14 +22 2 10 12 13 +23 4 13 12 15 +24 4 13 12 14 +25 4 14 12 15 +26 4 10 16 17 +27 1 19 18 20 +28 1 22 21 23 +29 1 25 24 26 +30 1 28 27 29 + +Dihedrals + +1 2 2 1 3 6 +2 2 2 1 3 4 +3 3 2 1 3 5 +4 1 1 3 6 8 +5 1 1 3 6 7 +6 5 4 3 6 8 +7 5 4 3 6 7 +8 5 5 3 6 8 +9 5 5 3 6 7 +10 4 3 6 8 9 +11 3 3 6 8 10 +12 3 7 6 8 9 +13 4 7 6 8 10 +14 2 6 8 10 12 +15 2 6 8 10 16 +16 2 6 8 10 11 +17 2 9 8 10 12 +18 4 9 8 10 16 +19 5 9 8 10 11 +20 5 8 10 12 13 +21 1 8 10 12 14 +22 5 8 10 12 15 +23 4 8 10 16 17 +24 5 11 10 12 13 +25 5 11 10 12 14 +26 5 11 10 12 15 +27 2 11 10 16 17 +28 2 12 10 16 17 +29 5 16 10 12 13 +30 5 16 10 12 14 +31 5 16 10 12 15 + +Impropers + +1 1 6 3 8 7 +2 2 8 6 10 9 diff --git a/unittest/commands/in.fourmol b/unittest/commands/in.fourmol deleted file mode 120000 index cc47b5adb9..0000000000 --- a/unittest/commands/in.fourmol +++ /dev/null @@ -1 +0,0 @@ -../force-styles/tests/in.fourmol \ No newline at end of file diff --git a/unittest/commands/in.fourmol b/unittest/commands/in.fourmol new file mode 100644 index 0000000000..df936da78e --- /dev/null +++ b/unittest/commands/in.fourmol @@ -0,0 +1,30 @@ +variable newton_pair index on +variable newton_bond index on +variable bond_factor index 0.10 +variable angle_factor index 0.25 +variable dihedral_factor index 0.50 +variable units index real +variable input_dir index . +variable data_file index ${input_dir}/data.fourmol +variable pair_style index 'zero 8.0' +variable bond_style index zero +variable angle_style index zero +variable dihedral_style index zero +variable improper_style index zero +variable t_target index 100.0 + +atom_style full +atom_modify map array +neigh_modify delay 2 every 2 check no +units ${units} +timestep 0.1 +newton ${newton_pair} ${newton_bond} +special_bonds lj/coul ${bond_factor} ${angle_factor} ${dihedral_factor} + +pair_style ${pair_style} +bond_style ${bond_style} +angle_style ${angle_style} +dihedral_style ${dihedral_style} +improper_style ${improper_style} + +read_data ${data_file} diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index 9d69b5412e..a356a02cca 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -34,7 +34,6 @@ using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { using ::testing::ExitedWithCode; -using ::testing::MatchesRegex; using ::testing::StrEq; class GroupTest : public LAMMPSTest { diff --git a/unittest/commands/test_kim_commands.cpp b/unittest/commands/test_kim_commands.cpp index 183d333ab4..953b4e5a00 100644 --- a/unittest/commands/test_kim_commands.cpp +++ b/unittest/commands/test_kim_commands.cpp @@ -33,7 +33,6 @@ bool verbose = false; using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { -using ::testing::MatchesRegex; using ::testing::StrEq; class KimCommandsTest : public LAMMPSTest { diff --git a/unittest/commands/test_lattice_region.cpp b/unittest/commands/test_lattice_region.cpp index 1bbda21001..4f314b1669 100644 --- a/unittest/commands/test_lattice_region.cpp +++ b/unittest/commands/test_lattice_region.cpp @@ -35,8 +35,8 @@ bool verbose = false; using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { +using ::testing::ContainsRegex; using ::testing::ExitedWithCode; -using ::testing::MatchesRegex; using ::testing::StrEq; class LatticeRegionTest : public LAMMPSTest { @@ -82,7 +82,7 @@ TEST_F(LatticeRegionTest, lattice_sc) BEGIN_CAPTURE_OUTPUT(); command("lattice sc 1.0 spacing 1.5 2.0 3.0"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 1.5.* 2.* 3.*")); + ASSERT_THAT(output, ContainsRegex(".*Lattice spacing in x,y,z = 1.5.* 2.* 3.*")); auto lattice = lmp->domain->lattice; ASSERT_EQ(lattice->xlattice, 1.5); @@ -92,7 +92,7 @@ TEST_F(LatticeRegionTest, lattice_sc) BEGIN_CAPTURE_OUTPUT(); command("lattice sc 2.0"); output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 2.* 2.* 2.*")); + ASSERT_THAT(output, ContainsRegex(".*Lattice spacing in x,y,z = 2.* 2.* 2.*")); lattice = lmp->domain->lattice; ASSERT_EQ(lattice->style, Lattice::SC); diff --git a/unittest/commands/test_reset_ids.cpp b/unittest/commands/test_reset_ids.cpp index c67f90b341..1506f9a892 100644 --- a/unittest/commands/test_reset_ids.cpp +++ b/unittest/commands/test_reset_ids.cpp @@ -32,7 +32,6 @@ bool verbose = false; using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { -using ::testing::MatchesRegex; #define GETIDX(i) lmp->atom->map(i) @@ -47,8 +46,8 @@ protected: LAMMPSTest::SetUp(); if (info->has_style("atom", "full")) { BEGIN_HIDE_OUTPUT(); - command("variable input_dir index " STRINGIFY(TEST_INPUT_FOLDER)); - command("include ${input_dir}/in.fourmol"); + command("variable input_dir index \"" STRINGIFY(TEST_INPUT_FOLDER) "\""); + command("include \"${input_dir}/in.fourmol\""); END_HIDE_OUTPUT(); } } diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 1844752d33..acbade5ad8 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -39,8 +39,8 @@ bool verbose = false; using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { +using ::testing::ContainsRegex; using ::testing::ExitedWithCode; -using ::testing::MatchesRegex; using ::testing::StrEq; class SimpleCommandsTest : public LAMMPSTest { @@ -394,62 +394,62 @@ TEST_F(SimpleCommandsTest, Plugin) lmp->input->one(fmt::format(loadfmt, "hello")); auto text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Loading plugin: Hello world command.*")); + ASSERT_THAT(text, ContainsRegex(".*Loading plugin: Hello world command.*")); ::testing::internal::CaptureStdout(); 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, ContainsRegex(".*Open of file .*xxx.* failed.*")); ::testing::internal::CaptureStdout(); lmp->input->one(fmt::format(loadfmt, "nve2")); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Loading plugin: NVE2 variant fix style.*")); + ASSERT_THAT(text, ContainsRegex(".*Loading plugin: NVE2 variant fix style.*")); ::testing::internal::CaptureStdout(); lmp->input->one("plugin list"); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*1: command style plugin hello" - ".*2: fix style plugin nve2.*")); + ASSERT_THAT(text, ContainsRegex(".*1: command style plugin hello" + ".*2: fix style plugin nve2.*")); ::testing::internal::CaptureStdout(); lmp->input->one(fmt::format(loadfmt, "hello")); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Ignoring load of command style hello: " - "must unload existing hello plugin.*")); + ASSERT_THAT(text, ContainsRegex(".*Ignoring load of command style hello: " + "must unload existing hello plugin.*")); ::testing::internal::CaptureStdout(); lmp->input->one("plugin unload command hello"); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Unloading command style hello.*")); + ASSERT_THAT(text, ContainsRegex(".*Unloading command style hello.*")); ::testing::internal::CaptureStdout(); 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 from a plugin.*")); + ASSERT_THAT(text, ContainsRegex(".*Ignoring unload of pair style nve2: not from a plugin.*")); ::testing::internal::CaptureStdout(); lmp->input->one("plugin unload fix nve2"); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Unloading fix style nve2.*")); + ASSERT_THAT(text, ContainsRegex(".*Unloading fix style nve2.*")); ::testing::internal::CaptureStdout(); 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 from a plugin.*")); + ASSERT_THAT(text, ContainsRegex(".*Ignoring unload of fix style nve: not from a plugin.*")); ::testing::internal::CaptureStdout(); lmp->input->one("plugin list"); text = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << text; - ASSERT_THAT(text, MatchesRegex(".*Currently loaded plugins.*")); + ASSERT_THAT(text, ContainsRegex(".*Currently loaded plugins.*")); } #endif @@ -478,7 +478,13 @@ TEST_F(SimpleCommandsTest, Shell) test_var = getenv("TEST_VARIABLE"); ASSERT_NE(test_var, nullptr); +#if defined(_WIN32) + // we cannot create empty environment variables on Windows so platform::putenv() sets their + // value to "1" + ASSERT_THAT(test_var, StrEq("1")); +#else ASSERT_THAT(test_var, StrEq("")); +#endif } TEST_F(SimpleCommandsTest, CiteMe) @@ -495,8 +501,9 @@ TEST_F(SimpleCommandsTest, CiteMe) std::string text = END_CAPTURE_OUTPUT(); // find the two unique citations, but not the third - ASSERT_THAT(text, MatchesRegex(".*one.*two.*")); - ASSERT_THAT(text, Not(MatchesRegex(".*one.*two.*one.*"))); + ASSERT_THAT(text, ContainsRegex("test citation one.\n.*test citation two.*")); + ASSERT_THAT(text, Not(ContainsRegex( + "test citation one.\n.*test citation two.*\n.*test citation one.*"))); BEGIN_CAPTURE_OUTPUT(); lmp->citeme->add("test citation one:\n 0\n"); @@ -507,8 +514,8 @@ TEST_F(SimpleCommandsTest, CiteMe) text = END_CAPTURE_OUTPUT(); // find the forth (only differs in long citation) and sixth added citation - ASSERT_THAT(text, MatchesRegex(".*one.*three.*")); - ASSERT_THAT(text, Not(MatchesRegex(".*two.*"))); + ASSERT_THAT(text, ContainsRegex("test citation one.*\n.*test citation three.*")); + ASSERT_THAT(text, Not(ContainsRegex("test_citation two.*\n"))); BEGIN_CAPTURE_OUTPUT(); lmp->citeme->add("test citation one:\n 1\n"); @@ -521,7 +528,7 @@ TEST_F(SimpleCommandsTest, CiteMe) text = END_CAPTURE_OUTPUT(); // no new citation. no CITE-CITE-CITE- lines - ASSERT_THAT(text, Not(MatchesRegex(".*CITE-CITE-CITE-CITE.*"))); + ASSERT_THAT(text, Not(ContainsRegex(".*CITE-CITE-CITE-CITE.*"))); } } // namespace LAMMPS_NS diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index fb0aa58069..57a5d4f0ca 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -36,8 +36,8 @@ using LAMMPS_NS::MathConst::MY_PI; using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { +using ::testing::ContainsRegex; using ::testing::ExitedWithCode; -using ::testing::MatchesRegex; using ::testing::StrEq; class VariableTest : public LAMMPSTest { @@ -317,7 +317,7 @@ TEST_F(VariableTest, Expressions) ASSERT_TRUE(variable->equalstyle(ivar)); ASSERT_DOUBLE_EQ(variable->compute_equal(ivar), 2.0); ASSERT_DOUBLE_EQ(variable->compute_equal("v_three"), 3.0); - ASSERT_NEAR(variable->compute_equal("v_four"), MY_PI,1.0e-14); + ASSERT_NEAR(variable->compute_equal("v_four"), MY_PI, 1.0e-14); ASSERT_GE(variable->compute_equal("v_five"), 20210310); ASSERT_DOUBLE_EQ(variable->compute_equal("v_seven"), -1); ASSERT_DOUBLE_EQ(variable->compute_equal("v_eight"), 2.5); @@ -394,58 +394,58 @@ TEST_F(VariableTest, IfCommand) BEGIN_CAPTURE_OUTPUT(); command("if 1>0 then 'print \"bingo!\"'"); auto text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if 1>2 then 'print \"bingo!\"' else 'print \"nope?\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*nope\?.*")); + ASSERT_THAT(text, ContainsRegex(".*nope\?.*")); BEGIN_CAPTURE_OUTPUT(); command("if (1<=0) then 'print \"bingo!\"' else 'print \"nope?\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*nope\?.*")); + ASSERT_THAT(text, ContainsRegex(".*nope\?.*")); BEGIN_CAPTURE_OUTPUT(); command("if (-1.0e-1<0.0E+0)|^(1<0) then 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if (${one}==1.0)&&(2>=1) then 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if !((${one}!=1.0)||(2|^1)) then 'print \"missed\"' else 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if (1>=2)&&(0&&1) then 'print \"missed\"' else 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if !1 then 'print \"missed\"' else 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if !(a==b) then 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if x==x|^1==0 then 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); BEGIN_CAPTURE_OUTPUT(); command("if x!=x|^a!=b then 'print \"bingo!\"'"); text = END_CAPTURE_OUTPUT(); - ASSERT_THAT(text, MatchesRegex(".*bingo!.*")); + ASSERT_THAT(text, ContainsRegex(".*bingo!.*")); TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*", command("if () then 'print \"bingo!\"'");); diff --git a/unittest/cplusplus/CMakeLists.txt b/unittest/cplusplus/CMakeLists.txt index efd194b9d2..88f082a204 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) -add_test(LammpsClass test_lammps_class) +add_test(NAME LammpsClass COMMAND 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::GTestMain) -add_test(InputClass test_input_class) +add_test(NAME InputClass COMMAND test_input_class) add_executable(test_error_class test_error_class.cpp) target_link_libraries(test_error_class PRIVATE lammps GTest::GMock) -add_test(ErrorClass test_error_class) +add_test(NAME ErrorClass COMMAND test_error_class) diff --git a/unittest/cplusplus/test_error_class.cpp b/unittest/cplusplus/test_error_class.cpp index f4f0d3b28b..27318646be 100644 --- a/unittest/cplusplus/test_error_class.cpp +++ b/unittest/cplusplus/test_error_class.cpp @@ -17,7 +17,7 @@ bool verbose = false; namespace LAMMPS_NS { -using ::testing::MatchesRegex; +using ::testing::ContainsRegex; using utils::split_words; class Error_class : public LAMMPSTest { @@ -39,7 +39,7 @@ TEST_F(Error_class, message) auto output = CAPTURE_OUTPUT([&] { error->message(FLERR, "one message"); }); - ASSERT_THAT(output, MatchesRegex("one message .*test_error_class.cpp:.*")); + ASSERT_THAT(output, ContainsRegex("one message .*test_error_class.cpp:.*")); }; TEST_F(Error_class, warning) @@ -48,7 +48,7 @@ TEST_F(Error_class, warning) auto output = CAPTURE_OUTPUT([&] { error->warning(FLERR, "one warning"); }); - ASSERT_THAT(output, MatchesRegex("WARNING: one warning .*test_error_class.cpp:.*")); + ASSERT_THAT(output, ContainsRegex("WARNING: one warning .*test_error_class.cpp:.*")); ASSERT_THAT(error->get_maxwarn(), 100); // warnings disabled @@ -72,7 +72,7 @@ TEST_F(Error_class, warning) output = CAPTURE_OUTPUT([&] { thermo->lost_check(); }); - ASSERT_THAT(output, MatchesRegex("WARNING: Too many warnings: 5 vs 2. All future.*")); + ASSERT_THAT(output, ContainsRegex("WARNING: Too many warnings: 5 vs 2. All future.*")); output = CAPTURE_OUTPUT([&] { error->warning(FLERR, "one warning"); @@ -91,7 +91,7 @@ TEST_F(Error_class, warning) output = CAPTURE_OUTPUT([&] { error->warning(FLERR, "one warning"); }); - ASSERT_THAT(output, MatchesRegex("WARNING: one warning.*")); + ASSERT_THAT(output, ContainsRegex("WARNING: one warning.*")); BEGIN_HIDE_OUTPUT(); command("thermo_modify warn default"); diff --git a/unittest/cplusplus/test_input_class.cpp b/unittest/cplusplus/test_input_class.cpp index b1d8af28c6..6595c24695 100644 --- a/unittest/cplusplus/test_input_class.cpp +++ b/unittest/cplusplus/test_input_class.cpp @@ -60,13 +60,13 @@ TEST_F(Input_commands, from_file) const char cont_file[] = "in.cont"; fp = fopen(demo_file, "w"); - for (auto & inp : demo_input) { + for (auto &inp : demo_input) { fputs(inp, fp); fputc('\n', fp); } fclose(fp); fp = fopen(cont_file, "w"); - for (auto & inp : cont_input) { + for (auto &inp : cont_input) { fputs(inp, fp); fputc('\n', fp); } @@ -84,7 +84,7 @@ TEST_F(Input_commands, from_file) TEST_F(Input_commands, from_line) { EXPECT_EQ(lmp->atom->natoms, 0); - for (auto & inp : demo_input) { + for (auto &inp : demo_input) { lmp->input->one(inp); } EXPECT_EQ(lmp->atom->natoms, 1); diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index 3a1bde51ff..6c733a31e4 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -11,7 +11,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -using ::testing::MatchesRegex; +using ::testing::ContainsRegex; using ::testing::StartsWith; namespace LAMMPS_NS { @@ -90,14 +90,14 @@ TEST_F(LAMMPS_plain, InitMembers) EXPECT_EQ(lmp->memoryKK, nullptr); EXPECT_NE(lmp->python, nullptr); EXPECT_EQ(lmp->citeme, nullptr); - if (LAMMPS::has_git_info) { - EXPECT_STRNE(LAMMPS::git_commit, ""); - EXPECT_STRNE(LAMMPS::git_branch, ""); - EXPECT_STRNE(LAMMPS::git_descriptor, ""); + if (LAMMPS::has_git_info()) { + EXPECT_STRNE(LAMMPS::git_commit(), ""); + EXPECT_STRNE(LAMMPS::git_branch(), ""); + EXPECT_STRNE(LAMMPS::git_descriptor(), ""); } else { - EXPECT_STREQ(LAMMPS::git_commit, "(unknown)"); - EXPECT_STREQ(LAMMPS::git_branch, "(unknown)"); - EXPECT_STREQ(LAMMPS::git_descriptor, "(unknown)"); + EXPECT_STREQ(LAMMPS::git_commit(), "(unknown)"); + EXPECT_STREQ(LAMMPS::git_branch(), "(unknown)"); + EXPECT_STREQ(LAMMPS::git_descriptor(), "(unknown)"); } } @@ -225,14 +225,14 @@ TEST_F(LAMMPS_omp, InitMembers) EXPECT_EQ(lmp->memoryKK, nullptr); EXPECT_NE(lmp->python, nullptr); EXPECT_NE(lmp->citeme, nullptr); - if (LAMMPS::has_git_info) { - EXPECT_STRNE(LAMMPS::git_commit, ""); - EXPECT_STRNE(LAMMPS::git_branch, ""); - EXPECT_STRNE(LAMMPS::git_descriptor, ""); + if (LAMMPS::has_git_info()) { + EXPECT_STRNE(LAMMPS::git_commit(), ""); + EXPECT_STRNE(LAMMPS::git_branch(), ""); + EXPECT_STRNE(LAMMPS::git_descriptor(), ""); } else { - EXPECT_STREQ(LAMMPS::git_commit, "(unknown)"); - EXPECT_STREQ(LAMMPS::git_branch, "(unknown)"); - EXPECT_STREQ(LAMMPS::git_descriptor, "(unknown)"); + EXPECT_STREQ(LAMMPS::git_commit(), "(unknown)"); + EXPECT_STREQ(LAMMPS::git_branch(), "(unknown)"); + EXPECT_STREQ(LAMMPS::git_descriptor(), "(unknown)"); } } @@ -312,14 +312,14 @@ TEST_F(LAMMPS_kokkos, InitMembers) EXPECT_NE(lmp->memoryKK, nullptr); EXPECT_NE(lmp->python, nullptr); EXPECT_NE(lmp->citeme, nullptr); - if (LAMMPS::has_git_info) { - EXPECT_STRNE(LAMMPS::git_commit, ""); - EXPECT_STRNE(LAMMPS::git_branch, ""); - EXPECT_STRNE(LAMMPS::git_descriptor, ""); + if (LAMMPS::has_git_info()) { + EXPECT_STRNE(LAMMPS::git_commit(), ""); + EXPECT_STRNE(LAMMPS::git_branch(), ""); + EXPECT_STRNE(LAMMPS::git_descriptor(), ""); } else { - EXPECT_STREQ(LAMMPS::git_commit, "(unknown)"); - EXPECT_STREQ(LAMMPS::git_branch, "(unknown)"); - EXPECT_STREQ(LAMMPS::git_descriptor, "(unknown)"); + EXPECT_STREQ(LAMMPS::git_commit(), "(unknown)"); + EXPECT_STREQ(LAMMPS::git_branch(), "(unknown)"); + EXPECT_STREQ(LAMMPS::git_descriptor(), "(unknown)"); } } @@ -339,7 +339,7 @@ TEST(LAMMPS_init, OpenMP) ::testing::internal::CaptureStdout(); LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); - EXPECT_THAT(output, MatchesRegex(".*using 2 OpenMP thread.*per MPI task.*")); + EXPECT_THAT(output, ContainsRegex(".*using 2 OpenMP thread.*per MPI task.*")); if (LAMMPS_NS::Info::has_accelerator_feature("OPENMP", "api", "openmp")) EXPECT_EQ(lmp->comm->nthreads, 2); @@ -372,8 +372,8 @@ TEST(LAMMPS_init, NoOpenMP) ::testing::internal::CaptureStdout(); LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); - EXPECT_THAT(output, - MatchesRegex(".*OMP_NUM_THREADS environment is not set.*Defaulting to 1 thread.*")); + EXPECT_THAT(output, ContainsRegex( + ".*OMP_NUM_THREADS environment is not set.*Defaulting to 1 thread.*")); EXPECT_EQ(lmp->comm->nthreads, 1); ::testing::internal::CaptureStdout(); delete lmp; diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt index 464cd9426a..934c110b1f 100644 --- a/unittest/force-styles/CMakeLists.txt +++ b/unittest/force-styles/CMakeLists.txt @@ -46,11 +46,7 @@ else() endif() target_include_directories(style_tests PRIVATE ${LAMMPS_SOURCE_DIR}) target_link_libraries(style_tests PUBLIC gmock Yaml::Yaml lammps) -if(BUILD_MPI) - target_link_libraries(style_tests PUBLIC MPI::MPI_CXX) -else() - target_link_libraries(style_tests PUBLIC mpi_stubs) -endif() + # propagate sanitizer options to test tools if(ENABLE_SANITIZER AND (NOT (ENABLE_SANITIZER STREQUAL "none"))) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) @@ -72,6 +68,28 @@ if(FFT_SINGLE) target_compile_definitions(test_pair_style PRIVATE -DFFT_SINGLE) endif() +# prepare environment for testers +if(WIN32) + set(FORCE_TEST_ENVIRONMENT PYTHONPATH=${TEST_INPUT_FOLDER}) +else() + set(FORCE_TEST_ENVIRONMENT PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}) +endif() +list(APPEND FORCE_TEST_ENVIRONMENT "PYTHONUNBUFFERED=1") +list(APPEND FORCE_TEST_ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +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() +if(APPLE) + list(APPEND FORCE_TEST_ENVIRONMENT "DYLD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{DYLD_LIBRARY_PATH}") +elseif(WIN32) + list(APPEND FORCE_TEST_ENVIRONMENT "LAMMPSDLLPATH=${LAMMPS_LIB_PATH}") +else() + list(APPEND FORCE_TEST_ENVIRONMENT "LD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{LD_LIBRARY_PATH}") +endif() + # tests for molecular systems and related pair styles file(GLOB MOL_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/mol-pair-*.yaml) # cannot test MSM with single precision data @@ -81,8 +99,12 @@ endif() foreach(TEST ${MOL_PAIR_TESTS}) string(REGEX REPLACE "^.*mol-pair-(.*)\.yaml" "MolPairStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -91,8 +113,12 @@ file(GLOB ATOMIC_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/atomic-p foreach(TEST ${ATOMIC_PAIR_TESTS}) string(REGEX REPLACE "^.*atomic-pair-(.*)\.yaml" "AtomicPairStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -101,8 +127,12 @@ file(GLOB MANYBODY_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/manybo foreach(TEST ${MANYBODY_PAIR_TESTS}) string(REGEX REPLACE "^.*manybody-pair-(.*)\.yaml" "ManybodyPairStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -114,8 +144,12 @@ file(GLOB BOND_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/bond-*.yaml) foreach(TEST ${BOND_TESTS}) string(REGEX REPLACE "^.*bond-(.*)\.yaml" "BondStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_bond_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_bond_style ${TEST}) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -127,8 +161,12 @@ file(GLOB ANGLE_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/angle-*.yaml) foreach(TEST ${ANGLE_TESTS}) string(REGEX REPLACE "^.*angle-(.*)\.yaml" "AngleStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_angle_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_angle_style ${TEST}) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -141,8 +179,12 @@ endif() foreach(TEST ${KSPACE_TESTS}) string(REGEX REPLACE "^.*kspace-(.*)\.yaml" "KSpaceStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -158,8 +200,16 @@ file(GLOB FIX_TIMESTEP_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/fix-tim foreach(TEST ${FIX_TIMESTEP_TESTS}) string(REGEX REPLACE "^.*fix-timestep-(.*)\.yaml" "FixTimestep:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST}) +if(WIN32) + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}\\\;${LAMMPS_PYTHON_DIR}") +else() set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}") +endif() set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -171,7 +221,11 @@ file(GLOB DIHEDRAL_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/dihedral-*. foreach(TEST ${DIHEDRAL_TESTS}) string(REGEX REPLACE "^.*dihedral-(.*)\.yaml" "DihedralStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -184,7 +238,11 @@ file(GLOB IMPROPER_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/improper-*. foreach(TEST ${IMPROPER_TESTS}) string(REGEX REPLACE "^.*improper-(.*)\.yaml" "ImproperStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) - add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index 86050acb37..a617ec1783 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -285,7 +285,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // run_stress stress = lmp->force->angle->virial; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], - stress[1], stress[2], stress[3], stress[4], stress[5]); + stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); block.clear(); diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index f00e45b0aa..a851f4341f 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -285,7 +285,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // run_stress stress = lmp->force->bond->virial; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], - stress[1], stress[2], stress[3], stress[4], stress[5]); + stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); block.clear(); diff --git a/unittest/force-styles/test_config_reader.cpp b/unittest/force-styles/test_config_reader.cpp index e6cf73f10e..d152b4fcf4 100644 --- a/unittest/force-styles/test_config_reader.cpp +++ b/unittest/force-styles/test_config_reader.cpp @@ -374,7 +374,7 @@ void TestConfigReader::tags(const yaml_event_t &event) { std::stringstream data((char *)event.data.scalar.value); config.tags.clear(); - for (std::string tag; std::getline(data, tag, ','); ) { + for (std::string tag; std::getline(data, tag, ',');) { config.tags.push_back(trim(tag)); } } diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index e87f2c0f07..0156e8e021 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -288,7 +288,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // run_stress stress = lmp->force->dihedral->virial; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], - stress[1], stress[2], stress[3], stress[4], stress[5]); + stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); block.clear(); diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 6d91231d74..fcf6be39d3 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -204,8 +204,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) if (fix->thermo_virial) { auto stress = fix->virial; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} " - "{:23.16e} {:23.16e} {:23.16e}", - stress[0], stress[1], stress[2], stress[3], stress[4], stress[5]); + "{:23.16e} {:23.16e} {:23.16e}", + stress[0], stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); } diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 9e2a71e6ef..49b7d22cad 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -279,7 +279,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // run_stress stress = lmp->force->improper->virial; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], - stress[1], stress[2], stress[3], stress[4], stress[5]); + stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); block.clear(); diff --git a/unittest/force-styles/tests/mol-pair-harmonic_cut.yaml b/unittest/force-styles/tests/mol-pair-harmonic_cut.yaml index f1c39f1bd5..fb2714626f 100644 --- a/unittest/force-styles/tests/mol-pair-harmonic_cut.yaml +++ b/unittest/force-styles/tests/mol-pair-harmonic_cut.yaml @@ -1,6 +1,5 @@ --- lammps_version: 7 Jan 2022 -tags: generated date_generated: Sat Jan 15 17:42:24 2022 epsilon: 5e-14 skip_tests: diff --git a/unittest/formats/CMakeLists.txt b/unittest/formats/CMakeLists.txt index be8e055adb..8a198d4c64 100644 --- a/unittest/formats/CMakeLists.txt +++ b/unittest/formats/CMakeLists.txt @@ -1,49 +1,49 @@ add_executable(test_atom_styles test_atom_styles.cpp) 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_test(NAME AtomStyles COMMAND test_atom_styles) add_executable(test_image_flags test_image_flags.cpp) 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_test(NAME ImageFlags COMMAND test_image_flags) add_executable(test_input_convert test_input_convert.cpp) 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_test(NAME InputConvert COMMAND test_input_convert) add_executable(test_molecule_file test_molecule_file.cpp) 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_test(NAME MoleculeFile COMMAND test_molecule_file) add_executable(test_pair_unit_convert test_pair_unit_convert.cpp) 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}) +add_test(NAME PairUnitConvert COMMAND test_pair_unit_convert) 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) -add_test(NAME PotentialFileReader COMMAND test_potential_file_reader WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME PotentialFileReader COMMAND test_potential_file_reader) 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) - add_test(NAME EIMPotentialFileReader COMMAND test_eim_potential_file_reader WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME EIMPotentialFileReader COMMAND test_eim_potential_file_reader) 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) -add_test(NAME TextFileReader COMMAND test_text_file_reader WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME TextFileReader COMMAND test_text_file_reader) 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) -add_test(NAME FileOperations COMMAND test_file_operations WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME FileOperations COMMAND test_file_operations) add_executable(test_dump_atom test_dump_atom.cpp) target_link_libraries(test_dump_atom PRIVATE lammps GTest::GMock) -add_test(NAME DumpAtom COMMAND test_dump_atom WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME DumpAtom COMMAND test_dump_atom) set_tests_properties(DumpAtom PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") if(PKG_COMPRESS) @@ -64,19 +64,19 @@ if(PKG_COMPRESS) 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) - add_test(NAME DumpAtomGZ COMMAND test_dump_atom_compressed gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpAtomGZ COMMAND test_dump_atom_compressed gz) set_tests_properties(DumpAtomGZ PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${GZIP_BINARY}") - add_test(NAME DumpCustomGZ COMMAND test_dump_custom_compressed gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpCustomGZ COMMAND test_dump_custom_compressed gz) set_tests_properties(DumpCustomGZ PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${GZIP_BINARY}") - add_test(NAME DumpCfgGZ COMMAND test_dump_cfg_compressed gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpCfgGZ COMMAND test_dump_cfg_compressed gz) set_tests_properties(DumpCfgGZ PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${GZIP_BINARY}") - add_test(NAME DumpLocalGZ COMMAND test_dump_local_compressed gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpLocalGZ COMMAND test_dump_local_compressed gz) set_tests_properties(DumpLocalGZ PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${GZIP_BINARY}") - add_test(NAME DumpXYZGZ COMMAND test_dump_xyz_compressed gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpXYZGZ COMMAND test_dump_xyz_compressed gz) set_tests_properties(DumpXYZGZ PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${GZIP_BINARY}") find_package(PkgConfig REQUIRED) @@ -84,43 +84,43 @@ if(PKG_COMPRESS) find_program(ZSTD_BINARY NAMES zstd) if(Zstd_FOUND AND ZSTD_BINARY) - add_test(NAME DumpAtomZstd COMMAND test_dump_atom_compressed zstd WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpAtomZstd COMMAND test_dump_atom_compressed zstd) set_tests_properties(DumpAtomZstd PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${ZSTD_BINARY}") - add_test(NAME DumpCustomZstd COMMAND test_dump_custom_compressed zstd WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpCustomZstd COMMAND test_dump_custom_compressed zstd) set_tests_properties(DumpCustomZstd PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${ZSTD_BINARY}") - add_test(NAME DumpCfgZstd COMMAND test_dump_cfg_compressed zstd WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpCfgZstd COMMAND test_dump_cfg_compressed zstd) set_tests_properties(DumpCfgZstd PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${ZSTD_BINARY}") - add_test(NAME DumpLocalZstd COMMAND test_dump_local_compressed zstd WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpLocalZstd COMMAND test_dump_local_compressed zstd) set_tests_properties(DumpLocalZstd PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${ZSTD_BINARY}") - add_test(NAME DumpXYZZstd COMMAND test_dump_xyz_compressed zstd WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpXYZZstd COMMAND test_dump_xyz_compressed zstd) set_tests_properties(DumpXYZZstd PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};COMPRESS_BINARY=${ZSTD_BINARY}") endif() endif() add_executable(test_dump_custom test_dump_custom.cpp) target_link_libraries(test_dump_custom PRIVATE lammps GTest::GMock) -add_test(NAME DumpCustom COMMAND test_dump_custom WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME DumpCustom COMMAND test_dump_custom) 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) -add_test(NAME DumpCfg COMMAND test_dump_cfg WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME DumpCfg COMMAND test_dump_cfg) 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) -add_test(NAME DumpLocal COMMAND test_dump_local WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +add_test(NAME DumpLocal COMMAND test_dump_local) set_tests_properties(DumpLocal PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") if(PKG_NETCDF) find_program(NCDUMP NAMES ncdump ncdump.exe) add_executable(test_dump_netcdf test_dump_netcdf.cpp) target_link_libraries(test_dump_netcdf PRIVATE lammps GTest::GMock) - add_test(NAME DumpNetCDF COMMAND test_dump_netcdf WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + add_test(NAME DumpNetCDF COMMAND test_dump_netcdf) if(NOT (NCDUMP STREQUAL "NCDUMP-NOTFOUND")) set_tests_properties(DumpNetCDF PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};NCDUMP_BINARY=${NCDUMP}") endif() diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index 59c0e1350c..c4c79238aa 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -2123,7 +2123,7 @@ TEST_F(AtomStyleTest, body_nparticle) "12.0 0.0 12.0 0.0 0.0 0.0\n" "0.0 1.0 0.0\n" "0.0 -3.0 0.0\n"; - FILE *fp = fopen("input_atom_styles.data", "w"); + FILE *fp = fopen("input_atom_styles.data", "w"); fputs(data_file, fp); fclose(fp); BEGIN_HIDE_OUTPUT(); @@ -4809,6 +4809,446 @@ TEST_F(AtomStyleTest, property_atom) EXPECT_NEAR(three[GETIDX(2)], 0.5, EPSILON); } +TEST_F(AtomStyleTest, oxdna) +{ + if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!LAMMPS::is_installed_pkg("ASPHERE")) GTEST_SKIP(); + if (!LAMMPS::is_installed_pkg("CG-DNA")) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("atom_style hybrid bond ellipsoid oxdna"); + END_HIDE_OUTPUT(); + + AtomState expected; + expected.atom_style = "hybrid"; + expected.molecular = Atom::MOLECULAR; + expected.tag_enable = 1; + expected.molecule_flag = 1; + expected.ellipsoid_flag = 1; + expected.rmass_flag = 1; + expected.torque_flag = 1; + expected.angmom_flag = 1; + expected.has_type = true; + expected.has_mask = true; + expected.has_image = true; + expected.has_x = true; + expected.has_v = true; + expected.has_f = true; + expected.has_bonds = true; + expected.has_nspecial = true; + expected.has_special = true; + expected.map_style = 3; + + ASSERT_ATOM_STATE_EQ(lmp->atom, expected); + + auto hybrid = (AtomVecHybrid *)lmp->atom->avec; + ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_EQ(hybrid->nstyles, 3); + ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("bond")); + ASSERT_THAT(std::string(hybrid->keywords[1]), Eq("ellipsoid")); + ASSERT_THAT(std::string(hybrid->keywords[2]), Eq("oxdna")); + ASSERT_NE(hybrid->styles[0], nullptr); + ASSERT_NE(hybrid->styles[1], nullptr); + ASSERT_NE(hybrid->styles[2], nullptr); + + BEGIN_HIDE_OUTPUT(); + command("units lj"); + command("dimension 3"); + command("newton on"); + command("boundary p p p"); + command("atom_modify sort 0 1.0"); + command("neighbor 2.0 bin"); + command("neigh_modify every 1 delay 0 check yes"); + command("region mybox block -20 20 -20 20 -20 20"); + command("create_box 4 mybox bond/types 1 extra/bond/per/atom 2 extra/special/per/atom 4"); + command("create_atoms 1 single -0.33741452300167507 -0.43708835412476305 0.6450685042019271"); + command("create_atoms 2 single -0.32142606102826937 -0.7137743037592722 1.1817366147004618"); + command("create_atoms 3 single -0.130363628207774 -0.9147144801536078 1.62581312195109"); + command("create_atoms 4 single 0.16795127962282844 -0.9808507459807022 2.0894908590909003"); + command("create_atoms 1 single 0.46370423490634166 -0.7803347954883079 2.4251986815515827"); + command("create_atoms 4 single -0.4462950185476711 0.09062163051035639 2.4668941268777607"); + command("create_atoms 1 single -0.03377054097560965 0.20979847489755046 2.078208732038921"); + command("create_atoms 2 single 0.3297325391466579 0.17657587120899895 1.7206328374934152"); + command("create_atoms 3 single 0.6063699309305985 0.04682595158675571 1.2335049647817748"); + command("create_atoms 4 single 0.8003979559814726 -0.364393011459011 0.9884025318908612"); + command("set type 1 mass 3.1575"); + command("set type 2 mass 3.1575"); + command("set type 3 mass 3.1575"); + command("set type 4 mass 3.1575"); + command("mass 1 3.1575"); + command("mass 2 3.1575"); + command("mass 3 3.1575"); + command("mass 4 3.1575"); + command("set atom 1 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 2 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 3 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 4 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 5 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 6 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 7 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 8 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 9 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 10 shape 1.173984503142341 1.173984503142341 1.173984503142341"); + command("set atom 1 quat 0.120438343611269 -0.970540441176996 0.208676441957758 16.990727782866998"); + command("set atom 2 quat 0.122039415796829 -0.068232256412985 0.990177125658213 40.001729435287870"); + command("set atom 3 quat 0.052760168698289 0.030943512185297 0.998127679033382 69.627682451632380"); + command("set atom 4 quat -0.037622918613871 0.030623545471522 0.998822664169035 97.038820280300570"); + command("set atom 5 quat 0.055056042946138 0.077631917807377 0.995460756369964 137.7813218321917"); + command("set atom 6 quat 0.931128471673637 -0.355724722922553 -0.080372201291206 166.2836226291888"); + command("set atom 7 quat 0.753526078198930 -0.648440397941919 0.108275111595674 200.6802564250672"); + command("set atom 8 quat 0.553942138074214 -0.829580511279186 0.070315595507185 192.0355407659524"); + command("set atom 9 quat -0.373540155765431 0.913070802138105 -0.163613759548524 171.0789308260751"); + command("set atom 10 quat 0.027515673832457 0.998248649922676 -0.052369080773879 161.2621224558284"); + command("bond_style oxdna2/fene"); + command("bond_coeff * 2.0 0.25 0.7564"); + command("special_bonds lj 0 1 1"); + command("create_bonds single/bond 1 1 2"); + command("create_bonds single/bond 1 2 3"); + command("create_bonds single/bond 1 3 4"); + command("create_bonds single/bond 1 4 5"); + command("create_bonds single/bond 1 6 7"); + command("create_bonds single/bond 1 7 8"); + command("create_bonds single/bond 1 8 9"); + command("create_bonds single/bond 1 9 10"); + command("pair_style hybrid/overlay oxdna2/excv oxdna2/stk oxdna2/hbond oxdna2/xstk oxdna2/coaxstk oxdna2/dh"); + command("pair_coeff * * oxdna2/excv 2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32"); + command("pair_coeff * * oxdna2/stk seqdep 0.1 1.3523 2.6717 6.0 0.4 0.9 0.32 0.75 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65"); + command("pair_coeff * * oxdna2/hbond seqdep 0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"); + command("pair_coeff 1 4 oxdna2/hbond seqdep 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"); + command("pair_coeff 2 3 oxdna2/hbond seqdep 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"); + command("pair_coeff * * oxdna2/xstk 47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68"); + command("pair_coeff * * oxdna2/coaxstk 58.5 0.4 0.6 0.22 0.58 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793"); + command("pair_coeff * * oxdna2/dh 0.1 0.2 0.815"); + END_HIDE_OUTPUT(); + + ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_NE(lmp->atom->avec, nullptr); + ASSERT_EQ(lmp->atom->natoms, 10); + ASSERT_EQ(lmp->atom->nbonds, 8); + ASSERT_EQ(lmp->atom->nbondtypes, 1); + ASSERT_EQ(lmp->atom->nellipsoids, 10); + ASSERT_EQ(lmp->atom->nlocal, 10); + ASSERT_EQ(lmp->atom->nghost, 0); + ASSERT_NE(lmp->atom->nmax, -1); + ASSERT_EQ(lmp->atom->tag_enable, 1); + ASSERT_EQ(lmp->atom->molecular, Atom::MOLECULAR); + ASSERT_EQ(lmp->atom->ntypes, 4); + ASSERT_EQ(lmp->atom->nextra_grow, 0); + ASSERT_EQ(lmp->atom->nextra_restart, 0); + ASSERT_EQ(lmp->atom->nextra_border, 0); + ASSERT_EQ(lmp->atom->nextra_grow_max, 0); + ASSERT_EQ(lmp->atom->nextra_restart_max, 0); + ASSERT_EQ(lmp->atom->nextra_border_max, 0); + ASSERT_EQ(lmp->atom->nextra_store, 0); + ASSERT_EQ(lmp->atom->extra_grow, nullptr); + ASSERT_EQ(lmp->atom->extra_restart, nullptr); + ASSERT_EQ(lmp->atom->extra_border, nullptr); + ASSERT_EQ(lmp->atom->extra, nullptr); + ASSERT_NE(lmp->atom->mass, nullptr); + ASSERT_NE(lmp->atom->rmass, nullptr); + ASSERT_EQ(lmp->atom->ellipsoid_flag, 1); + ASSERT_NE(lmp->atom->ellipsoid, nullptr); + ASSERT_NE(lmp->atom->mass_setflag, nullptr); + ASSERT_NE(lmp->atom->id5p, nullptr); + + BEGIN_HIDE_OUTPUT(); + command("write_data test_atom_styles.data nocoeff"); + command("clear"); + command("units lj"); + command("dimension 3"); + command("newton on"); + command("boundary p p p"); + command("atom_style hybrid bond ellipsoid oxdna"); + command("atom_modify sort 0 1.0"); + command("neighbor 2.0 bin"); + command("neigh_modify every 1 delay 0 check yes"); + command("read_data test_atom_styles.data"); + command("set type 1 mass 3.1575"); + command("set type 2 mass 3.1575"); + command("set type 3 mass 3.1575"); + command("set type 4 mass 3.1575"); + command("mass 1 3.1575"); + command("mass 2 3.1575"); + command("mass 3 3.1575"); + command("mass 4 3.1575"); + command("bond_style oxdna2/fene"); + command("bond_coeff * 2.0 0.25 0.7564"); + command("special_bonds lj 0 1 1"); + command("pair_style hybrid/overlay oxdna2/excv oxdna2/stk oxdna2/hbond oxdna2/xstk oxdna2/coaxstk oxdna2/dh"); + command("pair_coeff * * oxdna2/excv 2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32"); + command("pair_coeff * * oxdna2/stk seqdep 0.1 1.3523 2.6717 6.0 0.4 0.9 0.32 0.75 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65"); + command("pair_coeff * * oxdna2/hbond seqdep 0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"); + command("pair_coeff 1 4 oxdna2/hbond seqdep 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"); + command("pair_coeff 2 3 oxdna2/hbond seqdep 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"); + command("pair_coeff * * oxdna2/xstk 47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68"); + command("pair_coeff * * oxdna2/coaxstk 58.5 0.4 0.6 0.22 0.58 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793"); + command("pair_coeff * * oxdna2/dh 0.1 0.2 0.815"); + + ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_NE(lmp->atom->avec, nullptr); + hybrid = (AtomVecHybrid *)lmp->atom->avec; + + ASSERT_EQ(hybrid->nstyles, 3); + ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("bond")); + ASSERT_THAT(std::string(hybrid->keywords[1]), Eq("ellipsoid")); + ASSERT_THAT(std::string(hybrid->keywords[2]), Eq("oxdna")); + ASSERT_NE(hybrid->styles[0], nullptr); + ASSERT_NE(hybrid->styles[1], nullptr); + ASSERT_NE(hybrid->styles[2], nullptr); + + ASSERT_EQ(lmp->atom->natoms, 10); + ASSERT_EQ(lmp->atom->nbonds, 8); + ASSERT_EQ(lmp->atom->nbondtypes, 1); + ASSERT_EQ(lmp->atom->nellipsoids, 10); + ASSERT_EQ(lmp->atom->nlocal, 10); + ASSERT_EQ(lmp->atom->nghost, 0); + ASSERT_NE(lmp->atom->nmax, -1); + ASSERT_EQ(lmp->atom->tag_enable, 1); + ASSERT_EQ(lmp->atom->molecular, Atom::MOLECULAR); + ASSERT_EQ(lmp->atom->ntypes, 4); + ASSERT_EQ(lmp->atom->nextra_grow, 0); + ASSERT_EQ(lmp->atom->nextra_restart, 0); + ASSERT_EQ(lmp->atom->nextra_border, 0); + ASSERT_EQ(lmp->atom->nextra_grow_max, 0); + ASSERT_EQ(lmp->atom->nextra_restart_max, 0); + ASSERT_EQ(lmp->atom->nextra_border_max, 0); + ASSERT_EQ(lmp->atom->nextra_store, 0); + ASSERT_EQ(lmp->atom->extra_grow, nullptr); + ASSERT_EQ(lmp->atom->extra_restart, nullptr); + ASSERT_EQ(lmp->atom->extra_border, nullptr); + ASSERT_EQ(lmp->atom->extra, nullptr); + ASSERT_NE(lmp->atom->mass, nullptr); + ASSERT_NE(lmp->atom->rmass, nullptr); + ASSERT_EQ(lmp->atom->ellipsoid_flag, 1); + ASSERT_NE(lmp->atom->ellipsoid, nullptr); + ASSERT_NE(lmp->atom->mass_setflag, nullptr); + ASSERT_NE(lmp->atom->id5p, nullptr); + + auto x = lmp->atom->x; + auto v = lmp->atom->v; + auto type = lmp->atom->type; + auto ellipsoid = lmp->atom->ellipsoid; + auto rmass = lmp->atom->rmass; + + auto avec = (AtomVecEllipsoid *)hybrid->styles[1]; + auto bonus = avec->bonus; + + EXPECT_NEAR(x[GETIDX(1)][0], -0.33741452300167507, EPSILON); + EXPECT_NEAR(x[GETIDX(1)][1], -0.43708835412476305, EPSILON); + EXPECT_NEAR(x[GETIDX(1)][2], 0.6450685042019271, EPSILON); + EXPECT_NEAR(x[GETIDX(2)][0], -0.32142606102826937, EPSILON); + EXPECT_NEAR(x[GETIDX(2)][1], -0.7137743037592722, EPSILON); + EXPECT_NEAR(x[GETIDX(2)][2], 1.1817366147004618, EPSILON); + EXPECT_NEAR(x[GETIDX(3)][0], -0.130363628207774, EPSILON); + EXPECT_NEAR(x[GETIDX(3)][1], -0.9147144801536078, EPSILON); + EXPECT_NEAR(x[GETIDX(3)][2], 1.62581312195109, EPSILON); + EXPECT_NEAR(x[GETIDX(4)][0], 0.16795127962282844, EPSILON); + EXPECT_NEAR(x[GETIDX(4)][1], -0.9808507459807022, EPSILON); + EXPECT_NEAR(x[GETIDX(4)][2], 2.0894908590909003, EPSILON); + EXPECT_NEAR(x[GETIDX(5)][0], 0.46370423490634166, EPSILON); + EXPECT_NEAR(x[GETIDX(5)][1], -0.7803347954883079, EPSILON); + EXPECT_NEAR(x[GETIDX(5)][2], 2.4251986815515827, EPSILON); + EXPECT_NEAR(x[GETIDX(6)][0], -0.4462950185476711, EPSILON); + EXPECT_NEAR(x[GETIDX(6)][1], 0.09062163051035639, EPSILON); + EXPECT_NEAR(x[GETIDX(6)][2], 2.4668941268777607, EPSILON); + EXPECT_NEAR(x[GETIDX(7)][0], -0.03377054097560965, EPSILON); + EXPECT_NEAR(x[GETIDX(7)][1], 0.20979847489755046, EPSILON); + EXPECT_NEAR(x[GETIDX(7)][2], 2.078208732038921, EPSILON); + EXPECT_NEAR(x[GETIDX(8)][0], 0.3297325391466579, EPSILON); + EXPECT_NEAR(x[GETIDX(8)][1], 0.17657587120899895, EPSILON); + EXPECT_NEAR(x[GETIDX(8)][2], 1.7206328374934152, EPSILON); + EXPECT_NEAR(x[GETIDX(9)][0], 0.6063699309305985, EPSILON); + EXPECT_NEAR(x[GETIDX(9)][1], 0.04682595158675571, EPSILON); + EXPECT_NEAR(x[GETIDX(9)][2], 1.2335049647817748, EPSILON); + EXPECT_NEAR(x[GETIDX(10)][0], 0.8003979559814726, EPSILON); + EXPECT_NEAR(x[GETIDX(10)][1], -0.364393011459011, EPSILON); + EXPECT_NEAR(x[GETIDX(10)][2], 0.9884025318908612, EPSILON); + + EXPECT_NEAR(v[GETIDX(1)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(1)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(1)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(2)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(2)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(2)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(3)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(3)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(3)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(4)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(4)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(4)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(5)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(5)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(5)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(6)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(6)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(6)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(7)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(7)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(7)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(8)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(8)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(8)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(9)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(9)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(9)][2], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(10)][0], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(10)][1], 0.0, EPSILON); + EXPECT_NEAR(v[GETIDX(10)][2], 0.0, EPSILON); + + ASSERT_EQ(type[GETIDX(1)], 1); + ASSERT_EQ(type[GETIDX(2)], 2); + ASSERT_EQ(type[GETIDX(3)], 3); + ASSERT_EQ(type[GETIDX(4)], 4); + ASSERT_EQ(type[GETIDX(5)], 1); + ASSERT_EQ(type[GETIDX(6)], 4); + ASSERT_EQ(type[GETIDX(7)], 1); + ASSERT_EQ(type[GETIDX(8)], 2); + ASSERT_EQ(type[GETIDX(9)], 3); + ASSERT_EQ(type[GETIDX(10)], 4); + + ASSERT_EQ(ellipsoid[GETIDX(1)], 0); + ASSERT_EQ(ellipsoid[GETIDX(2)], 1); + ASSERT_EQ(ellipsoid[GETIDX(3)], 2); + ASSERT_EQ(ellipsoid[GETIDX(4)], 3); + ASSERT_EQ(ellipsoid[GETIDX(5)], 4); + ASSERT_EQ(ellipsoid[GETIDX(6)], 5); + ASSERT_EQ(ellipsoid[GETIDX(7)], 6); + ASSERT_EQ(ellipsoid[GETIDX(8)], 7); + ASSERT_EQ(ellipsoid[GETIDX(9)], 8); + ASSERT_EQ(ellipsoid[GETIDX(10)], 9); + + EXPECT_NEAR(rmass[GETIDX(1)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(2)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(3)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(4)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(5)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(6)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(7)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(8)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(9)], 3.1575, EPSILON); + EXPECT_NEAR(rmass[GETIDX(10)], 3.1575, EPSILON); + + EXPECT_NEAR(bonus[0].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[0].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[0].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[1].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[1].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[1].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[2].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[2].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[2].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[3].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[3].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[3].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[4].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[4].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[4].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[5].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[5].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[5].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[6].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[6].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[6].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[7].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[7].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[7].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[8].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[8].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[8].shape[2], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[9].shape[0], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[9].shape[1], 0.5869922515711705, EPSILON); + EXPECT_NEAR(bonus[9].shape[2], 0.5869922515711705, EPSILON); + + EXPECT_NEAR(bonus[0].quat[0], 0.9890278201757743, EPSILON); + EXPECT_NEAR(bonus[0].quat[1], 0.01779228232037064, EPSILON); + EXPECT_NEAR(bonus[0].quat[2], -0.14337734159225404, EPSILON); + EXPECT_NEAR(bonus[0].quat[3], 0.030827642240801516, EPSILON); + EXPECT_NEAR(bonus[1].quat[0], 0.939687458852748, EPSILON); + EXPECT_NEAR(bonus[1].quat[1], 0.04174166924055095, EPSILON); + EXPECT_NEAR(bonus[1].quat[2], -0.023337773785056866, EPSILON); + EXPECT_NEAR(bonus[1].quat[3], 0.338674565089608, EPSILON); + EXPECT_NEAR(bonus[2].quat[0], 0.8210113150655425, EPSILON); + EXPECT_NEAR(bonus[2].quat[1], 0.03012140921736572, EPSILON); + EXPECT_NEAR(bonus[2].quat[2], 0.017666019956944813, EPSILON); + EXPECT_NEAR(bonus[2].quat[3], 0.5698429897612057, EPSILON); + EXPECT_NEAR(bonus[3].quat[0], 0.6623662858285051, EPSILON); + EXPECT_NEAR(bonus[3].quat[1], -0.028186343967346823, EPSILON); + EXPECT_NEAR(bonus[3].quat[2], 0.022942552517501488, EPSILON); + EXPECT_NEAR(bonus[3].quat[3], 0.7482981175276918, EPSILON); + EXPECT_NEAR(bonus[4].quat[0], 0.3601488726765216, EPSILON); + EXPECT_NEAR(bonus[4].quat[1], 0.0513614985821682, EPSILON); + EXPECT_NEAR(bonus[4].quat[2], 0.0724224158335286, EPSILON); + EXPECT_NEAR(bonus[4].quat[3], 0.9286602067807472, EPSILON); + EXPECT_NEAR(bonus[5].quat[0], 0.11941234710084649, EPSILON); + EXPECT_NEAR(bonus[5].quat[1], 0.9244660117493703, EPSILON); + EXPECT_NEAR(bonus[5].quat[2], -0.35317942248051865, EPSILON); + EXPECT_NEAR(bonus[5].quat[3], -0.07979711784524246, EPSILON); + EXPECT_NEAR(bonus[6].quat[0], -0.17949125421205164, EPSILON); + EXPECT_NEAR(bonus[6].quat[1], 0.7412884899431119, EPSILON); + EXPECT_NEAR(bonus[6].quat[2], -0.6379094464220707, EPSILON); + EXPECT_NEAR(bonus[6].quat[3], 0.1065166771202199, EPSILON); + EXPECT_NEAR(bonus[7].quat[0], -0.10483691088405202, EPSILON); + EXPECT_NEAR(bonus[7].quat[1], 0.5508895999584645, EPSILON); + EXPECT_NEAR(bonus[7].quat[2], -0.8250090480220789, EPSILON); + EXPECT_NEAR(bonus[7].quat[3], 0.06992811634525403, EPSILON); + EXPECT_NEAR(bonus[8].quat[0], 0.07777239911646, EPSILON); + EXPECT_NEAR(bonus[8].quat[1], -0.3724087549185288, EPSILON); + EXPECT_NEAR(bonus[8].quat[2], 0.9103052384821374, EPSILON); + EXPECT_NEAR(bonus[8].quat[3], -0.1631181963720798, EPSILON); + EXPECT_NEAR(bonus[9].quat[0], 0.16279109707978262, EPSILON); + EXPECT_NEAR(bonus[9].quat[1], 0.027148630125149613, EPSILON); + EXPECT_NEAR(bonus[9].quat[2], 0.9849325709665359, EPSILON); + EXPECT_NEAR(bonus[9].quat[3], -0.0516705065113425, EPSILON); + + auto num_bond = lmp->atom->num_bond; + auto bond_type = lmp->atom->bond_type; + auto bond_atom = lmp->atom->bond_atom; + auto id5p = lmp->atom->id5p; + + ASSERT_EQ(num_bond[GETIDX(1)], 1); + ASSERT_EQ(num_bond[GETIDX(2)], 1); + ASSERT_EQ(num_bond[GETIDX(3)], 1); + ASSERT_EQ(num_bond[GETIDX(4)], 1); + ASSERT_EQ(num_bond[GETIDX(5)], 0); + ASSERT_EQ(num_bond[GETIDX(6)], 1); + ASSERT_EQ(num_bond[GETIDX(7)], 1); + ASSERT_EQ(num_bond[GETIDX(8)], 1); + ASSERT_EQ(num_bond[GETIDX(9)], 1); + ASSERT_EQ(num_bond[GETIDX(10)], 0); + + ASSERT_EQ(bond_type[GETIDX(1)][0], 1); + ASSERT_EQ(bond_type[GETIDX(2)][0], 1); + ASSERT_EQ(bond_type[GETIDX(3)][0], 1); + ASSERT_EQ(bond_type[GETIDX(4)][0], 1); + ASSERT_EQ(bond_type[GETIDX(6)][0], 1); + ASSERT_EQ(bond_type[GETIDX(7)][0], 1); + ASSERT_EQ(bond_type[GETIDX(8)][0], 1); + ASSERT_EQ(bond_type[GETIDX(9)][0], 1); + + ASSERT_EQ(bond_atom[GETIDX(1)][0], 2); + ASSERT_EQ(bond_atom[GETIDX(2)][0], 3); + ASSERT_EQ(bond_atom[GETIDX(3)][0], 4); + ASSERT_EQ(bond_atom[GETIDX(4)][0], 5); + ASSERT_EQ(bond_atom[GETIDX(6)][0], 7); + ASSERT_EQ(bond_atom[GETIDX(7)][0], 8); + ASSERT_EQ(bond_atom[GETIDX(8)][0], 9); + ASSERT_EQ(bond_atom[GETIDX(9)][0], 10); + + ASSERT_EQ(id5p[GETIDX(1)], 2); + ASSERT_EQ(id5p[GETIDX(2)], 3); + ASSERT_EQ(id5p[GETIDX(3)], 4); + ASSERT_EQ(id5p[GETIDX(4)], 5); + ASSERT_EQ(id5p[GETIDX(5)], -1); + ASSERT_EQ(id5p[GETIDX(6)], 7); + ASSERT_EQ(id5p[GETIDX(7)], 8); + ASSERT_EQ(id5p[GETIDX(8)], 9); + ASSERT_EQ(id5p[GETIDX(9)], 10); + ASSERT_EQ(id5p[GETIDX(10)], -1); + + END_HIDE_OUTPUT(); + +} + } // namespace LAMMPS_NS int main(int argc, char **argv) diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index a73204fb92..6303d2c019 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -547,12 +547,12 @@ TEST_F(DumpAtomTest, rerun_bin) command(fmt::format("rerun {} first 1 last 1 every 1 post no dump x y z", dump_file)); }); lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); - ASSERT_NEAR(pe_1, pe_rerun,1.0e-14); + ASSERT_NEAR(pe_1, pe_rerun, 1.0e-14); HIDE_OUTPUT([&] { command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file)); }); lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); - ASSERT_NEAR(pe_2, pe_rerun,1.0e-14); + ASSERT_NEAR(pe_2, pe_rerun, 1.0e-14); delete_file(dump_file); } diff --git a/unittest/formats/test_dump_cfg.cpp b/unittest/formats/test_dump_cfg.cpp index a180c6b342..c2ab96c5ed 100644 --- a/unittest/formats/test_dump_cfg.cpp +++ b/unittest/formats/test_dump_cfg.cpp @@ -81,6 +81,7 @@ TEST_F(DumpCfgTest, write_dump) auto fields = "mass type xs ys zs id proc procp1 x y z ix iy iz vx vy vz fx fy fz"; BEGIN_HIDE_OUTPUT(); + command("run 0 post no"); command(std::string("write_dump all cfg dump_cfg.melt.cfg ") + fields); command(std::string("write_dump all cfg dump_cfg*.melt.cfg ") + fields); END_HIDE_OUTPUT(); diff --git a/unittest/formats/test_dump_custom.cpp b/unittest/formats/test_dump_custom.cpp index 434acf462c..40e22f5a11 100644 --- a/unittest/formats/test_dump_custom.cpp +++ b/unittest/formats/test_dump_custom.cpp @@ -346,7 +346,7 @@ TEST_F(DumpCustomTest, rerun) }); lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); ASSERT_DOUBLE_EQ(pe_1, pe_rerun); - + HIDE_OUTPUT([&] { command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file)); }); @@ -375,12 +375,12 @@ TEST_F(DumpCustomTest, rerun_bin) command(fmt::format("rerun {} first 1 last 1 every 1 post no dump x y z", dump_file)); }); lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); - ASSERT_NEAR(pe_1, pe_rerun,1.0e-14); + ASSERT_NEAR(pe_1, pe_rerun, 1.0e-14); HIDE_OUTPUT([&] { command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file)); }); lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); - ASSERT_NEAR(pe_2, pe_rerun,1.0e-14); + ASSERT_NEAR(pe_2, pe_rerun, 1.0e-14); delete_file(dump_file); } diff --git a/unittest/formats/test_file_operations.cpp b/unittest/formats/test_file_operations.cpp index bb26dff391..fdb3e1a815 100644 --- a/unittest/formats/test_file_operations.cpp +++ b/unittest/formats/test_file_operations.cpp @@ -29,7 +29,6 @@ using namespace LAMMPS_NS; -using testing::MatchesRegex; using testing::StrEq; using utils::read_lines_from_file; @@ -335,7 +334,9 @@ TEST_F(FileOperationsTest, write_restart) ASSERT_FILE_EXISTS("multi2-0.restart"); ASSERT_FILE_EXISTS("multi3-base.restart"); ASSERT_FILE_EXISTS("multi3-0.restart"); - if (info->has_package("MPIIO")) ASSERT_FILE_EXISTS("test.restart.mpiio"); + if (info->has_package("MPIIO")) { + ASSERT_FILE_EXISTS("test.restart.mpiio"); + } if (!info->has_package("MPIIO")) { TEST_FAILURE(".*ERROR: Writing to MPI-IO filename when MPIIO package is not inst.*", diff --git a/unittest/formats/test_molecule_file.cpp b/unittest/formats/test_molecule_file.cpp index e802ebfa2c..17bd30a349 100644 --- a/unittest/formats/test_molecule_file.cpp +++ b/unittest/formats/test_molecule_file.cpp @@ -26,7 +26,7 @@ using namespace LAMMPS_NS; -using testing::MatchesRegex; +using testing::ContainsRegex; using testing::StrEq; using utils::split_words; @@ -173,7 +173,8 @@ TEST_F(MoleculeFileTest, minimal) BEGIN_CAPTURE_OUTPUT(); run_mol_cmd(test_name, "", "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Read molecule template.*1 molecules.*1 atoms.*0 bonds.*")); + ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*1 molecules.*\n" + ".*0 fragments.*\n.*1 atoms.*\n.*0 bonds.*")); } TEST_F(MoleculeFileTest, notype) @@ -184,10 +185,11 @@ TEST_F(MoleculeFileTest, notype) command("create_box 1 box"); run_mol_cmd(test_name, "", "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Read molecule template.*1 molecules.*1 atoms.*0 bonds.*")); + ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*1 molecules.*\n" + ".*0 fragments.*\n.*1 atoms.*\n.*0 bonds.*")); TEST_FAILURE(".*ERROR: Create_atoms molecule must have atom types.*", command("create_atoms 0 single 0.0 0.0 0.0 mol notype 542465");); - } +} TEST_F(MoleculeFileTest, extramass) { @@ -195,12 +197,13 @@ TEST_F(MoleculeFileTest, extramass) command("atom_style atomic"); command("region box block 0 1 0 1 0 1"); command("create_box 1 box"); - run_mol_cmd(test_name, "", "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n" + run_mol_cmd(test_name, "", + "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n" " Types\n\n 1 1\n Masses\n\n 1 1.0\n"); command("create_atoms 0 single 0.0 0.0 0.0 mol extramass 73546"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*WARNING: Molecule attributes do not match " - "system attributes.*")); + ASSERT_THAT(output, ContainsRegex(".*WARNING: Molecule attributes do not match " + "system attributes.*")); } TEST_F(MoleculeFileTest, twomols) @@ -211,8 +214,8 @@ TEST_F(MoleculeFileTest, twomols) " Coords\n\n 1 0.0 0.0 0.0\n 2 0.0 0.0 1.0\n" " Molecules\n\n 1 1\n 2 2\n\n Types\n\n 1 1\n 2 2\n\n"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Read molecule template.*2 molecules.*2 atoms " - "with max type 2.*0 bonds.*")); + ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*2 molecules.*\n" + ".*0 fragments.*\n.*2 atoms with max type 2.*\n.*0 bonds.*")); } TEST_F(MoleculeFileTest, twofiles) @@ -220,12 +223,14 @@ TEST_F(MoleculeFileTest, twofiles) BEGIN_CAPTURE_OUTPUT(); command("molecule twomols moltest.h2o.mol moltest.co2.mol offset 2 1 1 0 0"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Read molecule template twomols:.*1 molecules.*3 atoms " - "with max type 2.*2 bonds with max type 1.*" - "1 angles with max type 1.*0 dihedrals.*" - ".*Read molecule template twomols:.*1 molecules.*3 atoms " - "with max type 4.*2 bonds with max type 2.*" - "1 angles with max type 2.*0 dihedrals.*")); + ASSERT_THAT( + output, + ContainsRegex(".*Read molecule template twomols:.*\n.*1 molecules.*\n" + ".*0 fragments.*\n.*3 atoms with max type 2.*\n.*2 bonds with max type 1.*\n" + ".*1 angles with max type 1.*\n.*0 dihedrals.*\n.*0 impropers.*\n" + ".*Read molecule template twomols:.*\n.*1 molecules.*\n" + ".*0 fragments.*\n.*3 atoms with max type 4.*\n.*2 bonds with max type 2.*\n" + ".*1 angles with max type 2.*\n.*0 dihedrals.*")); } TEST_F(MoleculeFileTest, bonds) @@ -254,14 +259,15 @@ TEST_F(MoleculeFileTest, bonds) " 1 1 1 2\n" " 2 2 1 3\n\n"); auto output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Read molecule template.*1 molecules.*4 atoms.*type.*2.*" - "2 bonds.*type.*2.*0 angles.*")); + ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*1 molecules.*\n" + ".*0 fragments.*\n.*4 atoms.*type.*2.*\n" + ".*2 bonds.*type.*2.*\n.*0 angles.*")); BEGIN_CAPTURE_OUTPUT(); command("mass * 2.0"); command("create_atoms 0 single 0.5 0.5 0.5 mol bonds 67235"); output = END_CAPTURE_OUTPUT(); - ASSERT_THAT(output, MatchesRegex(".*Created 4 atoms.*")); + ASSERT_THAT(output, ContainsRegex(".*Created 4 atoms.*")); BEGIN_HIDE_OUTPUT(); Molecule *mol = lmp->atom->molecules[0]; diff --git a/unittest/formats/test_potential_file_reader.cpp b/unittest/formats/test_potential_file_reader.cpp index 7a6e41da79..db235722a4 100644 --- a/unittest/formats/test_potential_file_reader.cpp +++ b/unittest/formats/test_potential_file_reader.cpp @@ -37,7 +37,6 @@ #include using namespace LAMMPS_NS; -using ::testing::MatchesRegex; using utils::split_words; // whether to print verbose output (i.e. not capturing LAMMPS screen output). @@ -301,7 +300,7 @@ TEST_F(OpenPotentialTest, Sw_noconv) BEGIN_HIDE_OUTPUT(); command("units real"); END_HIDE_OUTPUT(); - TEST_FAILURE(".*potential.*requires metal units but real.*", + TEST_FAILURE(".*Potential.*requires metal units but real.*", utils::open_potential("Si.sw", lmp, nullptr);); BEGIN_HIDE_OUTPUT(); command("units lj"); diff --git a/unittest/formats/test_text_file_reader.cpp b/unittest/formats/test_text_file_reader.cpp index 6fcc21fb33..4965daab5d 100644 --- a/unittest/formats/test_text_file_reader.cpp +++ b/unittest/formats/test_text_file_reader.cpp @@ -72,7 +72,7 @@ TEST_F(TextFileReaderTest, permissions) { platform::unlink("text_reader_noperms.file"); FILE *fp = fopen("text_reader_noperms.file", "w"); - ASSERT_NE(fp,nullptr); + ASSERT_NE(fp, nullptr); fputs("word\n", fp); fclose(fp); chmod("text_reader_noperms.file", 0); diff --git a/unittest/fortran/CMakeLists.txt b/unittest/fortran/CMakeLists.txt index 6e7e165018..2e7703747b 100644 --- a/unittest/fortran/CMakeLists.txt +++ b/unittest/fortran/CMakeLists.txt @@ -26,11 +26,11 @@ if(CMAKE_Fortran_COMPILER) 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::GTestMain) - add_test(FortranOpen test_fortran_create) + add_test(NAME FortranOpen COMMAND 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::GTestMain) - add_test(FortranCommands test_fortran_commands) + add_test(NAME FortranCommands COMMAND test_fortran_commands) else() message(STATUS "Skipping Tests for the LAMMPS Fortran Module: no Fortran compiler") endif() diff --git a/unittest/fortran/mpi_stubs.f90 b/unittest/fortran/mpi_stubs.f90 index 3f87fc38f7..8601f436d2 100644 --- a/unittest/fortran/mpi_stubs.f90 +++ b/unittest/fortran/mpi_stubs.f90 @@ -9,7 +9,7 @@ MODULE MPI mpi_comm_split CONTAINS - + SUBROUTINE mpi_comm_split(comm,color,key,newcomm,ierr) INTEGER, INTENT(in) :: comm,color,key INTEGER, INTENT(out) :: newcomm,ierr diff --git a/unittest/python/CMakeLists.txt b/unittest/python/CMakeLists.txt index f61a9c61ab..7f9b5e71b2 100644 --- a/unittest/python/CMakeLists.txt +++ b/unittest/python/CMakeLists.txt @@ -12,12 +12,12 @@ if(NOT BUILD_SHARED_LIBS) endif() if(CMAKE_VERSION VERSION_LESS 3.12) - find_package(PythonInterp 3.5) # Deprecated since version 3.12 + find_package(PythonInterp 3.6) # Deprecated since version 3.12 if(PYTHONINTERP_FOUND) set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) endif() else() - find_package(Python3 COMPONENTS Interpreter Development) + find_package(Python3 3.6 COMPONENTS Interpreter Development) endif() add_executable(test_python_package test_python_package.cpp) @@ -28,25 +28,34 @@ if(Python3_Development_FOUND) target_compile_definitions(test_python_package PRIVATE -DTEST_HAVE_PYTHON_DEVELOPMENT=1) target_link_libraries(test_python_package PRIVATE Python3::Python) endif() -add_test(NAME PythonPackage COMMAND test_python_package WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -set_tests_properties(PythonPackage PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH};PYTHONUNBUFFERED=1") +add_test(NAME PythonPackage COMMAND test_python_package) + +# build list of environment variables for testing python functionality +if(WIN32) + set(PYTHON_TEST_ENVIRONMENT PYTHONPATH=${LAMMPS_PYTHON_DIR}) +else() + set(PYTHON_TEST_ENVIRONMENT PYTHONPATH=${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}) +endif() +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 "PYTHONUNBUFFERED=1") +if(APPLE) + list(APPEND PYTHON_TEST_ENVIRONMENT "DYLD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{DYLD_LIBRARY_PATH}") +elseif(WIN32) + list(APPEND PYTHON_TEST_ENVIRONMENT "LAMMPSDLLPATH=${LAMMPS_LIB_PATH}") +else() + list(APPEND PYTHON_TEST_ENVIRONMENT "LD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{LD_LIBRARY_PATH}") +endif() +set_tests_properties(PythonPackage PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") 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=${LAMMPS_LIB_PATH}:$ENV{DYLD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") - else() - list(APPEND PYTHON_TEST_ENVIRONMENT "LD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{LD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") - endif() + list(APPEND PYTHON_TEST_ENVIRONMENT "LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt") if(LAMMPS_MACHINE) # convert from '_machine' to 'machine' string(SUBSTRING ${LAMMPS_MACHINE} 1 -1 LAMMPS_MACHINE_NAME) @@ -89,10 +98,14 @@ if(Python_EXECUTABLE) WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) set_tests_properties(PythonCapabilities PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + message(STATUS "Skipping Tests for PyLammps Module: not yet ported to Windows") +else() add_test(NAME PythonPyLammps COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-pylammps.py -v WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) set_tests_properties(PythonPyLammps PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") +endif() add_test(NAME PythonFormats COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-formats.py -v diff --git a/unittest/python/test_python_package.cpp b/unittest/python/test_python_package.cpp index e04be89df1..db7a7a41b6 100644 --- a/unittest/python/test_python_package.cpp +++ b/unittest/python/test_python_package.cpp @@ -43,9 +43,9 @@ bool verbose = false; using LAMMPS_NS::utils::split_words; namespace LAMMPS_NS { +using ::testing::ContainsRegex; using ::testing::Eq; using ::testing::HasSubstr; -using ::testing::MatchesRegex; using ::testing::StrEq; class PythonPackageTest : public LAMMPSTest { @@ -89,7 +89,7 @@ TEST_F(PythonPackageTest, InvokeFunctionFromFile) auto output = CAPTURE_OUTPUT([&]() { command("python printnum invoke"); }); - ASSERT_THAT(output, HasSubstr("2.25\n")); + ASSERT_THAT(output, HasSubstr("2.25")); } #if defined(TEST_HAVE_PYTHON_DEVELOPMENT) @@ -210,7 +210,7 @@ TEST_F(PythonPackageTest, InvokeOtherFunctionFromFile) auto output = CAPTURE_OUTPUT([&] { command("python printtxt invoke"); }); - ASSERT_THAT(output, HasSubstr("sometext\n")); + ASSERT_THAT(output, HasSubstr("sometext")); } TEST_F(PythonPackageTest, InvokeFunctionThatUsesLAMMPSModule) @@ -224,7 +224,7 @@ TEST_F(PythonPackageTest, InvokeFunctionThatUsesLAMMPSModule) auto output = CAPTURE_OUTPUT([&] { command("python getidxvar invoke"); }); - ASSERT_THAT(output, HasSubstr("2.25\n")); + ASSERT_THAT(output, HasSubstr("2.25")); } TEST_F(PythonPackageTest, python_variable) @@ -238,7 +238,7 @@ TEST_F(PythonPackageTest, python_variable) std::string output = CAPTURE_OUTPUT([&] { command("print \"${sq}\""); }); - ASSERT_THAT(output, MatchesRegex("print.*2.25.*")); + ASSERT_THAT(output, ContainsRegex("print.*\n.*2.25.*")); } TEST_F(PythonPackageTest, InlineFunction) @@ -309,7 +309,7 @@ TEST_F(FixPythonInvokeTest, end_of_step) auto output = CAPTURE_OUTPUT([&] { command("run 50"); }); - + fprintf(stderr,"lines: %s\n",output.c_str()); auto lines = utils::split_lines(output); int count = 0; diff --git a/unittest/testing/core.h b/unittest/testing/core.h index c922e96cc0..81a7112934 100644 --- a/unittest/testing/core.h +++ b/unittest/testing/core.h @@ -28,20 +28,20 @@ using namespace LAMMPS_NS; -using ::testing::MatchesRegex; +using ::testing::ContainsRegex; #define TEST_FAILURE(errmsg, ...) \ if (Info::has_exceptions()) { \ ::testing::internal::CaptureStdout(); \ ASSERT_ANY_THROW({__VA_ARGS__}); \ auto mesg = ::testing::internal::GetCapturedStdout(); \ - ASSERT_THAT(mesg, MatchesRegex(errmsg)); \ + ASSERT_THAT(mesg, ContainsRegex(errmsg)); \ } else { \ if (platform::mpi_vendor() != "Open MPI") { \ ::testing::internal::CaptureStdout(); \ ASSERT_DEATH({__VA_ARGS__}, ""); \ auto mesg = ::testing::internal::GetCapturedStdout(); \ - ASSERT_THAT(mesg, MatchesRegex(errmsg)); \ + ASSERT_THAT(mesg, ContainsRegex(errmsg)); \ } else { \ std::cerr << "[ ] [ INFO ] Skipping death test (no exception support) \n"; \ } \ diff --git a/unittest/utils/CMakeLists.txt b/unittest/utils/CMakeLists.txt index 28486048c4..c01313ad8d 100644 --- a/unittest/utils/CMakeLists.txt +++ b/unittest/utils/CMakeLists.txt @@ -1,22 +1,23 @@ + add_executable(test_tokenizer test_tokenizer.cpp) target_link_libraries(test_tokenizer PRIVATE lammps GTest::GMockMain) -add_test(Tokenizer test_tokenizer) +add_test(NAME Tokenizer COMMAND test_tokenizer) add_executable(test_mempool test_mempool.cpp) target_link_libraries(test_mempool PRIVATE lammps GTest::GMockMain) -add_test(MemPool test_mempool) +add_test(NAME MemPool COMMAND test_mempool) add_executable(test_argutils test_argutils.cpp) target_link_libraries(test_argutils PRIVATE lammps GTest::GMockMain) -add_test(ArgUtils test_argutils) +add_test(NAME ArgUtils COMMAND test_argutils) add_executable(test_utils test_utils.cpp) target_link_libraries(test_utils PRIVATE lammps GTest::GMockMain) -add_test(Utils test_utils) +add_test(NAME Utils COMMAND test_utils) add_executable(test_platform test_platform.cpp) target_link_libraries(test_platform PRIVATE lammps GTest::GMockMain) -add_test(Platform test_platform) +add_test(NAME Platform COMMAND test_platform) set_tests_properties(Utils Platform PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") @@ -35,8 +36,8 @@ endif() add_executable(test_fmtlib test_fmtlib.cpp) target_link_libraries(test_fmtlib PRIVATE lammps GTest::GMockMain) -add_test(FmtLib test_fmtlib) +add_test(NAME FmtLib COMMAND test_fmtlib) add_executable(test_math_eigen_impl test_math_eigen_impl.cpp) target_include_directories(test_math_eigen_impl PRIVATE ${LAMMPS_SOURCE_DIR}) -add_test(MathEigen test_math_eigen_impl 10 5) +add_test(NAME MathEigen COMMAND test_math_eigen_impl 10 5) diff --git a/unittest/utils/test_math_eigen_impl.cpp b/unittest/utils/test_math_eigen_impl.cpp index 47ca8d9cca..b38438d1f7 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 (! 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 (! 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; } } @@ -464,7 +464,7 @@ void TestJacobi(int n, //::SORT_INCREASING_ABS_EVALS); #else ecalc.Diagonalize(M, evals, evecs, - Jacobi::SORT_INCREASING_ABS_EVALS); #endif @@ -488,7 +488,7 @@ void TestJacobi(int n, //::SORT_DECREASING_ABS_EVALS); #else ecalc.Diagonalize(M, evals, evecs, - Jacobi::SORT_DECREASING_ABS_EVALS); #endif @@ -511,7 +511,7 @@ void TestJacobi(int n, //::SORT_INCREASING_EVALS); #else ecalc.Diagonalize(M, evals, evecs, - Jacobi::SORT_INCREASING_EVALS); #endif for (int i = 1; i < n; i++) @@ -533,8 +533,8 @@ void TestJacobi(int n, //::DO_NOT_SORT); #else ecalc.Diagonalize( - M, evals, evecs, - Jacobi::DO_NOT_SORT); + M, evals, evecs, + Jacobi::DO_NOT_SORT); #endif } // if (test_code_coverage) diff --git a/unittest/utils/test_platform.cpp b/unittest/utils/test_platform.cpp index ace546ba90..37e749b9be 100644 --- a/unittest/utils/test_platform.cpp +++ b/unittest/utils/test_platform.cpp @@ -68,10 +68,10 @@ TEST(Platform, putenv_unsetenv) ASSERT_EQ(platform::unsetenv(""), -1); ASSERT_EQ(platform::unsetenv("UNITTEST_VAR3=two"), -1); - var = getenv("UNITTEST_VAR1"); + var = getenv("UNITTEST_VAR1"); ASSERT_NE(var, nullptr); ASSERT_EQ(platform::unsetenv("UNITTEST_VAR1"), 0); - var = getenv("UNITTEST_VAR1"); + var = getenv("UNITTEST_VAR1"); ASSERT_EQ(var, nullptr); } diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 72a90a95a0..dccbdb4118 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -838,15 +838,15 @@ TEST(Utils, date2num) TEST(Utils, current_date) { - auto vals = ValueTokenizer(utils::current_date(),"-"); - int year = vals.next_int(); + auto vals = ValueTokenizer(utils::current_date(), "-"); + int year = vals.next_int(); int month = vals.next_int(); - int day = vals.next_int(); - ASSERT_GT(year,2020); - ASSERT_GE(month,1); - ASSERT_GE(day,1); - ASSERT_LE(month,12); - ASSERT_LE(day,31); + int day = vals.next_int(); + ASSERT_GT(year, 2020); + ASSERT_GE(month, 1); + ASSERT_GE(day, 1); + ASSERT_LE(month, 12); + ASSERT_LE(day, 31); } TEST(Utils, binary_search)