diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0e42635244..007ac2ca3c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -38,6 +38,7 @@ src/ML-HDNNP/* @singraber src/ML-IAP/* @athomps src/ML-PACE/* @yury-lysogorskiy src/ML-POD/* @exapde +src/ML-UF3/* @monk-04 src/MOFFF/* @hheenen src/MOLFILE/* @akohlmey src/NETCDF/* @pastewka @@ -72,6 +73,8 @@ src/MC/fix_sgcmc.* @athomps src/REAXFF/compute_reaxff_atom.* @rbberger src/KOKKOS/compute_reaxff_atom_kokkos.* @rbberger src/REPLICA/fix_pimd_langevin.* @Yi-FanLi +src/DPD-BASIC/pair_dpd_coul_slater_long.* @Eddy-Barraud +src/GPU/pair_dpd_coul_slater_long.* @Eddy-Barraud # core LAMMPS classes src/lammps.* @sjplimp diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f87c92396f..ada38138f6 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -256,6 +256,7 @@ set(STANDARD_PACKAGES DRUDE EFF ELECTRODE + EXTRA-COMMAND EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX @@ -285,6 +286,7 @@ set(STANDARD_PACKAGES ML-RANN ML-SNAP ML-POD + ML-UF3 MOFFF MOLECULE MOLFILE @@ -689,7 +691,7 @@ endif() # packages which selectively include variants based on enabled styles # e.g. accelerator packages ###################################################################### -foreach(PKG_WITH_INCL CORESHELL DPD-SMOOTH MC MISC PHONON QEQ OPENMP KOKKOS OPT INTEL GPU) +foreach(PKG_WITH_INCL CORESHELL DPD-BASIC DPD-SMOOTH MC MISC PHONON QEQ OPENMP KOKKOS OPT INTEL GPU) if(PKG_${PKG_WITH_INCL}) include(Packages/${PKG_WITH_INCL}) endif() diff --git a/cmake/Modules/Packages/DPD-BASIC.cmake b/cmake/Modules/Packages/DPD-BASIC.cmake new file mode 100644 index 0000000000..b92d4b56a1 --- /dev/null +++ b/cmake/Modules/Packages/DPD-BASIC.cmake @@ -0,0 +1,9 @@ +# pair style dpd/coul/slater/long may only be installed if also KSPACE is installed +if(NOT PKG_KSPACE) + get_property(LAMMPS_PAIR_HEADERS GLOBAL PROPERTY PAIR) + list(REMOVE_ITEM LAMMPS_PAIR_HEADERS ${LAMMPS_SOURCE_DIR}/DPD-BASIC/pair_dpd_coul_slater_long.h) + set_property(GLOBAL PROPERTY PAIR "${LAMMPS_PAIR_HEADERS}") + get_target_property(LAMMPS_SOURCES lammps SOURCES) + list(REMOVE_ITEM LAMMPS_SOURCES ${LAMMPS_SOURCE_DIR}/DPD-BASIC/pair_dpd_coul_slater_long.cpp) + set_property(TARGET lammps PROPERTY SOURCES "${LAMMPS_SOURCES}") +endif() diff --git a/cmake/Modules/Packages/PLUMED.cmake b/cmake/Modules/Packages/PLUMED.cmake index b1a4f3cc72..8312589478 100644 --- a/cmake/Modules/Packages/PLUMED.cmake +++ b/cmake/Modules/Packages/PLUMED.cmake @@ -1,5 +1,9 @@ # Plumed2 support for PLUMED package +# for supporting multiple concurrent plumed2 installations for debugging and testing +set(PLUMED_SUFFIX "" CACHE STRING "Suffix for Plumed2 library") +mark_as_advanced(PLUMED_SUFFIX) + if(BUILD_MPI) set(PLUMED_CONFIG_MPI "--enable-mpi") set(PLUMED_CONFIG_CC ${CMAKE_MPI_C_COMPILER}) @@ -21,9 +25,11 @@ else() set(PLUMED_CONFIG_OMP "--disable-openmp") endif() -set(PLUMED_URL "https://github.com/plumed/plumed2/releases/download/v2.8.3/plumed-src-2.8.3.tgz" +# Note: must also adjust check for supported API versions in +# fix_plumed.cpp when version changes from v2.n.x to v2.n+1.y +set(PLUMED_URL "https://github.com/plumed/plumed2/releases/download/v2.9.1/plumed-src-2.9.1.tgz" CACHE STRING "URL for PLUMED tarball") -set(PLUMED_MD5 "76d23cd394eba9e6530316ed1184e219" CACHE STRING "MD5 checksum of PLUMED tarball") +set(PLUMED_MD5 "c3b2d31479c1e9ce211719d40e9efbd7" CACHE STRING "MD5 checksum of PLUMED tarball") mark_as_advanced(PLUMED_URL) mark_as_advanced(PLUMED_MD5) @@ -151,15 +157,15 @@ else() file(MAKE_DIRECTORY ${INSTALL_DIR}/include) else() find_package(PkgConfig REQUIRED) - pkg_check_modules(PLUMED REQUIRED plumed) + pkg_check_modules(PLUMED REQUIRED plumed${PLUMED_SUFFIX}) add_library(LAMMPS::PLUMED INTERFACE IMPORTED) if(PLUMED_MODE STREQUAL "STATIC") - include(${PLUMED_LIBDIR}/plumed/src/lib/Plumed.cmake.static) + include(${PLUMED_LIBDIR}/plumed${PLUMED_SUFFIX}/src/lib/Plumed.cmake.static) elseif(PLUMED_MODE STREQUAL "SHARED") - include(${PLUMED_LIBDIR}/plumed/src/lib/Plumed.cmake.shared) + include(${PLUMED_LIBDIR}/plumed${PLUMED_SUFFIX}/src/lib/Plumed.cmake.shared) elseif(PLUMED_MODE STREQUAL "RUNTIME") - set_target_properties(LAMMPS::PLUMED PROPERTIES INTERFACE_COMPILE_DEFINITIONS "__PLUMED_DEFAULT_KERNEL=${PLUMED_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}plumedKernel${CMAKE_SHARED_LIBRARY_SUFFIX}") - include(${PLUMED_LIBDIR}/plumed/src/lib/Plumed.cmake.runtime) + set_target_properties(LAMMPS::PLUMED PROPERTIES INTERFACE_COMPILE_DEFINITIONS "__PLUMED_DEFAULT_KERNEL=${PLUMED_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}plumed${PLUMED_SUFFIX}Kernel${CMAKE_SHARED_LIBRARY_SUFFIX}") + include(${PLUMED_LIBDIR}/plumed${PLUMED_SUFFIX}/src/lib/Plumed.cmake.runtime) endif() set_target_properties(LAMMPS::PLUMED PROPERTIES INTERFACE_LINK_LIBRARIES "${PLUMED_LOAD}") set_target_properties(LAMMPS::PLUMED PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${PLUMED_INCLUDE_DIRS}") diff --git a/cmake/packaging/build_linux_tgz.sh b/cmake/packaging/build_linux_tgz.sh index 48e3017f61..ea2fb7fb10 100755 --- a/cmake/packaging/build_linux_tgz.sh +++ b/cmake/packaging/build_linux_tgz.sh @@ -59,12 +59,14 @@ done echo "Set up wrapper script" MYDIR=$(dirname "$0") +cp ${MYDIR}/xdg-open ${DESTDIR}/bin cp ${MYDIR}/linux_wrapper.sh ${DESTDIR}/bin for s in ${DESTDIR}/bin/* do \ EXE=$(basename $s) test ${EXE} = linux_wrapper.sh && continue test ${EXE} = qt.conf && continue + test ${EXE} = xdg-open && continue ln -s bin/linux_wrapper.sh ${DESTDIR}/${EXE} done diff --git a/cmake/packaging/linux_wrapper.sh b/cmake/packaging/linux_wrapper.sh index a679030188..b777c09eb1 100755 --- a/cmake/packaging/linux_wrapper.sh +++ b/cmake/packaging/linux_wrapper.sh @@ -4,15 +4,17 @@ # reset locale to avoid problems with decimal numbers export LC_ALL=C -BASEDIR=$(dirname "$0") -EXENAME=$(basename "$0") +BASEDIR="$(dirname "$0")" +EXENAME="$(basename "$0")" + +PATH="${BASEDIR}/bin:${PATH}" # append to LD_LIBRARY_PATH to prefer local (newer) libs -LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${BASEDIR}/lib +LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${BASEDIR}/lib" # set some environment variables for LAMMPS etc. -LAMMPS_POTENTIALS=${BASEDIR}/share/lammps/potentials -MSI2LMP_LIBRARY=${BASEDIR}/share/lammps/frc_files -export LD_LIBRARY_PATH LAMMPS_POTENTIALS MSI2LMP_LIBRARY +LAMMPS_POTENTIALS="${BASEDIR}/share/lammps/potentials" +MSI2LMP_LIBRARY="${BASEDIR}/share/lammps/frc_files" +export LD_LIBRARY_PATH LAMMPS_POTENTIALS MSI2LMP_LIBRARY PATH exec "${BASEDIR}/bin/${EXENAME}" "$@" diff --git a/cmake/packaging/xdg-open b/cmake/packaging/xdg-open new file mode 100755 index 0000000000..d282bb3d11 --- /dev/null +++ b/cmake/packaging/xdg-open @@ -0,0 +1,1074 @@ +#!/usr/bin/sh +#--------------------------------------------- +# xdg-open +# +# Utility script to open a URL in the registered default application. +# +# Refer to the usage() function below for usage. +# +# Copyright 2009-2010, Fathi Boudra +# Copyright 2009-2016, Rex Dieter +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#--------------------------------------------- + +NEW_LIBRARY_PATH="/usr/local/lib64" +for s in $(echo $LD_LIBRARY_PATH | sed -e 's/:/ /g') +do \ + echo $s | grep LAMMPS_GUI > /dev/null || NEW_LIBRARY_PATH="${NEW_LIBRARY_PATH}:$s" +done +export LD_LIBRARY_PATH="${NEW_LIBRARY_PATH}" +unset NEW_LIBRARY_PATH + +manualpage() +{ +cat << _MANUALPAGE +Name + + xdg-open - opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +Description + + xdg-open opens a file or URL in the user's preferred + application. If a URL is provided the URL will be opened in the + user's preferred web browser. If a file is provided the file + will be opened in the preferred application for files of that + type. xdg-open supports file, ftp, http and https URLs. + + xdg-open is for use inside a desktop session only. It is not + recommended to use xdg-open as root. + +Options + + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. + +Exit Codes + + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. + +See Also + + xdg-mime(1), xdg-settings(1), MIME applications associations + specification + +Examples + +xdg-open 'http://www.freedesktop.org/' + + Opens the freedesktop.org website in the user's default + browser. + +xdg-open /tmp/foobar.png + + Opens the PNG image file /tmp/foobar.png in the user's default + image viewing application. +_MANUALPAGE +} + +usage() +{ +cat << _USAGE + xdg-open - opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + # Check if desktop file contains - + if [ "${desktop#*-}" != "$desktop" ]; then + vendor=${desktop%-*} + app=${desktop#*-} + if [ -r $dir/applications/$vendor/$app ]; then + file_path=$dir/applications/$vendor/$app + elif [ -r $dir/applnk/$vendor/$app ]; then + file_path=$dir/applnk/$vendor/$app + fi + fi + if test -z "$file_path" ; then + for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do + file="$indir/$desktop" + if [ -r "$file" ]; then + file_path=$file + break + fi + done + fi + if [ -r "$file_path" ]; then + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + fi + done +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + echo "Try 'xdg-open --help' for more information." >&2 + else + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to write a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [[:alpha:]]*-*) + return + ;; + esac + + echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-open 1.1.3+" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + DEEPIN|Deepin|deepin) + DE=deepin; + ;; + LXDE) + DE=lxde; + ;; + LXQt) + DE=lxqt; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then DE=lxqt; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" + fi + + if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then + DE="flatpak" + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` + major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +#---------------------------------------------------------------------------- +# Returns true if there is a graphical display attached. + +has_display() +{ + if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then + return 0 + else + return 1 + fi +} + +# This handles backslashes but not quote marks. +last_word() +{ + read first rest + echo "$rest" +} + +# Get the value of a key in a desktop file's Desktop Entry group. +# Example: Use get_key foo.desktop Exec +# to get the values of the Exec= key for the Desktop Entry group. +get_key() +{ + local file="${1}" + local key="${2}" + local desktop_entry="" + + IFS_="${IFS}" + IFS="" + while read line + do + case "$line" in + "[Desktop Entry]") + desktop_entry="y" + ;; + # Reset match flag for other groups + "["*) + desktop_entry="" + ;; + "${key}="*) + # Only match Desktop Entry group + if [ -n "${desktop_entry}" ] + then + echo "${line}" | cut -d= -f 2- + fi + esac + done < "${file}" + IFS="${IFS_}" +} + +# Returns true if argument is a file:// URL or path +is_file_url_or_path() +{ + if echo "$1" | grep -q '^file://' \ + || ! echo "$1" | grep -Eq '^[[:alpha:]][[:alpha:][:digit:]+\.\-]*:'; then + return 0 + else + return 1 + fi +} + +# If argument is a file URL, convert it to a (percent-decoded) path. +# If not, leave it as it is. +file_url_to_path() +{ + local file="$1" + if echo "$file" | grep -q '^file://\(localhost\)\?/'; then + file=${file#file://localhost} + file=${file#file://} + file=${file%%#*} + file=$(echo "$file" | sed -r 's/\?.*$//') + local printf=printf + if [ -x /usr/bin/printf ]; then + printf=/usr/bin/printf + fi + file=$($printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')") + fi + echo "$file" +} + +open_cygwin() +{ + cygstart "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_darwin() +{ + open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_kde() +{ + if [ -n "${KDE_SESSION_VERSION}" ]; then + case "${KDE_SESSION_VERSION}" in + 4) + kde-open "$1" + ;; + 5) + kde-open${KDE_SESSION_VERSION} "$1" + ;; + esac + else + kfmclient exec "$1" + kfmclient_fix_exit_code $? + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_deepin() +{ + if dde-open -version >/dev/null 2>&1; then + dde-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome3() +{ + if gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + if gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + elif gnome-open --help 2>/dev/null 1>&2; then + gnome-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_mate() +{ + if gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + elif mate-open --help 2>/dev/null 1>&2; then + mate-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_xfce() +{ + if exo-open --help 2>/dev/null 1>&2; then + exo-open "$1" + elif gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_enlightenment() +{ + if enlightenment_open --help 2>/dev/null 1>&2; then + enlightenment_open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_flatpak() +{ + gdbus call --session \ + --dest org.freedesktop.portal.Desktop \ + --object-path /org/freedesktop/portal/desktop \ + --method org.freedesktop.portal.OpenURI.OpenURI \ + "" "$1" {} + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +#----------------------------------------- +# Recursively search .desktop file + +search_desktop_file() +{ + local default="$1" + local dir="$2" + local target="$3" + + local file="" + # look for both vendor-app.desktop, vendor/app.desktop + if [ -r "$dir/$default" ]; then + file="$dir/$default" + elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then + file="$dir/`echo $default | sed -e 's|-|/|'`" + fi + + if [ -r "$file" ] ; then + command="$(get_key "${file}" "Exec" | first_word)" + command_exec=`which $command 2>/dev/null` + icon="$(get_key "${file}" "Icon")" + # FIXME: Actually LC_MESSAGES should be used as described in + # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html + localised_name="$(get_key "${file}" "Name")" + set -- $(get_key "${file}" "Exec" | last_word) + # We need to replace any occurrence of "%f", "%F" and + # the like by the target file. We examine each + # argument and append the modified argument to the + # end then shift. + local args=$# + local replaced=0 + while [ $args -gt 0 ]; do + case $1 in + %[c]) + replaced=1 + arg="${localised_name}" + shift + set -- "$@" "$arg" + ;; + %[fFuU]) + replaced=1 + arg="$target" + shift + set -- "$@" "$arg" + ;; + %[i]) + replaced=1 + shift + set -- "$@" "--icon" "$icon" + ;; + *) + arg="$1" + shift + set -- "$@" "$arg" + ;; + esac + args=$(( $args - 1 )) + done + [ $replaced -eq 1 ] || set -- "$@" "$target" + "$command_exec" "$@" + + if [ $? -eq 0 ]; then + exit_success + fi + fi + + for d in "$dir/"*/; do + [ -d "$d" ] && search_desktop_file "$default" "$d" "$target" + done +} + + +open_generic_xdg_mime() +{ + filetype="$2" + default=`xdg-mime query default "$filetype"` + if [ -n "$default" ] ; then + xdg_user_dir="$XDG_DATA_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" + + xdg_system_dirs="$XDG_DATA_DIRS" + [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ + +DEBUG 3 "$xdg_user_dir:$xdg_system_dirs" + for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do + search_desktop_file "$default" "$x/applications/" "$1" + done + fi +} + +open_generic_xdg_file_mime() +{ + filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"` + open_generic_xdg_mime "$1" "$filetype" +} + +open_generic_xdg_x_scheme_handler() +{ + scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`" + if [ -n $scheme ]; then + filetype="x-scheme-handler/$scheme" + open_generic_xdg_mime "$1" "$filetype" + fi +} + +has_single_argument() +{ + test $# = 1 +} + +open_envvar() +{ + local oldifs="$IFS" + local browser browser_with_arg + + IFS=":" + for browser in $BROWSER; do + IFS="$oldifs" + + if [ -z "$browser" ]; then + continue + fi + + if echo "$browser" | grep -q %s; then + # Avoid argument injection. + # See https://bugs.freedesktop.org/show_bug.cgi?id=103807 + # URIs don't have IFS characters spaces anyway. + has_single_argument $1 && $(printf "$browser" "$1") + else + $browser "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + fi + done +} + +open_generic() +{ + if is_file_url_or_path "$1"; then + local file="$(file_url_to_path "$1")" + + check_input_file "$file" + + if has_display; then + filetype=`xdg-mime query filetype "$file" | sed "s/;.*//"` + open_generic_xdg_mime "$file" "$filetype" + fi + + if which run-mailcap 2>/dev/null 1>&2; then + run-mailcap --action=view "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + + if has_display && mimeopen -v 2>/dev/null 1>&2; then + mimeopen -L -n "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + fi + + if has_display; then + open_generic_xdg_x_scheme_handler "$1" + fi + + if [ -n "$BROWSER" ]; then + open_envvar "$1" + fi + + # if BROWSER variable is not set, check some well known browsers instead + if [ x"$BROWSER" = x"" ]; then + BROWSER=www-browser:links2:elinks:links:lynx:w3m + if has_display; then + BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium:chromium-browser:google-chrome:$BROWSER + fi + fi + + open_envvar "$1" + + exit_failure_operation_impossible "no method available for opening '$1'" +} + +open_lxde() +{ + + # pcmanfm only knows how to handle file:// urls and filepaths, it seems. + if pcmanfm --help >/dev/null 2>&1 && is_file_url_or_path "$1"; then + local file="$(file_url_to_path "$1")" + + # handle relative paths + if ! echo "$file" | grep -q ^/; then + file="$(pwd)/$file" + fi + + pcmanfm "$file" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_lxqt() +{ + open_generic "$1" +} + +[ x"$1" != x"" ] || exit_failure_syntax + +url= +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ -n "$url" ] ; then + exit_failure_syntax "unexpected argument '$parm'" + fi + url="$parm" + ;; + esac +done + +if [ -z "${url}" ] ; then + exit_failure_syntax "file or URL argument missing" +fi + +detectDE + +if [ x"$DE" = x"" ]; then + DE=generic +fi + +DEBUG 2 "Selected DE $DE" + +# sanitize BROWSER (avoid calling ourselves in particular) +case "${BROWSER}" in + *:"xdg-open"|"xdg-open":*) + BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g') + ;; + "xdg-open") + BROWSER= + ;; +esac + +case "$DE" in + kde) + open_kde "$url" + ;; + + deepin) + open_deepin "$url" + ;; + + gnome3|cinnamon) + open_gnome3 "$url" + ;; + + gnome) + open_gnome "$url" + ;; + + mate) + open_mate "$url" + ;; + + xfce) + open_xfce "$url" + ;; + + lxde) + open_lxde "$url" + ;; + + lxqt) + open_lxqt "$url" + ;; + + enlightenment) + open_enlightenment "$url" + ;; + + cygwin) + open_cygwin "$url" + ;; + + darwin) + open_darwin "$url" + ;; + + flatpak) + open_flatpak "$url" + ;; + + generic) + open_generic "$url" + ;; + + *) + exit_failure_operation_impossible "no method available for opening '$url'" + ;; +esac diff --git a/cmake/presets/all_off.cmake b/cmake/presets/all_off.cmake index e078879f70..59ac760f6a 100644 --- a/cmake/presets/all_off.cmake +++ b/cmake/presets/all_off.cmake @@ -28,6 +28,7 @@ set(ALL_PACKAGES DRUDE ELECTRODE EFF + EXTRA-COMMAND EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX @@ -60,6 +61,7 @@ set(ALL_PACKAGES ML-QUIP ML-RANN ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/all_on.cmake b/cmake/presets/all_on.cmake index 3f44a863f7..a75ab0d9b2 100644 --- a/cmake/presets/all_on.cmake +++ b/cmake/presets/all_on.cmake @@ -30,6 +30,7 @@ set(ALL_PACKAGES DRUDE ELECTRODE EFF + EXTRA-COMMAND EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX @@ -62,6 +63,7 @@ set(ALL_PACKAGES ML-QUIP ML-RANN ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/mingw-cross.cmake b/cmake/presets/mingw-cross.cmake index f3565668b2..8ca9b97e35 100644 --- a/cmake/presets/mingw-cross.cmake +++ b/cmake/presets/mingw-cross.cmake @@ -24,6 +24,7 @@ set(WIN_PACKAGES DRUDE ELECTRODE EFF + EXTRA-COMMAND EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX @@ -50,6 +51,7 @@ set(WIN_PACKAGES ML-POD ML-RANN ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/most.cmake b/cmake/presets/most.cmake index 2356e24764..d01642f94d 100644 --- a/cmake/presets/most.cmake +++ b/cmake/presets/most.cmake @@ -26,6 +26,7 @@ set(ALL_PACKAGES DRUDE EFF ELECTRODE + EXTRA-COMMAND EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX @@ -45,6 +46,7 @@ set(ALL_PACKAGES ML-IAP ML-POD ML-SNAP + ML-UF3 MOFFF MOLECULE OPENMP diff --git a/cmake/presets/windows.cmake b/cmake/presets/windows.cmake index 9655134e7f..5e400e9de9 100644 --- a/cmake/presets/windows.cmake +++ b/cmake/presets/windows.cmake @@ -22,6 +22,7 @@ set(WIN_PACKAGES DRUDE EFF ELECTRODE + EXTRA-COMMAND EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX @@ -42,6 +43,7 @@ set(WIN_PACKAGES ML-IAP ML-POD ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/doc/src/Commands_bond.rst b/doc/src/Commands_bond.rst index fcd725d787..73235cf3c6 100644 --- a/doc/src/Commands_bond.rst +++ b/doc/src/Commands_bond.rst @@ -27,7 +27,7 @@ OPT. * :doc:`none ` * :doc:`zero ` - * :doc:`hybrid ` + * :doc:`hybrid (k) ` * * * @@ -72,7 +72,7 @@ OPT. * :doc:`none ` * :doc:`zero ` - * :doc:`hybrid (k) ` + * :doc:`hybrid ` * * * diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 514785c15c..d357595d64 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -25,16 +25,16 @@ OPT. * :doc:`none ` * :doc:`zero ` - * :doc:`hybrid (k) ` - * :doc:`hybrid/overlay (k) ` - * :doc:`hybrid/scaled ` + * :doc:`hybrid (ko) ` + * :doc:`hybrid/molecular (o) ` + * :doc:`hybrid/overlay (ko) ` + * :doc:`hybrid/scaled (o) ` * :doc:`kim ` * :doc:`list ` * :doc:`tracker ` * * * - * * :doc:`adp (ko) ` * :doc:`agni (o) ` * :doc:`aip/water/2dm (t) ` @@ -94,9 +94,10 @@ OPT. * :doc:`coul/wolf (ko) ` * :doc:`coul/wolf/cs ` * :doc:`dpd (giko) ` - * :doc:`dpd/fdt ` + * :doc:`dpd/coul/slater/long (g) ` * :doc:`dpd/ext (ko) ` * :doc:`dpd/ext/tstat (ko) ` + * :doc:`dpd/fdt ` * :doc:`dpd/fdt/energy (k) ` * :doc:`dpd/tstat (gko) ` * :doc:`dsmc ` @@ -269,7 +270,7 @@ OPT. * :doc:`smd/ulsph ` * :doc:`smtbq ` * :doc:`snap (ik) ` - * :doc:`soft (go) ` + * :doc:`soft (gko) ` * :doc:`sph/heatconduction (g) ` * :doc:`sph/idealgas ` * :doc:`sph/lj (g) ` @@ -303,6 +304,7 @@ OPT. * :doc:`tip4p/long/soft (o) ` * :doc:`tri/lj ` * :doc:`ufm (got) ` + * :doc:`uf3 (k) ` * :doc:`vashishta (gko) ` * :doc:`vashishta/table (o) ` * :doc:`wf/cut ` diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index ff46fff267..e759e3bd18 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -52,6 +52,7 @@ page gives those details. * :ref:`DRUDE ` * :ref:`EFF ` * :ref:`ELECTRODE ` + * :ref:`EXTRA-COMMAND ` * :ref:`EXTRA-COMPUTE ` * :ref:`EXTRA-DUMP ` * :ref:`EXTRA-FIX ` @@ -84,6 +85,7 @@ page gives those details. * :ref:`ML-QUIP ` * :ref:`ML-RANN ` * :ref:`ML-SNAP ` + * :ref:`ML-UF3 ` * :ref:`MOFFF ` * :ref:`MOLECULE ` * :ref:`MOLFILE ` @@ -677,7 +679,12 @@ DPD-BASIC package Pair styles for the basic dissipative particle dynamics (DPD) method and DPD thermostatting. -**Author:** Kurt Smith (U Pittsburgh), Martin Svoboda, Martin Lisal (ICPF and UJEP) +Pair style :doc:`dpd/coul/slater/long ` also +includes smeared charges for coulomb interactions and thus requires the +:ref:`KSPACE ` package to be installed to handle the long-range +Coulomb part of the interactions. + +**Authors:** Kurt Smith (U Pittsburgh), Martin Svoboda, Martin Lisal (ICPF and UJEP), Eddy Barraud (IFPEN) **Supporting info:** @@ -686,6 +693,7 @@ and DPD thermostatting. * :doc:`pair_style dpd/tstat ` * :doc:`pair_style dpd/ext ` * :doc:`pair_style dpd/ext/tstat ` +* :doc:`pair_style dpd/coul/slater/long ` * examples/PACKAGES/dpd-basic ---------- @@ -887,6 +895,22 @@ This package has :ref:`specific installation instructions ` on the ---------- +.. _PKG-EXTRA-COMMAND: + +EXTRA-COMMAND package +--------------------- + +**Contents:** + +Additional command styles that are less commonly used. + +**Supporting info:** + +* src/EXTRA-COMMAND: filenames -> commands +* :doc:`general commands ` + +---------- + .. _PKG-EXTRA-COMPUTE: EXTRA-COMPUTE package @@ -1926,6 +1950,31 @@ computes which analyze attributes of the potential. ---------- +.. _PKG-ML-UF3: + +ML-UF3 package +-------------- + +**Contents:** + +A pair style for the ultra-fast force field potentials (UF3). UF3 is a +methodology for deriving a highly accurate classical potential which is +fast to evaluate and is fitted to a large archives of quantum mechanical +(DFT) data. The use of b-spline basis set in UF3 enables the rapid +evaluation of 2-body and 3-body interactions. + +**Authors:** Ajinkya C Hire (University of Florida), +Hendrik Krass (University of Constance), +Matthias Rupp (Luxembourg Institute of Science and Technology), +Richard Hennig (University of Florida) + +**Supporting info:** + +* src/ML-UF3: filenames -> commands +* :doc:`pair_style uf3 ` +* examples/uf3 +* https://github.com/uf3/uf3 + .. _PKG-MOFFF: MOFFF package diff --git a/doc/src/Packages_list.rst b/doc/src/Packages_list.rst index c0a1164513..d1422c5f09 100644 --- a/doc/src/Packages_list.rst +++ b/doc/src/Packages_list.rst @@ -158,6 +158,11 @@ whether an extra library is needed to build and use the package: - :doc:`fix electrode/conp ` - PACKAGES/electrode - no + * - :ref:`EXTRA-COMMAND ` + - additional command styles + - :doc:`general commands ` + - n/a + - no * - :ref:`EXTRA-COMPUTE ` - additional compute styles - :doc:`compute ` @@ -318,6 +323,11 @@ whether an extra library is needed to build and use the package: - :doc:`pair_style snap ` - snap - no + * - :ref:`ML-UF3 ` + - quantum-fitted ultra fast potentials + - :doc:`pair_style uf3 ` + - PACKAGES/uf3 + - no * - :ref:`MOFFF ` - styles for `MOF-FF `_ force field - :doc:`pair_style buck6d/coul/gauss ` diff --git a/doc/src/Tools.rst b/doc/src/Tools.rst index 342ef081de..e5429bc68d 100644 --- a/doc/src/Tools.rst +++ b/doc/src/Tools.rst @@ -728,8 +728,8 @@ CMake is required. The LAMMPS GUI has been successfully compiled and tested on: - Ubuntu Linux 20.04LTS x86_64 using GCC 9, Qt version 5.12 -- Fedora Linux 38 x86\_64 using GCC 13 and Clang 16, Qt version 5.15LTS -- Fedora Linux 38 x86\_64 using GCC 13, Qt version 6.5LTS +- Fedora Linux 40 x86\_64 using GCC 14 and Clang 17, Qt version 5.15LTS +- Fedora Linux 40 x86\_64 using GCC 14, Qt version 6.5LTS - Apple macOS 12 (Monterey) and macOS 13 (Ventura) with Xcode on arm64 and x86\_64, Qt version 5.15LTS - Windows 10 and 11 x86_64 with Visual Studio 2022 and Visual C++ 14.36, Qt version 5.15LTS - Windows 10 and 11 x86_64 with MinGW / GCC 10.0 cross-compiler on Fedora 38, Qt version 5.15LTS @@ -771,22 +771,23 @@ if necessary. When both, Qt5 and Qt6 are available, Qt6 will be preferred unless ``-D LAMMPS_GUI_USE_QT5=yes`` is set. It should be possible to build the LAMMPS GUI as a standalone -compilation (e.g. when LAMMPS has been compiled with traditional make), -then the CMake configuration needs to be told where to find the LAMMPS +compilation (e.g. when LAMMPS has been compiled with traditional make). +Then the CMake configuration needs to be told where to find the LAMMPS headers and the LAMMPS library, via ``-D LAMMPS_SOURCE_DIR=/path/to/lammps/src``. CMake will try to guess a build folder with the LAMMPS library from that path, but it can also be set with ``-D LAMMPS_LIB_DIR=/path/to/lammps/lib``. Rather than linking to the LAMMPS library during compilation, it is also -possible to compile the GUI with a plugin loader library that will load +possible to compile the GUI with a plugin loader that will load the LAMMPS library dynamically at runtime during the start of the GUI from a shared library; e.g. ``liblammps.so`` or ``liblammps.dylib`` or ``liblammps.dll`` (depending on the operating system). This has the -advantage that the LAMMPS library can be updated LAMMPS without having -to recompile the GUI. The ABI of the LAMMPS C-library interface is very -stable and generally backward compatible. This feature is enabled by -setting ``-D LAMMPS_GUI_USE_PLUGIN=on`` and then ``-D +advantage that the LAMMPS library can be built from updated or modified +LAMMPS source without having to recompile the GUI. The ABI of the +LAMMPS C-library interface is very stable and generally backward +compatible. This feature is enabled by setting +``-D LAMMPS_GUI_USE_PLUGIN=on`` and then ``-D LAMMPS_PLUGINLIB_DIR=/path/to/lammps/plugin/loader``. Typically, this would be the ``examples/COUPLE/plugin`` folder of the LAMMPS distribution. @@ -798,8 +799,8 @@ macOS """"" When building on macOS, the build procedure will try to manufacture a -drag-n-drop installer, LAMMPS-macOS-multiarch.dmg, when using the 'dmg' -target (i.e. ``cmake --build --target dmg`` or ``make dmg``. +drag-n-drop installer, ``LAMMPS-macOS-multiarch.dmg``, when using the +'dmg' target (i.e. ``cmake --build --target dmg`` or ``make dmg``. To build multi-arch executables that will run on both, arm64 and x86_64 architectures natively, it is necessary to set the CMake variable ``-D @@ -839,11 +840,11 @@ and LAMMPS GUI can be launched from anywhere from the command line. The standard CMake build procedure can be applied and the ``mingw-cross.cmake`` preset used. By using ``mingw64-cmake`` the CMake command will automatically include a suitable CMake toolset file (the -regular cmake command can be used after that). After building the -libraries and executables, you can build the target 'zip' -(i.e. ``cmake --build --target zip`` or ``make zip`` -to stage all installed files into a LAMMPS_GUI folder and then -run a script to copy all required dependencies, some other files, +regular cmake command can be used after that to modify the configuration +settings, if needed). After building the libraries and executables, +you can build the target 'zip' (i.e. ``cmake --build --target zip`` +or ``make zip`` to stage all installed files into a LAMMPS_GUI folder +and then run a script to copy all required dependencies, some other files, and create a zip file from it. Linux diff --git a/doc/src/fix_deform.rst b/doc/src/fix_deform.rst index 9146b987c8..2c76463369 100644 --- a/doc/src/fix_deform.rst +++ b/doc/src/fix_deform.rst @@ -64,6 +64,8 @@ Syntax effectively an engineering shear strain rate *erate* value = R R = engineering shear strain rate (1/time units) + *erate/rescale* value = R (ONLY available in :doc:`fix deform/pressure ` command) + R = engineering shear strain rate (1/time units) *trate* value = R R = true shear strain rate (1/time units) *wiggle* values = A Tp diff --git a/doc/src/fix_sgcmc.rst b/doc/src/fix_sgcmc.rst index 6be5cd2e1a..51ec572a47 100644 --- a/doc/src/fix_sgcmc.rst +++ b/doc/src/fix_sgcmc.rst @@ -15,7 +15,7 @@ Syntax * every_nsteps = number of MD steps between MC cycles * swap_fraction = fraction of a full MC cycle carried out at each call (a value of 1.0 will perform as many trial moves as there are atoms) * temperature = temperature that enters Boltzmann factor in Metropolis criterion (usually the same as MD temperature) -* deltamu = chemical potential difference(s) (`N-1` values must be provided, with `N` being the number of elements) +* deltamu = `N-1` chemical potential differences :math:`\mu_1-\mu_2, \ldots, \mu_1-\mu_N` (`N` is the number of atom types) * Zero or more keyword/value pairs may be appended to fix definition line: .. parsed-literal:: @@ -23,7 +23,7 @@ Syntax keyword = *variance* or *randseed* or *window_moves* or *window_size* *variance* kappa conc1 [conc2] ... [concN] kappa = variance constraint parameter - conc1,conc2,... = target concentration(s) in the range 0.0-1.0 (*N-1* values must be provided, with *N* being the number of elements) + `c_2`, `c_3`,..., `c_N` = `N-1` target concentration fractions *randseed* N N = seed for pseudo random number generator *window_moves* N @@ -90,11 +90,10 @@ the simulation, e.g., to speed up equilibration at low temperatures. ------------ -The parameter *deltamu* is used to set the chemical potential difference -in the SGC MC algorithm (see Eq. 16 in :ref:`Sadigh1 `). By -convention it is the difference of the chemical potentials of elements -`B`, `C` ..., with respect to element A. When the simulation includes -`N` elements, `N-1` values must be specified. +The parameter *deltamu* is used to set the chemical potential differences +in the SGC MC algorithm (see Eq. 16 in :ref:`Sadigh1 `). +The `N-1` differences are defined as :math:`\mu_1-\mu_2, \ldots, \mu_1-\mu_N`, +where `N` is the number of atom types. ------------ @@ -104,12 +103,12 @@ the effective average constraint in the parallel VC-SGC MC algorithm (parameter :math:`\delta\mu_0` in Eq. (20) of :ref:`Sadigh1 `). The parameter *kappa* specifies the variance constraint (see Eqs. (20-21) in :ref:`Sadigh1 `). - -The parameter *conc* sets the target concentration (parameter -:math:`c_0` in Eqs. (20-21) of :ref:`Sadigh1 `). The atomic -concentrations refer to components `B`, `C` ..., with `A` being set -automatically. When the simulation includes `N` elements, `N-1` -concentration values must be specified. +The parameter *conc* sets the `N-1` target atomic concentration +fractions (parameter :math:`c_0` in Eqs. (20-21) of :ref:`Sadigh1 `) +:math:`0 \le c_2, \ldots, c_N \le 1`, with +:math:`c_1 = 1 - \Sigma_{i=2}^N c_i`. +When the simulation includes `N` atom types (elements), +`N-1` concentration values must be specified. ------------ @@ -143,10 +142,10 @@ components of the vector represent the following quantities: * 1 = The absolute number of accepted trial swaps during the last MC step * 2 = The absolute number of rejected trial swaps during the last MC step -* 3 = The current global concentration of species *A* (= number of atoms of type 1 / total number of atoms) -* 4 = The current global concentration of species *B* (= number of atoms of type 2 / total number of atoms) +* 3 = Current global concentration `c_1` (= number of atoms of type 1 / total number of atoms) +* 4 = Current global concentration `c_2` (= number of atoms of type 2 / total number of atoms) * ... -* N+2: The current global concentration of species *X* (= number of atoms of type *N* / total number of atoms) +* N+2: Current global concentration `c_N` (= number of atoms of type *N* / total number of atoms) The vector values calculated by this fix are "intensive". diff --git a/doc/src/fix_wall_gran.rst b/doc/src/fix_wall_gran.rst index f6465d1159..25d659241c 100644 --- a/doc/src/fix_wall_gran.rst +++ b/doc/src/fix_wall_gran.rst @@ -115,6 +115,18 @@ friction and twisting friction supported by the :doc:`pair_style granular `. +.. note:: + When *fstyle* *granular* is specified, the associated *fstyle_params* are taken as + those for a wall/particle interaction. For example, for the *hertz/material* normal + contact model with :math:`E = 960` and :math:`\nu = 0.2`, the effective Young's + modulus for a wall/particle interaction is computed as + :math:`E_{eff} = \frac{960}{2(1-0.2^2)} = 500`. Any pair coefficients defined by + :doc:`pair_style granular ` are not taken into consideration. To + model different wall/particle interactions for particles of different material + types, the user may define multiple fix wall/gran commands operating on separate + groups (e.g. based on particle type) each with a different wall/particle effective + Young's modulus. + Note that you can choose a different force styles and/or different values for the wall/particle coefficients than for particle/particle interactions. E.g. if you wish to model the wall as a different diff --git a/doc/src/group2ndx.rst b/doc/src/group2ndx.rst index 077f88e3e8..19c472e109 100644 --- a/doc/src/group2ndx.rst +++ b/doc/src/group2ndx.rst @@ -34,32 +34,66 @@ Description Write or read a Gromacs style index file in text format that associates atom IDs with the corresponding group definitions. This index file can be used with in combination with Gromacs analysis tools or to import group -definitions into the :doc:`fix colvars ` input file. It can -also be used to save and restore group definitions for static groups. +definitions into the :doc:`fix colvars ` input file. + +It can also be used to save and restore group definitions for static groups +using the individual atom IDs. This may be important if the original +group definition depends on a region or otherwise on the geometry and thus +cannot be easily recreated. + +Another application would be to import atom groups defined for Gromacs +simulation into LAMMPS. When translating Gromacs topology and geometry +data to LAMMPS. The *group2ndx* command will write group definitions to an index file. -Without specifying any group IDs, all groups will be written to the index -file. When specifying group IDs, only those groups will be written to the -index file. In order to follow the Gromacs conventions, the group *all* -will be renamed to *System* in the index file. +Without specifying any group IDs, all groups will be written to the +index file. When specifying group IDs, only those groups will be +written to the index file. In order to follow the Gromacs conventions, +the group *all* will be renamed to *System* in the index file. -The *ndx2group* command will create of update group definitions from those -stored in an index file. Without specifying any group IDs, all groups except -*System* will be read from the index file and the corresponding groups -recreated. If a group of the same name already exists, it will be completely -reset. When specifying group IDs, those groups, if present, will be read -from the index file and restored. +The *ndx2group* command will create of update group definitions from +those stored in an index file. Without specifying any group IDs, all +groups except *System* will be read from the index file and the +corresponding groups recreated. If a group of the same name already +exists, it will be completely reset. When specifying group IDs, those +groups, if present, will be read from the index file and restored. + +File Format +""""""""""" + +The file format is equivalent and compatible with what is produced by +the `Gromacs make_ndx command `_. +and follows the `Gromacs definition of an ndx file `_ + +Each group definition begins with the group name in square brackets with +blanks, e.g. \[ water \] and is then followed by the list of atom +indices, which may be spread over multiple lines. Here is a small +example file: + +.. code-block:: ini + + [ Oxygen ] + 1 4 7 + [ Hydrogen ] + 2 3 5 6 + 8 9 + [ Water ] + 1 2 3 4 5 6 7 8 9 + +The index file defines 3 groups: Oxygen, Hydrogen, and Water and the +latter happens to be the union of the first two. ---------- Restrictions """""""""""" -This command requires that atoms have atom IDs, since this is the +These commands require that atoms have atom IDs, since this is the information that is written to the index file. -These commands are part of the COLVARS package. They are only -enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +These commands are part of the EXTRA-COMMAND package. They are only +enabled if LAMMPS was built with that package. See the +:doc:`Build package ` page for more info. Related commands """""""""""""""" diff --git a/doc/src/pair_dpd_coul_slater_long.rst b/doc/src/pair_dpd_coul_slater_long.rst new file mode 100644 index 0000000000..24e8a3b09f --- /dev/null +++ b/doc/src/pair_dpd_coul_slater_long.rst @@ -0,0 +1,179 @@ +.. index:: pair_style dpd/coul/slater/long +.. index:: pair_style dpd/coul/slater/long/gpu + +pair_style dpd/coul/slater/long command +======================================= + +Accelerator Variants: *dpd/coul/slater/long/gpu* + +Syntax +"""""" + +.. code-block:: LAMMPS + + pair_style dpd/coul/slater/long T cutoff_DPD seed lambda cutoff_coul + + pair_coeff I J a_IJ Gamma is_charged + +* T = temperature (temperature units) (dpd only) +* cutoff_DPD = global cutoff for DPD interactions (distance units) +* seed = random # seed (positive integer) +* lambda = decay length of the charge (distance units) +* cutoff_coul = real part cutoff for Coulombic interactions (distance units) +* I,J = numeric atom types, or type labels +* Gamma = DPD Gamma coefficient +* is_charged (boolean) set to yes if I and J are charged beads + +Examples +"""""""" + +.. code-block:: LAMMPS + + pair_style dpd/coul/slater/long 1.0 2.5 34387 0.25 3.0 + pair_coeff 1 1 78.0 4.5 # not charged by default + pair_coeff 2 2 78.0 4.5 yes + + +Description +""""""""""" + +.. versionadded:: TBD + +Style *dpd/coul/slater/long* computes a force field for dissipative particle dynamics +(DPD) following the exposition in :ref:`(Groot) ` with the addition of +electrostatic interactions. The coulombic forces in mesoscopic models +employ potentials without explicit excluded-volume interactions. +The goal is to prevent artificial ionic pair formation by including a charge +distribution in the Coulomb potential, following the formulation of +:ref:`(Melchor) `: + +The force on bead I due to bead J is given as a sum +of 4 terms + +.. math:: + + \vec{f} = & (F^C + F^D + F^R + F^E) \hat{r_{ij}} \\ + F^C = & A w(r) \qquad \qquad \qquad \qquad \qquad r < r_c \\ + F^D = & - \gamma w^2(r) (\hat{r_{ij}} \bullet \vec{v}_{ij}) \qquad \qquad r < r_c \\ + F^R = & \sigma w(r) \alpha (\Delta t)^{-1/2} \qquad \qquad \qquad r < r_c \\ + w(r) = & 1 - \frac{r}{r_c} \\ + F^E = & \frac{Cq_iq_j}{\epsilon r^2} \left( 1- exp\left( \frac{2r_{ij}}{\lambda} \right) \left( 1 + \frac{2r_{ij}}{\lambda} \left( 1 + \frac{r_{ij}}{\lambda} \right)\right) \right) + +where :math:`F^C` is a conservative force, :math:`F^D` is a dissipative +force, :math:`F^R` is a random force, and :math:`F^E` is an electrostatic force. +:math:`\hat{r_{ij}}` is a unit vector in the direction +:math:`r_i - r_j`, :math:`\vec{v}_{ij}` is +the vector difference in velocities of the two atoms :math:`\vec{v}_i - +\vec{v}_j`, :math:`\alpha` is a Gaussian random number with zero mean +and unit variance, *dt* is the timestep size, and :math:`w(r)` is a +weighting factor that varies between 0 and 1. :math:`r_c` is the +pairwise cutoff. :math:`\sigma` is set equal to :math:`\sqrt{2 k_B T +\gamma}`, where :math:`k_B` is the Boltzmann constant and *T* is the +temperature parameter in the pair_style command. +C is the same Coulomb conversion factor as in the pair_styles +coul/cut and coul/long. In this way the Coulomb +interaction between ions is corrected at small distances r, and +the long-range interactions are computed either by the Ewald or the PPPM technique. + + +The following parameters must be defined for each +pair of atoms types via the :doc:`pair_coeff ` command as in +the examples above, or in the data file or restart files read by the +:doc:`read_data ` or :doc:`read_restart ` +commands: + +* A (force units) +* :math:`\gamma` (force/velocity units) +* is_charged (boolean) + + +.. note:: + + This style is the combination of :doc:`pair_style dpd ` and :doc:`pair_style coul/slater/long `. + +---------- + +.. include:: accel_styles.rst + +---------- + +Mixing, shift, table, tail correction, restart, rRESPA info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This pair style does not support mixing. Thus, coefficients for all +I,J pairs must be specified explicitly. + +This pair style does not support the :doc:`pair_modify ` +shift option for the energy of the pair interaction. + +The :doc:`pair_modify ` table option is not relevant +for this pair style. + +This pair style does not support the :doc:`pair_modify ` +tail option for adding long-range tail corrections to energy and +pressure. + +This pair style writes its information to :doc:`binary restart files +`, so pair_style and pair_coeff commands do not need to be +specified in an input script that reads a restart file. Note that the +user-specified random number seed is stored in the restart file, so when +a simulation is restarted, each processor will re-initialize its random +number generator the same way it did initially. This means the random +forces will be random, but will not be the same as they would have been +if the original simulation had continued past the restart time. + +This pair style can only be used via the *pair* keyword of the +:doc:`run_style respa ` command. They do not support the +*inner*, *middle*, *outer* keywords. + + +---------- + +Restrictions +"""""""""""" + +This style is part of the DPD-BASIC package. It is only enabled if +LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +The default frequency for rebuilding neighbor lists is every 10 steps +(see the :doc:`neigh_modify ` command). This may be too +infrequent since particles move rapidly and +can overlap by large amounts. If this setting yields a non-zero number +of "dangerous" reneighborings (printed at the end of a simulation), you +should experiment with forcing reneighboring more often and see if +system energies/trajectories change. + +This pair style requires you to use the :doc:`comm_modify vel yes +` command so that velocities are stored by ghost atoms. + +This pair style also requires the long-range solvers included in the KSPACE package. + + +This pair style will not restart exactly when using the +:doc:`read_restart ` command, though they should provide +statistically similar results. This is because the forces they compute +depend on atom velocities. See the :doc:`read_restart ` +command for more details. + +Related commands +"""""""""""""""" + +:doc:`pair_style dpd `, :doc:`pair_style coul/slater/long `, +:doc:`pair_coeff `, :doc:`fix nvt `, :doc:`fix langevin `, +:doc:`pair_style srp `, :doc:`fix mvv/dpd `. + +Default +""""""" + +is_charged = no + +---------- + +.. _Groot5: + +**(Groot)** Groot and Warren, J Chem Phys, 107, 4423-35 (1997). + +.. _Melchor1: + +**(Melchor)** Gonzalez-Melchor, Mayoral, Velazquez, and Alejandre, J Chem Phys, 125, 224107 (2006). diff --git a/doc/src/pair_granular.rst b/doc/src/pair_granular.rst index 597869a05b..dca85d8be1 100644 --- a/doc/src/pair_granular.rst +++ b/doc/src/pair_granular.rst @@ -111,7 +111,7 @@ For the *hertz* model, the normal component of force is given by: \mathbf{F}_{ne, Hertz} = k_n R_{eff}^{1/2}\delta_{ij}^{3/2} \mathbf{n} -Here, :math:`R_{eff} = \frac{R_i R_j}{R_i + R_j}` is the effective +Here, :math:`R_{eff} = R = \frac{R_i R_j}{R_i + R_j}` is the effective radius, denoted for simplicity as *R* from here on. For *hertz*, the units of the spring constant :math:`k_n` are *force*\ /\ *length*\ \^2, or equivalently *pressure*\ . @@ -120,13 +120,14 @@ For the *hertz/material* model, the force is given by: .. math:: - \mathbf{F}_{ne, Hertz/material} = \frac{4}{3} E_{eff} R_{eff}^{1/2}\delta_{ij}^{3/2} \mathbf{n} + \mathbf{F}_{ne, Hertz/material} = \frac{4}{3} E_{eff} R^{1/2}\delta_{ij}^{3/2} \mathbf{n} -Here, :math:`E_{eff} = E = \left(\frac{1-\nu_i^2}{E_i} + \frac{1-\nu_j^2}{E_j}\right)^{-1}` is the effective Young's -modulus, with :math:`\nu_i, \nu_j` the Poisson ratios of the particles of -types *i* and *j*\ . Note that if the elastic modulus and the shear -modulus of the two particles are the same, the *hertz/material* model -is equivalent to the *hertz* model with :math:`k_n = 4/3 E_{eff}` +Here, :math:`E_{eff} = E = \left(\frac{1-\nu_i^2}{E_i} + \frac{1-\nu_j^2}{E_j}\right)^{-1}` +is the effective Young's modulus, with :math:`\nu_i, \nu_j` the Poisson ratios +of the particles of types *i* and *j*. :math:`E_{eff}` is denoted as *E* from here on. +Note that if the elastic modulus and the shear modulus of the two particles are the +same, the *hertz/material* model is equivalent to the *hertz* model with +:math:`k_n = 4/3 E` The *dmt* model corresponds to the :ref:`(Derjaguin-Muller-Toporov) ` cohesive model, where the force @@ -270,7 +271,8 @@ where :math:`k_n = \frac{4}{3} E_{eff}` for the *hertz/material* model. Since *coeff_restitution* accounts for the effective mass, effective radius, and pairwise overlaps (except when used with the *hooke* normal model) when calculating the damping coefficient, it accurately reproduces the specified coefficient of -restitution for both monodisperse and polydisperse particle pairs. +restitution for both monodisperse and polydisperse particle pairs. This damping +model is not compatible with cohesive normal models such as *JKR* or *DMT*. The total normal force is computed as the sum of the elastic and damping components: @@ -441,11 +443,11 @@ discussion above. To match the Mindlin solution, one should set G_{eff} = \left(\frac{2-\nu_i}{G_i} + \frac{2-\nu_j}{G_j}\right)^{-1} -where :math:`G` is the shear modulus, related to Young's modulus :math:`E` -and Poisson's ratio :math:`\nu` by :math:`G = E/(2(1+\nu))`. This can also be -achieved by specifying *NULL* for :math:`k_t`, in which case a -normal contact model that specifies material parameters :math:`E` and -:math:`\nu` is required (e.g. *hertz/material*, *dmt* or *jkr*\ ). In this +where :math:`G_i` is the shear modulus of a particle of type :math:`i`, related to Young's +modulus :math:`E_i` and Poisson's ratio :math:`\nu_i` by :math:`G_i = E_i/(2(1+\nu_i))`. +This can also be achieved by specifying *NULL* for :math:`k_t`, in which case a +normal contact model that specifies material parameters :math:`E_i` and +:math:`\nu_i` is required (e.g. *hertz/material*, *dmt* or *jkr*\ ). In this case, mixing of the shear modulus for different particle types *i* and *j* is done according to the formula above. @@ -575,7 +577,7 @@ opposite torque on each particle, according to: .. math:: - \tau_{roll,i} = R_{eff} \mathbf{n} \times \mathbf{F}_{roll} + \tau_{roll,i} = R \mathbf{n} \times \mathbf{F}_{roll} .. math:: diff --git a/doc/src/pair_hybrid.rst b/doc/src/pair_hybrid.rst index a33991e43e..634717f8a8 100644 --- a/doc/src/pair_hybrid.rst +++ b/doc/src/pair_hybrid.rst @@ -1,28 +1,41 @@ .. index:: pair_style hybrid .. index:: pair_style hybrid/kk +.. index:: pair_style hybrid/omp +.. index:: pair_style hybrid/molecular +.. index:: pair_style hybrid/molecular/omp .. index:: pair_style hybrid/overlay +.. index:: pair_style hybrid/overlay/omp .. index:: pair_style hybrid/overlay/kk .. index:: pair_style hybrid/scaled +.. index:: pair_style hybrid/scaled/omp pair_style hybrid command ========================= -Accelerator Variants: *hybrid/kk* +Accelerator Variants: *hybrid/kk*, *hybrid/omp* + +pair_style hybrid/molecular command +=================================== + +Accelerator Variant: *hybrid/molecular/omp* pair_style hybrid/overlay command ================================= -Accelerator Variants: *hybrid/overlay/kk* +Accelerator Variants: *hybrid/overlay/kk*, *hybrid/overlay/omp* pair_style hybrid/scaled command ================================== +Accelerator Variant: *hybrid/scaled/omp* + Syntax """""" .. code-block:: LAMMPS pair_style hybrid style1 args style2 args ... + pair_style hybrid/molecular factor1 style1 args factor2 style 2 args pair_style hybrid/overlay style1 args style2 args ... pair_style hybrid/scaled factor1 style1 args factor2 style 2 args ... @@ -47,6 +60,10 @@ Examples pair_coeff * * tersoff Si.tersoff Si pair_coeff * * sw Si.sw Si + pair_style hybrid/molecular lj/cut 2.5 lj/cut 2.5 + pair_coeff * * lj/cut 1 1.0 1.0 + pair_coeff * * lj/cut 2 1.5 1.0 + variable one equal ramp(1.0,0.0) variable two equal 1.0-v_one pair_style hybrid/scaled v_one lj/cut 2.5 v_two morse 2.5 @@ -56,17 +73,26 @@ Examples Description """"""""""" -The *hybrid*, *hybrid/overlay*, and *hybrid/scaled* styles enable the -use of multiple pair styles in one simulation. With the *hybrid* style, -exactly one pair style is assigned to each pair of atom types. With the -*hybrid/overlay* and *hybrid/scaled* styles, one or more pair styles can -be assigned to each pair of atom types. The assignment of pair styles -to type pairs is made via the :doc:`pair_coeff ` command. -The major difference between the *hybrid/overlay* and *hybrid/scaled* -styles is that the *hybrid/scaled* adds a scale factor for each -sub-style contribution to forces, energies and stresses. Because of the -added complexity, the *hybrid/scaled* style has more overhead and thus -may be slower than *hybrid/overlay*. +The *hybrid*, *hybrid/overlay*, *hybrid/molecular*, and *hybrid/scaled* +styles enable the use of multiple pair styles in one simulation. With +the *hybrid* style, exactly one pair style is assigned to each pair of +atom types. With the *hybrid/overlay* and *hybrid/scaled* styles, one +or more pair styles can be assigned to each pair of atom types. With +the hybrid/molecular style, pair styles are assigned to either intra- +or inter-molecular interactions. + +The assignment of pair styles to type pairs is made via the +:doc:`pair_coeff ` command. The major difference between +the *hybrid/overlay* and *hybrid/scaled* styles is that the +*hybrid/scaled* adds a scale factor for each sub-style contribution to +forces, energies and stresses. Because of the added complexity, the +*hybrid/scaled* style has more overhead and thus may be slower than +*hybrid/overlay*. + +The *hybrid/molecular* pair style accepts *only* two sub-styles: the +first is assigned to intra-molecular interactions (i.e. both atoms +have the same molecule ID), the second to inter-molecular interactions +(i.e. interacting atoms have different molecule IDs). Here are two examples of hybrid simulations. The *hybrid* style could be used for a simulation of a metal droplet on a LJ surface. The metal @@ -476,6 +502,8 @@ the same or else LAMMPS will generate an error. Pair style *hybrid/scaled* currently only works for non-accelerated pair styles and pair styles from the OPT package. +Pair style *hybrid/molecular* is not compatible with manybody potentials. + When using pair styles from the GPU package they must not be listed multiple times. LAMMPS will detect this and abort. diff --git a/doc/src/pair_soft.rst b/doc/src/pair_soft.rst index e21ae28432..1405cb8101 100644 --- a/doc/src/pair_soft.rst +++ b/doc/src/pair_soft.rst @@ -1,11 +1,12 @@ .. index:: pair_style soft .. index:: pair_style soft/gpu +.. index:: pair_style soft/kk .. index:: pair_style soft/omp pair_style soft command ======================= -Accelerator Variants: *soft/gpu*, *soft/omp* +Accelerator Variants: *soft/gpu*, *soft/kk*, *soft/omp* Syntax """""" diff --git a/doc/src/pair_style.rst b/doc/src/pair_style.rst index 74dfce6b01..75157d6127 100644 --- a/doc/src/pair_style.rst +++ b/doc/src/pair_style.rst @@ -108,6 +108,7 @@ accelerated styles exist. * :doc:`none ` - turn off pairwise interactions * :doc:`hybrid ` - multiple styles of pairwise interactions +* :doc:`hybrid/molecular ` - different pair styles for intra- and inter-molecular interactions * :doc:`hybrid/overlay ` - multiple styles of superposed pairwise interactions * :doc:`hybrid/scaled ` - multiple styles of scaled superposed pairwise interactions * :doc:`zero ` - neighbor list but no interactions @@ -171,6 +172,7 @@ accelerated styles exist. * :doc:`coul/wolf ` - Coulomb via Wolf potential * :doc:`coul/wolf/cs ` - Coulomb via Wolf potential with core/shell adjustments * :doc:`dpd ` - dissipative particle dynamics (DPD) +* :doc:`dpd/coul/slater/long ` - dissipative particle dynamics (DPD) with electrostatic interactions * :doc:`dpd/ext ` - generalized force field for DPD * :doc:`dpd/ext/tstat ` - pairwise DPD thermostatting with generalized force field * :doc:`dpd/fdt ` - DPD for constant temperature and pressure @@ -382,6 +384,7 @@ accelerated styles exist. * :doc:`tracker ` - monitor information about pairwise interactions * :doc:`tri/lj ` - LJ potential between triangles * :doc:`ufm ` - +* :doc:`uf3 ` - UF3 machine-learning potential * :doc:`vashishta ` - Vashishta 2-body and 3-body potential * :doc:`vashishta/table ` - * :doc:`wf/cut ` - Wang-Frenkel Potential for short-ranged interactions diff --git a/doc/src/pair_uf3.rst b/doc/src/pair_uf3.rst new file mode 100644 index 0000000000..ce07e2206f --- /dev/null +++ b/doc/src/pair_uf3.rst @@ -0,0 +1,213 @@ +.. index:: pair_style uf3 +.. index:: pair_style uf3/kk + +pair_style uf3 command +====================== + +Accelerator Variants: *uf3/kk* + +Syntax +"""""" + +.. code-block:: LAMMPS + + pair_style style BodyFlag + +* style = *uf3* or *uf3/kk* + + .. parsed-literal:: + + BodyFlag = Indicates whether to calculate only 2-body or 2 and 3-body interactions. Possible values: 2 or 3 + +Examples +"""""""" + +.. code-block:: LAMMPS + + pair_style uf3 3 + pair_coeff * * Nb.uf3 Nb + + pair_style uf3 2 + pair_coeff * * NbSn.uf3 Nb Sn + + pair_style uf3 3 + pair_coeff * * NbSn.uf3 Nb Sn + +Description +""""""""""" + +.. versionadded:: TBD + +The *uf3* style computes the :ref:`Ultra-Fast Force Fields (UF3) +` potential, a machine-learning interatomic potential. In UF3, +the total energy of the system is defined via two- and three-body +interactions: + +.. math:: + + E & = \sum_{i,j} V_2(r_{ij}) + \sum_{i,j,k} V_3 (r_{ij},r_{ik},r_{jk}) \\ + V_2(r_{ij}) & = \sum_{n=0}^N c_n B_n(r_{ij}) \\ + V_3 (r_{ij},r_{ik},r_{jk}) & = \sum_{l=0}^{N_l} \sum_{m=0}^{N_m} \sum_{n=0}^{N_n} c_{l,m,n} B_l(r_{ij}) B_m(r_{ik}) B_n(r_{jk}) + +where :math:`V_2(r_{ij})` and :math:`V_3 (r_{ij},r_{ik},r_{jk})` are the +two- and three-body interactions, respectively. For the two-body the +summation is over all neighbors J and for the three-body the summation +is over all neighbors J and K of atom I within a cutoff distance +determined from the potential files. :math:`B_n(r_{ij})` are the cubic +b-spline basis, :math:`c_n` and :math:`c_{l,m,n}` are the machine-learned +interaction parameters and :math:`N`, :math:`N_l`, :math:`N_m`, and +:math:`N_n` denote the number of basis functions per spline or tensor +spline dimension. + +With *uf3* style only a single pair_coeff command is used to indicate the +UF3 LAMMPS potential file containing all the two- and three-body interactions +followed by N additional arguments specifying the mapping of UF3 elements to +LAMMPS atom types, where N is the number of LAMMPS atom types: + +* UF3 LAMMPS potential file +* N elements names = mapping of UF3 elements to atom types + +As an example, if a LAMMPS simulation contains 2 atom types (elements +'A' and 'B'), the pair_coeff command will be: + +.. code-block:: LAMMPS + + pair_style uf3 3 + pair_coeff * * AB.uf3 A B + +The AB.uf3 file should contain all two-body (A-A, A-B, B-B) and three-body +(A-A-A, A-A-B, A-B-B, B-A-A, B-A-B, B-B-B). + +If a value of "2" is specified in the :code:`pair_style uf3` command, +only the two-body potentials are needed. For 3-body interaction the +first atom type is the central atom. We recommend using the +:code:`generate_uf3_lammps_pots.py` script (found `here +`_) for +generating the UF3 LAMMPS potential file from the UF3 JSON potentials. + +---------- + +UF3 LAMMPS potential file in the *potentials* directory of the LAMMPS +distribution have a ".uf3" suffix. The interaction block in UF3 LAMMPS potential +file should start with :code:`#UF3 POT` and end with :code:`#` characters. +Following shows the format of a generic 2-body and 3-body potential block in +UF3 LAMMPS potential file- + +.. code-block:: LAMMPS + + #UF3 POT UNITS: units DATE: POT_GEN_DATE AUTHOR: AUTHOR_NAME CITATION: CITE + 2B ELEMENT1 ELEMENT2 LEADING_TRIM TRAILING_TRIM + Rij_CUTOFF NUM_OF_KNOTS + BSPLINE_KNOTS + NUM_OF_COEFF + COEFF + # + #UF3 POT UNITS: units DATE: POT_GEN_DATE AUTHOR: AUTHOR_NAME CITATION: CITE + 3B ELEMENT1 ELEMENT2 ELEMENT3 LEADING_TRIM TRAILING_TRIM + Rjk_CUTOFF Rik_CUTOFF Rij_CUTOFF NUM_OF_KNOTS_JK NUM_OF_KNOTS_IK NUM_OF_KNOTS_IJ + BSPLINE_KNOTS_FOR_JK + BSPLINE_KNOTS_FOR_IK + BSPLINE_KNOTS_FOR_IJ + SHAPE_OF_COEFF_MATRIX[I][J][K] + COEFF_MATRIX[0][0][K] + COEFF_MATRIX[0][1][K] + COEFF_MATRIX[0][2][K] + . + . + . + COEFF_MATRIX[1][0][K] + COEFF_MATRIX[1][1][K] + COEFF_MATRIX[1][2][K] + . + . + . + # + +The second line indicates whether the block contains data for 2-body +(:code:`2B`) or 3-body (:code:`3B`) interaction. This is followed by element +combination interaction, :code:`LEADING_TRIM` and :code:`TRAILING_TRIM` +number on the same line. The current implementation is only tested for +:code:`LEADING_TRIM=0` and :code:`TRAILING_TRIM=3`. +If other values are used LAMMPS is terminated after issuing an error message. +The :code:`Rij_CUTOFF` sets the 2-body cutoff for the interaction described +by the potential block. :code:`NUM_OF_KNOTS` is the number of knots +(or the length of the knot vector) present on the very next line. The +:code:`BSPLINE_KNOTS` line should contain all the knots in ascending order. +:code:`NUM_OF_COEFF` is the number of coefficients in the :code:`COEFF` line. +All the numbers in the BSPLINE_KNOTS and COEFF line should be space-separated. +Similar to the 2-body potential block, the third line sets the cutoffs and +length of the knots. The cutoff distance between atom-type I and J is +:code:`Rij_CUTOFF`, atom-type I and K is :code:`Rik_CUTOFF` and between +J and K is :code:`Rjk_CUTOFF`. + +.. note:: + + The current implementation only works for UF3 potentials with cutoff + distances for 3-body interactions that follows + :code:`2Rij_CUTOFF=2Rik_CUTOFF=Rjk_CUTOFF` relation. + +The :code:`BSPLINE_KNOTS_FOR_JK`, :code:`BSPLINE_KNOTS_FOR_IK`, and +:code:`BSPLINE_KNOTS_FOR_IJ` lines (note the order) contain the knots in +increasing order for atoms J and K, I and K, and atoms I and J +respectively. The number of knots is defined by the +:code:`NUM_OF_KNOTS_*` characters in the previous line. The shape of +the coefficient matrix is defined on the +:code:`SHAPE_OF_COEFF_MATRIX[I][J][K]` line followed by the columns of +the coefficient matrix, one per line, as shown above. For example, if +the coefficient matrix has the shape of 8x8x13, then +:code:`SHAPE_OF_COEFF_MATRIX[I][J][K]` will be :code:`8 8 13` followed +by 64 (8x8) lines each containing 13 coefficients separated by space. + +---------- + +.. include:: accel_styles.rst + +---------- + +Mixing, shift, table, tail correction, restart, rRESPA info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +For atom type pairs I,J and I != J, where types I and J correspond to +two different element types, mixing is performed by LAMMPS as described +above from values in the potential file. + +This pair style does not support the :doc:`pair_modify ` +shift, table, and tail options. + +This pair style does not write its information to :doc:`binary restart +files `, since it is stored in potential file. + +This pair style can only be used via the *pair* keyword of the +:doc:`run_style respa ` command. It does not support the +*inner*, *middle*, *outer* keywords. + +Restrictions +"""""""""""" + +The 'uf3' pair style is part of the ML-UF3 package. It is only enabled +if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +This pair style requires the :doc:`newton ` setting to be "on". + +The UF3 LAMMPS potential file provided with LAMMPS (see the potentials +directory) are parameterized for metal :doc:`units `. + +The single() function of 'uf3' pair style only return the 2-body +interaction energy. + +Related commands +"""""""""""""""" + +:doc:`pair_coeff ` + +Default +""""""" + +none + +---------- + +.. _Xie23: + +**(Xie23)** Xie, S.R., Rupp, M. & Hennig, R.G. Ultra-fast interpretable machine-learning potentials. npj Comput Mater 9, 162 (2023). https://doi.org/10.1038/s41524-023-01092-7 diff --git a/doc/src/run_style.rst b/doc/src/run_style.rst index d2e47c0884..c06cef4296 100644 --- a/doc/src/run_style.rst +++ b/doc/src/run_style.rst @@ -327,10 +327,12 @@ Restrictions """""""""""" The *verlet/split* style can only be used if LAMMPS was built with the -REPLICA package. Correspondingly the *respa/omp* style is available +REPLICA package. Correspondingly the *respa/omp* style is available only if the OPENMP package was included. See the :doc:`Build package -` page for more info. It is not compatible with -kspace styles from the INTEL package. +` page for more info. + +Run style *verlet/split* is not compatible with kspace styles from +the INTEL package and it is not compatible with any TIP4P styles. Whenever using rRESPA, the user should experiment with trade-offs in speed and accuracy for their system, and verify that they are diff --git a/doc/utils/requirements.txt b/doc/utils/requirements.txt index 816d52bf54..5bb8e3911d 100644 --- a/doc/utils/requirements.txt +++ b/doc/utils/requirements.txt @@ -1,4 +1,4 @@ -Sphinx >= 5.3.0, <7.3 +Sphinx >= 5.3.0, <8.0 sphinxcontrib-spelling sphinxcontrib-jquery git+https://github.com/akohlmey/sphinx-fortran@parallel-read diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index cf98475098..b189e16953 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1434,6 +1434,7 @@ Hendrik Henin Henkelman Henkes +Hennig henrich Henrich Hermitian @@ -1595,6 +1596,7 @@ interlayer intermolecular interoperable Interparticle +interpretable interstitials intertube Intr @@ -1817,6 +1819,7 @@ Koziol Kp kradius Kraker +Krass Kraus Kremer Kress @@ -2959,6 +2962,7 @@ Priya proc Proc procs +proggrid progguide Prony ps @@ -3271,6 +3275,7 @@ Rudranarayan Rudzinski Runge runtime +Rupp Rutuparna rx rxd @@ -3820,6 +3825,8 @@ uChem uCond uef UEF +uf +uf3 ufm Uhlenbeck Ui diff --git a/examples/PACKAGES/dpd-basic/README b/examples/PACKAGES/dpd-basic/README index aec19f4fcb..64c26d8880 100644 --- a/examples/PACKAGES/dpd-basic/README +++ b/examples/PACKAGES/dpd-basic/README @@ -14,3 +14,5 @@ pair styles from the DPD-BASIC package. 4) 'dpdext_tstat' - coarse-grained SPC/E water example for 'dpd/ext/tstat' pair style (in.dpdext_tstat), an initial configuration (dpdext.data) and tabulated potential (cg_spce_table.pot) obtained by bottom-up coarse-graining of the atomistic SPC/E water. + +5) 'dpd_coul_slater_long' - simple example (DPD ionic fluid) for 'dpd/coul/slater/long' pair style (in.dpd_coul_slater_long). diff --git a/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/data.dpd_coul_slater_long b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/data.dpd_coul_slater_long new file mode 100644 index 0000000000..91ddddf4ec --- /dev/null +++ b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/data.dpd_coul_slater_long @@ -0,0 +1,779 @@ +LAMMPS data file via write_data, version 17 Apr 2024, timestep = 1394, units = lj + +375 atoms +3 atom types + +0 5 xlo xhi +0 5 ylo yhi +0 5 zlo zhi + +Masses + +1 1 +2 1 +3 1 + +PairIJ Coeffs # dpd/coul/slater/long + +1 1 78 4.5 yes 1 +1 2 78 4.5 yes 1 +1 3 78 4.5 yes 1 +2 2 78 4.5 no 1 +2 3 78 4.5 no 1 +3 3 78 4.5 no 1 + +Atoms # full + +189 0 1 0 0.8621554018960034 1.5213257556560191 0.4064444607843129 0 1 0 +107 0 1 0 2.040249318291146 0.3862591116608294 1.8661957131854634 0 0 0 +253 0 1 0 3.511834308089607 0.7338273870464224 0.801173549802059 0 1 1 +163 0 1 0 2.303289649738226 0.6809493239075631 0.7383435796468727 0 1 0 +26 0 1 0 0.03534770106704549 1.4889933012536283 1.4815498922617432 0 0 0 +27 0 1 0 4.170525658289272 1.8438490221677797 2.1918634082517614 -1 0 0 +56 0 1 0 2.9501314702448633 2.322938987390429 0.6158870411938201 0 0 0 +167 0 1 0 1.948558457807243 0.1261294591496785 0.039492485708843984 0 1 0 +364 0 3 -1 4.538825953029656 0.2655458359259118 2.131668601530241 0 1 0 +61 0 1 0 4.645784299395809 0.3574274125207269 1.7056474795918568 -1 0 0 +222 0 1 0 4.41481966340897 2.262979887349817 1.1679075968940398 0 0 0 +332 0 2 1 3.853874714249102 0.1758912358513287 0.8799773810713412 0 1 0 +1 0 1 0 4.608301143657016 1.4090100132224024 1.218887039455649 -1 0 0 +319 0 2 1 3.732213186171727 0.981827023519373 2.3857377768158727 -1 0 0 +53 0 1 0 2.380311878254328 0.953677113042391 1.8268738776443192 0 0 0 +68 0 1 0 0.33279009298924916 1.0106375746131884 0.7038515854567269 0 0 0 +220 0 1 0 1.1094848303775686 2.378414106514282 1.4793246435196352 1 0 0 +44 0 1 0 0.12449238274832848 1.7475396894040345 0.5495194876290164 0 0 0 +55 0 1 0 0.1451415441609303 2.337329820574407 0.940744164662616 0 0 0 +362 0 3 -1 1.2987762452744613 1.8352325797868587 1.1809674941775483 0 0 0 +165 0 1 0 0.6610209400465688 2.22554349560855 1.971912177574677 0 0 0 +60 0 1 0 1.8643313870571518 0.6352678895179578 1.4416996493100478 0 0 0 +202 0 1 0 0.007896731087640774 1.5385720917803027 0.18965671583085075 0 1 0 +85 0 1 0 1.5630176980330266 1.1482985441214197 2.019916217302335 1 0 0 +73 0 1 0 0.5556133646182337 1.6170466333456652 2.101792903006452 0 0 0 +96 0 1 0 1.6611967219346682 0.07688637034882238 0.46572063062814617 0 0 1 +30 0 1 0 0.46644353751713447 1.8254820637852556 1.2380479793915407 1 0 0 +67 0 1 0 3.4270812515248483 2.350996339385886 1.77527952461483 0 0 0 +349 0 3 -1 1.7935506583370944 1.7235931740659332 0.4478371869612185 1 0 0 +132 0 1 0 4.951074988035153 1.5039089286454406 2.4219801232797398 -1 0 0 +328 0 2 1 0.8958492991096989 1.2809413147557527 1.0440931858570435 0 0 1 +161 0 1 0 4.798276598985588 0.9882558902185279 2.462987088497934 0 1 0 +185 0 1 0 0.6126520391294695 0.04940161418784647 0.6135262263024062 0 1 0 +219 0 1 0 1.647872968759676 2.305100092833184 2.0217182617222096 0 0 0 +8 0 1 0 2.8077478718165207 0.7661158156519451 1.3602857540877684 0 0 0 +69 0 1 0 2.8568644931819835 0.13340029053585767 2.106212637519767 0 0 0 +3 0 1 0 1.908450187819087 2.298808713848062 0.4221817812562634 0 0 0 +7 0 1 0 1.8799145446976495 0.9814789886011673 0.955308672406064 0 0 0 +329 0 2 1 0.9727877144189607 0.8906662949552561 1.4472553696387669 0 1 0 +174 0 1 0 3.9905681672951636 0.6401683928312465 1.0284041192891435 -1 1 0 +20 0 1 0 3.392515194191721 2.0774851454870427 0.8812446323305514 0 0 0 +57 0 1 0 4.874212056539195 0.13899230379169403 0.7199140773346149 0 0 0 +325 0 2 1 1.362093021934204 2.3422237404192465 0.6655225660551776 0 0 1 +40 0 1 0 4.306473534903154 1.7047871476017826 0.8560715024613603 0 0 0 +51 0 1 0 2.297377802384159 0.11499650506694176 1.4731005354419167 0 0 0 +54 0 1 0 2.971300335884777 1.8792385205105047 1.3973014092900102 0 0 0 +186 0 1 0 3.583414064904102 1.7542346893771112 0.35130247738019466 0 0 0 +289 0 1 0 2.5651653875350906 1.4858962835620086 0.6587351599193196 0 0 1 +75 0 1 0 3.132107705055228 0.19794042232605677 0.44488993973642094 0 0 1 +48 0 1 0 3.4384178020381717 0.7217742755424055 1.7304812232062636 0 0 0 +66 0 1 0 3.191389133037332 1.1674191637093172 1.7413707516914332 0 0 0 +52 0 1 0 1.856006413772654 1.871405713016935 1.5164995404363106 0 0 0 +158 0 1 0 3.725559226243618 1.2320067990055215 0.4240371305587515 -1 1 0 +330 0 2 1 0.4226192821951129 0.22648053650193767 0.04025715930862768 1 1 0 +359 0 3 -1 4.4476116877707925 0.8271711042623823 1.1688054720798116 0 1 0 +366 0 3 -1 0.13989896192253948 0.6502137062351493 0.845841913773404 1 1 0 +196 0 1 0 0.21878194805964699 2.4139077401885523 1.602735237996178 1 0 0 +128 0 1 0 2.474112780481313 1.5036993910540244 1.234391076605564 0 0 1 +118 0 1 0 0.1703454662324439 0.9401878407982331 0.17224714060344348 0 0 1 +43 0 1 0 3.708324777814944 2.4767443359210524 0.5791362456922102 0 0 0 +184 0 1 0 0.4061592126934206 0.22209165285150972 1.3598048859115588 0 1 0 +360 0 3 -1 1.225690366400486 0.4472136514952278 1.0864811555493794 0 1 0 +64 0 1 0 2.6116937036965266 1.793563094424563 2.091822223631947 0 0 0 +285 0 1 0 0.7747031518566616 0.24118573693540882 2.1434463705260494 0 1 0 +58 0 1 0 1.598997109049339 1.2355543729347458 1.1437352681100093 0 0 0 +257 0 1 0 0.02882436640692898 0.8179392413775496 1.6880006059524528 1 1 0 +356 0 3 -1 2.0441963785801733 1.236982129976697 2.2147135788798726 0 0 0 +100 0 1 0 3.653446945164378 0.3462603812889145 1.6428480228892703 0 0 0 +121 0 1 0 3.3427026587713 1.3818800793465942 1.0715223415915789 0 0 1 +130 0 1 0 3.3647959804349648 1.6468424783155522 2.142743574286686 0 0 1 +238 0 1 0 1.3459228411155364 0.633596613028775 2.1301210835283637 0 1 0 +211 0 1 0 0.6615598402766512 2.33271179551025 0.47581804017205676 1 0 0 +208 0 1 0 2.962020456626749 0.2159270527386094 1.30534135402314 0 1 0 +63 0 1 0 1.3612122125160733 0.010635376740000254 1.5982897032081793 0 0 0 +22 0 1 0 4.210300352056279 0.36529901441609736 0.22595511161653342 0 0 0 +355 0 3 -1 1.2042503283777344 1.597276477439138 1.9589099368399292 0 0 0 +70 0 1 0 4.378695647703822 2.2211752925991073 0.5054248018357668 0 0 0 +65 0 1 0 4.730200694542147 1.8860651406962996 1.9541188923646609 0 0 0 +182 0 1 0 0.6006579892093956 1.0766698682185656 1.8982320873119558 0 1 0 +188 0 1 0 3.968278800401347 2.2778420975676017 1.5855956915283134 -1 0 0 +35 0 1 0 2.223480574739111 2.044750380955685 1.1501174861326973 0 0 0 +6 0 1 0 4.393818207857278 0.9691596735067866 0.4973738964333318 0 0 0 +346 0 3 -1 1.799292171051204 0.9378491451956622 0.32819450450408366 0 0 0 +14 0 1 0 4.116276227278533 0.9144868046413738 1.9001996318293624 0 0 0 +15 0 1 0 4.057083687324151 1.5512296337030849 1.8388944544921122 0 0 0 +16 0 1 0 3.82411370026405 1.5506478336832812 1.2725337401183239 0 0 0 +287 0 1 0 2.6387027215894454 1.893079917045916 0.49300315071401646 0 0 1 +81 0 1 0 0.23374890251430025 0.34479122000015083 2.377074044522331 1 0 0 +114 0 1 0 2.97788308248854 0.8029642133737654 0.43679357743492564 0 0 1 +232 0 1 0 1.1637120121074183 0.7914170906883582 0.5169414304881136 1 1 1 +50 0 1 0 1.3582030484899448 1.733969902734067 2.475757370252963 0 0 -1 +79 0 1 0 4.002398001699839 2.453310546669259 2.3569732163529196 0 0 0 +74 0 1 0 2.5693171940612936 0.3236751012125613 0.052755933881527994 0 0 1 +194 0 1 0 2.8970695996535842 1.3203227830648074 2.4866087995688972 0 0 0 +133 0 1 0 2.6178632265286743 1.0115830273791913 0.19081692003348572 0 0 1 +311 0 1 0 3.3683313684704523 1.1471203834722834 0.04523595785096113 0 1 1 +115 0 1 0 0.43505007353257874 2.385803272207332 0.02841287624716582 0 0 1 +4 0 1 0 4.3073950086925725 2.400627067573385 4.56127636601268 -1 0 -1 +151 0 1 0 0.6919123879927325 2.1849820555988084 3.5078472275384267 0 0 0 +306 0 1 0 0.5589151617318056 0.058029533314856774 4.427085995859885 0 1 0 +138 0 1 0 1.7147207261520883 1.4323880737092538 3.757478681577442 0 0 0 +110 0 1 0 1.3876397037618702 1.3714565550984217 4.5219172301432895 0 0 0 +251 0 1 0 2.788428291071368 2.3409448558940977 3.4381375025566263 0 0 0 +331 0 2 1 2.838525921735314 0.09442598845901452 3.3146265769160324 0 1 0 +243 0 1 0 4.489290143790526 2.26853729359999 3.7839844553823094 0 0 0 +156 0 1 0 0.23302160032454478 1.3603287603692662 4.342729568698205 1 1 -1 +32 0 1 0 2.081389395149717 0.4938421510915584 2.707994013583073 0 0 0 +205 0 1 0 0.09940021857353744 2.408012210772126 3.2074615425616426 0 0 0 +41 0 1 0 4.323708181823033 0.4958928465474822 2.525689303250374 0 0 0 +28 0 1 0 4.717322170568759 1.0215969335342936 3.32138298357052 -1 0 -1 +322 0 2 1 2.2029274368349303 2.0230576314539634 3.254975041225457 0 0 0 +103 0 1 0 3.4039994449255992 0.5284405133705601 4.809880920488395 0 0 0 +353 0 3 -1 1.1636351711418296 1.6849823280188108 3.628904996363181 0 0 0 +295 0 1 0 2.015582444660267 2.152457218882018 4.802270482662931 0 0 0 +365 0 3 -1 0.1355221924615853 0.6843479265638512 3.832358314244189 0 0 0 +98 0 1 0 2.5146420394624114 1.4050031824562241 2.965312255745623 0 0 0 +33 0 1 0 2.3626541269063335 0.301607887792709 4.126675184172655 0 0 0 +39 0 1 0 1.0864796756700101 0.14884263883618853 3.538403788545902 0 0 -1 +343 0 2 1 1.4514575528852092 0.7274022675751877 4.022000140293159 0 1 0 +259 0 1 0 3.655779855306037 1.3576945405765304 3.834017837247726 0 0 0 +77 0 1 0 0.8784812240014032 1.3079405939838267 3.865082861143354 1 0 0 +140 0 1 0 0.8162940643502995 1.1305386542609035 4.8092097458556715 0 0 0 +111 0 1 0 4.795245146003238 1.9956723305718642 3.9129401250192046 0 0 0 +129 0 1 0 0.34843108982968385 0.5298485948666217 2.8292148084141364 0 0 0 +317 0 2 1 4.124560425539725 0.9992026808502931 4.821938521772994 0 0 -1 +25 0 1 0 2.8922318837378698 0.9335539802277806 4.287158919025898 -1 0 -1 +21 0 1 0 4.585171090824654 1.3705322366558885 4.19496485298651 0 0 -1 +276 0 1 0 2.403137350597824 1.5009012449757657 3.808385508050605 0 0 0 +160 0 1 0 2.937633869764959 0.00248285164262807 4.155863012635541 0 1 -1 +308 0 1 0 2.007117640798801 0.07533937286437335 3.949461187876648 0 1 0 +313 0 1 0 3.138628385914381 0.06932121228333508 4.61254641181726 0 1 0 +71 0 1 0 0.7604830442534299 1.8783527414570997 4.529066129071014 0 0 -1 +42 0 1 0 0.8786351691021071 1.5220089570408293 2.909825736835378 0 0 0 +83 0 1 0 2.268823589694475 0.8105925806076607 3.3728322715236114 0 0 0 +123 0 1 0 1.7884920869805707 1.339956019375266 2.861286357841185 0 0 0 +29 0 1 0 4.460413120634612 1.661186434187469 2.731131826280074 0 0 0 +291 0 1 0 0.0035749317593865015 0.21166749654426853 3.275077495308186 1 1 0 +299 0 1 0 0.6601895850752213 0.7060682406274252 3.722602054061811 0 1 0 +87 0 1 0 3.635932620062484 1.4708618427874118 4.477899978536171 0 0 0 +78 0 1 0 1.5540100281849198 2.289959113070306 3.8245622090496108 0 0 0 +5 0 1 0 2.937548438619819 2.211877405174181 2.85571535820357 0 0 0 +95 0 1 0 3.105981604150784 2.188298914603185 4.094702761761116 0 0 0 +352 0 3 -1 0.11773003147587424 1.9458234584845089 4.811739126011424 0 0 0 +281 0 1 0 1.1502488869841234 0.20873030537461357 4.295523149721441 1 1 0 +206 0 1 0 3.330001486381421 1.53529174323865 3.1417824971878447 0 0 0 +241 0 1 0 3.878317992103332 2.023909280872213 4.783549131197242 0 0 0 +109 0 1 0 2.580544454574246 2.2025316047831676 4.264813345165653 0 0 0 +126 0 1 0 2.6463397268489866 0.7745950386723881 3.699331340328284 0 0 0 +62 0 1 0 0.10088965537315422 1.464964032622401 3.4200098453857786 0 0 -1 +145 0 1 0 4.7108240170803874 2.1614660538205466 3.070399886653731 -1 0 0 +354 0 3 -1 1.610893620580725 0.7512309895438358 3.571881076052697 0 0 0 +248 0 1 0 2.3260578668858516 2.409053529199307 3.878500098271755 0 0 0 +278 0 1 0 1.0565916295142963 0.21636101668521504 2.9280061580151355 1 1 0 +334 0 2 1 3.3217760513533556 0.20221074730138347 3.857259461716569 0 0 0 +344 0 2 1 2.145759202198284 0.8646312386735645 4.34482845102358 0 0 0 +84 0 1 0 3.310133712882211 0.8325063678401754 3.1928917336760043 0 0 0 +135 0 1 0 0.5746060669769325 0.007152134736939431 3.7081262585514363 1 0 0 +124 0 1 0 1.5924837125088054 2.3295502621690507 3.1555629363203055 0 0 0 +301 0 1 0 1.3559071869586012 2.104676990793624 4.2855408539569995 0 0 0 +221 0 1 0 4.025760501970453 0.12181323773082332 4.427152392469986 0 1 -1 +149 0 1 0 1.288517578213514 1.1078634671167045 3.0983488547366833 -1 1 -1 +235 0 1 0 3.722079255584157 0.731147796276342 4.106075812812072 0 1 0 +268 0 1 0 4.725777687386199 0.0696714424235374 3.965580233489741 -1 1 0 +229 0 1 0 4.9205143154909035 0.5378937212478773 4.686090920391123 0 1 -1 +144 0 1 0 4.391887063016131 1.3427912572926557 3.770425380327373 0 0 0 +142 0 1 0 1.8346060623646443 0.7517320991384026 4.677813188511546 0 0 0 +119 0 1 0 3.2188591291035764 1.8480317120563596 4.70754013191232 0 0 0 +218 0 1 0 4.590989187547614 0.7832518807186819 4.248448878177557 -1 1 -1 +269 0 1 0 3.83528197952535 2.2671443874151396 3.9458234070905074 0 0 0 +171 0 1 0 1.1367690782529518 0.30653599490724565 4.981237832751898 0 1 -1 +347 0 3 -1 2.730105013349213 1.5732651978450825 4.737616332834529 0 0 -1 +117 0 1 0 2.893231454879688 1.6327429583278301 3.809375824669355 0 0 0 +244 0 1 0 1.903054222598179 1.4266071609686257 4.248317450667845 1 0 0 +46 0 1 0 0.6110511992687845 0.9392825733011035 4.4718586456826115 1 0 -1 +97 0 1 0 3.9786678543088594 1.7659872954929934 3.352752402727882 0 0 0 +155 0 1 0 3.5064237015545134 2.2748461716495725 3.3907408576276095 0 0 0 +190 0 1 0 3.6257913177213887 1.8596172005909988 2.624582193387495 0 0 0 +141 0 1 0 4.133819851057611 1.125460792510254 2.8214638820568316 0 0 0 +261 0 1 0 0.48116423022710325 1.98166727716818 4.003063462271802 1 1 0 +92 0 1 0 3.749162681150054 0.5480152103582329 3.44882074629632 0 0 0 +327 0 2 1 4.261412399401647 0.5826170932678485 3.573292268629846 0 0 0 +337 0 2 1 1.6827282642347854 0.2789473832751784 2.9589468652224666 0 1 0 +45 0 1 0 0.31403607701825803 1.3800214560597042 2.9837533879244087 1 0 0 +200 0 1 0 1.995256276504289 1.4516800278315318 4.898899074068972 0 1 -1 +19 0 1 0 1.2925196386926214 2.321053353209675 4.936516373289165 0 0 -1 +137 0 1 0 0.8617630289962365 2.28834525235633 2.787630960107895 0 0 0 +127 0 1 0 0.19137038400231676 2.1505994041298755 2.5584316139464898 1 0 0 +9 0 1 0 4.475150825165361 1.5978909296640629 4.832730899627523 -1 0 -1 +122 0 1 0 0.6525439970988997 0.9547926616198447 2.731781719219051 0 0 1 +213 0 1 0 4.260400034205448 0.19910770741166325 2.9310219053551076 0 1 0 +136 0 1 0 2.2005511013729873 1.8455801462092951 2.556685426816697 0 0 0 +37 0 1 0 3.4251867503322573 0.6527991402153643 2.527078438582748 0 0 0 +34 0 1 0 2.9175944797670583 0.13654347040781536 2.8820983415866803 0 0 0 +217 0 1 0 2.6954995241935262 0.7710325900782893 2.5236360609937285 0 0 0 +250 0 1 0 3.6726666633431457 4.6018232175750455 1.320473043522378 0 0 1 +166 0 1 0 4.7009740947187035 3.7966019637038317 2.3031579729427096 0 0 0 +150 0 1 0 0.04748930775599636 4.455597613980116 1.8427292493854273 0 0 0 +368 0 3 -1 2.4584991330272654 3.7591217299647854 0.426379021376866 0 0 1 +339 0 2 1 4.156459282343587 3.061985537069849 1.9932515879322967 0 0 0 +340 0 2 1 1.9850368150824245 4.230758829154677 0.5294221302127794 0 0 1 +338 0 2 1 0.9865267877252728 4.5330122869142055 1.0314881718061573 0 0 0 +201 0 1 0 3.4754534022764494 3.0217470705506297 1.6935508350107573 0 0 0 +101 0 1 0 2.4842203411723074 4.89685402639858 2.0242798213421707 0 -1 0 +209 0 1 0 0.013989467358051372 4.330201393745349 0.7846247571577325 0 0 0 +168 0 1 0 3.6350006680732463 4.754122434939927 0.3223377232438807 0 0 0 +216 0 1 0 2.9114246475391328 3.433945937453107 1.8710068661397548 0 0 0 +203 0 1 0 1.3574269717949698 4.456732218277533 1.5387489126454328 0 0 0 +179 0 1 0 0.522179118267259 2.8689808625572804 0.9077030710981577 0 0 0 +181 0 1 0 3.6672727729190364 3.878549463830204 1.3381224951621222 0 0 0 +236 0 1 0 4.185529129045369 4.161219716693221 2.3595808103262947 0 0 0 +18 0 1 0 1.9980056628841183 4.320068243150856 1.6822915445402666 0 -1 0 +363 0 3 -1 2.235554720706489 2.906908244875693 1.036143254738836 0 0 0 +198 0 1 0 0.5887731317025171 3.6812050133593415 0.29825916210104214 1 0 0 +146 0 1 0 4.960647912886466 3.5092208739797943 1.7004652621516252 0 -1 0 +284 0 1 0 0.7836145638659848 4.548012471030345 0.34455457204719553 0 0 1 +207 0 1 0 0.7814740880134713 3.3714021164537535 1.118310228903454 0 0 0 +183 0 1 0 1.7161486342210968 3.5481236466130888 1.4041933001601494 0 0 0 +90 0 1 0 3.016201247291213 2.9587290353837226 0.5684151813116627 0 0 1 +159 0 1 0 2.232365423522552 2.6465053064946784 0.3759996466051841 0 0 0 +274 0 1 0 0.5881709093591322 4.080889794199071 2.280264861574092 0 0 0 +303 0 1 0 3.246061664307446 4.37314477200102 0.7856213092562913 0 0 1 +315 0 1 0 0.35327667038742755 3.029146608728807 0.0791450986650732 0 0 1 +11 0 1 0 1.8285612986193809 3.353968071719668 0.5643737651851671 0 0 0 +176 0 1 0 0.2508944492255997 3.000972330471306 2.0071913487423076 0 0 0 +304 0 1 0 3.0726902044877265 4.647914126011872 0.9996827940171641 0 0 1 +143 0 1 0 3.9352261868949907 3.898490778762382 0.7840306203684324 -1 0 1 +275 0 1 0 3.0573248045448427 3.8840876505181687 1.5573196095677335 0 0 0 +242 0 1 0 0.4226727582609528 4.737822957131883 1.387223661593226 1 0 0 +169 0 1 0 0.620846920150785 3.1839828246731394 2.426601824718326 0 0 0 +86 0 1 0 1.5665987066447504 4.978509835006031 2.1415023910919806 0 -1 0 +333 0 2 1 2.445920926535492 4.47766917410732 1.1358754296155358 0 0 0 +294 0 1 0 1.1981531521673625 2.8049885346916006 2.111987077826676 1 0 0 +310 0 1 0 1.9298476539189637 4.937913932158907 1.030730042471827 0 0 1 +192 0 1 0 4.108736026656326 4.6378045277922135 1.671217346737129 0 0 0 +280 0 1 0 1.8281315737488533 2.7749825164949944 1.6554178103691615 0 0 0 +164 0 1 0 1.3010575917308485 4.494402162669739 0.041752472824225825 0 0 0 +170 0 1 0 3.650388228932189 2.9899308003889966 1.067251647123858 0 0 0 +256 0 1 0 0.3339581189133178 3.843411762565409 0.9273636798830823 1 0 1 +305 0 1 0 1.025180078056553 3.006380787860488 0.2873424831400842 0 0 1 +321 0 2 1 1.3189364418815286 3.4276539374299775 2.089591655927524 0 0 0 +147 0 1 0 1.1461014570579835 3.8511084209677513 0.7525062047220421 0 0 0 +204 0 1 0 1.5112706244387488 2.8188173134434136 0.974908694884752 0 0 0 +215 0 1 0 2.343066001179666 3.1978495580526083 1.8659131264876065 0 0 0 +307 0 1 0 0.6571664267721125 3.1829219496620875 1.6123833084425085 0 0 0 +230 0 1 0 1.691826706532908 4.328533707881519 0.9338934645265112 0 0 0 +357 0 3 -1 0.9424908379877175 4.354374546920949 1.9334517447934154 1 -1 0 +273 0 1 0 2.7367589344269287 4.456539476093516 0.09405577094510116 0 0 1 +104 0 1 0 4.8224729965828805 2.532966442497679 2.359616149253149 -1 -1 0 +326 0 2 1 3.205170108738211 3.657764190269539 0.6059860569327459 0 0 1 +153 0 1 0 2.492658010069284 2.5549338497141174 2.359226108751561 0 0 0 +10 0 1 0 3.8691461518549306 3.358206982770836 0.5857517185532839 0 0 0 +17 0 1 0 1.4938724652414974 3.6267684500076256 0.6528239210562307 0 0 0 +172 0 1 0 2.222730505934896 3.9294618789141045 1.857472216603435 0 0 0 +187 0 1 0 4.12882439435804 4.373709089764649 0.7735950113473502 0 0 0 +246 0 1 0 2.819371376884619 2.580827865657106 1.2982493640886932 0 0 0 +175 0 1 0 3.6037043838950598 3.9741874494279883 2.1537260234843565 0 0 0 +233 0 1 0 2.4936360109190447 3.7461714899270047 1.0175156445748128 0 0 1 +197 0 1 0 4.513537428106752 3.877838158564245 0.23454380025260257 0 0 0 +36 0 1 0 4.75739982448861 2.993089291142829 1.2955298606828172 0 0 0 +157 0 1 0 4.577486719825762 2.5548383034837867 0.24912616922292966 -1 0 0 +212 0 1 0 3.0478551135031786 3.2498317267851125 1.1259910025155964 0 0 0 +369 0 3 -1 1.3808431418191394 3.7792710503646454 1.4792791648287753 0 0 0 +225 0 1 0 0.5765924415162327 3.9233350563958895 1.5040765765770432 0 0 0 +88 0 1 0 1.7263407212681612 4.0160590932504725 2.4625624343301684 0 -1 0 +180 0 1 0 2.957032676177556 4.366369702631684 1.8084697653437938 0 0 0 +228 0 1 0 4.007414662615488 3.641531116903689 1.6104136392925874 0 0 0 +296 0 1 0 4.449577191326246 2.7185852714293324 1.5770958226540965 0 0 1 +309 0 1 0 4.193664393097815 3.195309236798277 0.013138071944119596 0 0 1 +316 0 2 1 4.8850975785077875 3.1181643275208497 0.4988834454683537 0 0 0 +282 0 1 0 4.547534798722087 4.098196657638136 1.3514482711905391 -1 0 0 +223 0 1 0 4.070573701500224 3.0161107941779735 1.0525783618149982 0 0 0 +112 0 1 0 0.40619378501741044 4.581496953329872 2.4303817659862164 1 -1 0 +89 0 1 0 1.1309601445791022 2.8935782083274892 1.0807782088379005 0 0 0 +191 0 1 0 3.307024885373677 4.7782882192530485 2.015572284198738 0 0 0 +237 0 1 0 4.748120043170084 3.725460808317568 0.9522577175239182 0 0 0 +226 0 1 0 3.818166049029603 4.848449417426425 2.3600959505179793 0 0 0 +231 0 1 0 3.0678050795347436 2.5699968710786734 2.0631097277316033 0 0 0 +49 0 1 0 2.4740584898343307 4.766019947430475 0.6261200658844492 0 -1 0 +375 0 3 -1 3.3298272958028243 2.9611113328638377 0.026915061404104934 0 0 1 +265 0 1 0 1.84918915840028 3.334712440161601 2.324387380119898 0 0 0 +193 0 1 0 0.2324107132082972 4.337276389235211 0.15737812733136072 0 0 0 +318 0 2 1 4.741026775461015 4.950744240431997 0.09991000779517484 0 -1 0 +38 0 1 0 4.567313389179671 4.564683120735231 2.2383375090123745 0 -1 0 +195 0 1 0 4.276432197666434 4.550778719775141 0.01705180460738089 -1 0 0 +224 0 1 0 4.512998770219293 4.930686914076221 1.3263777979979738 0 0 0 +139 0 1 0 2.3611855680314053 2.5238664431540845 1.7400861072101907 0 0 0 +102 0 1 0 1.3179823049817583 4.634953041690075 2.4318467808197792 0 -1 0 +263 0 1 0 1.7520030887065592 2.504606951431736 2.4950818538423345 0 0 0 +361 0 3 -1 4.0568544056493225 3.3144731773008287 2.4514614954683602 -1 0 0 +298 0 1 0 2.2362905839125626 4.407255609537625 2.480448696532583 0 0 0 +106 0 1 0 0.017457347778004895 4.764685683823287 3.185502158549636 1 -1 0 +288 0 1 0 1.4779816621680442 4.314571361320767 3.1205014313954074 0 0 0 +320 0 2 1 0.07352439249274566 2.7314754874268874 4.438222837395544 0 0 0 +12 0 1 0 0.8318394760130385 3.0151110605041334 4.63155060662692 0 0 -1 +350 0 3 -1 3.745719265020869 3.633969589456328 4.863558280777614 0 0 -1 +255 0 1 0 3.7208321476425765 2.5430981712665512 4.92336590272389 0 0 0 +264 0 1 0 0.6187322774863372 4.591988430718435 2.99409822364528 0 0 0 +131 0 1 0 1.2363781535890241 3.269322268996143 2.994313299793769 0 -1 0 +271 0 1 0 1.547729125698992 3.0254742510247556 3.7969510998815252 0 0 0 +239 0 1 0 2.9727140078350547 4.458728462772902 2.589816182926471 0 0 0 +247 0 1 0 4.723447954180547 4.559587825067703 4.2844794465287395 -1 0 0 +336 0 2 1 4.30377897745755 3.6083219532870245 3.0751026181087915 -1 0 0 +80 0 1 0 3.9139985069210037 4.2026902501983585 3.687780496901057 0 -1 0 +351 0 3 -1 2.3310951879832125 4.1532874672431905 3.1481350248436812 0 -1 0 +345 0 2 1 2.1434754823364397 3.630858480566402 4.76111427884395 0 0 0 +23 0 1 0 0.1116865464821783 3.425858998459883 3.8315121362406237 1 0 -1 +372 0 3 -1 0.2013553605339663 4.542002104842189 4.709301425799447 0 0 0 +374 0 3 -1 4.681869085817003 3.6012197326454385 3.5343842160338768 -1 0 0 +99 0 1 0 2.0103450534211995 4.916636042614968 2.7722290840703248 0 -1 0 +134 0 1 0 1.2868072532982127 3.6027664980659657 4.834686879117821 0 0 0 +94 0 1 0 3.4969553288958197 4.191479164754045 3.257611668733077 0 -1 0 +108 0 1 0 1.069116967523645 3.8915098801681096 3.4741345909171617 0 -1 0 +116 0 1 0 1.7110071948939123 3.003308695307758 4.880957418376936 0 0 0 +47 0 1 0 0.6144957209089892 4.086034990124086 3.6421216730599935 0 -1 0 +177 0 1 0 1.9967818019099437 4.223293250522419 4.123286584622672 0 0 -1 +154 0 1 0 2.9241663178555766 3.006235461853767 2.736488872218668 0 0 0 +272 0 1 0 3.6421402582975864 3.397998711089007 3.420005877158591 0 0 0 +292 0 1 0 0.9456777627899714 2.854242407065964 3.6713102734015375 0 0 0 +348 0 3 -1 3.602827568682842 4.841299797785864 3.0727220886411226 0 -1 0 +113 0 1 0 4.09715162476059 4.796283984467532 3.6675472388615478 0 -1 0 +76 0 1 0 3.0081758606102404 4.473089701483304 3.4619137215698026 0 -1 0 +178 0 1 0 0.1695480127810721 4.181202627391224 3.659798577645965 1 0 -1 +82 0 1 0 4.308822049710188 2.5505905907422872 2.8631988472742047 0 -1 0 +358 0 3 -1 3.000038253202886 3.679700145601949 3.1009139360007207 0 -1 0 +302 0 1 0 0.8272609584103479 4.003958148100786 4.445729848848656 0 0 0 +13 0 1 0 3.9722298533039946 4.5610720224823025 4.234031447999139 -1 -1 -1 +72 0 1 0 4.772965920074378 3.1606932108115786 2.6365859592135936 -1 -1 0 +245 0 1 0 2.197144845045862 4.9556893549684515 3.4030216646163236 0 0 0 +234 0 1 0 1.6678259516197003 2.9505643678051627 4.390951365364965 0 0 0 +300 0 1 0 1.6328211445692586 4.819932075478693 4.586452176846693 0 0 0 +105 0 1 0 1.892439317939264 4.041167636776589 4.848755937425436 0 -1 0 +254 0 1 0 1.9694419982366302 2.9792140111735144 3.3447749736668477 0 0 0 +371 0 3 -1 0.7643208588903881 2.802514146046753 4.3289561641866845 1 0 0 +262 0 1 0 3.7153807374055208 2.9342246849719764 3.2753284900477935 0 0 0 +266 0 1 0 1.0036319050407299 3.924029109027026 2.765363860481497 0 0 0 +31 0 1 0 3.2842646038163683 3.4104333522804806 4.272304684998637 -1 0 -1 +267 0 1 0 0.3478333275641798 3.7705819143047163 4.485021488086793 1 0 0 +290 0 1 0 3.1115982282440853 2.9295831819273586 3.5626146396041767 0 0 0 +324 0 2 1 2.771587476254712 3.9414271647783257 4.230821042895357 0 -1 0 +293 0 1 0 4.214234541195906 3.262981149206049 4.090936501706094 0 0 0 +323 0 2 1 2.8122245885603756 2.580830565080179 4.80431964625616 0 0 0 +335 0 2 1 1.4810951840990771 4.639126972487052 3.6567291514204365 0 0 0 +270 0 1 0 4.9358344334018485 3.549094534023696 4.864412320210946 0 0 0 +173 0 1 0 3.117530919934732 3.684181958243471 4.8516982526619845 0 0 -1 +2 0 1 0 0.3021690885489914 2.659446894836416 4.0367641920770465 1 0 0 +210 0 1 0 1.1142397715035879 4.4046148625915365 4.3150622960514795 0 0 -1 +125 0 1 0 2.7530308932307075 2.8955411122664563 4.086365750770761 0 0 0 +214 0 1 0 2.447949785773993 3.4411883728706667 3.42533264878368 0 0 0 +258 0 1 0 2.4686303390297684 4.538868481224538 4.639944166832721 0 0 0 +93 0 1 0 3.788036472073458 2.8805091146305495 4.207262328768323 0 0 0 +24 0 1 0 1.1758426635439467 2.95987521811849 2.7491364787864434 0 -1 -1 +152 0 1 0 2.4635622448768637 3.071194152656136 4.899091259343484 0 0 -1 +367 0 3 -1 3.1644043863749083 3.8654934982056908 3.8521845414359994 0 0 -1 +249 0 1 0 0.8478947214959758 3.5141550038968123 4.043189817151755 1 0 0 +252 0 1 0 3.6043032286195786 2.7211428234421744 2.6278508560867944 0 0 0 +227 0 1 0 2.617074822292329 4.356852917720359 3.706994190844186 0 0 0 +120 0 1 0 4.569034188524726 2.9098756991392434 3.6702905357629025 -1 0 0 +342 0 2 1 0.04291508283574702 3.9189332996339656 3.0034347187387493 1 0 0 +370 0 3 -1 2.5035109101131465 3.367965526536857 4.050360185006087 0 0 0 +283 0 1 0 4.572823838429256 4.030918642578753 4.393803855463066 0 0 0 +279 0 1 0 4.173810766411638 3.812475242565163 4.301379932392817 0 0 0 +314 0 1 0 4.4933290428810615 4.490246675016839 3.151051409399978 0 0 0 +297 0 1 0 4.726982536341496 3.1414792583129945 4.429739330385717 0 0 0 +341 0 2 1 1.8003373130876947 3.4781354307892713 2.899858395353646 0 0 0 +312 0 1 0 2.303209904055366 2.9656095134210108 2.8204198689888864 0 0 0 +373 0 3 -1 3.565365933175215 4.286825401805136 4.955585318174815 0 0 0 +91 0 1 0 1.9018724274489394 3.9228474975062673 3.538137694177671 1 0 0 +260 0 1 0 3.349946104166285 4.305285613626282 4.371436905009239 0 0 0 +286 0 1 0 3.4730325337603043 3.45134046911952 2.570996040716748 0 0 0 +277 0 1 0 3.893007381012101 4.253386877442837 2.9065935101973173 0 0 0 +162 0 1 0 1.6103352066101007 3.6182097268745603 4.028619192357339 0 0 -1 +148 0 1 0 0.47140654288437406 3.361602614222439 3.2833125638624368 0 0 0 +199 0 1 0 0.45641137753428773 2.8928189398052093 3.055011726454653 0 0 0 +59 0 1 0 2.603235557919487 3.7590996377530255 2.60080520480327 0 -1 0 +240 0 1 0 0.03755253175857831 3.8996655727813736 2.694428316121082 0 0 0 + +Velocities + +189 -0.32037987935911505 -1.8545793275796412 -0.3389478887810303 +107 0.3468735347167663 -0.2955882500703209 0.7493971092549213 +253 -0.48452738488616026 0.9567078415781696 -0.25617231541775964 +163 0.05392635484651058 1.4098736248940131 -0.9551003900232069 +26 -1.617929859419785 -1.7202842142734436 0.11135553428439426 +27 -0.29551994504699913 1.1370741945626326 0.41194386832776464 +56 0.16870751745665893 0.5465328233065259 -1.6661100877128618 +167 -0.697267953141008 -1.9033337525745169 -0.31395781199009537 +364 -1.400949260052127 0.7984877976989593 1.9724238551125475 +61 -0.07154629291712847 0.7516744652931485 1.9678922707455193 +222 0.23902932306419583 0.792970583016431 0.1021330637484922 +332 2.0928445946235548 0.5309926353418448 1.5604773439112944 +1 -0.28287953739229227 -0.029534368909520013 1.0355343887239448 +319 -1.0849228432051101 -0.23080330071554434 1.1791104359270128 +53 0.9157229929216929 -2.3903991179046433 -1.5736773702897364 +68 0.17385350731976662 -0.30161653041932146 -0.39368426363389786 +220 2.5382960064880953 0.2591819621699902 -0.624753681550235 +44 -1.6451203378616364 -0.9239543258332603 1.132412983542016 +55 -0.08195646053083308 0.37533078137864123 -0.36860166560573604 +362 -0.4446005218467803 -0.13521669762509536 -0.3021189485210508 +165 -0.3037978228853421 0.48479699556498196 -0.14302405851335173 +60 -0.544505644947158 0.17484779434446918 0.5635832746819489 +202 0.40080169998085574 0.6655121110868133 0.4354226901236873 +85 -0.08059699858936498 -0.02186022407318814 -1.2385638610310603 +73 1.183399433007768 -0.5106063831888463 1.1937543804310102 +96 1.2595243589106713 -0.013906208472664688 0.4458849845729422 +30 0.5511059698244886 -0.6732784212785152 -1.0116331060036698 +67 -1.9023068008435087 1.0951572746798406 -2.0479882413103634 +349 1.4237209300898004 0.30323664052562727 0.19232435921291324 +132 -0.48867767658730155 0.09532364712318463 -0.42068909019073003 +328 -0.5663127928136679 0.37616782849718877 0.4297794152083855 +161 0.7703317540205181 0.6774326958924123 -0.3026855763654866 +185 -0.023401903290328513 0.2511657303041649 -1.3088367457780965 +219 1.2737339284351616 1.028957623073161 -1.0554246534519245 +8 -0.06863366403807239 -1.6556315386699292 -0.23974376153400073 +69 0.1565812662607089 -1.2971845847251846 2.613897358932758 +3 0.8019572100951472 0.849648794229192 0.11213159968547601 +7 0.25284839489562 1.491377162402211 -0.0841367270980815 +329 0.6351810405065701 0.25238586135592256 0.8556983715790075 +174 -0.5484640782672199 -0.14739645457730516 -0.17643270798617747 +20 -0.7181391568279812 -0.22546080581710778 -0.48698419533440007 +57 -1.6318504400975429 1.5493172313080645 0.4266085421953033 +325 0.061765643056371416 -0.0060236030310999444 -1.8483177209317203 +40 -0.6621905409370356 -1.2253334788867594 -1.2773646990414835 +51 -1.1432987328508335 -0.3034502864840843 -0.09847735528475197 +54 -0.8020221565243566 -0.0015208681811410135 -0.6007775452455262 +186 -0.33099994137011096 -1.131278148973123 -0.7879194313488349 +289 -0.9130924589993602 -2.639634662624726 0.09890031992023729 +75 -0.8396764454636105 0.15798357570063332 -0.8477685915025622 +48 -1.154914948896169 0.8466957349051685 0.8313924234437813 +66 0.654607723623097 -0.41464584514495073 0.3609107252534362 +52 -1.0586581647402704 0.5087601698575234 0.021025900110182197 +158 1.3322996283718878 0.9345320009185999 -1.0328661925117097 +330 2.4383540085998128 0.9866744795842981 -0.275795472471459 +359 -1.057214010787649 -0.4364851954003303 0.2310265064750756 +366 2.636570585206883 -0.3884825767632163 -0.7217671918096393 +196 0.657853761584953 2.3775812813720982 -0.5436441623798505 +128 1.7541843513017408 0.7453187167218113 1.2179212772328478 +118 -1.59209911141696 -0.07364502396325014 0.7936184535797746 +43 0.6237868379926791 -0.5784415822689247 -0.5803521937322204 +184 -0.05277645327535091 0.45761568472864167 1.6427093411481584 +360 -0.5648148491925004 0.5433424409581341 -0.49847380874912023 +64 -1.8023545518136344 1.2913349276666013 0.12717943337914392 +285 0.5736914459809833 0.5401354659943393 -0.28034343867615685 +58 -0.36569579675665037 0.07239846277520536 -1.1013654261669847 +257 1.552014566999722 -0.27948696231751907 -0.19503371520168367 +356 0.7682896155635832 0.8280820699807006 1.3752233131249456 +100 -1.0184796009907435 0.4605961843295614 -0.704442145669238 +121 -0.38173838277886674 0.1959729194377248 -0.339617988229434 +130 0.22178015355919917 -0.8675864036237741 1.1703244653493718 +238 0.8237981930471431 -1.5493771904591997 -0.24060309819018327 +211 -0.9664235140040581 1.0444826618189473 -0.7001322318514289 +208 -1.1981085340301125 -0.7027352973576034 0.5185067521926653 +63 0.08370101334493428 0.12218456306348915 0.049185735912721115 +22 0.30188358915891 -1.3418299707096835 1.1148332854869305 +355 -1.6654429777296822 -0.6945382472719116 -3.1744183147606044 +70 -0.08375793026685956 0.8125324795960583 0.6134941598297233 +65 -1.1244245803291022 -0.9361082187681131 1.1324057744996805 +182 2.412056789726208 1.2486258334638396 0.20473073207056972 +188 -0.37468794463000277 -1.2934293589793593 0.9691264102882897 +35 0.6406020314671873 0.49864731329733636 -1.7724168624616223 +6 -1.3537464971191604 -0.20927181650199864 -1.5167116889460597 +346 0.30631209820842736 -0.7471003495751499 -1.6323676491850723 +14 -0.7975238331233878 -0.2181017429474187 -0.632027008590476 +15 -0.32436974395845447 0.3065062429708726 0.4060390267782001 +16 0.07956951912756546 -1.0048987407630834 -0.36004318524122436 +287 -0.5959260893373665 -0.1854042515514421 1.0130704394383132 +81 0.9472416915759921 -0.6006345374524827 -0.24694710732081407 +114 1.525743657374327 0.04312008580379893 -0.7588343858546425 +232 -2.2017540835769154 -0.886310786043688 0.20387430412267815 +50 0.8784604270190535 0.0011080801156705886 0.5856470163400485 +79 -1.071058278656874 -0.006257268621159592 -1.4196804350916041 +74 -0.7639977049209028 -2.6659874189534594 1.1890689974611952 +194 0.865474812438892 -0.5155997613354885 -1.9207758859429034 +133 0.38706903000333437 -0.9520916056321852 0.8541781745856745 +311 0.5008213609458084 -0.07623241918788479 0.5610893061215554 +115 0.15935870900356716 -0.882694140477557 0.6905790810816846 +4 -0.9205904536679229 -0.7764649294266535 1.1104783428010845 +151 0.6813124939707291 2.326468648189791 2.249632338275329 +306 -0.18710153508281002 -0.3863205254514582 0.5475210927789089 +138 -1.6956647006569652 -1.151952653064399 -0.554024796221634 +110 -0.39629567812811123 -0.4259264444322932 0.44254068082874265 +251 1.5245566481568409 -0.04190307638919144 1.0804352846040617 +331 -0.9795637705792982 -0.02610365622846786 2.5830426945375367 +243 0.45087912305781325 -1.355797680211566 0.4004209604371337 +156 0.651222966601892 0.4174674307414501 -1.1666370354607374 +32 -0.5950276948154204 -0.8393986824943023 -0.7189711727165591 +205 0.3776877212460598 2.3109152071487427 0.6245197680183613 +41 -0.9842633414094011 -0.8809111823971685 -1.2837012228899978 +28 0.18078855219728557 -0.13909035935407538 -0.19886968753018486 +322 1.1176391816577027 -0.8011078770573403 0.21746550449618066 +103 1.2549030850211156 -0.8081818878065185 -0.27748891746378196 +353 -1.5194865665198567 -0.5579729356084093 -2.0775398105335463 +295 0.22655387403623733 2.9916385717293763 -0.43349783976321543 +365 0.16554102729886308 -0.4745928131492317 -0.03803439542786842 +98 -0.4618022678057757 -0.6029234473896345 0.6725224603911311 +33 -1.7236841295071144 -0.3068526804764886 -0.20580599603270883 +39 1.2772591923409662 2.1497013660971303 -2.56219215061276 +343 -0.2927424336003138 0.9775658544657785 0.2011269771824622 +259 0.24216001573068768 1.8155597582018805 -1.0537870123381061 +77 -0.1324758963152601 0.38342267896154975 -0.04929261328552273 +140 0.38183354460675634 0.6132141691538076 0.442562890919203 +111 -0.8964279708048736 -0.8793266310917598 0.00861098502364186 +129 -1.1765926408865686 -1.0237122510048935 -0.27213291220171076 +317 0.8853758404732577 -1.1912915511525315 -0.2565808529702654 +25 -0.41258107389034077 1.5982277861548693 1.2605935861477815 +21 -0.9069821227261771 -0.4677412632169774 0.6873716589735867 +276 0.25907509449423294 -0.11278777358289174 -1.2598969980105488 +160 1.1310609970707983 -0.7180501046994335 -0.5753626368090448 +308 -0.5407967057189286 0.6940578777081593 -0.37557998557357736 +313 -0.7130409942586629 -1.681937934547073 0.1358119949043896 +71 0.667183519460017 0.3282177658608256 -2.7413950424049682 +42 1.1047543258650714 -0.8068929160871195 -1.2899950214337368 +83 1.7828282628616605 -2.004816043371422 1.2952692225001963 +123 -2.9004360498301707 0.9646317600839549 0.18131057792974167 +29 -1.3652408424575189 -1.009704628734932 0.43892722829821035 +291 1.0627401897900626 0.43489566519198664 -0.18784491971683132 +299 -0.26688361561559937 -1.6102635970374153 0.5079799986210346 +87 1.4011023956088358 0.32714083881834366 -0.7531211236916443 +78 0.1425369548627805 2.6493781694133145 -2.22950555437911 +5 1.3052777281483532 -0.9535145036740771 0.2654363506534612 +95 0.30567181776721686 1.1163897147224524 -0.5532613677186452 +352 0.8465877298612667 2.2107064094824453 -0.17116328451251087 +281 -0.07871622308682222 1.0856250342504348 1.1051209599756335 +206 1.0416994819210157 0.5672831409877002 1.6724372809390164 +241 -2.2941651916087253 1.9444171652571998 -1.2578222836508794 +109 -0.050748691911046466 1.0000918986528329 0.2015940504869988 +126 -0.8786798841416771 0.8497095311402493 1.3946275611382846 +62 -0.2164244387038406 0.8723775902261287 0.26553621918966663 +145 0.46930481759942066 0.7693145659657128 -0.037339037750325446 +354 -0.2098961088460406 -0.953758291681559 -0.403997005612617 +248 0.8565801706475304 0.8235709205269733 0.2955326303618714 +278 2.048784561206607 0.9072129491727593 -0.7581517712639704 +334 0.456898611136665 -0.02509977329095233 -0.9459879096811896 +344 0.8456571762985342 0.4633497822367495 0.8285234460659753 +84 0.40873630171375086 -0.18526388419408432 -0.06542872798585272 +135 2.013756885383165 -0.15612654092659334 0.5349019283627415 +124 -0.5212908614174182 0.7685855427870887 -0.12228979391994671 +301 0.48855352634840166 -1.2406754622002991 -0.08431072249939792 +221 -1.2260526209132598 0.7697110508869727 -0.5542459265345273 +149 -0.2107348825202514 0.22490448892353535 -0.5734046758064464 +235 -1.4630566299287793 0.5127970335856704 -0.6004850345593133 +268 0.5661524540264498 0.8991784804895261 -0.005988273242503317 +229 -0.8584020647535824 -0.25056183768697937 0.6902063254564769 +144 -0.46291169716408886 0.5111551390891086 1.1711664705383293 +142 -0.41757592752156836 0.21324275041440427 -1.2569024662297255 +119 0.5340652441413375 0.3164807148267359 -1.4743337919796309 +218 -1.0392995481658593 0.26241789884459166 0.7357941801129729 +269 0.7678562785093035 -1.9170146057209667 0.7772238925448399 +171 -0.4969590584187104 -0.596095006981118 -0.10809390580507182 +347 0.8436056567675704 -0.5476600028413069 -1.3395269452969696 +117 0.8095357513993098 0.14859594003753698 0.9460359145433276 +244 0.09898637700604154 1.9714533954146634 -1.2087777946497995 +46 -0.3820366350713078 0.32336042217403327 -0.9227515950377472 +97 -1.7189935642347989 -1.5765158910467392 0.8063603306333886 +155 0.36326503759730183 0.6548052876982512 1.620348248115881 +190 0.7808450444577382 0.6656743687730368 0.7660461630595695 +141 0.8693957537631642 1.3523683215558047 1.2211970208170133 +261 0.28442666039427394 -0.32073173144758543 1.583985092925248 +92 -0.7345577665025577 0.016229401856888797 0.3571609110744681 +327 1.500595660011905 2.328516151626208 -1.0480316997941985 +337 -2.026559556886336 -1.0216544907269516 -1.6983898702416695 +45 0.7296312803407121 -1.3823715012836595 -0.001888700820258285 +200 -1.5125957105846846 0.21807330099838138 1.0211540585201806 +19 0.20095464395150656 0.876426388172185 1.1335083283234622 +137 -0.6544379260019478 0.3996572012861071 1.5228974656760543 +127 -1.1436027430113194 0.5730519130732912 0.008333961575108378 +9 -0.42750265926865316 -0.5165855700703796 -1.0737944161142243 +122 -0.3470793076769018 -0.34708198826094805 1.1255388427785304 +213 1.835703281018243 0.8847420691344063 1.6530535667302775 +136 0.43589519224927076 -0.020299972081583365 0.747684835626366 +37 -1.148425632972328 -0.00642821348241146 0.9184878168029185 +34 -1.4186726525732596 0.4531027449345908 3.0048537054226916 +217 1.915040996479654 -1.732542284842007 0.44651597348176714 +250 0.5621559470017148 0.4079874575005626 1.303044522453095 +166 0.7893755845011986 0.43466399248524873 1.160997706352551 +150 -0.37696033158301806 1.0863822179294413 -2.078278052131126 +368 2.210878478411088 0.38296799766548134 1.0444089386311377 +339 1.4973183477847594 -0.7580085092724449 0.11364576051168895 +340 -0.3257916484956234 0.0813898939784988 -1.1040698774178863 +338 -1.0699596370620241 -1.0120808096694316 1.833778928251108 +201 -0.23917814210651525 -0.03394921352802534 -0.9718396302546122 +101 0.02844691201485288 -0.6506751616189366 -0.03984644326365714 +209 -0.9153220207336246 -1.5186563759968537 -1.0205115163511242 +168 0.8206949111387913 -0.4245501681797143 -0.7447438734980448 +216 -0.43707878972381015 -0.5291981706606685 1.1132283784486239 +203 -0.8017105024810447 0.33314329697566913 -0.5162714638483775 +179 -1.8007654528739871 -0.4670778758036332 0.23458485261416823 +181 0.5555468330191876 0.25910041403756756 -0.3316347961383419 +236 -0.8012681820545456 -0.5344531291884258 -0.08163768189012148 +18 1.9065170422999271 1.3540018286545739 1.1100685009732258 +363 0.2827677278721721 -0.3503610814118505 -1.1797786001961337 +198 -0.41882935960212925 0.8056124759016018 1.8622528356092367 +146 0.1474073717281029 1.699648861146042 1.0589630664233587 +284 -0.407232387684036 -0.11824885032252892 1.360138277573833 +207 -0.3298855435595792 -0.006765921450541862 0.2769759320227882 +183 0.06337061105143588 -0.48367890148177073 0.5050176946201105 +90 0.3184428577661019 0.9432678954749032 0.8928827031242041 +159 -0.5105050211567479 1.9463424976868646 0.32689317369973153 +274 1.3982542011798467 -0.27549013447341186 0.8666525994391387 +303 0.4978908819019676 1.2437279316470162 -0.10162615038846663 +315 -1.0164590430058362 -0.03269995674634833 0.6833370972687541 +11 0.3622774648719034 1.2005608993134556 -0.7399401748200916 +176 0.12717484954669636 -0.1874453653833894 -0.5308623715664049 +304 0.06155270894330727 0.03603614146908593 0.1329179976636057 +143 0.26847678011717396 -0.3583390732477076 1.7051362686528129 +275 0.33838601766084075 0.2950617938645766 -0.09418120915803613 +242 0.3073988441018431 -1.8086100776648917 -0.42916540436389544 +169 0.14874973578643622 -1.3199432376066533 0.7087936697125053 +86 -0.5239538553467294 1.3403598560019885 -0.2254748591815899 +333 -0.21788548307133926 -0.7324156012520107 0.1425582466646254 +294 0.6218138152225486 0.21868791299154444 0.8803681463521291 +310 -0.5282668664359558 -0.46220541267842175 -1.0627944759334662 +192 0.8557275799833504 1.4638168802662663 -0.6584377242390569 +280 -0.09918465909102868 -1.0727882372767648 0.1410570176454262 +164 -0.008014496582185324 0.5157698128135756 0.46160123613104664 +170 1.4950197089701442 3.424612541884591 -1.314342167688277 +256 0.06221965545636296 -0.8559730346941176 1.8154628407737485 +305 0.30469481973038853 -0.03817030163277567 -1.2365844444400544 +321 -0.3202998744384521 1.2283112281779653 1.823191101425018 +147 0.5820565680991441 0.36342122556604795 -0.2612619382618049 +204 -0.008409550806661968 1.171175221811852 -0.2917927123166712 +215 0.46773636429619847 -0.41233509768776383 -0.3263056272548713 +307 -0.07908782350310187 2.164168859748066 -0.9789469165714956 +230 0.8852323551048787 1.3865626751983875 0.5628005219581595 +357 -1.2576148747792928 0.03308240972261274 -1.5084612011551441 +273 0.5606862174415299 0.5124906231131765 -1.3826770688817982 +104 -0.10795450062494798 -2.791328634167407 1.1620113801205978 +326 0.2071603034556735 -0.40909146487793213 -0.896060232043604 +153 -0.45260595455551345 -0.3277317537659357 -0.13439736779275077 +10 2.7196279602592033 0.48777338008418347 0.18107892198434122 +17 -0.8413852713221374 -1.1275004082730866 -1.4487171872195708 +172 1.2930259795119698 0.14131239886642913 0.5257996818615889 +187 -1.8173970648752318 -0.28759466349432383 -1.7755081990758885 +246 -1.0149452724155728 -1.300181341724771 -0.976220324472834 +175 1.0435736653798136 -0.6355996329080813 -0.6337776368224881 +233 1.2293937984927237 -0.905059289715439 0.8454304677995911 +197 -0.22773405357421111 -0.7410347767485816 1.126629391166937 +36 -0.9705558369369324 0.33702279037561017 -1.064377132550976 +157 -0.05834073541273116 1.2094227269795201 1.0222926092654627 +212 0.013232248632983099 0.9236140505707409 1.261304943429413 +369 0.3957125732954573 -0.5984876528890495 -0.6144811927659548 +225 0.6396689699095744 -0.38272720995061654 -0.691909782028554 +88 -0.4143004926247838 -1.2942068299775036 -0.546740943598064 +180 0.04523325776155317 -0.05945543703566272 0.47333576015888584 +228 0.8374889207264015 -0.5976967042166498 0.026290439671542307 +296 0.7603590023814826 1.798573173748085 0.09638254026567694 +309 0.26044897388340504 -0.6796155915915322 -0.5500226485278027 +316 0.7809829226880511 -0.9911482041657326 -0.5982510531417577 +282 2.813391256963532 -0.7389301719245412 -1.317705839191937 +223 0.42512280312483486 0.39540872471182203 0.1359105288746332 +112 0.3204862890962222 -0.5808767554272332 -0.7511556946241044 +89 0.30853654184225165 1.4220670510027051 -2.1642949762748867 +191 0.20906754014854564 0.026904283363689382 0.39272994979179504 +237 0.8114113274128864 -1.2134195876500447 -1.2542604312044792 +226 0.05086738376609842 1.9155895254467763 0.5909889856323195 +231 0.12002855122048815 0.02004736909508279 0.11081960871345642 +49 0.03966621608393742 -0.8770492944397817 0.8690111691798925 +375 0.9491508595606913 0.58883338187899 -0.3157968091718698 +265 -1.202404469596496 -1.5086124324682335 0.25807518315254696 +193 0.4146818842856516 0.2647601963673656 0.730972113530503 +318 -1.8694737066425302 -0.761959044368273 -0.7096835210855107 +38 1.4229802153283508 -1.36140802862721 -0.8467736118278119 +195 -0.8905011743693773 0.7285788649892662 -1.1668737157134021 +224 0.27425001045805447 -1.4123472657200646 -1.3276958804580687 +139 0.17701044314199935 1.2384991288614933 0.707649077312958 +102 -0.49170524562266826 0.9342585115109375 0.4160956308860243 +263 -0.7682667946507794 0.5411620297128601 -0.14243425461628567 +361 0.4874350807265555 -1.118941056651683 0.4602449779293269 +298 0.04321754250044474 -0.15386666534573679 -1.0460367336946477 +106 -0.3645858676063196 -0.008671871254614383 -1.0359720474498813 +288 -1.275865518017513 -1.0371041509619956 2.212604082967035 +320 -0.377092487120416 -0.5974519455300853 -0.22840203412473642 +12 -0.24251540706937524 -0.1402656612039157 0.2434885714233267 +350 1.1678886543574276 -0.45657425471012764 -0.2662438133234255 +255 0.5964565878330671 -1.3463852257768025 1.2786356338266742 +264 1.6104915551559742 1.8273229008351088 -0.9803231882687425 +131 -0.8634566501958852 -0.3775110787982123 -0.4297068950811986 +271 0.022978578950211624 0.1537857816854949 0.41326352661226756 +239 1.1101812509452746 -1.0996094771595475 -0.5405483522697302 +247 0.366683557977341 -0.40591154743605157 0.3199408653703203 +336 -0.4204708954513029 1.1245949705896916 0.14059678344621293 +80 0.7468471903560799 0.16912425014962304 0.9566573830732898 +351 0.07048942766011615 -1.3084119272893855 -1.2549170044600249 +345 0.7055909005169286 1.5707280888607302 2.170499205441559 +23 -1.331563904677986 0.7554001948296128 0.6695113635015243 +372 -1.4331361061806305 -0.7926393821400735 0.5238882724688806 +374 -0.825494743089428 1.5035094266963547 1.4373542115371403 +99 0.27578368704586625 -0.6711803184635016 0.5730720207589178 +134 -1.1904489259413122 1.5650039062713583 -0.4846706283407857 +94 0.9633444927305759 0.47059281614148496 0.1502870940642896 +108 0.26924336654778097 -0.21911864351862886 0.3263366196031549 +116 0.6191352094412962 -0.7085456797691245 -0.2795453344586494 +47 -0.81507518857967 0.5002361185490026 0.1633824556071923 +177 0.9242227597235199 -0.9239301127385003 -0.6516754024576575 +154 0.36428957391605954 1.0522574437068934 0.47589301799726774 +272 -1.0875391115124131 -0.5442742977183277 0.6272696858994802 +292 -2.3018786976959547 -0.719034234609397 -0.3976068240680647 +348 -0.7074103387842228 -0.0767390137549914 -0.963801034994381 +113 0.0030054733602942266 -1.3950743743038958 1.867999225141668 +76 1.5225615991122337 -0.6220818112064357 -0.15128024907071225 +178 -0.9036534708064256 0.27189024225898883 -1.310213331624685 +82 -0.42289693438412584 -0.022877233686993723 0.16757191063647395 +358 -1.084491323240786 0.309617438081422 0.19221704824216043 +302 -1.0553000696338095 -0.7753368184729383 -1.6522442141368283 +13 0.845507404222631 -1.1655430839109384 1.5339500987877546 +72 0.41215075448394733 -1.3387634915542448 -1.701720507581037 +245 -0.34884333851309834 -1.599607748547356 -0.08374549876035683 +234 -1.8167563819027162 -1.1826697278339255 1.1323923705559067 +300 -1.1492146391765459 0.2483076272654141 -0.7388669957162219 +105 1.860014533900312 0.7148855192575438 0.950732381457607 +254 -0.6941521238655652 1.3286658685743733 -0.09912945530019143 +371 -0.03007825734775041 0.17488055593531995 -0.5660994145015367 +262 1.1816791457721831 -0.2527818393194355 0.49550489641014006 +266 0.7025922230527104 -1.3294406800025553 -0.610134301603067 +31 -1.015719812353546 0.699060801172419 0.9860089149766915 +267 0.38654355926704703 -0.1264135931208901 0.1337359898717711 +290 1.0106897270034887 -0.6174340186836875 0.17719301929654596 +324 1.5906920275906873 -1.4359983538965082 -0.8582706716695392 +293 0.9982234808302441 0.543717193528767 -2.062895773562878 +323 0.17420566156018166 -0.8499393438675438 -0.22821645799213797 +335 -1.4047556653990858 0.2558049214304259 -0.20559797586706147 +270 -0.6321821769779428 -0.4192527616747393 -0.8336466516152516 +173 -1.454149943391539 -0.7091620301715705 0.1032726804162123 +2 -0.13160744352132697 -0.8530661810441926 -1.4081064081887786 +210 0.005780708280217166 -0.1314037001754253 -0.2650271980684433 +125 -0.09249384396894937 -1.1079543363063478 0.5855224371258938 +214 0.5201018860617912 1.5761782081656692 0.035238788848664875 +258 0.029258855657727026 0.9978609610551674 -0.14936661862149073 +93 1.3599706012850858 0.5138196159795498 -0.5479657931310508 +24 -0.36848780789234786 0.5502667846431184 -0.8219909931831206 +152 1.443106679308555 -1.5881504830897177 0.5251248932583428 +367 -0.8318296913109121 -1.0659118655536617 1.4652035277005255 +249 -0.7272493937720567 -1.0554246074355031 1.9106526180491246 +252 0.15824074140715003 1.3574893627297528 0.849299710142209 +227 -1.8919742394027095 0.35022746838873914 -0.8716265785931281 +120 -0.571575152303992 -1.2924338935753592 1.6398975078681308 +342 0.04170661506757478 -0.2554943852733288 1.2031995777997446 +370 -0.3474083481747786 -0.8268210706239789 0.11710668216712806 +283 0.34259631654561 -0.638600994930959 0.021713727624721322 +279 -2.1091380649692364 0.5683510572154551 -0.9091778578938636 +314 -0.43834173946024524 -1.6956466398316619 -1.741986521654538 +297 0.9805330343066516 1.9653989039948883 -0.06267823210622318 +341 0.6436707559323198 0.17740641651830055 0.7923601196148916 +312 -1.4662653378890305 0.8912504951091632 -3.2848373130153616 +373 -0.3818721621040007 1.1303100555115857 1.117083484179991 +91 -1.0354512700928402 0.7952901789933705 -1.3376868649958413 +260 -0.7142984506137289 0.4503083150384257 0.7493938136595016 +286 0.12497815933423412 -1.4185031297528174 -0.7147963619923647 +277 -0.04273979718334558 0.6681668442079539 -1.627755052910915 +162 0.6571166297602984 0.4444526727563672 1.4878784469904562 +148 0.3177520883327088 1.0855120103126268 -0.6584725796441712 +199 -1.2545559409413416 -0.5694770345954823 0.33932040400166985 +59 -0.6235113592986508 -0.2086994539745325 1.6873018374682558 +240 0.705376364763962 -0.6227531276788822 1.6071635134558022 diff --git a/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/in.dpd_coul_slater_long b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/in.dpd_coul_slater_long new file mode 100644 index 0000000000..bd405aad37 --- /dev/null +++ b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/in.dpd_coul_slater_long @@ -0,0 +1,58 @@ +# DPD Ionic Fluid + +variable T equal 1.0 +variable cut_DPD equal 1.0 +variable seed equal 165412 +variable lambda equal 0.25 +variable cut_coul equal 2.0 + +#------------------------------------------------------------------------------- +# Initialize LAMMPS run for 3-d periodic +#------------------------------------------------------------------------------- + +units lj +boundary p p p # periodic at all axes +atom_style full +dimension 3 + +bond_style none +angle_style none +dihedral_style none +improper_style none + +newton on +comm_modify vel yes # store info of ghost atoms btw processors + +#------------------------------------------------------------------------------- +# Box creation and configuration +#------------------------------------------------------------------------------- + +# Define pair style and coefficients +pair_style dpd/coul/slater/long ${T} ${cut_DPD} ${seed} ${lambda} ${cut_coul} + +read_data data.dpd_coul_slater_long + +# Enable long range electrostatics solver +kspace_style pppm 1e-04 + +# Construct neighbors every steps +neighbor 1.0 bin +neigh_modify every 1 delay 0 check yes + +#------------------------------------------------------------------------------- +# Run the simulation +#------------------------------------------------------------------------------- + +thermo_style custom step temp press vol evdwl ecoul elong pe ke fnorm fmax +thermo_modify norm no +thermo 100 + +timestep 0.01 +run_style verlet + +fix 1 all nve + +run 1000 + +unfix 1 + diff --git a/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/log.19Jun24.dpd_coul_slater.g++.1 b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/log.19Jun24.dpd_coul_slater.g++.1 new file mode 100644 index 0000000000..39c0ded481 --- /dev/null +++ b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/log.19Jun24.dpd_coul_slater.g++.1 @@ -0,0 +1,147 @@ +LAMMPS (17 Apr 2024 - Development - patch_17Apr2024-262-g0aff26705c-modified) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# DPD Ionic Fluid + +variable T equal 1.0 +variable cut_DPD equal 1.0 +variable seed equal 165412 +variable lambda equal 0.25 +variable cut_coul equal 2.0 + +#------------------------------------------------------------------------------- +# Initialize LAMMPS run for 3-d periodic +#------------------------------------------------------------------------------- + +units lj +boundary p p p # periodic at all axes +atom_style full +dimension 3 + +bond_style none +angle_style none +dihedral_style none +improper_style none + +newton on +comm_modify vel yes # store info of ghost atoms btw processors + +#------------------------------------------------------------------------------- +# Box creation and configuration +#------------------------------------------------------------------------------- + +# Define pair style and coefficients +pair_style dpd/coul/slater/long ${T} ${cut_DPD} ${seed} ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 ${cut_DPD} ${seed} ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 1 ${seed} ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 1 165412 ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 1 165412 0.25 ${cut_coul} +pair_style dpd/coul/slater/long 1 1 165412 0.25 2 + +read_data data.dpd_coul_slater_long +Reading data file ... + orthogonal box = (0 0 0) to (5 5 5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 375 atoms + reading velocities ... + 375 velocities +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 0 = max # of 1-2 neighbors + 0 = max # of 1-3 neighbors + 0 = max # of 1-4 neighbors + 1 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.003 seconds + +# Enable long range electrostatics solver +kspace_style pppm 1e-04 + +# Construct neighbors every steps +neighbor 1.0 bin +neigh_modify every 1 delay 0 check yes + +#------------------------------------------------------------------------------- +# Run the simulation +#------------------------------------------------------------------------------- + +thermo_style custom step temp press vol evdwl ecoul elong pe ke fnorm fmax +thermo_modify norm no +thermo 100 + +timestep 0.01 +run_style verlet + +fix 1 all nve + +run 1000 +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + G vector (1/distance) = 1.4828454 + grid = 20 20 20 + stencil order = 5 + estimated absolute RMS force accuracy = 7.7240141e-05 + estimated relative force accuracy = 7.7240141e-05 + using double precision FFTW3 + 3d grid and FFT values/proc = 24389 8000 +Generated 0 of 3 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 3 + ghost atom cutoff = 3 + binsize = 1.5, bins = 4 4 4 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair dpd/coul/slater/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 8.359 | 8.359 | 8.359 Mbytes + Step Temp Press Volume E_vdwl E_coul E_long PotEng KinEng Fnorm Fmax + 0 0.9849949 69.271905 125 4673.0443 0 -30.365103 4642.6792 552.58214 646.76798 65.851035 + 100 1.0614027 69.794624 125 4659.0139 0 -31.906319 4627.1075 595.44692 612.94396 60.338653 + 200 0.9422517 68.721098 125 4687.8862 0 -33.81531 4654.0709 528.6032 620.25627 62.726994 + 300 0.8956649 69.323482 125 4721.0824 0 -33.854275 4687.2281 502.46801 670.22699 73.087908 + 400 0.99584547 69.670416 125 4713.9086 0 -30.783633 4683.125 558.66931 607.65881 59.224652 + 500 1.0565931 69.497816 125 4701.2584 0 -26.80545 4674.4529 592.74873 646.18907 71.398122 + 600 1.0071523 70.26222 125 4659.2061 0 -29.98909 4629.217 565.01243 630.00244 58.264115 + 700 1.0507355 67.920078 125 4695.255 0 -32.649209 4662.6058 589.46259 651.80459 70.573524 + 800 0.98561942 68.279591 125 4745.7603 0 -28.98491 4716.7754 552.9325 627.14371 67.196483 + 900 0.96470105 70.742864 125 4706.3605 0 -30.271633 4676.0889 541.19729 644.43036 79.474998 + 1000 1.0204819 70.164419 125 4654.6077 0 -27.797433 4626.8103 572.49035 624.19728 71.825307 +Loop time of 2.10153 on 1 procs for 1000 steps with 375 atoms + +Performance: 411128.483 tau/day, 475.843 timesteps/s, 178.441 katom-step/s +99.7% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.1779 | 1.1779 | 1.1779 | 0.0 | 56.05 +Bond | 6.507e-05 | 6.507e-05 | 6.507e-05 | 0.0 | 0.00 +Kspace | 0.74636 | 0.74636 | 0.74636 | 0.0 | 35.51 +Neigh | 0.12903 | 0.12903 | 0.12903 | 0.0 | 6.14 +Comm | 0.039726 | 0.039726 | 0.039726 | 0.0 | 1.89 +Output | 0.00027587 | 0.00027587 | 0.00027587 | 0.0 | 0.01 +Modify | 0.0037596 | 0.0037596 | 0.0037596 | 0.0 | 0.18 +Other | | 0.004451 | | | 0.21 + +Nlocal: 375 ave 375 max 375 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 3613 ave 3613 max 3613 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 62354 ave 62354 max 62354 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 62354 +Ave neighs/atom = 166.27733 +Ave special neighs/atom = 0 +Neighbor list builds = 65 +Dangerous builds = 0 + +unfix 1 + +Total wall time: 0:00:02 diff --git a/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/log.19Jun24.dpd_coul_slater.g++.4 b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/log.19Jun24.dpd_coul_slater.g++.4 new file mode 100644 index 0000000000..445baac0f7 --- /dev/null +++ b/examples/PACKAGES/dpd-basic/dpd_coul_slater_long/log.19Jun24.dpd_coul_slater.g++.4 @@ -0,0 +1,147 @@ +LAMMPS (17 Apr 2024 - Development - patch_17Apr2024-262-g0aff26705c-modified) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# DPD Ionic Fluid + +variable T equal 1.0 +variable cut_DPD equal 1.0 +variable seed equal 165412 +variable lambda equal 0.25 +variable cut_coul equal 2.0 + +#------------------------------------------------------------------------------- +# Initialize LAMMPS run for 3-d periodic +#------------------------------------------------------------------------------- + +units lj +boundary p p p # periodic at all axes +atom_style full +dimension 3 + +bond_style none +angle_style none +dihedral_style none +improper_style none + +newton on +comm_modify vel yes # store info of ghost atoms btw processors + +#------------------------------------------------------------------------------- +# Box creation and configuration +#------------------------------------------------------------------------------- + +# Define pair style and coefficients +pair_style dpd/coul/slater/long ${T} ${cut_DPD} ${seed} ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 ${cut_DPD} ${seed} ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 1 ${seed} ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 1 165412 ${lambda} ${cut_coul} +pair_style dpd/coul/slater/long 1 1 165412 0.25 ${cut_coul} +pair_style dpd/coul/slater/long 1 1 165412 0.25 2 + +read_data data.dpd_coul_slater_long +Reading data file ... + orthogonal box = (0 0 0) to (5 5 5) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 375 atoms + reading velocities ... + 375 velocities +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 0 = max # of 1-2 neighbors + 0 = max # of 1-3 neighbors + 0 = max # of 1-4 neighbors + 1 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.003 seconds + +# Enable long range electrostatics solver +kspace_style pppm 1e-04 + +# Construct neighbors every steps +neighbor 1.0 bin +neigh_modify every 1 delay 0 check yes + +#------------------------------------------------------------------------------- +# Run the simulation +#------------------------------------------------------------------------------- + +thermo_style custom step temp press vol evdwl ecoul elong pe ke fnorm fmax +thermo_modify norm no +thermo 100 + +timestep 0.01 +run_style verlet + +fix 1 all nve + +run 1000 +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + G vector (1/distance) = 1.4828454 + grid = 20 20 20 + stencil order = 5 + estimated absolute RMS force accuracy = 7.7240141e-05 + estimated relative force accuracy = 7.7240141e-05 + using double precision FFTW3 + 3d grid and FFT values/proc = 10469 2000 +Generated 0 of 3 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 3 + ghost atom cutoff = 3 + binsize = 1.5, bins = 4 4 4 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair dpd/coul/slater/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 7.208 | 7.208 | 7.209 Mbytes + Step Temp Press Volume E_vdwl E_coul E_long PotEng KinEng Fnorm Fmax + 0 0.9849949 69.076433 125 4673.0443 0 -30.365103 4642.6792 552.58214 613.18374 70.700582 + 100 0.95374867 69.110009 125 4681.1097 0 -31.260804 4649.8489 535.053 629.95109 62.05418 + 200 1.0076152 69.824904 125 4670.7458 0 -28.382203 4642.3636 565.27213 656.8501 72.049813 + 300 1.0014752 69.666331 125 4696.454 0 -26.943577 4669.5105 561.8276 631.49861 74.737274 + 400 0.98863876 69.731774 125 4700.7552 0 -23.816077 4676.9391 554.62634 637.74742 68.928573 + 500 0.95782852 68.588075 125 4698.588 0 -29.249543 4669.3385 537.3418 646.31897 68.800569 + 600 0.97443232 70.864079 125 4674.8821 0 -26.415644 4648.4664 546.65653 606.50755 78.664429 + 700 0.98783988 68.908299 125 4692.5536 0 -28.092022 4664.4616 554.17817 638.98401 69.691814 + 800 0.98000145 69.83977 125 4706.6365 0 -29.648365 4676.9881 549.78082 626.84362 73.133934 + 900 1.0526251 69.466078 125 4671.9648 0 -30.941117 4641.0237 590.52269 618.1049 62.333546 + 1000 0.98340746 69.527121 125 4728.2894 0 -31.869907 4696.4195 551.69159 630.14208 61.392611 +Loop time of 0.928543 on 4 procs for 1000 steps with 375 atoms + +Performance: 930490.137 tau/day, 1076.956 timesteps/s, 403.859 katom-step/s +98.9% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.30761 | 0.34974 | 0.38864 | 4.9 | 37.67 +Bond | 8.4633e-05 | 9.0539e-05 | 9.9184e-05 | 0.0 | 0.01 +Kspace | 0.39038 | 0.42976 | 0.47215 | 4.4 | 46.28 +Neigh | 0.033986 | 0.035576 | 0.036791 | 0.5 | 3.83 +Comm | 0.10247 | 0.10324 | 0.10481 | 0.3 | 11.12 +Output | 0.00024145 | 0.00027404 | 0.00036867 | 0.0 | 0.03 +Modify | 0.0022402 | 0.0025068 | 0.0026343 | 0.3 | 0.27 +Other | | 0.007356 | | | 0.79 + +Nlocal: 93.75 ave 96 max 93 min +Histogram: 3 0 0 0 0 0 0 0 0 1 +Nghost: 2289.75 ave 2317 max 2271 min +Histogram: 1 1 0 0 1 0 0 0 0 1 +Neighs: 15590.2 ave 16765 max 14540 min +Histogram: 1 0 1 0 0 1 0 0 0 1 + +Total # of neighbors = 62361 +Ave neighs/atom = 166.296 +Ave special neighs/atom = 0 +Neighbor list builds = 64 +Dangerous builds = 0 + +unfix 1 + +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/uf3/Nb.uf3 b/examples/PACKAGES/uf3/Nb.uf3 new file mode 120000 index 0000000000..cb0fdd480d --- /dev/null +++ b/examples/PACKAGES/uf3/Nb.uf3 @@ -0,0 +1 @@ +../../../potentials/Nb.uf3 \ No newline at end of file diff --git a/examples/PACKAGES/uf3/in.uf3.Nb b/examples/PACKAGES/uf3/in.uf3.Nb new file mode 100644 index 0000000000..19b37ccc0b --- /dev/null +++ b/examples/PACKAGES/uf3/in.uf3.Nb @@ -0,0 +1,46 @@ +# Demonstrate UF3 W potential + +# # ============= Initialize simulation + +variable nsteps index 100 +variable nrep equal 4 +variable a equal 3.3005 +units metal + +# generate the box and atom positions using a BCC lattice + +variable nx equal ${nrep} +variable ny equal ${nrep} +variable nz equal ${nrep} + +boundary p p p + +lattice bcc $a +region box block 0 ${nx} 0 ${ny} 0 ${nz} +create_box 1 box +create_atoms 1 box + +mass 1 92.906 + +# # ============= set pair style + +pair_style uf3 3 +pair_coeff * * Nb.uf3 Nb + + +# # ============= Setup output + +thermo 10 +thermo_modify norm yes + +# # ============= Set up NVE run + +timestep 0.5e-3 +neighbor 1.0 bin +neigh_modify once no every 1 delay 0 check yes + +# # ============= Run MD + +velocity all create 300.0 2367804 loop geom +fix 1 all nve +run ${nsteps} diff --git a/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.1 b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.1 new file mode 100644 index 0000000000..0c9c0bffa2 --- /dev/null +++ b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.1 @@ -0,0 +1,118 @@ +LAMMPS (17 Apr 2024 - Development - patch_17Apr2024-199-g49f20229ad-modified) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Demonstrate UF3 W potential + +# # ============= Initialize simulation + +variable nsteps index 100 +variable nrep equal 4 +variable a equal 3.3005 +units metal + +# generate the box and atom positions using a BCC lattice + +variable nx equal ${nrep} +variable nx equal 4 +variable ny equal ${nrep} +variable ny equal 4 +variable nz equal ${nrep} +variable nz equal 4 + +boundary p p p + +lattice bcc $a +lattice bcc 3.3005 +Lattice spacing in x,y,z = 3.3005 3.3005 3.3005 +region box block 0 ${nx} 0 ${ny} 0 ${nz} +region box block 0 4 0 ${ny} 0 ${nz} +region box block 0 4 0 4 0 ${nz} +region box block 0 4 0 4 0 4 +create_box 1 box +Created orthogonal box = (0 0 0) to (13.202 13.202 13.202) + 1 by 1 by 1 MPI processor grid +create_atoms 1 box +Created 128 atoms + using lattice units in orthogonal box = (0 0 0) to (13.202 13.202 13.202) + create_atoms CPU = 0.000 seconds + +mass 1 92.906 + +# # ============= set pair style + +pair_style uf3 3 +pair_coeff * * Nb.uf3 Nb +Reading potential file Nb.uf3 with DATE: 2024-04-02 + + +# # ============= Setup output + +thermo 10 +thermo_modify norm yes + +# # ============= Set up NVE run + +timestep 0.5e-3 +neighbor 1.0 bin +neigh_modify once no every 1 delay 0 check yes + +# # ============= Run MD + +velocity all create 300.0 2367804 loop geom +fix 1 all nve +run ${nsteps} +run 100 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 9 + ghost atom cutoff = 9 + binsize = 4.5, bins = 3 3 3 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair uf3, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.376 | 3.376 | 3.376 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 300 -4.4256832 0 -4.3872081 90756.437 + 10 294.36659 -4.4249607 0 -4.3872081 91006.427 + 20 277.9021 -4.422849 0 -4.387208 91716.126 + 30 251.88303 -4.4195119 0 -4.3872078 92789.12 + 40 218.42803 -4.4152211 0 -4.3872076 94118.45 + 50 180.40641 -4.4103445 0 -4.3872073 95579.009 + 60 141.2326 -4.4053202 0 -4.3872071 97031.816 + 70 104.54429 -4.4006146 0 -4.3872068 98332.882 + 80 73.787889 -4.3966699 0 -4.3872066 99351.332 + 90 51.759956 -4.3938446 0 -4.3872064 99992.934 + 100 40.209821 -4.3923633 0 -4.3872064 100211.98 +Loop time of 0.385575 on 1 procs for 100 steps with 128 atoms + +Performance: 11.204 ns/day, 2.142 hours/ns, 259.353 timesteps/s, 33.197 katom-step/s +99.7% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.38403 | 0.38403 | 0.38403 | 0.0 | 99.60 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.00090609 | 0.00090609 | 0.00090609 | 0.0 | 0.23 +Output | 0.00017626 | 0.00017626 | 0.00017626 | 0.0 | 0.05 +Modify | 0.00018204 | 0.00018204 | 0.00018204 | 0.0 | 0.05 +Other | | 0.0002795 | | | 0.07 + +Nlocal: 128 ave 128 max 128 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1601 ave 1601 max 1601 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 21504 ave 21504 max 21504 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 21504 +Ave neighs/atom = 168 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.4 b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.4 new file mode 100644 index 0000000000..cd46d8da14 --- /dev/null +++ b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.4 @@ -0,0 +1,118 @@ +LAMMPS (17 Apr 2024 - Development - patch_17Apr2024-199-g49f20229ad-modified) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Demonstrate UF3 W potential + +# # ============= Initialize simulation + +variable nsteps index 100 +variable nrep equal 4 +variable a equal 3.3005 +units metal + +# generate the box and atom positions using a BCC lattice + +variable nx equal ${nrep} +variable nx equal 4 +variable ny equal ${nrep} +variable ny equal 4 +variable nz equal ${nrep} +variable nz equal 4 + +boundary p p p + +lattice bcc $a +lattice bcc 3.3005 +Lattice spacing in x,y,z = 3.3005 3.3005 3.3005 +region box block 0 ${nx} 0 ${ny} 0 ${nz} +region box block 0 4 0 ${ny} 0 ${nz} +region box block 0 4 0 4 0 ${nz} +region box block 0 4 0 4 0 4 +create_box 1 box +Created orthogonal box = (0 0 0) to (13.202 13.202 13.202) + 1 by 2 by 2 MPI processor grid +create_atoms 1 box +Created 128 atoms + using lattice units in orthogonal box = (0 0 0) to (13.202 13.202 13.202) + create_atoms CPU = 0.001 seconds + +mass 1 92.906 + +# # ============= set pair style + +pair_style uf3 3 +pair_coeff * * Nb.uf3 Nb +Reading potential file Nb.uf3 with DATE: 2024-04-02 + + +# # ============= Setup output + +thermo 10 +thermo_modify norm yes + +# # ============= Set up NVE run + +timestep 0.5e-3 +neighbor 1.0 bin +neigh_modify once no every 1 delay 0 check yes + +# # ============= Run MD + +velocity all create 300.0 2367804 loop geom +fix 1 all nve +run ${nsteps} +run 100 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 9 + ghost atom cutoff = 9 + binsize = 4.5, bins = 3 3 3 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair uf3, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.351 | 3.351 | 3.351 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 300 -4.4256832 0 -4.3872081 90756.437 + 10 294.36659 -4.4249607 0 -4.3872081 91006.427 + 20 277.9021 -4.422849 0 -4.387208 91716.126 + 30 251.88303 -4.4195119 0 -4.3872078 92789.12 + 40 218.42803 -4.4152211 0 -4.3872076 94118.45 + 50 180.40641 -4.4103445 0 -4.3872073 95579.009 + 60 141.2326 -4.4053202 0 -4.3872071 97031.816 + 70 104.54429 -4.4006146 0 -4.3872068 98332.882 + 80 73.787889 -4.3966699 0 -4.3872066 99351.332 + 90 51.759956 -4.3938446 0 -4.3872064 99992.934 + 100 40.209821 -4.3923633 0 -4.3872064 100211.98 +Loop time of 0.11881 on 4 procs for 100 steps with 128 atoms + +Performance: 36.361 ns/day, 0.660 hours/ns, 841.679 timesteps/s, 107.735 katom-step/s +99.3% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.10673 | 0.10875 | 0.11236 | 0.7 | 91.53 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.0057324 | 0.0093477 | 0.011375 | 2.4 | 7.87 +Output | 0.00016629 | 0.00018236 | 0.00022483 | 0.0 | 0.15 +Modify | 9.4948e-05 | 0.00010621 | 0.00012066 | 0.0 | 0.09 +Other | | 0.0004263 | | | 0.36 + +Nlocal: 32 ave 32 max 32 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Nghost: 1049 ave 1049 max 1049 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 5376 ave 5376 max 5376 min +Histogram: 4 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 21504 +Ave neighs/atom = 168 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/lib/gpu/lal_base_dpd.cpp b/lib/gpu/lal_base_dpd.cpp index 0ddd24d21e..dfeaf24ce9 100644 --- a/lib/gpu/lal_base_dpd.cpp +++ b/lib/gpu/lal_base_dpd.cpp @@ -57,7 +57,7 @@ int BaseDPDT::init_atomic(const int nlocal, const int nall, const double cell_size, const double gpu_split, FILE *_screen, const void *pair_program, const char *k_name, const int onetype, - const int extra_fields) { + const int extra_fields, bool need_charges) { screen=_screen; int gpu_nbor=0; @@ -73,7 +73,7 @@ int BaseDPDT::init_atomic(const int nlocal, const int nall, _threads_per_atom=device->threads_per_atom(); - bool charge = false; + bool charge = need_charges; bool rot = false; bool vel = true; _extra_fields = extra_fields; diff --git a/lib/gpu/lal_base_dpd.h b/lib/gpu/lal_base_dpd.h index 64ec725d95..658147419d 100644 --- a/lib/gpu/lal_base_dpd.h +++ b/lib/gpu/lal_base_dpd.h @@ -53,7 +53,8 @@ class BaseDPD { const int maxspecial, const double cell_size, const double gpu_split, FILE *screen, const void *pair_program, const char *k_name, - const int onetype=0, const int extra_fields=0); + const int onetype=0, const int extra_fields=0, + bool need_charges=false); /// Estimate the overhead for GPU context changes and CPU driver void estimate_gpu_overhead(); diff --git a/lib/gpu/lal_dpd_coul_slater_long.cpp b/lib/gpu/lal_dpd_coul_slater_long.cpp new file mode 100644 index 0000000000..aa2b73566c --- /dev/null +++ b/lib/gpu/lal_dpd_coul_slater_long.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + lal_dpd_coul_slater_long.cpp + ------------------- + Eddy BARRAUD (IFPEN/Sorbonne) + + Class for acceleration of the dpd/coul/slater/long pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : May 28, 2024 + email : eddy.barraud@outlook.fr + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "dpd_coul_slater_long_cl.h" +#elif defined(USE_CUDART) +const char *dpd_coul_slater_long=0; +#else +#include "dpd_coul_slater_long_cubin.h" +#endif + +#include "lal_dpd_coul_slater_long.h" +#include +namespace LAMMPS_AL { +#define DPDCoulSlaterLongT DPDCoulSlaterLong + +extern Device device; + +template +DPDCoulSlaterLongT::DPDCoulSlaterLong() : BaseDPD(), _allocated(false) { +} + +template +DPDCoulSlaterLongT::~DPDCoulSlaterLong() { + clear(); +} + +template +int DPDCoulSlaterLongT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int DPDCoulSlaterLongT::init(const int ntypes, + double **host_cutsq, double **host_a0, + double **host_gamma, double **host_sigma, + double **host_cut_dpd, double **host_cut_dpdsq, + double **host_cut_slatersq, double *host_special_lj, + const bool tstat_only, + const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, + const double gpu_split, FILE *_screen, double *host_special_coul, + const double qqrd2e, const double g_ewald, double lamda) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + int extra_fields = 4; // round up to accomodate quadruples of numtyp values + // q + int success; + bool need_charges = true; + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,dpd_coul_slater_long,"k_dpd_coul_slater_long",onetype, extra_fields, need_charges); + + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write_coul(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + sp_cl.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + for (int i=0; i<4; i++) { + host_write_coul[i]=host_special_coul[i]; + } + ucl_copy(sp_cl,host_write_coul,4,false); + + _lj_types=lj_types; + _qqrd2e=qqrd2e; + _g_ewald=g_ewald; + _lamda=lamda; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff,host_write,host_a0,host_gamma, + host_sigma,host_cut_dpd); + + cutsq.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,cutsq,host_write,host_cutsq, + host_cut_dpdsq,host_cut_slatersq); + + double special_sqrt[4]; + special_sqrt[0] = sqrt(host_special_lj[0]); + special_sqrt[1] = sqrt(host_special_lj[1]); + special_sqrt[2] = sqrt(host_special_lj[2]); + special_sqrt[3] = sqrt(host_special_lj[3]); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + sp_sqrt.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(special_sqrt,4,*(this->ucl_device)); + ucl_copy(sp_sqrt,dview,false); + + _tstat_only = 0; + if (tstat_only) _tstat_only=1; + + _allocated=true; + this->_max_bytes=coeff.row_bytes()+cutsq.row_bytes()+sp_lj.row_bytes()+sp_sqrt.row_bytes(); + return 0; +} + +template +void DPDCoulSlaterLongT::clear() { + if (!_allocated) + return; + _allocated=false; + + coeff.clear(); + cutsq.clear(); + sp_lj.clear(); + sp_sqrt.clear(); + this->clear_atomic(); +} + +template +double DPDCoulSlaterLongT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(DPDCoulSlaterLong); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int DPDCoulSlaterLongT::loop(const int eflag, const int vflag) { + + int nall = this->atom->nall(); + // signal that we need to transfer extra data from the host + + this->atom->extra_data_unavail(); + + numtyp4 *pextra=reinterpret_cast(&(this->atom->extra[0])); + + int n = 0; + int nstride = 1; + for (int i = 0; i < nall; i++) { + int idx = n+i*nstride; + numtyp4 v; + v.x = q[i]; + v.y = 0; + v.z = 0; + v.w = 0; + pextra[idx] = v; + } + this->atom->add_extra_data(); + + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &this->atom->extra, &coeff, &sp_lj, &sp_cl, &sp_sqrt, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, + &vflag, &ainum, &nbor_pitch, &this->atom->v, &cutsq, + &this->_dtinvsqrt, &this->_seed, &this->_timestep, + &_qqrd2e, &_g_ewald, &_lamda, + &this->_tstat_only, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &this->atom->extra, &coeff, &_lj_types, &sp_lj, &sp_cl, &sp_sqrt, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &cutsq, &this->_dtinvsqrt, + &this->_seed, &this->_timestep, + &_qqrd2e, &_g_ewald, &_lamda, + &this->_tstat_only, &this->_threads_per_atom); + } + this->time_pair.stop(); + return GX; +} + +template +void DPDCoulSlaterLongT::update_coeff(int ntypes, double **host_a0, double **host_gamma, + double **host_sigma, double **host_cut_dpd) +{ + UCL_H_Vec host_write(_lj_types*_lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + this->atom->type_pack4(ntypes,_lj_types,coeff,host_write,host_a0,host_gamma, + host_sigma,host_cut_dpd); +} + +// --------------------------------------------------------------------------- +// Get the extra data pointers from host +// --------------------------------------------------------------------------- + +template +void DPDCoulSlaterLongT::get_extra_data(double *host_q) { + q = host_q; +} + +template class DPDCoulSlaterLong; +} + + diff --git a/lib/gpu/lal_dpd_coul_slater_long.cu b/lib/gpu/lal_dpd_coul_slater_long.cu new file mode 100644 index 0000000000..d9679ccdfd --- /dev/null +++ b/lib/gpu/lal_dpd_coul_slater_long.cu @@ -0,0 +1,523 @@ +// ************************************************************************** +// dpd.cu +// ------------------- +// Eddy BARRAUD (IFPEN/Sorbonne) +// Trung Dac Nguyen (U Chicago) +// +// Device code for acceleration of the dpd/coul/slater/long pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : May 28, 2024 +// email : eddy.barraud@outlook.fr +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( vel_tex,float4); +#else +_texture_2d( pos_tex,int4); +_texture_2d( vel_tex,int4); +#endif +#else +#define pos_tex x_ +#define vel_tex v_ +#endif + +#define EPSILON (numtyp)1.0e-10 + +//#define _USE_UNIFORM_SARU_LCG +//#define _USE_UNIFORM_SARU_TEA8 +//#define _USE_GAUSSIAN_SARU_LCG + +#if !defined(_USE_UNIFORM_SARU_LCG) && !defined(_USE_UNIFORM_SARU_TEA8) && !defined(_USE_GAUSSIAN_SARU_LCG) +#define _USE_UNIFORM_SARU_LCG +#endif + +// References: +// 1. Y. Afshar, F. Schmid, A. Pishevar, S. Worley, Comput. Phys. Comm. 184 (2013), 1119–1128. +// 2. C. L. Phillips, J. A. Anderson, S. C. Glotzer, Comput. Phys. Comm. 230 (2011), 7191-7201. +// PRNG period = 3666320093*2^32 ~ 2^64 ~ 10^19 + +#define LCGA 0x4beb5d59 /* Full period 32 bit LCG */ +#define LCGC 0x2600e1f7 +#define oWeylPeriod 0xda879add /* Prime period 3666320093 */ +#define oWeylOffset 0x8009d14b +#define TWO_N32 0.232830643653869628906250e-9f /* 2^-32 */ + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] +// using the inherent LCG, then multiply u with sqrt(3) to "match" +// with a normal random distribution. +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +// Curly brackets to make variables local to the scope. +#ifdef _USE_UNIFORM_SARU_LCG +#define SQRT3 (numtyp)1.7320508075688772935274463 +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + unsigned int v = (state ^ (state>>26)) + wstate; \ + unsigned int s = (signed int)((v^(v>>20))*0x6957f5a7); \ + randnum = SQRT3*(s*TWO_N32*(numtyp)2.0-(numtyp)1.0); \ +} +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] using TEA8 +// then multiply u with sqrt(3) to "match" with a normal random distribution +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +#ifdef _USE_UNIFORM_SARU_TEA8 +#define SQRT3 (numtyp)1.7320508075688772935274463 +#define k0 0xA341316C +#define k1 0xC8013EA4 +#define k2 0xAD90777D +#define k3 0x7E95761E +#define delta 0x9e3779b9 +#define rounds 8 +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + unsigned int sum = 0; \ + for (int i=0; i < rounds; i++) { \ + sum += delta; \ + state += ((wstate<<4) + k0)^(wstate + sum)^((wstate>>5) + k1); \ + wstate += ((state<<4) + k2)^(state + sum)^((state>>5) + k3); \ + } \ + unsigned int v = (state ^ (state>>26)) + wstate; \ + unsigned int s = (signed int)((v^(v>>20))*0x6957f5a7); \ + randnum = SQRT3*(s*TWO_N32*(numtyp)2.0-(numtyp)1.0); \ +} +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns two uniformly distributed random numbers r1 and r2 in [-1.0;1.0], +// and uses the polar method (Marsaglia's) to transform to a normal random value +// This is used to compared with CPU DPD using RandMars::gaussian() +#ifdef _USE_GAUSSIAN_SARU_LCG +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state=0x12345678; \ + unsigned int wstate=12345678; \ + state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + unsigned int v, s; \ + numtyp r1, r2, rsq; \ + while (1) { \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + v = (state ^ (state>>26)) + wstate; \ + s = (signed int)((v^(v>>20))*0x6957f5a7); \ + r1 = s*TWO_N32*(numtyp)2.0-(numtyp)1.0; \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + v = (state ^ (state>>26)) + wstate; \ + s = (signed int)((v^(v>>20))*0x6957f5a7); \ + r2 = s*TWO_N32*(numtyp)2.0-(numtyp)1.0; \ + rsq = r1 * r1 + r2 * r2; \ + if (rsq < (numtyp)1.0) break; \ + } \ + numtyp fac = ucl_sqrt((numtyp)-2.0*log(rsq)/rsq); \ + randnum = r2*fac; \ +} +#endif + +__kernel void k_dpd_coul_slater_long(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict extra, + const __global numtyp4 *restrict coeff, + const int lj_types, + const __global numtyp *restrict sp_lj, + const __global numtyp *restrict sp_cl_in, + const __global numtyp *restrict sp_sqrt, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp4 *restrict v_, + const __global numtyp4 *restrict cutsq, + const numtyp dtinvsqrt, const int seed, + const int timestep, const numtyp qqrd2e, + const numtyp g_ewald, const numtyp lamda, + const int tstat_only, + const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + __local numtyp sp_cl[4]; + ///local_allocate_store_charge(); + + sp_cl[0]=sp_cl_in[0]; + sp_cl[1]=sp_cl_in[1]; + sp_cl[2]=sp_cl_in[2]; + sp_cl[3]=sp_cl_in[3]; + + int n_stride; + local_allocate_store_pair(); + + acctyp3 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp e_coul, energy, virial[6]; + if (EVFLAG) { + energy=(acctyp)0; + e_coul=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + + if (ii global squared cutoff + if (rsq DPD squared cutoff + if (rsq < cutsq[mtype].y && r > EPSILON) { + + numtyp rinv=ucl_recip(r); + numtyp delvx = iv.x - jv.x; + numtyp delvy = iv.y - jv.y; + numtyp delvz = iv.z - jv.z; + numtyp dot = delx*delvx + dely*delvy + delz*delvz; + numtyp wd = (numtyp)1.0 - r/coeff[mtype].w; + + unsigned int tag1=itag, tag2=jtag; + if (tag1 > tag2) { + tag1 = jtag; tag2 = itag; + } + + numtyp randnum = (numtyp)0.0; + saru(tag1, tag2, seed, timestep, randnum); + + // conservative force = a0 * wd, or 0 if tstat only + // drag force = -gamma * wd^2 * (delx dot delv) / r + // random force = sigma * wd * rnd * dtinvsqrt; + + if (!tstat_only) force_dpd = coeff[mtype].x*wd; + force_dpd -= coeff[mtype].y*wd*wd*dot*rinv; + force_dpd *= factor_dpd; + force_dpd += factor_sqrt*coeff[mtype].z*wd*randnum*dtinvsqrt; + force_dpd *=rinv; + + if (EVFLAG && eflag) { + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); + // eng shifted to 0.0 at cutoff + numtyp e = (numtyp)0.5*coeff[mtype].x*coeff[mtype].w * wd*wd; + energy += factor_dpd*e; + } + + }// if cut_dpdsq + + // apply Slater electrostatic force if distance below Slater cutoff + // and the two species have a slater coeff + // cutsq[mtype].z -> Coulombic squared cutoff + if ( cutsq[mtype].z != 0.0 && rsq < cutsq[mtype].z){ + numtyp r2inv=ucl_recip(rsq); + numtyp _erfc; + numtyp grij = g_ewald * r; + numtyp expm2 = ucl_exp(-grij*grij); + numtyp t = ucl_recip((numtyp)1.0 + EWALD_P*grij); + _erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + numtyp prefactor = extra[j].x; + prefactor *= qqrd2e * cutsq[mtype].z * qtmp/r; + numtyp rlamdainv = r * lamdainv; + numtyp exprlmdainv = ucl_exp((numtyp)-2.0*rlamdainv); + numtyp slater_term = exprlmdainv*((numtyp)1.0 + ((numtyp)2.0*rlamdainv*((numtyp)1.0+rlamdainv))); + force_coul = prefactor*(_erfc + EWALD_F*grij*expm2-slater_term); + if (factor_coul > (numtyp)0) force_coul -= factor_coul*prefactor*((numtyp)1.0-slater_term); + force_coul *= r2inv; + + if (EVFLAG && eflag) { + numtyp e_slater = ((numtyp)1.0 + rlamdainv)*exprlmdainv; + numtyp e = prefactor*(_erfc-e_slater); + if (factor_coul > (numtyp)0) e -= factor_coul*prefactor*((numtyp)1.0 - e_slater); + e_coul += e; + } + } // if cut_coulsq + + numtyp force = force_coul + force_dpd; + f.x += delx*force; + f.y += dely*force; + f.z += delz*force; + + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + + } // if cutsq + + } // for nbor + } // if ii + store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, + ans,engv); +} + +__kernel void k_dpd_coul_slater_long_fast(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict extra, + const __global numtyp4 *restrict coeff_in, + const __global numtyp *restrict sp_lj_in, + const __global numtyp *restrict sp_cl_in, + const __global numtyp *restrict sp_sqrt_in, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp4 *restrict v_, + const __global numtyp4 *restrict cutsq_in, + const numtyp dtinvsqrt, const int seed, + const int timestep, const numtyp qqrd2e, + const numtyp g_ewald, const numtyp lamda, + const int tstat_only, + const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + __local numtyp4 coeff[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp4 cutsq[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp sp_lj[4]; + __local numtyp sp_sqrt[4]; + /// COUL Init + __local numtyp sp_cl[4]; + if (tid<4) { + sp_lj[tid]=sp_lj_in[tid]; + sp_sqrt[tid]=sp_sqrt_in[tid]; + sp_cl[tid]=sp_cl_in[tid]; + } + if (tid DPD squared cutoff + if (rsq < cutsq[mtype].y && r > EPSILON) { + + numtyp rinv=ucl_recip(r); + numtyp delvx = iv.x - jv.x; + numtyp delvy = iv.y - jv.y; + numtyp delvz = iv.z - jv.z; + numtyp dot = delx*delvx + dely*delvy + delz*delvz; + numtyp wd = (numtyp)1.0 - r/coeff[mtype].w; + + unsigned int tag1=itag, tag2=jtag; + if (tag1 > tag2) { + tag1 = jtag; tag2 = itag; + } + + numtyp randnum = (numtyp)0.0; + saru(tag1, tag2, seed, timestep, randnum); + + // conservative force = a0 * wd, or 0 if tstat only + // drag force = -gamma * wd^2 * (delx dot delv) / r + // random force = sigma * wd * rnd * dtinvsqrt; + /// coeff.x = a0, coeff.y = gamma, coeff.z = sigma, coeff.w = cut_dpd + + if (!tstat_only) force_dpd = coeff[mtype].x*wd; + force_dpd -= coeff[mtype].y*wd*wd*dot*rinv; + force_dpd *= factor_dpd; + force_dpd += factor_sqrt*coeff[mtype].z*wd*randnum*dtinvsqrt; + force_dpd *=rinv; + + if (EVFLAG && eflag) { + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); + // eng shifted to 0.0 at cutoff + numtyp e = (numtyp)0.5*coeff[mtype].x*coeff[mtype].w * wd*wd; + energy += factor_dpd*e; + } + + }// if cut_dpdsq + + // apply Slater electrostatic force if distance below Slater cutoff + // and the two species have a slater coeff + // cutsq[mtype].z -> Coulombic squared cutoff + if ( cutsq[mtype].z != 0.0 && rsq < cutsq[mtype].z){ + numtyp r2inv=ucl_recip(rsq); + numtyp _erfc; + numtyp grij = g_ewald * r; + numtyp expm2 = ucl_exp(-grij*grij); + numtyp t = ucl_recip((numtyp)1.0 + EWALD_P*grij); + _erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + numtyp prefactor = extra[j].x; + prefactor *= qqrd2e * cutsq[mtype].z * qtmp/r; + numtyp rlamdainv = r * lamdainv; + numtyp exprlmdainv = ucl_exp((numtyp)-2.0*rlamdainv); + numtyp slater_term = exprlmdainv*((numtyp)1.0 + ((numtyp)2.0*rlamdainv*((numtyp)1.0+rlamdainv))); + force_coul = prefactor*(_erfc + EWALD_F*grij*expm2-slater_term); + if (factor_coul > (numtyp)0) force_coul -= factor_coul*prefactor*((numtyp)1.0-slater_term); + force_coul *= r2inv; + + if (EVFLAG && eflag) { + numtyp e_slater = ((numtyp)1.0 + rlamdainv)*exprlmdainv; + numtyp e_sf = prefactor*(_erfc-e_slater); + if (factor_coul > (numtyp)0) e_sf -= factor_coul*prefactor*((numtyp)1.0 - e_slater); + e_coul += e_sf; + } + } // if cut_coulsq + + numtyp force = force_coul + force_dpd; + f.x += delx*force; + f.y += dely*force; + f.z += delz*force; + + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + + } // if cutsq + + } // for nbor + } // if ii + store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, + ans,engv); +} + diff --git a/lib/gpu/lal_dpd_coul_slater_long.h b/lib/gpu/lal_dpd_coul_slater_long.h new file mode 100644 index 0000000000..1870255998 --- /dev/null +++ b/lib/gpu/lal_dpd_coul_slater_long.h @@ -0,0 +1,100 @@ +/*************************************************************************** + lal_dpd_coul_slater_long.h + ------------------- + Eddy BARRAUD (IFPEN/Sorbonne) + + Class for acceleration of the dpd/coul/slater/long pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : May 28, 2024 + email : eddy.barraud@outlook.fr + ***************************************************************************/ + +#ifndef LAL_DPD_CHARGED_H +#define LAL_DPD_CHARGED_H + +#include "lal_base_dpd.h" + +namespace LAMMPS_AL { + +template +class DPDCoulSlaterLong : public BaseDPD { + public: + DPDCoulSlaterLong(); + ~DPDCoulSlaterLong(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, double **host_a0, double **host_gamma, + double **host_sigma, double **host_cut_dpd, double **host_cut_dpdsq, + double **host_cut_slatersq, double *host_special_lj, bool tstat_only, const int nlocal, + const int nall, const int max_nbors, const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, double *host_special_coul, const double qqrd2e, + const double g_ewald, const double lamda); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + /// Update coeff if needed (tstat only) + void update_coeff(int ntypes, double **host_a0, double **host_gamma, + double **host_sigma, double **host_cut_dpd ); + + void get_extra_data(double *host_q); + + // --------------------------- TYPE DATA -------------------------- + + /// coeff.x = a0, coeff.y = gamma, coeff.z = sigma, coeff.w = cut_dpd + UCL_D_Vec coeff; + + /// cutsq.x = cutsq, cutsq.y = cut_dpdsq, cutsq.w = cut_slatersq + UCL_D_Vec cutsq; + + /// Special LJ values + UCL_D_Vec sp_lj, sp_sqrt; + + /// Special Coul values [0-3] + UCL_D_Vec sp_cl; + + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + /// Only used for thermostat + int _tstat_only; + + /// Coulombic terms + numtyp _qqrd2e, _g_ewald, _lamda; + + /// pointer to host data for atom charge + double *q; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_dpd_coul_slater_long_ext.cpp b/lib/gpu/lal_dpd_coul_slater_long_ext.cpp new file mode 100644 index 0000000000..ceed1b85be --- /dev/null +++ b/lib/gpu/lal_dpd_coul_slater_long_ext.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + lal_dpd_coul_slater_long_ext.cpp + ------------------- + Eddy BARRAUD (IFPEN/Sorbonne) + + Functions for LAMMPS access to dpd/coul/slater/long acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : May 28, 2024 + email : eddy.barraud@outlook.fr + ***************************************************************************/ + +#include +#include +#include + +#include "lal_dpd_coul_slater_long.h" + +using namespace std; +using namespace LAMMPS_AL; + +static DPDCoulSlaterLong DPDCMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int dpd_coul_slater_long_gpu_init(const int ntypes, double **host_cutsq, double **host_a0, + double **host_gamma, double **host_sigma, double **host_cut_dpd, + double **host_cut_dpdsq, double **host_cut_slatersq, + double *special_lj, const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, + double *host_special_coul, const double qqrd2e, + const double g_ewald, const double lamda) { + DPDCMF.clear(); + gpu_mode=DPDCMF.device->gpu_mode(); + double gpu_split=DPDCMF.device->particle_split(); + int first_gpu=DPDCMF.device->first_device(); + int last_gpu=DPDCMF.device->last_device(); + int world_me=DPDCMF.device->world_me(); + int gpu_rank=DPDCMF.device->gpu_rank(); + int procs_per_gpu=DPDCMF.device->procs_per_gpu(); + + DPDCMF.device->init_message(screen,"dpd",first_gpu,last_gpu); + + bool message=false; + if (DPDCMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=DPDCMF.init(ntypes, host_cutsq, host_a0, host_gamma, host_sigma, host_cut_dpd, + host_cut_dpdsq, host_cut_slatersq, special_lj, false, inum, nall, + max_nbors, maxspecial, cell_size, gpu_split, screen, host_special_coul, + qqrd2e, g_ewald, lamda); + + DPDCMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + DPDCMF.estimate_gpu_overhead(); + return init_ok; +} + +void dpd_coul_slater_long_gpu_clear() { + DPDCMF.clear(); +} + +int ** dpd_coul_slater_long_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v, const double dtinvsqrt, + const int seed, const int timestep, + double *boxlo, double *prd) { + return DPDCMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_v, dtinvsqrt, seed, timestep, boxlo, prd); +} + +void dpd_coul_slater_long_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **host_v, const double dtinvsqrt, + const int seed, const int timestep, + const int nlocal, double *boxlo, double *prd) { + DPDCMF.compute(ago, inum_full, nall, host_x, host_type, ilist, numj, + firstneigh, eflag, vflag, eatom, vatom, host_start, cpu_time, success, + tag, host_v, dtinvsqrt, seed, timestep, nlocal, boxlo, prd); +} + +void dpd_coul_slater_long_gpu_update_coeff(int ntypes, double **host_a0, double **host_gamma, + double **host_sigma, double **host_cut_dpd) +{ + DPDCMF.update_coeff(ntypes,host_a0,host_gamma,host_sigma, host_cut_dpd); +} + +void dpd_coul_slater_long_gpu_get_extra_data(double *host_q) { + DPDCMF.get_extra_data(host_q); +} + +double dpd_coul_slater_long_gpu_bytes() { + return DPDCMF.host_memory_usage(); +} + + diff --git a/lib/plumed/Install.py b/lib/plumed/Install.py index 4a158cb31f..66501a74e9 100644 --- a/lib/plumed/Install.py +++ b/lib/plumed/Install.py @@ -16,8 +16,10 @@ parser = ArgumentParser(prog='Install.py', description="LAMMPS library build wrapper script") # settings +# Note: must also adjust check for supported API versions in +# fix_plumed.cpp when version changes from v2.n.x to v2.n+1.y -version = "2.8.3" +version = "2.9.1" mode = "static" # help message @@ -46,7 +48,9 @@ checksums = { \ '2.8.1' : '6bfe72ebdae63dc38a9ca27d9b0e08f8', \ '2.8.2' : '599092b6a0aa6fff992612537ad98994', \ '2.8.3' : '76d23cd394eba9e6530316ed1184e219', \ + '2.8.4' : '9f59c4f9bda86fe5bef19543c295a981', \ '2.9.0' : '661eabeebee05cf84bbf9dc23d7d5f46', \ + '2.9.1' : 'c3b2d31479c1e9ce211719d40e9efbd7', \ } # parse and process arguments diff --git a/potentials/Nb.uf3 b/potentials/Nb.uf3 new file mode 100644 index 0000000000..5f1cdb6f63 --- /dev/null +++ b/potentials/Nb.uf3 @@ -0,0 +1,136 @@ +#UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: +2B Nb Nb 0 3 nk +8.0 31 +0.001 0.001 0.001 0.001 0.33429166666666665 0.66758333333333331 1.000875 1.3341666666666665 1.6674583333333333 2.00075 2.3340416666666663 2.6673333333333331 3.0006249999999999 3.3339166666666666 3.667208333333333 4.0004999999999997 4.3337916666666665 4.6670833333333333 5.000375 5.3336666666666668 5.6669583333333335 6.0002500000000003 6.3335416666666671 6.6668333333333338 7.0001249999999997 7.3334166666666665 7.6667083333333332 8 8 8 8 +27 +79.140244588519465 79.140244588519465 55.85833391113556 36.597903318706138 21.358952811231141 12.290000872768841 1.9593931914091953 -0.65697974623243804 -0.85177956270573463 -0.68929688239869991 -0.46787243412973262 -0.27624655899523165 -0.11912921944351409 -0.056302369393035338 -0.0049812809608429064 0.0085637634684603507 0.0034716161454604712 -0.0058751075573311978 -0.005453415412748467 -0.0015123194244718201 0.0011577919587182201 0.001583772506713282 -0.00049823976100720228 -0.0013902809146717273 0 0 0 +# +#UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: +3B Nb Nb Nb 0 3 nk +8.0 4.0 4.0 23 15 15 +0.001 0.001 0.001 0.001 0.50093749999999992 1.000875 1.5008124999999999 2.00075 2.5006874999999997 3.0006249999999999 3.5005624999999996 4.0004999999999997 4.5004375000000003 5.000375 5.5003124999999997 6.0002500000000003 6.5001875 7.0001249999999997 7.5000625000000003 8 8 8 8 +0.001 0.001 0.001 0.001 0.50087499999999996 1.00075 1.5006249999999999 2.0005000000000002 2.500375 3.0002499999999999 3.5001250000000002 4 4 4 4 +0.001 0.001 0.001 0.001 0.50087499999999996 1.00075 1.5006249999999999 2.0005000000000002 2.500375 3.0002499999999999 3.5001250000000002 4 4 4 4 +11 11 19 +-1.1790416072105636e-06 6.589114265858035e-08 2.1094970065385374e-06 4.7014910818419987e-07 8.288423734406254e-06 0.000186151370764668 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +3.2366723157260956e-05 2.6208783380066457e-05 1.0239981836366566e-05 1.8487993936404763e-05 2.1943710009352506e-05 2.6899947783571087e-07 5.002786118380638e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.0696915445106504e-05 6.184559535738335e-05 5.870203846064511e-05 -1.112085789465658e-05 -4.7600144351359347e-07 -5.861397594145908e-08 1.4524208784805573e-08 2.300649782987421e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +5.282737863089323e-05 6.328946161646202e-06 1.8329325276370316e-05 1.6423572667388823e-05 1.2653184610977003e-06 7.181714140248046e-06 3.491501462345434e-06 -7.285463619241614e-06 3.2609159022388403e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6.9413198850914024e-06 2.107626397843018e-05 1.8155172114721186e-05 2.0928626557075606e-06 1.5632037328512312e-06 -2.7335717313450097e-07 -7.2126792356200426e-09 9.213093725547886e-09 4.186629643010996e-08 8.198811769753182e-08 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +1.4231393739579515e-06 3.630746449160232e-07 9.318604659023228e-07 4.92311430374376e-07 -3.701479331898353e-09 2.1280257031614452e-07 1.2240989510544568e-06 5.3432540178806065e-06 2.043230389835189e-06 3.2740024159475547e-07 6.717304982644579e-07 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 5.196157077391817e-07 6.938124100654148e-08 7.597564197383545e-08 1.863740632660483e-07 4.437837629589167e-07 5.453941063185757e-07 1.5602917821833568e-06 3.404289212094662e-07 9.967447994956849e-07 5.8845599651090215e-06 1.5052240335012455e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 3.196534127251379e-06 -1.1872677866681306e-06 -2.5678892066098854e-08 5.139117071436217e-09 1.1142431390092631e-06 2.0605776537608227e-06 5.297265009242829e-06 6.713907186544732e-06 2.7028644452395994e-06 1.149242737988068e-06 2.2449682976927855e-06 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +3.2366723157260956e-05 2.6208783380066457e-05 1.0239981836366566e-05 1.8487993936404763e-05 2.1943710009352506e-05 2.6899947783571087e-07 5.002786118380638e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +9.36844864368356e-06 1.9223644807676324e-05 1.9979026246524356e-05 3.627062812549574e-05 9.775578281629195e-06 -5.894357549683858e-06 6.470814473155067e-07 2.31805322174729e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +2.2218614171918013e-06 5.325319655352672e-06 7.766746363269582e-06 9.361315506075464e-06 5.0417710282874456e-05 9.822946186678772e-05 0.00026400568406806884 0.00033610865151919737 0.00013239814531221768 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.4850777249143735e-05 7.094600012126306e-05 0.00030581781354430576 0.00044661036994300023 0.00016699596636619577 1.5860625743775105e-05 9.74250537001798e-07 5.385650613476577e-06 8.091278451728344e-06 1.2460869401480828e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0001028691918645833 0.0002737040057685444 0.0003861446001781946 0.0004042287651515365 0.0017229200225725174 0.003198296698131205 0.008774096120579751 0.011237818178923189 0.004334800036723805 0.0007344916552783145 -0.0001506915192259342 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-1.2482511756156149e-05 1.365124801275985e-05 1.3894049203809568e-05 2.3985465221727954e-05 3.3458449092465795e-05 0.00028172299406359233 0.00040056109827889085 0.0004621959325200118 0.0034637215474633033 0.009153352872912168 0.012804683731760212 0.010674833967812809 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.005346497059990333 -0.002010348201210142 -0.0010943235863089423 0.0001661513182702165 0.00012025969610516196 2.4949866002221845e-05 6.627236360802077e-06 3.003757825105864e-06 3.997348910159012e-05 0.000427961841918743 0.0007451357800599296 0.0011219432594133996 0.009685550613014016 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.013431011504370738 0.007883426617122005 0.007935899204760883 0.005880150773602205 0.0009832099103910489 0.005414528729313218 0.0015950126575825377 0.00024127039666882992 -1.5674461809944553e-05 1.0711548076574028e-05 7.830483572860064e-06 0.00011012649333888752 0.0005497452692208139 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.0696915445106504e-05 6.184559535738335e-05 5.870203846064511e-05 -1.112085789465658e-05 -4.7600144351359347e-07 -5.861397594145908e-08 1.4524208784805573e-08 2.300649782987421e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +2.2218614171918013e-06 5.325319655352672e-06 7.766746363269582e-06 9.361315506075464e-06 5.0417710282874456e-05 9.822946186678772e-05 0.00026400568406806884 0.00033610865151919737 0.00013239814531221768 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.00013804169495254125 0.0012238504051117233 0.01461439973735456 0.010197731078827295 0.009003775355755566 0.030381456320656558 0.024785731678029766 0.004637019267552505 -0.005938106654005813 -0.002605150959220643 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-0.0002216303488927365 0.0001541319391627563 4.83626397765333e-05 2.1041902272582753e-05 0.00026610797279588076 0.00045665788403242036 0.00017325291338578903 0.0035336618936866277 0.018540440861910777 0.003501320637152642 0.002219074201926699 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.01652594711887213 0.011725805945708163 0.011173124362203699 0.0024178633067081135 -0.01796173780303683 -0.011618890946870497 -0.0008528234196397706 -9.706084806556783e-05 -2.754043401157181e-06 0.0001324948483342069 5.482811058752758e-05 0.0003886706609323921 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.008855607599180339 0.015278371659152929 0.0023879884417463693 0.000935102721182137 0.0034651523786104546 0.005282714096158778 0.0012741283037854573 0.006268847413803995 0.004013755514818873 0.010363477891131097 0.007109323912817858 -0.0002600093944564617 -0.00034633976332068713 0.0 0.0 0.0 0.0 0.0 0.0 +-2.698386662730078e-05 2.754973422173369e-07 0.0001320534807487939 0.004372176148977807 0.0015642026255259442 0.004248632573013906 0.00040885420395593786 0.001088966135412402 0.004766232525411325 0.002205157762668968 0.007459939889093756 0.005587608653898612 -0.004720162133268877 -0.006593174803103767 0.0 0.0 0.0 0.0 0.0 +-7.940872165606751e-05 2.276762148612182e-06 0.00010635762128769112 2.049233578255131e-05 0.00042145671490654473 0.01249692872936893 0.0020370917425772224 0.0017316344055948985 0.0006574004028558345 0.0012283310563930355 0.0014629455315045585 -4.492954039177435e-06 0.00029547002108771967 0.002683727758662211 0.004096710661285439 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +5.282737863089323e-05 6.328946161646202e-06 1.8329325276370316e-05 1.6423572667388823e-05 1.2653184610977003e-06 7.181714140248046e-06 3.491501462345434e-06 -7.285463619241614e-06 3.2609159022388403e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.4850777249143735e-05 7.094600012126306e-05 0.00030581781354430576 0.00044661036994300023 0.00016699596636619577 1.5860625743775105e-05 9.74250537001798e-07 5.385650613476577e-06 8.091278451728344e-06 1.2460869401480828e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-0.0002216303488927365 0.0001541319391627563 4.83626397765333e-05 2.1041902272582753e-05 0.00026610797279588076 0.00045665788403242036 0.00017325291338578903 0.0035336618936866277 0.018540440861910777 0.003501320637152642 0.002219074201926699 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.003917873880791907 -0.0007874629498581528 -2.4595030318112164e-05 -2.8508297646329816e-06 1.8504666071760445e-07 0.0001190800388356091 0.0035373487148805376 0.00037674157183609377 0.0012087894330956167 0.0009651695201594091 4.769364472898923e-05 0.0004612591073953361 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.00022640297379380707 -0.0005111351623843819 0.0002024994190007784 0.00044921539785371963 0.001393999756415734 0.0011754659552919043 7.761533188706794e-05 5.8170561410888746e-05 -1.0918989217761552e-05 -2.9455190099531973e-07 2.0845708467284646e-07 1.0072947935068441e-06 2.449241542240889e-06 0.0 0.0 0.0 0.0 0.0 0.0 +5.3159155089314414e-05 1.2012438398909825e-05 3.274115317951001e-05 1.689353008824745e-05 -4.232110203859359e-07 7.656160171407207e-06 5.754938338062256e-05 0.0002687156220968384 9.768544317740195e-05 1.0129360414562531e-05 2.293272526112481e-05 1.8260890221186993e-05 1.7288534885724222e-06 1.8856324749638164e-06 0.0 0.0 0.0 0.0 0.0 +4.542360076931743e-06 1.2329326209575631e-05 1.7173803033436737e-05 5.0102066463061734e-05 1.09067765324765e-05 4.930240898900306e-05 0.00028721835291257015 0.0007503332386451459 0.00015238128535605624 -6.391111549761724e-05 -4.677072820313549e-06 -5.572104125200205e-06 2.707663268609677e-05 5.022846595129856e-05 0.00012970076559689836 0.0 0.0 0.0 0.0 +0.0001650881267658455 6.548635015912796e-05 3.282822556024051e-05 7.205996516588195e-05 0.00030710620226134084 0.0007279352507540159 0.000909918529220897 0.0017257383928761386 0.00047543969768972346 -0.00030462814537952123 2.7321207199326783e-05 0.00010130812246147248 5.4817489360932934e-05 0.00012640103175376577 0.00018995742264027741 0.00023929212126678798 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6.9413198850914024e-06 2.107626397843018e-05 1.8155172114721186e-05 2.0928626557075606e-06 1.5632037328512312e-06 -2.7335717313450097e-07 -7.2126792356200426e-09 9.213093725547886e-09 4.186629643010996e-08 8.198811769753182e-08 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0001028691918645833 0.0002737040057685444 0.0003861446001781946 0.0004042287651515365 0.0017229200225725174 0.003198296698131205 0.008774096120579751 0.011237818178923189 0.004334800036723805 0.0007344916552783145 -0.0001506915192259342 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.01652594711887213 0.011725805945708163 0.011173124362203699 0.0024178633067081135 -0.01796173780303683 -0.011618890946870497 -0.0008528234196397706 -9.706084806556783e-05 -2.754043401157181e-06 0.0001324948483342069 5.482811058752758e-05 0.0003886706609323921 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.00022640297379380707 -0.0005111351623843819 0.0002024994190007784 0.00044921539785371963 0.001393999756415734 0.0011754659552919043 7.761533188706794e-05 5.8170561410888746e-05 -1.0918989217761552e-05 -2.9455190099531973e-07 2.0845708467284646e-07 1.0072947935068441e-06 2.449241542240889e-06 0.0 0.0 0.0 0.0 0.0 0.0 +0.0016181071043329578 0.003179470547568356 0.008661622548635572 0.011071785334468471 0.004294892778359652 0.0017845979744737465 0.0034643761195723064 0.015112039067322293 0.022192108732694595 0.008134230944897397 0.0007595380961610584 1.6727218309602107e-05 0.00012823915020345735 0.0001971442066043176 0.0 0.0 0.0 0.0 0.0 +0.00033854327480422193 0.0032940012133255356 0.008932075729876752 0.012661798131960687 0.013919159699477152 0.08208818801401566 0.15644219608737447 0.4341503084393359 0.557964838826116 0.21173866865770563 0.03478604116524652 -0.007972916161324952 -0.0007132020154210059 0.0004420932693293155 0.0003860741867263207 0.0 0.0 0.0 0.0 +0.0005943091729493132 0.0009672866630600067 0.009096489467732383 0.01304005169719466 0.01734885651081947 0.1652472792755658 0.44880261475702005 0.6329167707872334 0.5244926606398645 0.26270394857828266 -0.10487776273847933 -0.05845317239353218 0.0032135333670803676 0.003777214235598332 0.0007681993725802362 0.00011959437074006901 0.0 0.0 0.0 +6.489304732024981e-05 0.0011748014116558024 0.014162497237899634 0.024470256017495366 0.046651858009005745 0.46415330969555396 0.6536160620847673 0.38295932353650225 0.39318393240673155 0.2877811024545165 0.03747496490739291 0.2654106688863148 0.074634565935104 0.012330295300167044 -0.0004996457463809098 0.00023089219471653216 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +1.4231393739579515e-06 3.630746449160232e-07 9.318604659023228e-07 4.92311430374376e-07 -3.701479331898353e-09 2.1280257031614452e-07 1.2240989510544568e-06 5.3432540178806065e-06 2.043230389835189e-06 3.2740024159475547e-07 6.717304982644579e-07 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-1.2482511756156149e-05 1.365124801275985e-05 1.3894049203809568e-05 2.3985465221727954e-05 3.3458449092465795e-05 0.00028172299406359233 0.00040056109827889085 0.0004621959325200118 0.0034637215474633033 0.009153352872912168 0.012804683731760212 0.010674833967812809 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.008855607599180339 0.015278371659152929 0.0023879884417463693 0.000935102721182137 0.0034651523786104546 0.005282714096158778 0.0012741283037854573 0.006268847413803995 0.004013755514818873 0.010363477891131097 0.007109323912817858 -0.0002600093944564617 -0.00034633976332068713 0.0 0.0 0.0 0.0 0.0 0.0 +5.3159155089314414e-05 1.2012438398909825e-05 3.274115317951001e-05 1.689353008824745e-05 -4.232110203859359e-07 7.656160171407207e-06 5.754938338062256e-05 0.0002687156220968384 9.768544317740195e-05 1.0129360414562531e-05 2.293272526112481e-05 1.8260890221186993e-05 1.7288534885724222e-06 1.8856324749638164e-06 0.0 0.0 0.0 0.0 0.0 +0.00033854327480422193 0.0032940012133255356 0.008932075729876752 0.012661798131960687 0.013919159699477152 0.08208818801401566 0.15644219608737447 0.4341503084393359 0.557964838826116 0.21173866865770563 0.03478604116524652 -0.007972916161324952 -0.0007132020154210059 0.0004420932693293155 0.0003860741867263207 0.0 0.0 0.0 0.0 +0.00018639122271027446 0.0034767153815636618 0.018231622622978436 0.0042988446466234575 0.05300133577632108 0.7250033316881788 0.4935009383219143 0.42606157195551264 1.5039118559972142 1.2303936880370434 0.22548363428435172 -0.30298333788301807 -0.13073656424500055 -0.010403074319359695 0.005059645288601829 0.0015181780063355998 0.0 0.0 0.0 +0.0005854549915295117 0.008715343377777027 0.015086646356161998 0.00551449475752511 0.16771008674532747 0.9262472909137329 0.16287454314633398 0.10026082406557575 0.8138824998965698 0.5734788502649438 0.5447903546528722 0.10618098607332271 -0.9103493511412221 -0.576660316279193 -0.03402023384277208 -0.0031478924709104684 0.0 0.0 0.0 +-0.00011090752856021898 0.0043805342288213535 0.0016927729283659975 0.012954305343473369 0.4368797400066579 0.7614408833500013 0.10944765261392181 0.0412051224385603 0.15805652281823218 0.2585893276179897 0.05949650977132904 0.30356693149425945 0.19493804255113664 0.5122323478146567 0.35279041052227494 -0.007488446744915854 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 5.196157077391817e-07 6.938124100654148e-08 7.597564197383545e-08 1.863740632660483e-07 4.437837629589167e-07 5.453941063185757e-07 1.5602917821833568e-06 3.404289212094662e-07 9.967447994956849e-07 5.8845599651090215e-06 1.5052240335012455e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.005346497059990333 -0.002010348201210142 -0.0010943235863089423 0.0001661513182702165 0.00012025969610516196 2.4949866002221845e-05 6.627236360802077e-06 3.003757825105864e-06 3.997348910159012e-05 0.000427961841918743 0.0007451357800599296 0.0011219432594133996 0.009685550613014016 0.0 0.0 0.0 0.0 0.0 0.0 +-2.698386662730078e-05 2.754973422173369e-07 0.0001320534807487939 0.004372176148977807 0.0015642026255259442 0.004248632573013906 0.00040885420395593786 0.001088966135412402 0.004766232525411325 0.002205157762668968 0.007459939889093756 0.005587608653898612 -0.004720162133268877 -0.006593174803103767 0.0 0.0 0.0 0.0 0.0 +4.542360076931743e-06 1.2329326209575631e-05 1.7173803033436737e-05 5.0102066463061734e-05 1.09067765324765e-05 4.930240898900306e-05 0.00028721835291257015 0.0007503332386451459 0.00015238128535605624 -6.391111549761724e-05 -4.677072820313549e-06 -5.572104125200205e-06 2.707663268609677e-05 5.022846595129856e-05 0.00012970076559689836 0.0 0.0 0.0 0.0 +0.0005943091729493132 0.0009672866630600067 0.009096489467732383 0.01304005169719466 0.01734885651081947 0.1652472792755658 0.44880261475702005 0.6329167707872334 0.5244926606398645 0.26270394857828266 -0.10487776273847933 -0.05845317239353218 0.0032135333670803676 0.003777214235598332 0.0007681993725802362 0.00011959437074006901 0.0 0.0 0.0 +0.0005854549915295117 0.008715343377777027 0.015086646356161998 0.00551449475752511 0.16771008674532747 0.9262472909137329 0.16287454314633398 0.10026082406557575 0.8138824998965698 0.5734788502649438 0.5447903546528722 0.10618098607332271 -0.9103493511412221 -0.576660316279193 -0.03402023384277208 -0.0031478924709104684 0.0 0.0 0.0 +-0.011510449622067839 -0.0007610595804959427 1.0172131902385016e-05 0.00448473230635448 0.2199020425072735 0.07466247888373397 0.21339517449435372 0.013531084627798973 0.04473458040783101 0.2378714243611067 0.10478901497777 0.37112701147924365 0.27817806337533985 -0.2385293501359752 -0.33578482057600856 -0.004009555340792723 0.0 0.0 0.0 +4.1934884152796484e-05 0.0035902058234846823 0.0005824017329515572 0.01441762880686721 0.6293209695433368 0.09572421881003676 0.08586090788885907 0.031601835145355577 0.06121858995657405 0.07315778164682188 -0.0013308261229131521 0.012882908917780034 0.13273058077548822 0.2035107778991338 0.1961396131043037 -0.04170252478795313 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 3.196534127251379e-06 -1.1872677866681306e-06 -2.5678892066098854e-08 5.139117071436217e-09 1.1142431390092631e-06 2.0605776537608227e-06 5.297265009242829e-06 6.713907186544732e-06 2.7028644452395994e-06 1.149242737988068e-06 2.2449682976927855e-06 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.013431011504370738 0.007883426617122005 0.007935899204760883 0.005880150773602205 0.0009832099103910489 0.005414528729313218 0.0015950126575825377 0.00024127039666882992 -1.5674461809944553e-05 1.0711548076574028e-05 7.830483572860064e-06 0.00011012649333888752 0.0005497452692208139 0.0 0.0 0.0 0.0 0.0 +-7.940872165606751e-05 2.276762148612182e-06 0.00010635762128769112 2.049233578255131e-05 0.00042145671490654473 0.01249692872936893 0.0020370917425772224 0.0017316344055948985 0.0006574004028558345 0.0012283310563930355 0.0014629455315045585 -4.492954039177435e-06 0.00029547002108771967 0.002683727758662211 0.004096710661285439 0.0 0.0 0.0 0.0 +0.0001650881267658455 6.548635015912796e-05 3.282822556024051e-05 7.205996516588195e-05 0.00030710620226134084 0.0007279352507540159 0.000909918529220897 0.0017257383928761386 0.00047543969768972346 -0.00030462814537952123 2.7321207199326783e-05 0.00010130812246147248 5.4817489360932934e-05 0.00012640103175376577 0.00018995742264027741 0.00023929212126678798 0.0 0.0 0.0 +6.489304732024981e-05 0.0011748014116558024 0.014162497237899634 0.024470256017495366 0.046651858009005745 0.46415330969555396 0.6536160620847673 0.38295932353650225 0.39318393240673155 0.2877811024545165 0.03747496490739291 0.2654106688863148 0.074634565935104 0.012330295300167044 -0.0004996457463809098 0.00023089219471653216 0.0 0.0 0.0 +-0.00011090752856021898 0.0043805342288213535 0.0016927729283659975 0.012954305343473369 0.4368797400066579 0.7614408833500013 0.10944765261392181 0.0412051224385603 0.15805652281823218 0.2585893276179897 0.05949650977132904 0.30356693149425945 0.19493804255113664 0.5122323478146567 0.35279041052227494 -0.007488446744915854 0.0 0.0 0.0 +4.1934884152796484e-05 0.0035902058234846823 0.0005824017329515572 0.01441762880686721 0.6293209695433368 0.09572421881003676 0.08586090788885907 0.031601835145355577 0.06121858995657405 0.07315778164682188 -0.0013308261229131521 0.012882908917780034 0.13273058077548822 0.2035107778991338 0.1961396131043037 -0.04170252478795313 0.0 0.0 0.0 +-0.0008465335016788498 -9.208409992139663e-05 -1.1210629044433908e-05 0.004300763141885697 0.1800503541691201 0.016819879476467067 0.060737350690215776 0.042330087306607714 0.0007006095666399378 0.02251352126872946 0.011185142175963118 -0.02716513333374441 0.00952941322650142 0.02210443704516212 0.07011148238258197 0.057840211345517194 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +# diff --git a/potentials/README b/potentials/README index 2cb4a383c5..2d6d4c172a 100644 --- a/potentials/README +++ b/potentials/README @@ -118,4 +118,5 @@ sw Stillinger-Weber potential tersoff Tersoff potential tersoff.mod modified Tersoff potential tersoff.zbl Tersoff with ZBL core +uf3 UF3 potential vashishta Vashishta 2-body and 3-body potential diff --git a/python/lammps/core.py b/python/lammps/core.py index 9ab6661df5..8966a77440 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -891,7 +891,7 @@ class lammps(object): # set length of vector for items that are not a scalar vec_dict = { 'boxlo':3, 'boxhi':3, 'sublo':3, 'subhi':3, 'sublo_lambda':3, 'subhi_lambda':3, 'periodicity':3, - 'special_lj':4, 'special_coul':4 } + 'special_lj':4, 'special_coul':4, 'procgrid':3 } if name in vec_dict: veclen = vec_dict[name] elif name == 'respa_dt': diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index 7dd3823bbf..96384255c2 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -796,18 +796,16 @@ class PyLammps(object): comm = {} comm['nprocs'] = self.lmp.extract_setting("world_size") comm['nthreads'] = self.lmp.extract_setting("nthreads") + comm['proc_grid'] = comm['procgrid'] = self.lmp.extract_global("procgrid") + idx = self.lmp.extract_setting("comm_style") + comm['comm_style'] = ('brick', 'tiled')[idx] + idx = self.lmp.extract_setting("comm_style") + comm['comm_layout'] = ('uniform', 'nonuniform', 'irregular')[idx] + comm['ghost_velocity'] = self.lmp.extract_setting("ghost_velocity") == 1 for line in output: if line.startswith("MPI library"): comm['mpi_version'] = line.split(':')[1].strip() - elif line.startswith("Comm style"): - parts = self._split_values(line) - comm['comm_style'] = self._get_pair(parts[0])[1] - comm['comm_layout'] = self._get_pair(parts[1])[1] - elif line.startswith("Processor grid"): - comm['proc_grid'] = [int(x) for x in self._get_pair(line)[1].split('x')] - elif line.startswith("Communicate velocities for ghost atoms"): - comm['ghost_velocity'] = (self._get_pair(line)[1] == "yes") return comm def _parse_element_list(self, output): diff --git a/src/.gitignore b/src/.gitignore index d7fa23a615..278d7ef6ce 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -169,6 +169,17 @@ /rann_*.cpp /rann_*.h +/pair_uf3.cpp +/pair_uf3.h +/uf3_bspline_basis2.cpp +/uf3_bspline_basis2.h +/uf3_bspline_basis3.cpp +/uf3_bspline_basis3.h +/uf3_pair_bspline.cpp +/uf3_pair_bspline.h +/uf3_triplet_bspline.cpp +/uf3_triplet_bspline.h + /compute_test_nbl.cpp /compute_test_nbl.h /pair_multi_lucy.cpp @@ -1706,6 +1717,8 @@ /pair_dpd.h /pair_dpd_tstat.cpp /pair_dpd_tstat.h +/pair_dpd_coul_slater_long.cpp +/pair_dpd_coul_slater_long.h /pair_dpd_ext.cpp /pair_dpd_ext.h /pair_dpd_ext_tstat.cpp diff --git a/src/BPM/bond_bpm.cpp b/src/BPM/bond_bpm.cpp index 9c2c680cc5..e8521df32a 100644 --- a/src/BPM/bond_bpm.cpp +++ b/src/BPM/bond_bpm.cpp @@ -352,19 +352,32 @@ void BondBPM::process_broken(int i, int j) { if (!break_flag) error->one(FLERR, "BPM bond broke with break no option"); - if (fix_store_local) { - for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n, i, j); - fix_store_local->add_data(output_data, i, j); + int nlocal = atom->nlocal; + if (fix_store_local) { + // If newton off, bond can break on two procs so only record if proc owns lower tag + // (BPM bond styles should sort so i -> atom with lower tag) + if (force->newton_bond || (i < nlocal)) { + for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n, i, j); + fix_store_local->add_data(output_data, i, j); + } } - if (fix_update_special_bonds) fix_update_special_bonds->add_broken_bond(i, j); + if (fix_update_special_bonds) { + // If this processor owns two copies of the bond (i.e. if the domain is periodic and 1 proc thick), + // skip instance where larger tag (j) owned + int check = 1; + if (i >= nlocal) { + int imap = atom->map(atom->tag[i]); + if (imap < nlocal) check = 0; + } + if (check) fix_update_special_bonds->add_broken_bond(i, j); + } // Manually search and remove from atom arrays // need to remove in case special bonds arrays rebuilt - int m, n; - int nlocal = atom->nlocal; + int m, n; tagint *tag = atom->tag; tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; diff --git a/src/BPM/compute_nbond_atom.cpp b/src/BPM/compute_nbond_atom.cpp index 4f0fc4c3f0..85ef6f3fce 100644 --- a/src/BPM/compute_nbond_atom.cpp +++ b/src/BPM/compute_nbond_atom.cpp @@ -65,14 +65,13 @@ void ComputeNBondAtom::compute_peratom() tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; - int ntotal = nlocal; - if (force->newton) ntotal += atom->nghost; - // set local nbond array int i, j, k; int *num_bond = atom->num_bond; int newton_bond = force->newton_bond; + int ntotal = nlocal; + if (newton_bond) ntotal += atom->nghost; for (i = 0; i < ntotal; i++) nbond[i] = 0; for (i = 0; i < nlocal; i++) { @@ -88,7 +87,7 @@ void ComputeNBondAtom::compute_peratom() } // communicate ghost nbond between neighbor procs - if (force->newton) comm->reverse_comm(this); + if (newton_bond) comm->reverse_comm(this); // zero nbond of atoms not in group // only do this after comm since ghost contributions must be included diff --git a/src/BPM/fix_update_special_bonds.cpp b/src/BPM/fix_update_special_bonds.cpp index cdc72ee987..1b408d6d4b 100644 --- a/src/BPM/fix_update_special_bonds.cpp +++ b/src/BPM/fix_update_special_bonds.cpp @@ -100,6 +100,7 @@ void FixUpdateSpecialBonds::pre_exchange() n1 = nspecial[i][0]; for (m = 0; m < n1; m++) if (slist[m] == tagj) break; + if (m == n1) error->one(FLERR, "Special bond {} {} not found", tagi, tagj); for (; m < n1 - 1; m++) slist[m] = slist[m + 1]; nspecial[i][0]--; nspecial[i][1] = nspecial[i][2] = nspecial[i][0]; @@ -110,6 +111,7 @@ void FixUpdateSpecialBonds::pre_exchange() n1 = nspecial[j][0]; for (m = 0; m < n1; m++) if (slist[m] == tagi) break; + if (m == n1) error->one(FLERR, "Special bond {} {} not found", tagi, tagj); for (; m < n1 - 1; m++) slist[m] = slist[m + 1]; nspecial[j][0]--; nspecial[j][1] = nspecial[j][2] = nspecial[j][0]; diff --git a/src/COLVARS/ndx_group.cpp b/src/COLVARS/ndx_group.cpp deleted file mode 100644 index 4170a9ea70..0000000000 --- a/src/COLVARS/ndx_group.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// clang-format off -// -*- c++ -*- - -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing author: Axel Kohlmeyer (Temple U) -------------------------------------------------------------------------- */ - -#include "ndx_group.h" - -#include "atom.h" -#include "comm.h" -#include "error.h" -#include "group.h" -#include "tokenizer.h" - -using namespace LAMMPS_NS; -static constexpr int BUFLEN = 4096; - -// read file until next section "name" or any next section if name == "" - -static std::string find_section(FILE *fp, const std::string &name) -{ - char linebuf[BUFLEN]; - - std::string pattern = "^\\s*\\[\\s+\\S+\\s+\\]\\s*$"; - if (!name.empty()) - pattern = fmt::format("^\\s*\\[\\s+{}\\s+\\]\\s*$",name); - - fgets(linebuf,BUFLEN,fp); - while (!feof(fp)) { - if (utils::strmatch(linebuf,pattern)) - return Tokenizer(linebuf).as_vector()[1]; - fgets(linebuf,BUFLEN,fp); - } - return ""; -} - -static std::vector read_section(FILE *fp, std::string &name) -{ - char linebuf[BUFLEN]; - std::vector tagbuf; - std::string pattern = "^\\s*\\[\\s+\\S+\\s+\\]\\s*$"; - - while (fgets(linebuf,BUFLEN,fp)) { - // start of new section. we are done, update "name" - if (utils::strmatch(linebuf,pattern)) { - name = Tokenizer(linebuf).as_vector()[1]; - return tagbuf; - } - ValueTokenizer values(linebuf); - while (values.has_next()) - tagbuf.push_back(values.next_tagint()); - } - // set empty name to indicate end of file - name = ""; - return tagbuf; -} - -/* ---------------------------------------------------------------------- */ - -void Ndx2Group::command(int narg, char **arg) -{ - int len; - bigint num; - FILE *fp; - std::string name, next; - - if (narg < 1) error->all(FLERR,"Illegal ndx2group command"); - if (atom->tag_enable == 0) - error->all(FLERR,"Must have atom IDs for ndx2group command"); - if (atom->map_style == Atom::MAP_NONE) - error->all(FLERR,"Must have an atom map for ndx2group command"); - if (comm->me == 0) { - fp = fopen(arg[0], "r"); - if (fp == nullptr) - error->one(FLERR,"Cannot open index file for reading: {}", - utils::getsyserror()); - utils::logmesg(lmp,"Reading groups from index file {}:\n",arg[0]); - } - - if (narg == 1) { // restore all groups - - if (comm->me == 0) { - name = find_section(fp,""); - while (!name.empty()) { - - // skip over group "all", which is called "System" in gromacs - if (name == "System") { - name = find_section(fp,""); - continue; - } - - utils::logmesg(lmp," Processing group '{}'\n",name); - len = name.size()+1; - MPI_Bcast(&len,1,MPI_INT,0,world); - if (len > 1) { - MPI_Bcast((void *)name.c_str(),len,MPI_CHAR,0,world); - - // read tags for atoms in group and broadcast - std::vector tags = read_section(fp,next); - num = tags.size(); - MPI_Bcast(&num,1,MPI_LMP_BIGINT,0,world); - MPI_Bcast((void *)tags.data(),num,MPI_LMP_TAGINT,0,world); - create(name,tags); - name = next; - } - } - len = -1; - MPI_Bcast(&len,1,MPI_INT,0,world); - - } else { - - while (true) { - MPI_Bcast(&len,1,MPI_INT,0,world); - if (len < 0) break; - if (len > 1) { - char *buf = new char[len]; - MPI_Bcast(buf,len,MPI_CHAR,0,world); - MPI_Bcast(&num,1,MPI_LMP_BIGINT,0,world); - tagint *tbuf = new tagint[num]; - MPI_Bcast(tbuf,num,MPI_LMP_TAGINT,0,world); - create(buf,std::vector(tbuf,tbuf+num)); - delete[] buf; - delete[] tbuf; - } - } - } - - } else { // restore selected groups - - for (int idx=1; idx < narg; ++idx) { - if (comm->me == 0) { - - // find named section, search from beginning of file - rewind(fp); - name = find_section(fp,arg[idx]); - utils::logmesg(lmp," {} group '{}'\n", name.size() - ? "Processing" : "Skipping",arg[idx]); - len = name.size()+1; - MPI_Bcast(&len,1,MPI_INT,0,world); - if (len > 1) { - MPI_Bcast((void *)name.c_str(),len,MPI_CHAR,0,world); - - // read tags for atoms in group and broadcast - std::vector tags = read_section(fp,next); - num = tags.size(); - MPI_Bcast(&num,1,MPI_LMP_BIGINT,0,world); - MPI_Bcast((void *)tags.data(),num,MPI_LMP_TAGINT,0,world); - create(name,tags); - name = next; - } - } else { - MPI_Bcast(&len,1,MPI_INT,0,world); - if (len > 1) { - char *buf = new char[len]; - MPI_Bcast(buf,len,MPI_CHAR,0,world); - MPI_Bcast(&num,1,MPI_LMP_BIGINT,0,world); - tagint *tbuf = new tagint[num]; - MPI_Bcast(tbuf,num,MPI_LMP_TAGINT,0,world); - create(buf,std::vector(tbuf,tbuf+num)); - delete[] buf; - delete[] tbuf; - } - } - } - } - if (comm->me == 0) fclose(fp); -} - -/* ---------------------------------------------------------------------- */ - -void Ndx2Group::create(const std::string &name, const std::vector &tags) -{ - // wipe out all members if the group exists. gid==0 is group "all" - int gid = group->find(name); - if (gid > 0) group->assign(name + " clear"); - - // map from global to local - const int nlocal = atom->nlocal; - int *flags = (int *)calloc(nlocal,sizeof(int)); - for (bigint i=0; i < (int)tags.size(); ++i) { - const int id = atom->map(tags[i]); - if (id < nlocal && id >= 0) flags[id] = 1; - } - group->create(name,flags); - free(flags); -} diff --git a/src/DPD-BASIC/Install.sh b/src/DPD-BASIC/Install.sh new file mode 100755 index 0000000000..7371e2fad6 --- /dev/null +++ b/src/DPD-BASIC/Install.sh @@ -0,0 +1,39 @@ +# Install/unInstall package files in LAMMPS +# mode = 0/1/2 for uninstall/install/update + +mode=$1 + +# enforce using portable C locale +LC_ALL=C +export LC_ALL + +# arg1 = file, arg2 = file it depends on + +action () { + if (test $mode = 0) then + rm -f ../$1 + elif (! cmp -s $1 ../$1) then + if (test -z "$2" || test -e ../$2) then + cp $1 .. + if (test $mode = 2) then + echo " updating src/$1" + fi + fi + elif (test -n "$2") then + if (test ! -e ../$2) then + rm -f ../$1 + fi + fi +} + +# list of files with optional dependcies +action pair_dpd_coul_slater_long.cpp pppm.cpp +action pair_dpd_coul_slater_long.h pppm.h +action pair_dpd.cpp +action pair_dpd_ext.cpp +action pair_dpd_ext.h +action pair_dpd_ext_tstat.cpp +action pair_dpd_ext_tstat.h +action pair_dpd.h +action pair_dpd_tstat.cpp +action pair_dpd_tstat.h diff --git a/src/DPD-BASIC/pair_dpd_coul_slater_long.cpp b/src/DPD-BASIC/pair_dpd_coul_slater_long.cpp new file mode 100644 index 0000000000..c4af283a9e --- /dev/null +++ b/src/DPD-BASIC/pair_dpd_coul_slater_long.cpp @@ -0,0 +1,544 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Eddy BARRAUD (IFPEN/Sorbonne) +------------------------------------------------------------------------- */ + +#include "pair_dpd_coul_slater_long.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "random_mars.h" +#include "update.h" + +#include "ewald_const.h" +#include "kspace.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace EwaldConst; + +static constexpr double EPSILON = 1.0e-10; + +/* ---------------------------------------------------------------------- */ + +PairDPDCoulSlaterLong::PairDPDCoulSlaterLong(LAMMPS *lmp) : + Pair(lmp), cut_dpd(nullptr), cut_dpdsq(nullptr), cut_slatersq(nullptr), + a0(nullptr), gamma(nullptr), sigma(nullptr), random(nullptr) +{ + writedata = 1; + ewaldflag = pppmflag = 1; + respa_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairDPDCoulSlaterLong::~PairDPDCoulSlaterLong() +{ + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(cut_dpd); + memory->destroy(cut_dpdsq); + memory->destroy(cut_slatersq); + + memory->destroy(cut); + memory->destroy(a0); + memory->destroy(gamma); + memory->destroy(sigma); + } + + if (random) delete random; +} + +/* ---------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair; + double vxtmp,vytmp,vztmp,delvx,delvy,delvz; + double r2inv,forcedpd,forcecoul,factor_coul; + double grij,expm2,prefactor,t,erfc; + double rsq,r,rinv,dot,wd,randnum,factor_dpd,factor_sqrt; + int *ilist,*jlist,*numneigh,**firstneigh; + double slater_term; + + evdwl = ecoul = 0.0; + ev_init(eflag,vflag); + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + double dtinvsqrt = 1.0/sqrt(update->dt); + + double *q = atom->q; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_dpd = special_lj[sbmask(j)]; + factor_sqrt = special_sqrt[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + // forces if below maximum cutoff + if (rsq < cutsq[itype][jtype]) { + r = sqrt(rsq); + if (evflag) evdwl = ecoul = 0.0; + + // apply DPD force if distance below DPD cutoff + if (rsq < cut_dpdsq[itype][jtype] && r > EPSILON) { + rinv = 1.0/r; + delvx = vxtmp - v[j][0]; + delvy = vytmp - v[j][1]; + delvz = vztmp - v[j][2]; + dot = delx*delvx + dely*delvy + delz*delvz; + wd = 1.0 - r/cut_dpd[itype][jtype]; + randnum = random->gaussian(); + + // conservative force = a0 * wd + // drag force = -gamma * wd^2 * (delx dot delv) / r + // random force = sigma * wd * rnd * dtinvsqrt; + // random force must be scaled by sqrt(factor_dpd) + + forcedpd = a0[itype][jtype]*wd; + forcedpd -= gamma[itype][jtype]*wd*wd*dot*rinv; + forcedpd *= factor_dpd; + forcedpd += factor_sqrt*sigma[itype][jtype]*wd*randnum*dtinvsqrt; + forcedpd *= rinv; + + if (eflag) { + // eng shifted to 0.0 at cutoff + evdwl = 0.5*a0[itype][jtype]*cut_dpd[itype][jtype] * wd*wd; + evdwl *= factor_dpd; + } + + } else forcedpd = 0.0; + + // apply Slater electrostatic force if distance below Slater cutoff + // and the two species are charged + if (rsq < cut_slatersq[itype][jtype]){ + r2inv = 1.0/rsq; + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + slater_term = exp(-2*r/lamda)*(1 + (2*r/lamda*(1+r/lamda))); + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2 - slater_term); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor*(1-slater_term); + forcecoul *= r2inv; + + if (eflag) { + ecoul = prefactor*(erfc - (1 + r/lamda)*exp(-2*r/lamda)); + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor*(1.0-(1 + r/lamda)*exp(-2*r/lamda)); + } + + } else forcecoul = 0.0; + + fpair = forcedpd + forcecoul; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,ecoul,fpair,delx,dely,delz); + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::allocate() +{ + int i,j; + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(cut_dpd,n+1,n+1,"pair:cut_dpd"); + memory->create(cut_dpdsq,n+1,n+1,"pair:cut_dpdsq"); + memory->create(cut_slatersq,n+1,n+1,"pair:cut_slatersq"); + memory->create(a0,n+1,n+1,"pair:a0"); + memory->create(gamma,n+1,n+1,"pair:gamma"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + for (i = 0; i <= atom->ntypes; i++) + for (j = 0; j <= atom->ntypes; j++) + sigma[i][j] = gamma[i][j] = 0.0; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::settings(int narg, char **arg) +{ + // params : T cut_dpd seed lambda cut_coul + if (narg != 5) error->all(FLERR,"Illegal pair_style command"); + + temperature = utils::numeric(FLERR,arg[0],false,lmp); + cut_global = utils::numeric(FLERR,arg[1],false,lmp); + seed = utils::inumeric(FLERR,arg[2],false,lmp); + lamda = utils::numeric(FLERR,arg[3],false,lmp); + cut_coul = utils::numeric(FLERR,arg[4],false,lmp); + + // initialize Marsaglia RNG with processor-unique seed + + if (seed <= 0) + error->all(FLERR,"Invalid random seed {} for pair_style dpd/coul/slater/long command", seed); + delete random; + random = new RanMars(lmp,seed + comm->me); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) + if (setflag[i][j]) cut_dpd[i][j] = MAX(cut_global,cut_coul); + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 6) + error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error); + utils::bounds(FLERR,arg[1],1,atom->ntypes,jlo,jhi,error); + + double a0_one = utils::numeric(FLERR,arg[2],false,lmp); + double gamma_one = utils::numeric(FLERR,arg[3],false,lmp); + + double cut_one = cut_global; + double cut_two = 0.0; + + if (narg > 4) { + bool do_slater = utils::logical(FLERR,arg[4],false,lmp); + if (do_slater) cut_two = cut_coul; + } + + if (narg > 5) cut_one = utils::numeric(FLERR,arg[5],false,lmp); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + a0[i][j] = a0_one; + gamma[i][j] = gamma_one; + cut_dpd[i][j] = cut_one; + cut_slatersq[i][j] = cut_two * cut_two; + cut[i][j] = MAX(cut_one, cut_two); + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::init_style() +{ + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair dpd requires ghost atoms store velocity"); + if (!atom->q_flag) + error->all(FLERR,"Pair style coul/slater/long requires atom attribute q"); + + // if newton off, forces between atoms ij will be double computed + // using different random numbers + + if (force->newton_pair == 0 && comm->me == 0) + error->warning(FLERR, "Pair dpd needs newton pair on for momentum conservation"); + + neighbor->add_request(this); + + // precompute random force scaling factors + + for (int i = 0; i < 4; ++i) special_sqrt[i] = sqrt(force->special_lj[i]); + + + // ensure use of KSpace long-range solver, set g_ewald + + if (force->kspace == nullptr) + error->all(FLERR,"Pair style requires a KSpace style"); + g_ewald = force->kspace->g_ewald; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i + return the maximum cutoff between Slater or DPD cutoff if charged + return the DPD cutoff for uncharged +------------------------------------------------------------------------- */ + +double PairDPDCoulSlaterLong::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + sigma[i][j] = sqrt(2.0*force->boltz*temperature*gamma[i][j]); + + cut_dpdsq[i][j] = cut_dpd[i][j] * cut_dpd[i][j]; + + a0[j][i] = a0[i][j]; + gamma[j][i] = gamma[i][j]; + sigma[j][i] = sigma[i][j]; + cut_dpd[j][i] = cut_dpd[i][j]; + cut[j][i] = cut[i][j]; + cut_dpdsq[j][i] = cut_dpdsq[i][j]; + cut_slatersq[j][i] = cut_slatersq[i][j]; + + return MAX(cut_dpd[i][j], sqrt(cut_slatersq[i][j])); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::write_restart(FILE *fp) +{ + write_restart_settings(fp); + + int i,j; + for (i = 1; i <= atom->ntypes; i++) { + for (j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j],sizeof(int),1,fp); + if (setflag[i][j]) { + fwrite(&a0[i][j],sizeof(double),1,fp); + fwrite(&gamma[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + fwrite(&cut_dpd[i][j],sizeof(double),1,fp); + fwrite(&cut_slatersq[i][j],sizeof(double),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::read_restart(FILE *fp) +{ + read_restart_settings(fp); + + allocate(); + + int i,j; + int me = comm->me; + for (i = 1; i <= atom->ntypes; i++) { + for (j = i; j <= atom->ntypes; j++) { + if (me == 0) utils::sfread(FLERR,&setflag[i][j],sizeof(int),1,fp,nullptr,error); + MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + if (setflag[i][j]) { + if (me == 0) { + utils::sfread(FLERR,&a0[i][j],sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&gamma[i][j],sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&cut[i][j],sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&cut_dpd[i][j],sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&cut_slatersq[i][j],sizeof(double),1,fp,nullptr,error); + } + MPI_Bcast(&a0[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gamma[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_dpd[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_slatersq[i][j],1,MPI_DOUBLE,0,world); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::write_restart_settings(FILE *fp) +{ + fwrite(&temperature,sizeof(double),1,fp); + fwrite(&cut_global,sizeof(double),1,fp); + fwrite(&seed,sizeof(int),1,fp); + fwrite(&lamda,sizeof(double),1,fp); + fwrite(&cut_coul,sizeof(double),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + utils::sfread(FLERR,&temperature,sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&cut_global,sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&seed,sizeof(int),1,fp,nullptr,error); + utils::sfread(FLERR,&lamda,sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&cut_coul,sizeof(double),1,fp,nullptr,error); + } + MPI_Bcast(&temperature,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&seed,1,MPI_INT,0,world); + MPI_Bcast(&lamda,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world); + + // initialize Marsaglia RNG with processor-unique seed + // same seed that pair_style command initially specified + + if (random) delete random; + random = new RanMars(lmp,seed + comm->me); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + fprintf(fp,"%d %g %g\n",i,a0[i][i],gamma[i][i]); +} + +/* ---------------------------------------------------------------------- + proc 0 writes all pairs to data file +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLong::write_data_all(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) + fprintf(fp,"%d %d %g %g %s %g\n",i,j,a0[i][j],gamma[i][j], + (cut_slatersq[i][j] == 0.0) ? "yes" : "no", cut_dpd[i][j]); +} + +/* ---------------------------------------------------------------------- */ + +double PairDPDCoulSlaterLong::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_dpd, double &fforce) +{ + double r,rinv,wd,phi; + double r2inv,grij,expm2,t,erfc,prefactor; + double slater_term; + double forcecoul,phicoul; + + double energy = 0.0; + fforce = 0.0; + + r = sqrt(rsq); + + // compute DPD force and energy + if (rsq < cut_dpdsq[itype][jtype] && r > EPSILON) { + rinv = 1.0/r; + wd = 1.0 - r/cut_dpd[itype][jtype]; + fforce += a0[itype][jtype]*wd * factor_dpd*rinv; + + phi = 0.5*a0[itype][jtype]*cut_dpd[itype][jtype] * wd*wd; + energy += factor_dpd*phi; + } + + // compute Slater coulombic force and energy + if (atom->q[i]*atom->q[j] != 0.0 && rsq < cut_slatersq[itype][jtype]) { + r2inv = 1.0/rsq; + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + slater_term = exp(-2*r/lamda)*(1 + (2*r/lamda*(1+r/lamda))); + prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2 - slater_term); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + fforce += forcecoul * r2inv; + phicoul = prefactor*(erfc - (1 + r/lamda)*exp(-2*r/lamda)); + if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; + energy += phicoul; + } + + return energy; +} + +void *PairDPDCoulSlaterLong::extract(const char *str, int &dim) +{ + dim = 0; + if (strcmp(str,"cut_coul") == 0) return (void *) &cut_coul; + if (strcmp(str,"lamda") == 0) return (void *) &lamda; + dim = 2; + if (strcmp(str,"a0") == 0) return (void *) a0; + if (strcmp(str,"gamma") == 0) return (void *) gamma; + return nullptr; +} diff --git a/src/DPD-BASIC/pair_dpd_coul_slater_long.h b/src/DPD-BASIC/pair_dpd_coul_slater_long.h new file mode 100644 index 0000000000..c5fb975fbe --- /dev/null +++ b/src/DPD-BASIC/pair_dpd_coul_slater_long.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(dpd/coul/slater/long,PairDPDCoulSlaterLong); +// clang-format on +#else + +#ifndef LMP_PAIR_DPD_COUL_SLATER_LONG_H +#define LMP_PAIR_DPD_COUL_SLATER_LONG_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairDPDCoulSlaterLong : public Pair { + public: + PairDPDCoulSlaterLong(class LAMMPS *); + ~PairDPDCoulSlaterLong() override; + void compute(int, int) override; + void settings(int, char **) override; + void coeff(int, char **) override; + void init_style() override; + double init_one(int, int) override; + void write_restart(FILE *) override; + void read_restart(FILE *) override; + void write_restart_settings(FILE *) override; + void read_restart_settings(FILE *) override; + void write_data(FILE *) override; + void write_data_all(FILE *) override; + double single(int, int, int, int, double, double, double, double &) override; + void *extract(const char *, int &) override; + + protected: + double cut_global, temperature; + double special_sqrt[4]; + int seed; + double **cut; + double **cut_dpd, **cut_dpdsq, **cut_slatersq; + double **a0, **gamma; + double **sigma; + class RanMars *random; + double cut_coul, qdist; + double lamda; + double g_ewald; + + virtual void allocate(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/Depend.sh b/src/Depend.sh index 3df1347e67..280fcdc4d8 100755 --- a/src/Depend.sh +++ b/src/Depend.sh @@ -116,6 +116,7 @@ if (test $1 = "KSPACE") then depend CG-SPICA depend CORESHELL depend DIELECTRIC + depend DPD-BASIC depend GPU depend KOKKOS depend OPT diff --git a/src/COLVARS/group_ndx.cpp b/src/EXTRA-COMMAND/group_ndx.cpp similarity index 59% rename from src/COLVARS/group_ndx.cpp rename to src/EXTRA-COMMAND/group_ndx.cpp index 05a50a1596..1dc0d3af97 100644 --- a/src/COLVARS/group_ndx.cpp +++ b/src/EXTRA-COMMAND/group_ndx.cpp @@ -1,4 +1,3 @@ -// clang-format off // -*- c++ -*- /* ---------------------------------------------------------------------- @@ -34,12 +33,15 @@ using namespace LAMMPS_NS; static int cmptagint(const void *p1, const void *p2) { - const tagint i1 = * static_cast(p1); - const tagint i2 = * static_cast(p2); - if (i1 == i2) return 0; + const tagint i1 = *static_cast(p1); + const tagint i2 = *static_cast(p2); + if (i1 == i2) + return 0; else { - if (i1 < i2) return -1; - else return 1; + if (i1 < i2) + return -1; + else + return 1; } } @@ -49,27 +51,24 @@ void Group2Ndx::command(int narg, char **arg) { FILE *fp = nullptr; - if (narg < 1) error->all(FLERR,"Illegal group2ndx command"); + if (narg < 1) utils::missing_cmd_args(FLERR, "group2ndx", error); - if (atom->tag_enable == 0) - error->all(FLERR,"Must have atom IDs for group2ndx command"); + if (atom->tag_enable == 0) error->all(FLERR, "Must have atom IDs for group2ndx command"); if (comm->me == 0) { fp = fopen(arg[0], "w"); if (fp == nullptr) - error->one(FLERR,"Cannot open index file for writing: {}", utils::getsyserror()); - utils::logmesg(lmp,"Writing groups to index file {}:\n",arg[0]); + error->one(FLERR, "Cannot open index file for writing: {}", utils::getsyserror()); + utils::logmesg(lmp, "Writing groups to index file {}:\n", arg[0]); } - if (narg == 1) { // write out all groups - for (int i=0; i < group->ngroup; ++i) { - write_group(fp,i); - } - } else { // write only selected groups - for (int i=1; i < narg; ++i) { + if (narg == 1) { // write out all groups + for (int i = 0; i < group->ngroup; ++i) { write_group(fp, i); } + } else { // write only selected groups + for (int i = 1; i < narg; ++i) { int gid = group->find(arg[i]); if (gid < 0) error->all(FLERR, "Non-existing group requested"); - write_group(fp,gid); + write_group(fp, gid); } } @@ -85,22 +84,26 @@ void Group2Ndx::write_group(FILE *fp, int gid) bigint gcount = group->count(gid); int lnum, width, cols; + if (utils::strmatch(group->names[gid], "\\s+")) { + if (fp) utils::logmesg(lmp, " skipping group {}...done", group->names[gid]); + return; + } if (fp) { - utils::logmesg(lmp," writing group {}...",group->names[gid]); + utils::logmesg(lmp, " writing group {}...", group->names[gid]); // the "all" group in LAMMPS is called "System" in Gromacs if (gid == 0) { fputs("[ System ]\n", fp); } else { - fmt::print(fp,"[ {} ]\n", group->names[gid]); + fmt::print(fp, "[ {} ]\n", group->names[gid]); } - width = log10((double) atom->natoms)+2; + width = log10((double) atom->natoms) + 2; cols = 80 / width; } if (gcount > 0) { - const int * const mask = atom->mask; - const tagint * const tag = atom->tag; + const int *const mask = atom->mask; + const tagint *const tag = atom->tag; const int groupbit = group->bitmask[gid]; const int nlocal = atom->nlocal; int i; @@ -111,45 +114,45 @@ void Group2Ndx::write_group(FILE *fp, int gid) for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) sendlist[lnum++] = tag[i]; - int nrecv=0; + int nrecv = 0; bigint allrecv; if (comm->me == 0) { MPI_Status status; MPI_Request request; - for (i=0; i < lnum; i++) - recvlist[i] = sendlist[i]; + for (i = 0; i < lnum; i++) recvlist[i] = sendlist[i]; allrecv = lnum; - for (i=1; i < comm->nprocs; ++i) { - MPI_Irecv(recvlist+allrecv,gcount-allrecv,MPI_LMP_TAGINT,i,0, world,&request); - MPI_Send(&nrecv,0,MPI_INT,i,0,world); // block rank "i" until we are ready to receive - MPI_Wait(&request,&status); - MPI_Get_count(&status,MPI_LMP_TAGINT,&nrecv); + for (i = 1; i < comm->nprocs; ++i) { + MPI_Irecv(recvlist + allrecv, gcount - allrecv, MPI_LMP_TAGINT, i, 0, world, &request); + // block rank "i" until we are ready to receive + MPI_Send(&nrecv, 0, MPI_INT, i, 0, world); + MPI_Wait(&request, &status); + MPI_Get_count(&status, MPI_LMP_TAGINT, &nrecv); allrecv += nrecv; } // sort received list - qsort((void *)recvlist, allrecv, sizeof(tagint), cmptagint); + qsort((void *) recvlist, allrecv, sizeof(tagint), cmptagint); } else { - MPI_Recv(&nrecv,0,MPI_INT,0,0,world,MPI_STATUS_IGNORE); - MPI_Rsend(sendlist,lnum,MPI_LMP_TAGINT,0,0,world); + MPI_Recv(&nrecv, 0, MPI_INT, 0, 0, world, MPI_STATUS_IGNORE); + MPI_Rsend(sendlist, lnum, MPI_LMP_TAGINT, 0, 0, world); } - delete [] sendlist; + delete[] sendlist; } if (fp) { int i, j; - for (i=0, j=0; i < gcount; ++i) { - fmt::print(fp,"{:>{}}",recvlist[i],width); + for (i = 0, j = 0; i < gcount; ++i) { + fmt::print(fp, "{:>{}}", recvlist[i], width); ++j; if (j == cols) { - fputs("\n",fp); + fputs("\n", fp); j = 0; } } - if (j > 0) fputs("\n",fp); - utils::logmesg(lmp,"done\n"); + if (j > 0) fputs("\n", fp); + utils::logmesg(lmp, "done\n"); } if (gcount > 0) delete[] recvlist; } diff --git a/src/COLVARS/group_ndx.h b/src/EXTRA-COMMAND/group_ndx.h similarity index 100% rename from src/COLVARS/group_ndx.h rename to src/EXTRA-COMMAND/group_ndx.h diff --git a/src/EXTRA-COMMAND/ndx_group.cpp b/src/EXTRA-COMMAND/ndx_group.cpp new file mode 100644 index 0000000000..c5b0d3cf8a --- /dev/null +++ b/src/EXTRA-COMMAND/ndx_group.cpp @@ -0,0 +1,220 @@ +// -*- c++ -*- + +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "ndx_group.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "group.h" +#include "tokenizer.h" + +using namespace LAMMPS_NS; +static constexpr int BUFLEN = 4096; + +// read file until next section "name" or any next section if name == "" + +static std::string find_section(FILE *fp, const std::string &name) +{ + char linebuf[BUFLEN]; + + fgets(linebuf, BUFLEN, fp); + while (!feof(fp)) { + if (utils::strmatch(linebuf, "^\\s*\\[.*\\]\\s*$")) { + auto words = Tokenizer(linebuf).as_vector(); + if (words.size() != 3) + throw TokenizerException("Invalid group name in index file", + utils::trim(utils::strfind(linebuf, "[^\\[^\\]]+"))); + if (name.empty() || (name == words[1])) return words[1]; + } + fgets(linebuf, BUFLEN, fp); + } + return ""; +} + +static std::vector read_section(FILE *fp, std::string &name) +{ + char linebuf[BUFLEN]; + std::vector tagbuf; + + while (fgets(linebuf, BUFLEN, fp)) { + // start of new section. we are done, update "name" + if (utils::strmatch(linebuf, "^\\s*\\[.*\\]\\s*$")) { + auto words = Tokenizer(linebuf).as_vector(); + if (words.size() != 3) + throw TokenizerException("Invalid group name in index file", + utils::trim(utils::strfind(linebuf, "[^\\[^\\]]+"))); + name = words[1]; + return tagbuf; + } + ValueTokenizer values(linebuf); + while (values.has_next()) tagbuf.push_back(values.next_tagint()); + } + // set empty name to indicate end of file + name = ""; + return tagbuf; +} + +/* ---------------------------------------------------------------------- */ + +void Ndx2Group::command(int narg, char **arg) +{ + int len; + bigint num; + FILE *fp; + std::string name, next; + + if (narg < 1) utils::missing_cmd_args(FLERR, "ndx2group", error); + if (atom->tag_enable == 0) error->all(FLERR, "Must have atom IDs for ndx2group command"); + if (atom->map_style == Atom::MAP_NONE) + error->all(FLERR, "Must have an atom map for ndx2group command"); + if (comm->me == 0) { + fp = fopen(arg[0], "r"); + if (fp == nullptr) + error->one(FLERR, "Cannot open index file for reading: {}", utils::getsyserror()); + utils::logmesg(lmp, "Reading groups from index file {}:\n", arg[0]); + } + + if (narg == 1) { // restore all groups + + if (comm->me == 0) { + try { + name = find_section(fp, ""); + } catch (std::exception &e) { + error->one(FLERR, e.what()); + } + + while (!name.empty()) { + // skip over group "all", which is called "System" in gromacs + if (name == "System") { + try { + name = find_section(fp, ""); + } catch (std::exception &e) { + error->one(FLERR, e.what()); + } + continue; + } + + utils::logmesg(lmp, " Processing group '{}'\n", name); + len = name.size() + 1; + MPI_Bcast(&len, 1, MPI_INT, 0, world); + if (len > 1) { + MPI_Bcast((void *) name.c_str(), len, MPI_CHAR, 0, world); + + // read tags for atoms in group and broadcast + std::vector tags; + try { + tags = read_section(fp, next); + } catch (std::exception &e) { + error->one(FLERR, e.what()); + } + num = tags.size(); + MPI_Bcast(&num, 1, MPI_LMP_BIGINT, 0, world); + MPI_Bcast((void *) tags.data(), num, MPI_LMP_TAGINT, 0, world); + create(name, tags); + name = next; + } + } + len = -1; + MPI_Bcast(&len, 1, MPI_INT, 0, world); + + } else { + + while (true) { + MPI_Bcast(&len, 1, MPI_INT, 0, world); + if (len < 0) break; + if (len > 1) { + char *buf = new char[len]; + MPI_Bcast(buf, len, MPI_CHAR, 0, world); + MPI_Bcast(&num, 1, MPI_LMP_BIGINT, 0, world); + tagint *tbuf = new tagint[num]; + MPI_Bcast(tbuf, num, MPI_LMP_TAGINT, 0, world); + create(buf, std::vector(tbuf, tbuf + num)); + delete[] buf; + delete[] tbuf; + } + } + } + + } else { // restore selected groups + + for (int idx = 1; idx < narg; ++idx) { + if (comm->me == 0) { + + // find named section, search from beginning of file + rewind(fp); + try { + name = find_section(fp, arg[idx]); + } catch (std::exception &e) { + error->one(FLERR, e.what()); + } + utils::logmesg(lmp, " {} group '{}'\n", name.size() ? "Processing" : "Skipping", arg[idx]); + len = name.size() + 1; + MPI_Bcast(&len, 1, MPI_INT, 0, world); + if (len > 1) { + MPI_Bcast((void *) name.c_str(), len, MPI_CHAR, 0, world); + + // read tags for atoms in group and broadcast + std::vector tags; + try { + tags = read_section(fp, next); + } catch (std::exception &e) { + error->one(FLERR, e.what()); + } + num = tags.size(); + MPI_Bcast(&num, 1, MPI_LMP_BIGINT, 0, world); + MPI_Bcast((void *) tags.data(), num, MPI_LMP_TAGINT, 0, world); + create(name, tags); + name = next; + } + } else { + MPI_Bcast(&len, 1, MPI_INT, 0, world); + if (len > 1) { + char *buf = new char[len]; + MPI_Bcast(buf, len, MPI_CHAR, 0, world); + MPI_Bcast(&num, 1, MPI_LMP_BIGINT, 0, world); + tagint *tbuf = new tagint[num]; + MPI_Bcast(tbuf, num, MPI_LMP_TAGINT, 0, world); + create(buf, std::vector(tbuf, tbuf + num)); + delete[] buf; + delete[] tbuf; + } + } + } + } + if (comm->me == 0) fclose(fp); +} + +/* ---------------------------------------------------------------------- */ + +void Ndx2Group::create(const std::string &name, const std::vector &tags) +{ + // wipe out all members if the group exists. gid==0 is group "all" + int gid = group->find(name); + if (gid > 0) group->assign(name + " clear"); + + // map from global to local + const int nlocal = atom->nlocal; + int *flags = (int *) calloc(nlocal, sizeof(int)); + for (bigint i = 0; i < (int) tags.size(); ++i) { + const int id = atom->map(tags[i]); + if (id < nlocal && id >= 0) flags[id] = 1; + } + group->create(name, flags); + free(flags); +} diff --git a/src/COLVARS/ndx_group.h b/src/EXTRA-COMMAND/ndx_group.h similarity index 100% rename from src/COLVARS/ndx_group.h rename to src/EXTRA-COMMAND/ndx_group.h diff --git a/src/EXTRA-PAIR/pair_coul_slater_long.cpp b/src/EXTRA-PAIR/pair_coul_slater_long.cpp index 65906f73b5..09926f6533 100644 --- a/src/EXTRA-PAIR/pair_coul_slater_long.cpp +++ b/src/EXTRA-PAIR/pair_coul_slater_long.cpp @@ -39,7 +39,6 @@ using namespace EwaldConst; PairCoulSlaterLong::PairCoulSlaterLong(LAMMPS *lmp) : Pair(lmp) { ewaldflag = pppmflag = 1; - qdist = 0.0; } /* ---------------------------------------------------------------------- */ @@ -232,7 +231,7 @@ void PairCoulSlaterLong::init_style() double PairCoulSlaterLong::init_one(int i, int j) { scale[j][i] = scale[i][j]; - return cut_coul+2.0*qdist; + return cut_coul; } /* ---------------------------------------------------------------------- diff --git a/src/EXTRA-PAIR/pair_coul_slater_long.h b/src/EXTRA-PAIR/pair_coul_slater_long.h index ef1742ece1..04e0bfe35b 100644 --- a/src/EXTRA-PAIR/pair_coul_slater_long.h +++ b/src/EXTRA-PAIR/pair_coul_slater_long.h @@ -41,9 +41,7 @@ class PairCoulSlaterLong : public Pair { void *extract(const char *, int &) override; protected: - double cut_coul, cut_coulsq, qdist; - double lamda; - double g_ewald; + double cut_coul, cut_coulsq, lamda, g_ewald; double **scale; virtual void allocate(); diff --git a/src/GPU/pair_dpd_coul_slater_long_gpu.cpp b/src/GPU/pair_dpd_coul_slater_long_gpu.cpp new file mode 100644 index 0000000000..1acd95b30c --- /dev/null +++ b/src/GPU/pair_dpd_coul_slater_long_gpu.cpp @@ -0,0 +1,474 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Eddy BARRAUD (IFPEN/Sorbonne) +------------------------------------------------------------------------- */ + +#include "pair_dpd_coul_slater_long_gpu.h" + +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" +#include "update.h" + +#include "ewald_const.h" +#include "kspace.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace EwaldConst; + +// External functions from cuda library for atom decomposition + +int dpd_coul_slater_long_gpu_init(const int ntypes, double **cutsq, double **host_a0, + double **host_gamma, double **host_sigma, double **host_cut_dpd, + double **host_cut_dpdsq, double **host_cut_slatersq, + double *special_lj, const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, + double *host_special_coul, const double qqrd2e, + const double g_ewald, const double lamda); +void dpd_coul_slater_long_gpu_clear(); +int **dpd_coul_slater_long_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, + bool &success, double **host_v, const double dtinvsqrt, + const int seed, const int timestep, double *boxlo, + double *prd); +void dpd_coul_slater_long_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **host_v, const double dtinvsqrt, const int seed, + const int timestep, const int nlocal, double *boxlo, + double *prd); + +void dpd_coul_slater_long_gpu_get_extra_data(double *host_q); + +double dpd_coul_slater_long_gpu_bytes(); + +static constexpr double EPSILON = 1.0e-10; + +//#define _USE_UNIFORM_SARU_LCG +//#define _USE_UNIFORM_SARU_TEA8 +//#define _USE_GAUSSIAN_SARU_LCG + +#if !defined(_USE_UNIFORM_SARU_LCG) && !defined(_USE_UNIFORM_SARU_TEA8) && \ + !defined(_USE_GAUSSIAN_SARU_LCG) +#define _USE_UNIFORM_SARU_LCG +#endif + +// References: +// 1. Y. Afshar, F. Schmid, A. Pishevar, S. Worley, Comput. Phys. Comm. 184 (2013), 1119–1128. +// 2. C. L. Phillips, J. A. Anderson, S. C. Glotzer, Comput. Phys. Comm. 230 (2011), 7191-7201. +// PRNG period = 3666320093*2^32 ~ 2^64 ~ 10^19 + +#define LCGA 0x4beb5d59 // Full period 32 bit LCG +#define LCGC 0x2600e1f7 +#define oWeylPeriod 0xda879add // Prime period 3666320093 +#define oWeylOffset 0x8009d14b +#define TWO_N32 0.232830643653869628906250e-9f /* 2^-32 */ + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] +// using the inherent LCG, then multiply u with sqrt(3) to "match" +// with a normal random distribution. +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +// Curly brackets to make variables local to the scope. +#ifdef _USE_UNIFORM_SARU_LCG +#define numtyp double +#define SQRT3 (numtyp) 1.7320508075688772935274463 +#define saru(seed1, seed2, seed, timestep, randnum) \ + { \ + unsigned int seed3 = seed + timestep; \ + seed3 ^= (seed1 << 7) ^ (seed2 >> 6); \ + seed2 += (seed1 >> 4) ^ (seed3 >> 15); \ + seed1 ^= (seed2 << 9) + (seed3 << 8); \ + seed3 ^= 0xA5366B4D * ((seed2 >> 11) ^ (seed1 << 1)); \ + seed2 += 0x72BE1579 * ((seed1 << 4) ^ (seed3 >> 16)); \ + seed1 ^= 0x3F38A6ED * ((seed3 >> 5) ^ (((signed int) seed2) >> 22)); \ + seed2 += seed1 * seed3; \ + seed1 += seed3 ^ (seed2 >> 2); \ + seed2 ^= ((signed int) seed2) >> 17; \ + unsigned int state = 0x79dedea3 * (seed1 ^ (((signed int) seed1) >> 14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int) state) >> 8); \ + state = state + (wstate * (wstate ^ 0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate >> 1); \ + state = LCGA * state + LCGC; \ + wstate = wstate + oWeylOffset + ((((signed int) wstate) >> 31) & oWeylPeriod); \ + unsigned int v = (state ^ (state >> 26)) + wstate; \ + unsigned int s = (signed int) ((v ^ (v >> 20)) * 0x6957f5a7); \ + randnum = SQRT3 * (s * TWO_N32 * (numtyp) 2.0 - (numtyp) 1.0); \ + } +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] using TEA8 +// then multiply u with sqrt(3) to "match" with a normal random distribution +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +#ifdef _USE_UNIFORM_SARU_TEA8 +#define numtyp double +#define SQRT3 (numtyp) 1.7320508075688772935274463 +#define k0 0xA341316C +#define k1 0xC8013EA4 +#define k2 0xAD90777D +#define k3 0x7E95761E +#define delta 0x9e3779b9 +#define rounds 8 +#define saru(seed1, seed2, seed, timestep, randnum) \ + { \ + unsigned int seed3 = seed + timestep; \ + seed3 ^= (seed1 << 7) ^ (seed2 >> 6); \ + seed2 += (seed1 >> 4) ^ (seed3 >> 15); \ + seed1 ^= (seed2 << 9) + (seed3 << 8); \ + seed3 ^= 0xA5366B4D * ((seed2 >> 11) ^ (seed1 << 1)); \ + seed2 += 0x72BE1579 * ((seed1 << 4) ^ (seed3 >> 16)); \ + seed1 ^= 0x3F38A6ED * ((seed3 >> 5) ^ (((signed int) seed2) >> 22)); \ + seed2 += seed1 * seed3; \ + seed1 += seed3 ^ (seed2 >> 2); \ + seed2 ^= ((signed int) seed2) >> 17; \ + unsigned int state = 0x79dedea3 * (seed1 ^ (((signed int) seed1) >> 14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int) state) >> 8); \ + state = state + (wstate * (wstate ^ 0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate >> 1); \ + unsigned int sum = 0; \ + for (int i = 0; i < rounds; i++) { \ + sum += delta; \ + state += ((wstate << 4) + k0) ^ (wstate + sum) ^ ((wstate >> 5) + k1); \ + wstate += ((state << 4) + k2) ^ (state + sum) ^ ((state >> 5) + k3); \ + } \ + unsigned int v = (state ^ (state >> 26)) + wstate; \ + unsigned int s = (signed int) ((v ^ (v >> 20)) * 0x6957f5a7); \ + randnum = SQRT3 * (s * TWO_N32 * (numtyp) 2.0 - (numtyp) 1.0); \ + } +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns two uniformly distributed random numbers r1 and r2 in [-1.0;1.0], +// and uses the polar method (Marsaglia's) to transform to a normal random value +// This is used to compared with CPU DPD using RandMars::gaussian() +#ifdef _USE_GAUSSIAN_SARU_LCG +#define numtyp double +#define saru(seed1, seed2, seed, timestep, randnum) \ + { \ + unsigned int seed3 = seed + timestep; \ + seed3 ^= (seed1 << 7) ^ (seed2 >> 6); \ + seed2 += (seed1 >> 4) ^ (seed3 >> 15); \ + seed1 ^= (seed2 << 9) + (seed3 << 8); \ + seed3 ^= 0xA5366B4D * ((seed2 >> 11) ^ (seed1 << 1)); \ + seed2 += 0x72BE1579 * ((seed1 << 4) ^ (seed3 >> 16)); \ + seed1 ^= 0x3F38A6ED * ((seed3 >> 5) ^ (((signed int) seed2) >> 22)); \ + seed2 += seed1 * seed3; \ + seed1 += seed3 ^ (seed2 >> 2); \ + seed2 ^= ((signed int) seed2) >> 17; \ + unsigned int state = 0x12345678; \ + unsigned int wstate = 12345678; \ + state = 0x79dedea3 * (seed1 ^ (((signed int) seed1) >> 14)); \ + wstate = (state + seed2) ^ (((signed int) state) >> 8); \ + state = state + (wstate * (wstate ^ 0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate >> 1); \ + unsigned int v, s; \ + numtyp r1, r2, rsq; \ + while (1) { \ + state = LCGA * state + LCGC; \ + wstate = wstate + oWeylOffset + ((((signed int) wstate) >> 31) & oWeylPeriod); \ + v = (state ^ (state >> 26)) + wstate; \ + s = (signed int) ((v ^ (v >> 20)) * 0x6957f5a7); \ + r1 = s * TWO_N32 * (numtyp) 2.0 - (numtyp) 1.0; \ + state = LCGA * state + LCGC; \ + wstate = wstate + oWeylOffset + ((((signed int) wstate) >> 31) & oWeylPeriod); \ + v = (state ^ (state >> 26)) + wstate; \ + s = (signed int) ((v ^ (v >> 20)) * 0x6957f5a7); \ + r2 = s * TWO_N32 * (numtyp) 2.0 - (numtyp) 1.0; \ + rsq = r1 * r1 + r2 * r2; \ + if (rsq < (numtyp) 1.0) break; \ + } \ + numtyp fac = sqrt((numtyp) -2.0 * log(rsq) / rsq); \ + randnum = r2 * fac; \ + } +#endif + +/* ---------------------------------------------------------------------- */ + +PairDPDCoulSlaterLongGPU::PairDPDCoulSlaterLongGPU(LAMMPS *lmp) : PairDPDCoulSlaterLong(lmp), gpu_mode(GPU_FORCE) +{ + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairDPDCoulSlaterLongGPU::~PairDPDCoulSlaterLongGPU() +{ + dpd_coul_slater_long_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLongGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + double dtinvsqrt = 1.0 / sqrt(update->dt); + + bool success = true; + int *ilist, *numneigh, **firstneigh; + + double *q = atom->q; + dpd_coul_slater_long_gpu_get_extra_data(q); + + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = dpd_coul_slater_long_gpu_compute_n( + neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, atom->nspecial, + atom->special, eflag, vflag, eflag_atom, vflag_atom, host_start, &ilist, &numneigh, + cpu_time, success, atom->v, dtinvsqrt, seed, update->ntimestep, domain->boxlo, domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + dpd_coul_slater_long_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, atom->tag, + atom->v, dtinvsqrt, seed, update->ntimestep, atom->nlocal, domain->boxlo, + domain->prd); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); + if (host_start < inum) { + cpu_time = platform::walltime(); + cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh); + cpu_time = platform::walltime() - cpu_time; + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLongGPU::init_style() +{ + + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair dpd requires ghost atoms store velocity"); + if (!atom->q_flag) + error->all(FLERR,"Pair style coul/slater/long requires atom attribute q"); + // ensure use of KSpace long-range solver, set g_ewald + if (force->kspace == nullptr) error->all(FLERR, "Pair style requires a KSpace style"); + g_ewald = force->kspace->g_ewald; + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double mcut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + mcut = init_one(i, j); + mcut *= mcut; + if (mcut > maxcut) maxcut = mcut; + cutsq[i][j] = cutsq[j][i] = mcut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + dpd_coul_slater_long_gpu_init(atom->ntypes + 1, cutsq, a0, gamma, sigma, + cut_dpd, cut_dpdsq, cut_slatersq, force->special_lj, atom->nlocal, + atom->nlocal + atom->nghost, mnf, maxspecial, cell_size, gpu_mode, screen, + force->special_coul, force->qqrd2e, g_ewald, lamda); + GPU_EXTRA::check_flag(success, error, world); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); + +} + +/* ---------------------------------------------------------------------- */ + +double PairDPDCoulSlaterLongGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + dpd_coul_slater_long_gpu_bytes(); +} + +/* ---------------------------------------------------------------------- */ + +void PairDPDCoulSlaterLongGPU::cpu_compute(int start, int inum, int eflag, int /* vflag */, int *ilist, + int *numneigh, int **firstneigh) +{ + int i, j, ii, jj, jnum, itype, jtype; + double qtmp, xtmp, ytmp, ztmp, delx, dely, delz, evdwl, ecoul, fpair; + double vxtmp, vytmp, vztmp, delvx, delvy, delvz; + double r2inv,forcedpd,forcecoul,factor_coul; + double grij,expm2,prefactor,t,erfc; + double rsq,r,rinv,dot,wd,randnum,factor_dpd,factor_sqrt; + int *jlist; + double slater_term; + + tagint itag, jtag; + + double *q = atom->q; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + + evdwl = 0.0; + ecoul = 0.0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + tagint *tag = atom->tag; + double *special_lj = force->special_lj; + double dtinvsqrt = 1.0 / sqrt(update->dt); + int timestep = (int) update->ntimestep; + + // loop over neighbors of my atoms + + for (ii = start; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + itype = type[i]; + itag = tag[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_dpd = special_lj[sbmask(j)]; + factor_sqrt = special_sqrt[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + jtag = tag[j]; + + // forces if below maximum cutoff + if (rsq < cutsq[itype][jtype]) { + r = sqrt(rsq); + if (evflag) evdwl = ecoul = 0.0; + // apply DPD force if distance below DPD cutoff + if (rsq < cut_dpdsq[itype][jtype] && r > EPSILON ) { + rinv = 1.0 / r; + delvx = vxtmp - v[j][0]; + delvy = vytmp - v[j][1]; + delvz = vztmp - v[j][2]; + dot = delx * delvx + dely * delvy + delz * delvz; + wd = 1.0 - r / cut[itype][jtype]; + + unsigned int tag1 = itag, tag2 = jtag; + if (tag1 > tag2) { + tag1 = jtag; + tag2 = itag; + } + + randnum = 0.0; + saru(tag1, tag2, seed, timestep, randnum); + + // conservative force = a0 * wd + // drag force = -gamma * wd^2 * (delx dot delv) / r + // random force = sigma * wd * rnd * dtinvsqrt; + forcedpd = a0[itype][jtype]*wd; + forcedpd -= gamma[itype][jtype]*wd*wd*dot*rinv; + forcedpd *= factor_dpd; + forcedpd += factor_sqrt*sigma[itype][jtype]*wd*randnum*dtinvsqrt; + forcedpd *= rinv; + + if (eflag) { + // eng shifted to 0.0 at cutoff + evdwl = 0.5*a0[itype][jtype]*cut_dpd[itype][jtype] * wd*wd; + evdwl *= factor_dpd; + } + + } else forcedpd = 0.0; + + // apply Slater electrostatic force if distance below Slater cutoff + // and the two species are charged + if (rsq < cut_slatersq[itype][jtype]){ + r2inv = 1.0/rsq; + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + slater_term = exp(-2*r/lamda)*(1 + (2*r/lamda*(1+r/lamda))); + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2 - slater_term); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor*(1-slater_term); + forcecoul *= r2inv; + + if (eflag) { + ecoul = prefactor*(erfc - (1 + r/lamda)*exp(-2*r/lamda)); + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor*(1.0-(1 + r/lamda)*exp(-2*r/lamda)); + } + + } else forcecoul = 0.0; + + fpair = forcedpd + forcecoul; + + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; + + if (evflag) ev_tally_full(i, evdwl, ecoul, fpair, delx, dely, delz); + } + } + } +} diff --git a/src/GPU/pair_dpd_coul_slater_long_gpu.h b/src/GPU/pair_dpd_coul_slater_long_gpu.h new file mode 100644 index 0000000000..5903391d4d --- /dev/null +++ b/src/GPU/pair_dpd_coul_slater_long_gpu.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(dpd/coul/slater/long/gpu,PairDPDCoulSlaterLongGPU); +// clang-format on +#else + +#ifndef LMP_PAIR_DPD_COUL_SLATER_LONG_GPU_H +#define LMP_PAIR_DPD_COUL_SLATER_LONG_GPU_H + +#include "pair_dpd_coul_slater_long.h" + +namespace LAMMPS_NS { + +class PairDPDCoulSlaterLongGPU : public PairDPDCoulSlaterLong { + public: + PairDPDCoulSlaterLongGPU(LAMMPS *lmp); + ~PairDPDCoulSlaterLongGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + private: + int gpu_mode; + double cpu_time; +}; + +} // namespace LAMMPS_NS +#endif +#endif diff --git a/src/GRANULAR/gran_sub_mod_damping.cpp b/src/GRANULAR/gran_sub_mod_damping.cpp index df7146a619..1745f6addf 100644 --- a/src/GRANULAR/gran_sub_mod_damping.cpp +++ b/src/GRANULAR/gran_sub_mod_damping.cpp @@ -156,6 +156,7 @@ double GranSubModDampingTsuji::calculate_forces() GranSubModDampingCoeffRestitution::GranSubModDampingCoeffRestitution(GranularModel *gm, LAMMPS *lmp) : GranSubModDamping(gm, lmp) { + allow_cohesion = 0; } void GranSubModDampingCoeffRestitution::init() @@ -173,6 +174,12 @@ void GranSubModDampingCoeffRestitution::init() double GranSubModDampingCoeffRestitution::calculate_forces() { - damp_prefactor = damp * sqrt(gm->meff * gm->Fnormal / gm->delta); + // in case argument <= 0 due to precision issues + double sqrt1; + if (gm->delta > 0.0) + sqrt1 = MAX(0.0, gm->meff * gm->Fnormal / gm->delta); + else + sqrt1 = 0.0; + damp_prefactor = damp * sqrt(sqrt1); return -damp_prefactor * gm->vnnr; } diff --git a/src/INTEL/npair_skip_intel.cpp b/src/INTEL/npair_skip_intel.cpp index 3596237746..9353a6f520 100644 --- a/src/INTEL/npair_skip_intel.cpp +++ b/src/INTEL/npair_skip_intel.cpp @@ -74,9 +74,13 @@ void NPairSkipIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, const int nlocal = atom->nlocal; const int e_nall = nlocal + atom->nghost; const int * _noalias const type = atom->type; + const tagint * _noalias const molecule = atom->molecule; + int * _noalias const ilist = list->ilist; int * _noalias const numneigh = list->numneigh; int ** _noalias const firstneigh = (int ** const)list->firstneigh; // NOLINT + const int molskip = list->molskip; + const int * _noalias const ilist_skip = list->listskip->ilist; const int * _noalias const numneigh_skip = list->listskip->numneigh; const int ** _noalias const firstneigh_skip = (const int ** const)list->listskip->firstneigh; // NOLINT @@ -110,7 +114,7 @@ void NPairSkipIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, for (int ii = ifrom; ii < ito; ii++) { const int i = ilist_skip[ii]; const int itype = type[i]; - if (iskip[itype]) continue; + if (!molskip && iskip[itype]) continue; int n = 0; int *neighptr = ipage.vget(); @@ -142,7 +146,11 @@ void NPairSkipIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, for (int jj = 0; jj < jnum; jj++) { const int joriginal = jlist[jj]; const int j = joriginal & NEIGHMASK; - if (!ijskip[itype][type[j]]) neighptr[n++] = joriginal; + if (!molskip && ijskip[itype][type[j]]) continue; + if ((molskip == NeighRequest::INTRA) && (molecule[i] != molecule[j])) continue; + if ((molskip == NeighRequest::INTER) && (molecule[i] == molecule[j])) continue; + + neighptr[n++] = joriginal; } } @@ -269,9 +277,13 @@ void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, const int e_nall = nlocal + atom->nghost; const ATOM_T * _noalias const x = buffers->get_x(); const int * _noalias const type = atom->type; + const tagint * _noalias const molecule = atom->molecule; + int * _noalias const ilist = list->ilist; int * _noalias const numneigh = list->numneigh; int ** _noalias const firstneigh = (int ** const)list->firstneigh; // NOLINT + const int molskip = list->molskip; + const int * _noalias const ilist_skip = list->listskip->ilist; const int * _noalias const numneigh_skip = list->listskip->numneigh; const int ** _noalias const firstneigh_skip = (const int ** const)list->listskip->firstneigh; // NOLINT @@ -306,7 +318,7 @@ void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, for (int ii = ifrom; ii < ito; ii++) { const int i = ilist_skip[ii]; const int itype = type[i]; - if (iskip[itype]) continue; + if (!molskip && iskip[itype]) continue; const flt_t xtmp = x[i].x; const flt_t ytmp = x[i].y; @@ -370,7 +382,9 @@ void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, const int j = joriginal & NEIGHMASK; int addme = 1; - if (ijskip[itype][type[j]]) addme = 0; + if (!molskip && ijskip[itype][type[j]]) addme = 0; + if ((molskip == NeighRequest::INTRA) && (molecule[i] != molecule[j])) addme = 0; + if ((molskip == NeighRequest::INTER) && (molecule[i] == molecule[j])) addme = 0; // trim to shorter cutoff diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 86acbe97b2..25a9bcd0c2 100755 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -365,6 +365,8 @@ action pair_reaxff_kokkos.h pair_reaxff.h action pair_snap_kokkos_impl.h pair_snap.cpp action pair_snap_kokkos.cpp pair_snap.cpp action pair_snap_kokkos.h pair_snap.h +action pair_soft_kokkos.cpp +action pair_soft_kokkos.h action pair_sw_kokkos.cpp pair_sw.cpp action pair_sw_kokkos.h pair_sw.h action pair_table_kokkos.cpp diff --git a/src/KOKKOS/pair_soft_kokkos.cpp b/src/KOKKOS/pair_soft_kokkos.cpp new file mode 100644 index 0000000000..2b36c22486 --- /dev/null +++ b/src/KOKKOS/pair_soft_kokkos.cpp @@ -0,0 +1,255 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "pair_soft_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "error.h" +#include "force.h" +#include "kokkos.h" +#include "math_const.h" +#include "memory_kokkos.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "respa.h" +#include "update.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +/* ---------------------------------------------------------------------- */ + +template +PairSoftKokkos::PairSoftKokkos(LAMMPS *lmp) : PairSoft(lmp) +{ + respa_enable = 0; + + kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; +} + +/* ---------------------------------------------------------------------- */ + +template +PairSoftKokkos::~PairSoftKokkos() +{ + if (copymode) return; + + if (allocated) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->destroy_kokkos(k_vatom,vatom); + memoryKK->destroy_kokkos(k_cutsq,cutsq); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void PairSoftKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (neighflag == FULL) no_virial_fdotr_compute = 1; + + ev_init(eflag,vflag,0); + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); + d_eatom = k_eatom.view(); + } + if (vflag_atom) { + memoryKK->destroy_kokkos(k_vatom,vatom); + memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom"); + d_vatom = k_vatom.view(); + } + + atomKK->sync(execution_space,datamask_read); + k_cutsq.template sync(); + k_params.template sync(); + if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + else atomKK->modified(execution_space,F_MASK); + + x = atomKK->k_x.view(); + c_x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + type = atomKK->k_type.view(); + nlocal = atom->nlocal; + nall = atom->nlocal + atom->nghost; + newton_pair = force->newton_pair; + special_lj[0] = force->special_lj[0]; + special_lj[1] = force->special_lj[1]; + special_lj[2] = force->special_lj[2]; + special_lj[3] = force->special_lj[3]; + + // loop over neighbors of my atoms + + copymode = 1; + + EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); + + if (eflag_global) eng_vdwl += ev.evdwl; + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + copymode = 0; +} + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairSoftKokkos:: +compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + const F_FLOAT r = sqrt(rsq); + const F_FLOAT cut_ij = STACKPARAMS?m_params[itype][jtype].cut:params(itype,jtype).cut; + const F_FLOAT prefactor_ij = STACKPARAMS?m_params[itype][jtype].prefactor:params(itype,jtype).prefactor; + const F_FLOAT arg = MY_PI*r/cut_ij; + + F_FLOAT fpair = 0.0; + if (r > 0.0) fpair = prefactor_ij * + sin(arg) * MY_PI/cut_ij/r; + + return fpair; +} + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairSoftKokkos:: +compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + const F_FLOAT r = sqrt(rsq); + const F_FLOAT cut_ij = STACKPARAMS?m_params[itype][jtype].cut:params(itype,jtype).cut; + const F_FLOAT prefactor_ij = STACKPARAMS?m_params[itype][jtype].prefactor:params(itype,jtype).prefactor; + const F_FLOAT arg = MY_PI*r/cut_ij; + + return prefactor_ij*(1.0+cos(arg)); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +template +void PairSoftKokkos::allocate() +{ + PairSoft::allocate(); + + int n = atom->ntypes; + memory->destroy(cutsq); + memoryKK->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); + k_params = Kokkos::DualView("PairSoft::params",n+1,n+1); + params = k_params.template view(); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +template +void PairSoftKokkos::settings(int narg, char **arg) +{ + if (narg > 2) error->all(FLERR,"Illegal pair_style command"); + + PairSoft::settings(1,arg); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +template +void PairSoftKokkos::init_style() +{ + PairSoft::init_style(); + + // error if rRESPA with inner levels + + if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) { + int respa = 0; + if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; + if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; + if (respa) + error->all(FLERR,"Cannot use Kokkos pair style with rRESPA inner/middle"); + } + + // adjust neighbor list request for KOKKOS + + neighflag = lmp->kokkos->neighflag; + auto request = neighbor->find_request(this); + request->set_kokkos_host(std::is_same_v && + !std::is_same_v); + request->set_kokkos_device(std::is_same_v); + if (neighflag == FULL) request->enable_full(); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairSoftKokkos::init_one(int i, int j) +{ + double cutone = PairSoft::init_one(i,j); + + k_params.h_view(i,j).prefactor = prefactor[i][j]; + k_params.h_view(i,j).cut = cutone; + k_params.h_view(i,j).cutsq = cutone*cutone; + k_params.h_view(j,i) = k_params.h_view(i,j); + if (i(); + k_params.template modify(); + + return cutone; +} + +namespace LAMMPS_NS { +template class PairSoftKokkos; +#ifdef LMP_KOKKOS_GPU +template class PairSoftKokkos; +#endif +} + diff --git a/src/KOKKOS/pair_soft_kokkos.h b/src/KOKKOS/pair_soft_kokkos.h new file mode 100644 index 0000000000..060d760937 --- /dev/null +++ b/src/KOKKOS/pair_soft_kokkos.h @@ -0,0 +1,114 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(soft/kk,PairSoftKokkos); +PairStyle(soft/kk/device,PairSoftKokkos); +PairStyle(soft/kk/host,PairSoftKokkos); +// clang-format on +#else + +// clang-format off +#ifndef LMP_PAIR_SOFT_KOKKOS_H +#define LMP_PAIR_SOFT_KOKKOS_H + +#include "pair_kokkos.h" +#include "pair_soft.h" +#include "neigh_list_kokkos.h" + +namespace LAMMPS_NS { + +template +class PairSoftKokkos : public PairSoft { + public: + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF}; + enum {COUL_FLAG=0}; + typedef DeviceType device_type; + typedef ArrayTypes AT; + PairSoftKokkos(class LAMMPS *); + ~PairSoftKokkos() override; + + void compute(int, int) override; + + void settings(int, char **) override; + void init_style() override; + double init_one(int, int) override; + + struct params_soft{ + KOKKOS_INLINE_FUNCTION + params_soft() {cutsq=0,cut=0,prefactor=0;}; + KOKKOS_INLINE_FUNCTION + params_soft(int /*i*/) {cutsq=0,cut=0,prefactor=0;}; + F_FLOAT cutsq,cut,prefactor; + }; + + protected: + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_ecoul(const F_FLOAT& /*rsq*/, const int& /*i*/, const int& /*j*/, + const int& /*itype*/, const int& /*jtype*/) const { return 0; } + + Kokkos::DualView k_params; + typename Kokkos::DualView::t_dev_const_um params; + params_soft m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; // hardwired to space for 12 atom types + F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + typename AT::t_x_array_randomread x; + typename AT::t_x_array c_x; + typename AT::t_f_array f; + typename AT::t_int_1d_randomread type; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; + + int newton_pair; + double special_lj[4]; + + typename AT::tdual_ffloat_2d k_cutsq; + typename AT::t_ffloat_2d d_cutsq; + + int neighflag; + int nlocal,nall,eflag,vflag; + + void allocate() override; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend struct PairComputeFunctor; + friend EV_FLOAT pair_compute_neighlist(PairSoftKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist(PairSoftKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist(PairSoftKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist(PairSoftKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute(PairSoftKokkos*,NeighListKokkos*); + friend void pair_virial_fdotr_compute(PairSoftKokkos*); +}; + +} + +#endif +#endif + diff --git a/src/KOKKOS/pair_uf3_kokkos.cpp b/src/KOKKOS/pair_uf3_kokkos.cpp new file mode 100644 index 0000000000..4a3bcc164b --- /dev/null +++ b/src/KOKKOS/pair_uf3_kokkos.cpp @@ -0,0 +1,1661 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#include "pair_uf3.h" +#include "pair_uf3_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "kokkos.h" +#include "kokkos_type.h" +#include "math_const.h" +#include "math_special_kokkos.h" +#include "memory.h" +#include "memory_kokkos.h" +#include "neigh_list_kokkos.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "pair_kokkos.h" +#include "text_file_reader.h" + +#include +#include +#include + +using namespace LAMMPS_NS; +using namespace MathConst; +using MathSpecialKokkos::cube; +using MathSpecialKokkos::square; + +template PairUF3Kokkos::PairUF3Kokkos(LAMMPS *lmp) : PairUF3(lmp) +{ + respa_enable = 0; + + //kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TAG_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + +} + +template PairUF3Kokkos::~PairUF3Kokkos() +{ + if (!copymode) { + memoryKK->destroy_kokkos(k_eatom, eatom); //destory eatom from host, set it to nullptr + //Also set k_eatom to empty View + memoryKK->destroy_kokkos(k_vatom, vatom); + memoryKK->destroy_kokkos(k_cutsq,cutsq); + destroy_3d(k_cut_3b,cut_3b); + destroy_4d(k_min_cut_3b,min_cut_3b); + eatom = NULL; + vatom = NULL; + cvatom = NULL; + } +} + +template +template +void PairUF3Kokkos::destroy_3d(TYPE data, typename TYPE::value_type*** &array) +{ + if (array == nullptr) return; + data = TYPE(); + memory->sfree(array); + array = nullptr; +} + +template +template +void PairUF3Kokkos::destroy_4d(TYPE data, typename TYPE::value_type**** &array) +{ + if (array == nullptr) return; + data = TYPE(); + memory->sfree(array); + array = nullptr; +} + +/* ---------------------------------------------------------------------- + * global settings + * ---------------------------------------------------------------------- */ + +template void PairUF3Kokkos::settings(int narg, char **arg) +{ + PairUF3::settings(narg, arg); + //1. Determines whether the simulation is 2-body or 2 and 3-body + //2. Set nbody_flag, num_of_elements, pot_3b +} + +/* ---------------------------------------------------------------------- + * set coeffs for one or more type pairs + * ---------------------------------------------------------------------- */ +template void PairUF3Kokkos::coeff(int narg, char **arg) +{ + PairUF3::coeff(narg,arg); + //Also calls allocate internally + //Grows arrays to the right dimensions --> setflag, cutsq, cut, knot_spacing_type_2b, + //knot_spacing_2b, n2b_knots_array_size, n2b_coeff_array_size, setflag_3b, + //cut_3b, cut_3b_list, min_cut_3b, knot_spacing_type_3b, knot_spacing_3b, + //tot_interaction_count_3b, map_3b, n3b_knots_array_size, n3b_coeff_array_size, + //neighshort + // + //Also reads the pot_files_internally + +} + +template +void PairUF3Kokkos::allocate() +{ + if (!allocated) PairUF3::allocate(); + int n = atom->ntypes; + memory->destroy(cutsq); //Why are we destroying cutsq? cutsq is allocated when + //PairUF3::coeff or PairUF3::allocate is called; in the next step when k_cutsq + //is created cutsq is set to point to the host array of k_cutsq + //memory->destroy(cut_3b); + + memoryKK->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); //assignment; get the device + //view of k_cutsq and assign it to d_cutsq; in the header file we just + //decleared d_cutsq's type + memoryKK->create_kokkos(k_cut_3b,n+1,n+1,n+1,"threebody:cut"); + memoryKK->create_kokkos(k_min_cut_3b,n+1,n+1,n+1,3,"threebody:cut"); + d_cut_3b = k_cut_3b.template view(); + d_min_cut_3b = k_min_cut_3b.template view(); +} + + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +template void PairUF3Kokkos::init_style() +{ + + PairUF3::init_style(); + + neighflag = lmp->kokkos->neighflag; + + auto request = neighbor->find_request(this); + request->set_kokkos_host(std::is_same::value && + !std::is_same::value); + request->set_kokkos_device(std::is_same::value); + + request->enable_full(); + request->enable_ghost(); +} + +/* ---------------------------------------------------------------------- + init list sets the pointer to full neighbour list requested in previous function +------------------------------------------------------------------------- */ + +template +void PairUF3Kokkos::init_list(int /*id*/, class NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ +template double PairUF3Kokkos::init_one(int i, int j) +{ + double cutone = PairUF3::init_one(i, j); + + if (!coefficients_created) create_coefficients(); + + k_cutsq.h_view(i,j) = k_cutsq.h_view(j,i) = cutone*cutone; //Update the k_cutsq's + //host memory + k_cutsq.template modify(); //Record that k_cutsq's host memory has + //been modified + + return cutone; +} + +template void PairUF3Kokkos::create_coefficients() +{ + const int num_of_elements = atom->ntypes; + coefficients_created = 1; + + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + k_cut_3b.h_view(i,j,k) = cut_3b[i][j][k]; + + // Notice the order of min_cut_3b[i][j][k] + //In min_cut_3b[i][j][k], + //min_cut_3b[i][j][k][0] is the knot_vector along jk, + //min_cut_3b[i][j][k][1] is the knot_vector along ik, + //min_cut_3b[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + k_min_cut_3b.h_view(i,j,k,0) = min_cut_3b[i][j][k][0]; + k_min_cut_3b.h_view(i,j,k,1) = min_cut_3b[i][j][k][1]; + k_min_cut_3b.h_view(i,j,k,2) = min_cut_3b[i][j][k][2]; + } + } + } + k_cut_3b.template modify(); + k_min_cut_3b.template modify(); + } + + //No allocation on device for --> setflag, cut, knot_spacing_type_2b, + //n2b_knot, n2b_coeff, n2b_knot[i], n2b_coeff[i], setflag_3b, cut_3b, + //cut_3b_list, min_cut_3b, knot_spacing_type_3b, cut_3b_list, n3b_knot_matrix, + //neighshort + + //UFBS2b and UFBS3b are array of objects. Bad idea to use kokkos view(array) + //for it + create_2b_coefficients(); + if (pot_3b) create_3b_coefficients(); + +} + +template void PairUF3Kokkos::create_2b_coefficients() +{ + const int num_of_elements = atom->ntypes; + + // Setup interaction pair map + //TODO: Instead of using map2b and map3b use simple indexing + Kokkos::realloc(map2b, num_of_elements + 1, num_of_elements + 1); + auto map2b_view = Kokkos::create_mirror(map2b); + + int interaction_count = 0; + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + map2b_view(i, j) = interaction_count; + map2b_view(j, i) = interaction_count++; + } + } + Kokkos::deep_copy(map2b, map2b_view); + + // Count max knots for array size + + int max_knots = max_num_knots_2b; + + // Copy coefficients to view + + Kokkos::realloc(d_coefficients_2b, interaction_count, max_knots - 4); + auto d_coefficients_2b_view = Kokkos::create_mirror(d_coefficients_2b); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int k = 0; k < max_num_coeff_2b; k++) { + d_coefficients_2b_view(map2b_view(i, j), k) = n2b_coeff_array[i][j][k]; + } + } + } + Kokkos::deep_copy(d_coefficients_2b, d_coefficients_2b_view); + + // Copy knots from array to view + + Kokkos::realloc(d_n2b_knot, interaction_count, max_knots); + Kokkos::realloc(d_n2b_knot_spacings, interaction_count); + auto d_n2b_knot_view = Kokkos::create_mirror(d_n2b_knot); + auto d_n2b_knot_spacings_view = Kokkos::create_mirror(d_n2b_knot_spacings); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int k = 0; k < max_num_knots_2b; k++) { + d_n2b_knot_view(map2b_view(i, j), k) = n2b_knots_array[i][j][k]; + } + d_n2b_knot_spacings_view(map2b_view(i, j)) = n2b_knots_array[i][j][4] - n2b_knots_array[i][j][3]; + } + } + + Kokkos::deep_copy(d_n2b_knot, d_n2b_knot_view); + Kokkos::deep_copy(d_n2b_knot_spacings, d_n2b_knot_spacings_view); + // Set spline constants + + Kokkos::realloc(constants_2b, interaction_count, max_knots - 4); + auto constants_2b_view = Kokkos::create_mirror(constants_2b); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int l = 0; l < n2b_knots_array_size[i][j] - 4; l++) { + //n2b_knot[i][j].size() - 4; l++) { + auto c = get_constants(&n2b_knots_array[i][j][l], n2b_coeff_array[i][j][l]); + for (int k = 0; k < 16; k++) + constants_2b_view(map2b_view(i, j), l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 + : c[k]; + } + } + } + Kokkos::deep_copy(constants_2b, constants_2b_view); + + Kokkos::realloc(dnconstants_2b, interaction_count, max_knots - 5); + auto dnconstants_2b_view = Kokkos::create_mirror(dnconstants_2b); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int l = 0; l < n2b_knots_array_size[i][j] - 5; l++) { + double dntemp4 = 3 / (n2b_knots_array[i][j][l + 4] - n2b_knots_array[i][j][l + 1]); + double coeff = (n2b_coeff_array[i][j][l + 1] - n2b_coeff_array[i][j][l]) * dntemp4; + auto c = get_dnconstants(&n2b_knots_array[i][j][l + 1], coeff); + for (int k = 0; k < 9; k++) + dnconstants_2b_view(map2b_view(i, j), l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + } + } + Kokkos::deep_copy(dnconstants_2b, dnconstants_2b_view); +} + +template void PairUF3Kokkos::create_3b_coefficients() +{ + const int num_of_elements = atom->ntypes; + // Init interaction map for 3B + + Kokkos::realloc(map3b, num_of_elements + 1, num_of_elements + 1, num_of_elements + 1); + auto map3b_view = Kokkos::create_mirror(map3b); + + int interaction_count = 0; + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + map3b_view(i, j, k) = interaction_count; + interaction_count++; + } + } + } + Kokkos::deep_copy(map3b, map3b_view); + + // Count max knots for view + + int max_knots = max_num_knots_3b; + //In n3b_knot_matrix[i][j][k], + //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + + + // Init knot matrix view + + Kokkos::realloc(d_n3b_knot_matrix, interaction_count, 3, max_knots); + Kokkos::realloc(d_n3b_knot_matrix_spacings, interaction_count, 3); + auto d_n3b_knot_matrix_view = Kokkos::create_mirror(d_n3b_knot_matrix); + auto d_n3b_knot_matrix_spacings_view = Kokkos::create_mirror(d_n3b_knot_matrix_spacings); + + for (int i = 1; i < num_of_elements + 1; i++) + for (int j = 1; j < num_of_elements + 1; j++) + for (int k = 1; k < num_of_elements + 1; k++) { + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][0]; m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 0, m) = + n3b_knots_array[map_3b[i][j][k]][0][m]; + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][1]; m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 1, m) = + n3b_knots_array[map_3b[i][j][k]][1][m]; + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][2]; m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 2, m) = + n3b_knots_array[map_3b[i][j][k]][2][m]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),2) = + n3b_knots_array[map_3b[i][j][k]][2][4] - n3b_knots_array[map_3b[i][j][k]][2][3]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),1) = + n3b_knots_array[map_3b[i][j][k]][1][4] - n3b_knots_array[map_3b[i][j][k]][1][3]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),0) = + n3b_knots_array[map_3b[i][j][k]][0][4] - n3b_knots_array[map_3b[i][j][k]][0][3]; + } + Kokkos::deep_copy(d_n3b_knot_matrix, d_n3b_knot_matrix_view); + Kokkos::deep_copy(d_n3b_knot_matrix_spacings, d_n3b_knot_matrix_spacings_view); + + // Set knots spacings + + Kokkos::realloc(d_n3b_knot_spacings, interaction_count, 3); + auto d_n3b_knot_spacings_view = Kokkos::create_mirror(d_n3b_knot_spacings); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + d_n3b_knot_spacings_view(map3b_view(i, j, k), 0) = + 1 / (n3b_knots_array[map_3b[i][j][k]][0][5] - n3b_knots_array[map_3b[i][j][k]][0][4]); + + d_n3b_knot_spacings_view(map3b_view(i, j, k), 1) = + 1 / (n3b_knots_array[map_3b[i][j][k]][1][5] - n3b_knots_array[map_3b[i][j][k]][1][4]); + + d_n3b_knot_spacings_view(map3b_view(i, j, k), 2) = + 1 / (n3b_knots_array[map_3b[i][j][k]][2][5] - n3b_knots_array[map_3b[i][j][k]][2][4]); + } + } + } + Kokkos::deep_copy(d_n3b_knot_spacings, d_n3b_knot_spacings_view); + + // Copy coefficients + + Kokkos::realloc(d_coefficients_3b, interaction_count, max_knots - 4, max_knots - 4, + max_knots - 4); + auto d_coefficients_3b_view = Kokkos::create_mirror(d_coefficients_3b); + + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + for (int i = 0; i < n3b_coeff_array_size[map_3b[n][m][o]][0]; i++) { + for (int j = 0; j < n3b_coeff_array_size[map_3b[n][m][o]][1]; j++) { + for (int k = 0; k < n3b_coeff_array_size[map_3b[n][m][o]][2]; k++) { + d_coefficients_3b_view(map3b_view(n, m, o), i, j, k) = + n3b_coeff_array[map_3b[n][m][o]][i][j][k]; + } + } + } + } + } + } + Kokkos::deep_copy(d_coefficients_3b, d_coefficients_3b_view); + // + // Create derivative coefficients + + // TODO: Shrink size + Kokkos::realloc(d_dncoefficients_3b, interaction_count, 3, max_knots - 4, max_knots - 4, + max_knots - 4); + auto d_dncoefficients_3b_view = Kokkos::create_mirror(d_dncoefficients_3b); + + //Notice the order for d_dncoefficients_3b_view(map3b_view(n, m, o), X, i, j, k) + //d_dncoefficients_3b_view(map3b_view(n, m, o), 2, i, j, k) --> coeff for rjk + //d_dncoefficients_3b_view(map3b_view(n, m, o), 1, i, j, k) --> coeff for rik + //d_dncoefficients_3b_view(map3b_view(n, m, o), 0, i, j, k) --> coeff for rij + // + //This is because- + //In n3b_knot_matrix[i][j][k], + //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + int coeff_dim1 = n3b_coeff_array_size[map_3b[n][m][o]][0]; + int coeff_dim2 = n3b_coeff_array_size[map_3b[n][m][o]][1]; + int coeff_dim3 = n3b_coeff_array_size[map_3b[n][m][o]][2]; + for (int i = 0; i < coeff_dim1; i++) { + for (int j = 0; j < coeff_dim2; j++) { + for (int k = 0; k < coeff_dim3; k++) { + F_FLOAT dntemp4 = + 3 / (n3b_knots_array[map_3b[n][m][o]][0][k + 4] - n3b_knots_array[map_3b[n][m][o]][0][k + 1]); + + d_dncoefficients_3b_view(map3b_view(n, m, o), 2, i, j, k) = + (n3b_coeff_array[map_3b[n][m][o]][i][j][k + 1] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + } + } + } + + for (int i = 0; i < coeff_dim1; i++) { + std::vector> dncoeff_vect2; + for (int j = 0; j < coeff_dim2; j++) { + F_FLOAT dntemp4 = + 3 / (n3b_knots_array[map_3b[n][m][o]][1][j + 4] - n3b_knots_array[map_3b[n][m][o]][1][j + 1]); + + std::vector dncoeff_vect; + for (int k = 0; k < coeff_dim3; k++) { + d_dncoefficients_3b_view(map3b_view(n, m, o), 1, i, j, k) = + (n3b_coeff_array[map_3b[n][m][o]][i][j + 1][k] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + } + } + } + + for (int i = 0; i < coeff_dim1; i++) { + F_FLOAT dntemp4 = + 3 / (n3b_knots_array[map_3b[n][m][o]][2][i + 4] - n3b_knots_array[map_3b[n][m][o]][2][i + 1]); + for (int j = 0; j < coeff_dim2; j++) { + for (int k = 0; k < coeff_dim3; k++) { + d_dncoefficients_3b_view(map3b_view(n, m, o), 0, i, j, k) = + (n3b_coeff_array[map_3b[n][m][o]][i + 1][j][k] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + } + } + } + } + } + } + Kokkos::deep_copy(d_dncoefficients_3b, d_dncoefficients_3b_view); + + // Set spline constants + + Kokkos::realloc(constants_3b, interaction_count, 3, max_knots - 4); + auto constants_3b_view = Kokkos::create_mirror(constants_3b); + + //In n3b_knot_matrix[i][j][k], + //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][2] - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][2][l], 1); + for (int k = 0; k < 16; k++) + constants_3b_view(map3b_view(n, m, o), 0, l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][1] - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][1][l], 1); + for (int k = 0; k < 16; k++) + constants_3b_view(map3b_view(n, m, o), 1, l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][0] -4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][0][l], 1); + for (int k = 0; k < 16; k++) + constants_3b_view(map3b_view(n, m, o), 2, l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + } + } + } + Kokkos::deep_copy(constants_3b, constants_3b_view); + + Kokkos::realloc(dnconstants_3b, interaction_count, 3, max_knots - 6); + auto dnconstants_3b_view = Kokkos::create_mirror(dnconstants_3b); + + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][2] - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][2][l], 1); + for (int k = 0; k < 9; k++) + dnconstants_3b_view(map3b_view(n, m, o), 0, l - 1, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][1] - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][1][l], 1); + for (int k = 0; k < 9; k++) + dnconstants_3b_view(map3b_view(n, m, o), 1, l - 1, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][0] - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][0][l], 1); + for (int k = 0; k < 9; k++) + dnconstants_3b_view(map3b_view(n, m, o), 2, l - 1, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + } + } + } + Kokkos::deep_copy(dnconstants_3b, dnconstants_3b_view); +} + +template +template +KOKKOS_INLINE_FUNCTION void PairUF3Kokkos::twobody(const int itype, const int jtype, + const F_FLOAT r, F_FLOAT &evdwl, + F_FLOAT &fpair) const +{ + + // Find knot starting position + int interaction_id = map2b(itype, jtype); + int start_index = 3; + while (r > d_n2b_knot(interaction_id, start_index + 1)) start_index++; + //int start_index = 3+(int)((r-d_n2b_knot(interaction_id,0))/d_n2b_knot_spacings(interaction_id)); + + F_FLOAT r_values[4]; + r_values[0] = 1; + r_values[1] = r; + r_values[2] = r_values[1] * r_values[1]; + + if (EVFLAG) { + r_values[3] = r_values[2] * r_values[1]; + // Calculate energy + evdwl = constants_2b(interaction_id, start_index, 0); + evdwl += r_values[1] * constants_2b(interaction_id, start_index, 1); + evdwl += r_values[2] * constants_2b(interaction_id, start_index, 2); + evdwl += r_values[3] * constants_2b(interaction_id, start_index, 3); + evdwl += constants_2b(interaction_id, start_index - 1, 4); + evdwl += r_values[1] * constants_2b(interaction_id, start_index - 1, 5); + evdwl += r_values[2] * constants_2b(interaction_id, start_index - 1, 6); + evdwl += r_values[3] * constants_2b(interaction_id, start_index - 1, 7); + evdwl += constants_2b(interaction_id, start_index - 2, 8); + evdwl += r_values[1] * constants_2b(interaction_id, start_index - 2, 9); + evdwl += r_values[2] * constants_2b(interaction_id, start_index - 2, 10); + evdwl += r_values[3] * constants_2b(interaction_id, start_index - 2, 11); + evdwl += constants_2b(interaction_id, start_index - 3, 12); + evdwl += r_values[1] * constants_2b(interaction_id, start_index - 3, 13); + evdwl += r_values[2] * constants_2b(interaction_id, start_index - 3, 14); + evdwl += r_values[3] * constants_2b(interaction_id, start_index - 3, 15); + } + + // Calculate force + fpair = dnconstants_2b(interaction_id, start_index - 1, 0); + fpair += r_values[1] * dnconstants_2b(interaction_id, start_index - 1, 1); + fpair += r_values[2] * dnconstants_2b(interaction_id, start_index - 1, 2); + fpair += dnconstants_2b(interaction_id, start_index - 2, 3); + fpair += r_values[1] * dnconstants_2b(interaction_id, start_index - 2, 4); + fpair += r_values[2] * dnconstants_2b(interaction_id, start_index - 2, 5); + fpair += dnconstants_2b(interaction_id, start_index - 3, 6); + fpair += r_values[1] * dnconstants_2b(interaction_id, start_index - 3, 7); + fpair += r_values[2] * dnconstants_2b(interaction_id, start_index - 3, 8); +} + +template +template +KOKKOS_INLINE_FUNCTION void PairUF3Kokkos::threebody( + const int itype, const int jtype, const int ktype, const F_FLOAT value_rij, + const F_FLOAT value_rik, const F_FLOAT value_rjk, F_FLOAT &evdwl, F_FLOAT (&fforce)[3]) const +{ + evdwl = 0; + fforce[0] = 0; + fforce[1] = 0; + fforce[2] = 0; + + F_FLOAT evals[3][4]; + F_FLOAT dnevals[3][4]; + int start_indices[3]; + F_FLOAT r[3] = {value_rij, value_rik, value_rjk}; + int interaction_id = map3b(itype, jtype, ktype); + + auto coefficients = + Kokkos::subview(d_coefficients_3b, interaction_id, Kokkos::ALL, Kokkos::ALL, Kokkos::ALL); + auto dncoefficients = Kokkos::subview(d_dncoefficients_3b, interaction_id, Kokkos::ALL, + Kokkos::ALL, Kokkos::ALL, Kokkos::ALL); + //Notice the 2-d in d_n3b_knot_matrix + // + //In d_n3b_knot_matrix[i][j][k], + //d_n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //d_n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //d_n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + // + //and r[0] = rij, r[1] = rik and r[2] = rjk + //see n3b_knot_matrix and pair_uf3.cpp for more details + for (int d = 0; d < 3; d++) { + start_indices[d] = 3; + while (r[d] > d_n3b_knot_matrix(interaction_id, 2-d, start_indices[d] + 1)) start_indices[d]++; + //start_indices[d] = 3+(int)((r[d]-d_n3b_knot_matrix(interaction_id, 2-d, 0))/d_n3b_knot_matrix_spacings(interaction_id, 2-d)); + + F_FLOAT r_values[4]; + r_values[0] = 1; + r_values[1] = r[d]; + r_values[2] = r_values[1] * r_values[1]; + + r_values[3] = r_values[2] * r_values[1]; + + // Calculate energy + evals[d][0] = constants_3b(interaction_id, d, start_indices[d], 0); + evals[d][0] += r_values[1] * constants_3b(interaction_id, d, start_indices[d], 1); + evals[d][0] += r_values[2] * constants_3b(interaction_id, d, start_indices[d], 2); + evals[d][0] += r_values[3] * constants_3b(interaction_id, d, start_indices[d], 3); + evals[d][1] = constants_3b(interaction_id, d, start_indices[d] - 1, 4); + evals[d][1] += r_values[1] * constants_3b(interaction_id, d, start_indices[d] - 1, 5); + evals[d][1] += r_values[2] * constants_3b(interaction_id, d, start_indices[d] - 1, 6); + evals[d][1] += r_values[3] * constants_3b(interaction_id, d, start_indices[d] - 1, 7); + evals[d][2] = constants_3b(interaction_id, d, start_indices[d] - 2, 8); + evals[d][2] += r_values[1] * constants_3b(interaction_id, d, start_indices[d] - 2, 9); + evals[d][2] += r_values[2] * constants_3b(interaction_id, d, start_indices[d] - 2, 10); + evals[d][2] += r_values[3] * constants_3b(interaction_id, d, start_indices[d] - 2, 11); + evals[d][3] = constants_3b(interaction_id, d, start_indices[d] - 3, 12); + evals[d][3] += r_values[1] * constants_3b(interaction_id, d, start_indices[d] - 3, 13); + evals[d][3] += r_values[2] * constants_3b(interaction_id, d, start_indices[d] - 3, 14); + evals[d][3] += r_values[3] * constants_3b(interaction_id, d, start_indices[d] - 3, 15); + + dnevals[d][0] = dnconstants_3b(interaction_id, d, start_indices[d] - 1, 0); + dnevals[d][0] += r_values[1] * dnconstants_3b(interaction_id, d, start_indices[d] - 1, 1); + dnevals[d][0] += r_values[2] * dnconstants_3b(interaction_id, d, start_indices[d] - 1, 2); + dnevals[d][1] = dnconstants_3b(interaction_id, d, start_indices[d] - 2, 3); + dnevals[d][1] += r_values[1] * dnconstants_3b(interaction_id, d, start_indices[d] - 2, 4); + dnevals[d][1] += r_values[2] * dnconstants_3b(interaction_id, d, start_indices[d] - 2, 5); + dnevals[d][2] = dnconstants_3b(interaction_id, d, start_indices[d] - 3, 6); + dnevals[d][2] += r_values[1] * dnconstants_3b(interaction_id, d, start_indices[d] - 3, 7); + dnevals[d][2] += r_values[2] * dnconstants_3b(interaction_id, d, start_indices[d] - 3, 8); + dnevals[d][3] = 0; + } + + if (EVFLAG) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + evdwl += coefficients(start_indices[0] - i, start_indices[1] - j, start_indices[2] - k) * + evals[0][i] * evals[1][j] * evals[2][k]; + } + } + } + } + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + fforce[0] += dncoefficients(0, start_indices[0] - 3 + i, start_indices[1] - 3 + j, + start_indices[2] - 3 + k) * + dnevals[0][2 - i] * evals[1][3 - j] * evals[2][3 - k]; + } + } + } + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 4; k++) { + fforce[1] += dncoefficients(1, start_indices[0] - 3 + i, start_indices[1] - 3 + j, + start_indices[2] - 3 + k) * + evals[0][3 - i] * dnevals[1][2 - j] * evals[2][3 - k]; + } + } + } + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 3; k++) { + fforce[2] += dncoefficients(2, start_indices[0] - 3 + i, start_indices[1] - 3 + j, + start_indices[2] - 3 + k) * + evals[0][3 - i] * evals[1][3 - j] * dnevals[2][2 - k]; + } + } + } +} + +template void PairUF3Kokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (neighflag == FULL) no_virial_fdotr_compute = 1; + + ev_init(eflag, vflag, 0); + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memoryKK->destroy_kokkos(k_eatom, eatom); + memoryKK->create_kokkos(k_eatom, eatom, maxeatom, "pair:eatom"); + d_eatom = k_eatom.view(); + } + if (vflag_atom) { + memoryKK->destroy_kokkos(k_vatom, vatom); + memoryKK->create_kokkos(k_vatom, vatom, maxvatom, "pair:vatom"); + d_vatom = k_vatom.view(); + } + + atomKK->sync(execution_space, datamask_read); + if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + else atomKK->modified(execution_space,F_MASK); + + x = atomKK->k_x.template view(); + f = atomKK->k_f.template view(); + tag = atomKK->k_tag.template view(); + type = atomKK->k_type.template view(); + nlocal = atom->nlocal; + newton_pair = force->newton_pair; + nall = atom->nlocal + atom->nghost; + k_cutsq.template sync(); //Sync the device memory of k_cutsq with + //the array from the host memory; this updates d_cutsq also + k_cut_3b.template sync(); + k_min_cut_3b.template sync(); + + inum = list->inum; + const int ignum = inum + list->gnum; + NeighListKokkos *k_list = static_cast *>(list); + d_ilist = k_list->d_ilist; + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + + copymode = 1; + + escatter = ScatterEType(d_eatom); + fscatter = ScatterFType(f); + vscatter = ScatterVType(d_vatom); + //cvscatter = ScatterCVType(d_cvatom); + + EV_FLOAT ev; + EV_FLOAT ev_all; + + // build short neighbor list + + int max_neighs = d_neighbors.extent(1); + + if (((int)d_neighbors_short.extent(1) != max_neighs) || + ((int)d_neighbors_short.extent(0) != ignum)) { + d_neighbors_short = Kokkos::View("UF3::neighbors_short", ignum, max_neighs); + } + if (d_numneigh_short.extent(0) != ignum) + d_numneigh_short = Kokkos::View("UF3::numneighs_short", ignum); + Kokkos::parallel_for( + Kokkos::RangePolicy(0, ignum), *this); + + // loop over neighbor list of my atoms + + if (evflag) { + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0, inum), *this, ev); + } + else{ + Kokkos::parallel_for( + Kokkos::RangePolicy>(0, inum), *this); + } + ev_all += ev; + + Kokkos::Experimental::contribute(d_eatom, escatter); + Kokkos::Experimental::contribute(d_vatom, vscatter); + //Kokkos::Experimental::contribute(d_cvatom, cvscatter); + Kokkos::Experimental::contribute(f, fscatter); + + if (eflag_global) eng_vdwl += ev_all.evdwl; + if (vflag_global) { + virial[0] += ev_all.v[0]; + virial[1] += ev_all.v[1]; + virial[2] += ev_all.v[2]; + virial[3] += ev_all.v[3]; + virial[4] += ev_all.v[4]; + virial[5] += ev_all.v[5]; + } + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + if (cvflag_atom) { + //k_cvatom.template modify(); + //k_cvatom.template sync(); + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + copymode = 0; +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION void PairUF3Kokkos::operator()(TagPairUF3ComputeShortNeigh, + const int &ii) const +{ + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i, 0); + const X_FLOAT ytmp = x(i, 1); + const X_FLOAT ztmp = x(i, 2); + + const int jnum = d_numneigh[i]; + int inside = 0; + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i, jj); + j &= NEIGHMASK; + + const X_FLOAT delx = xtmp - x(j, 0); + const X_FLOAT dely = ytmp - x(j, 1); + const X_FLOAT delz = ztmp - x(j, 2); + const F_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + const int itype = type[i]; + const int jtype = type[j]; + + if (rsq <= d_cutsq(itype, jtype)) { + d_neighbors_short(i, inside) = j; + inside++; + } + } + d_numneigh_short(i) = inside; +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::operator()(TagPairUF3ComputeFullA, const int &ii, + EV_FLOAT &ev) const +{ + // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + + auto v_f = vscatter.access(); + auto a_f = fscatter.access(); + auto a_cvatom = cvscatter.access(); + + F_FLOAT del_rji[3], del_rki[3], del_rkj[3], triangle_eval[3]; + F_FLOAT fij[3], fik[3], fjk[3]; + F_FLOAT fji[3], fki[3], fkj[3]; + F_FLOAT Fj[3], Fk[3]; + F_FLOAT evdwl = 0, evdwl3 = 0; + F_FLOAT fpair = 0; + + const int i = d_ilist[ii]; + const int itype = type[i]; + const X_FLOAT xtmp = x(i, 0); + const X_FLOAT ytmp = x(i, 1); + const X_FLOAT ztmp = x(i, 2); + + // two-body interactions + + const int jnum = d_numneigh_short[i]; + + F_FLOAT fxtmpi = 0.0; + F_FLOAT fytmpi = 0.0; + F_FLOAT fztmpi = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors_short(i, jj); + j &= NEIGHMASK; + const int jtype = type[j]; + + const X_FLOAT delx = xtmp - x(j, 0); + const X_FLOAT dely = ytmp - x(j, 1); + const X_FLOAT delz = ztmp - x(j, 2); + const F_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + if (rsq >= d_cutsq(itype, jtype)) continue; + + const F_FLOAT rij = sqrt(rsq); + this->template twobody(itype, jtype, rij, evdwl, fpair); + + fpair = -fpair / rij; + + fxtmpi += delx * fpair; + fytmpi += dely * fpair; + fztmpi += delz * fpair; + a_f(j, 0) -= delx * fpair; + a_f(j, 1) -= dely * fpair; + a_f(j, 2) -= delz * fpair; + + if (EVFLAG) { + if (eflag) ev.evdwl += evdwl; + if (vflag_either || eflag_atom) + this->template ev_tally(ev, i, j, evdwl, fpair, delx, dely, delz); + } + } + + // 3-body interaction + // jth atom + const int jnumm1 = jnum - 1; + for (int jj = 0; jj < jnumm1; jj++) { + int j = d_neighbors_short(i, jj); + j &= NEIGHMASK; + const int jtype = type[j]; + del_rji[0] = x(j, 0) - xtmp; + del_rji[1] = x(j, 1) - ytmp; + del_rji[2] = x(j, 2) - ztmp; + F_FLOAT rij = sqrt(del_rji[0] * del_rji[0] + del_rji[1] * del_rji[1] + del_rji[2] * del_rji[2]); + + F_FLOAT fxtmpj = 0.0; + F_FLOAT fytmpj = 0.0; + F_FLOAT fztmpj = 0.0; + + for (int kk = jj + 1; kk < jnum; kk++) { + int k = d_neighbors_short(i, kk); + k &= NEIGHMASK; + const int ktype = type[k]; + + // Notice the order of d_min_cut_3b[i][j][k] + //In d_min_cut_3b[i][j][k], + //d_min_cut_3b[i][j][k][0] is the knot_vector along jk, + //d_min_cut_3b[i][j][k][1] is the knot_vector along ik, + //d_min_cut_3b[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + if (rij < d_min_cut_3b(itype, jtype, ktype, 2)) continue; + if (rij > d_cut_3b(itype, jtype, ktype)) continue; + + del_rki[0] = x(k, 0) - xtmp; + del_rki[1] = x(k, 1) - ytmp; + del_rki[2] = x(k, 2) - ztmp; + F_FLOAT rik = + sqrt(del_rki[0] * del_rki[0] + del_rki[1] * del_rki[1] + del_rki[2] * del_rki[2]); + + if (rik < d_min_cut_3b(itype, jtype, ktype, 1)) continue; + if (rik > d_cut_3b(itype, ktype, jtype)) continue; + + del_rkj[0] = x(k, 0) - x(j, 0); + del_rkj[1] = x(k, 1) - x(j, 1); + del_rkj[2] = x(k, 2) - x(j, 2); + F_FLOAT rjk = + sqrt(del_rkj[0] * del_rkj[0] + del_rkj[1] * del_rkj[1] + del_rkj[2] * del_rkj[2]); + if (rjk < d_min_cut_3b(itype, jtype, ktype, 0)) continue; + this->template threebody(itype, jtype, ktype, rij, rik, rjk, evdwl3, triangle_eval); + + fij[0] = *(triangle_eval + 0) * (del_rji[0] / rij); + fji[0] = -fij[0]; + fik[0] = *(triangle_eval + 1) * (del_rki[0] / rik); + fki[0] = -fik[0]; + fjk[0] = *(triangle_eval + 2) * (del_rkj[0] / rjk); + fkj[0] = -fjk[0]; + + fij[1] = *(triangle_eval + 0) * (del_rji[1] / rij); + fji[1] = -fij[1]; + fik[1] = *(triangle_eval + 1) * (del_rki[1] / rik); + fki[1] = -fik[1]; + fjk[1] = *(triangle_eval + 2) * (del_rkj[1] / rjk); + fkj[1] = -fjk[1]; + + fij[2] = *(triangle_eval + 0) * (del_rji[2] / rij); + fji[2] = -fij[2]; + fik[2] = *(triangle_eval + 1) * (del_rki[2] / rik); + fki[2] = -fik[2]; + fjk[2] = *(triangle_eval + 2) * (del_rkj[2] / rjk); + fkj[2] = -fjk[2]; + + Fj[0] = fji[0] + fjk[0]; + Fj[1] = fji[1] + fjk[1]; + Fj[2] = fji[2] + fjk[2]; + + Fk[0] = fki[0] + fkj[0]; + Fk[1] = fki[1] + fkj[1]; + Fk[2] = fki[2] + fkj[2]; + + fxtmpi += (fij[0] + fik[0]); + fytmpi += (fij[1] + fik[1]); + fztmpi += (fij[2] + fik[2]); + fxtmpj += Fj[0]; + fytmpj += Fj[1]; + fztmpj += Fj[2]; + a_f(k, 0) += Fk[0]; + a_f(k, 1) += Fk[1]; + a_f(k, 2) += Fk[2]; + + if (EVFLAG) { + if (eflag) { ev.evdwl += evdwl3; } + if (vflag_either || eflag_atom) { + this->template ev_tally3(ev, i, j, k, evdwl3, 0.0, Fj, Fk, del_rji, del_rki); + if (cvflag_atom) { + + F_FLOAT ric[3]; + ric[0] = THIRD * (-del_rji[0] - del_rki[0]); + ric[1] = THIRD * (-del_rji[1] - del_rki[1]); + ric[2] = THIRD * (-del_rji[2] - del_rki[2]); + a_cvatom(i, 0) += ric[0] * (-Fj[0] - Fk[0]); + a_cvatom(i, 1) += ric[1] * (-Fj[1] - Fk[1]); + a_cvatom(i, 2) += ric[2] * (-Fj[2] - Fk[2]); + a_cvatom(i, 3) += ric[0] * (-Fj[1] - Fk[1]); + a_cvatom(i, 4) += ric[0] * (-Fj[2] - Fk[2]); + a_cvatom(i, 5) += ric[1] * (-Fj[2] - Fk[2]); + a_cvatom(i, 6) += ric[1] * (-Fj[0] - Fk[0]); + a_cvatom(i, 7) += ric[2] * (-Fj[0] - Fk[0]); + a_cvatom(i, 8) += ric[2] * (-Fj[1] - Fk[1]); + + double rjc[3]; + rjc[0] = THIRD * (del_rji[0] - del_rkj[0]); + rjc[1] = THIRD * (del_rji[1] - del_rkj[1]); + rjc[2] = THIRD * (del_rji[2] - del_rkj[2]); + + a_cvatom(j, 0) += rjc[0] * Fj[0]; + a_cvatom(j, 1) += rjc[1] * Fj[1]; + a_cvatom(j, 2) += rjc[2] * Fj[2]; + a_cvatom(j, 3) += rjc[0] * Fj[1]; + a_cvatom(j, 4) += rjc[0] * Fj[2]; + a_cvatom(j, 5) += rjc[1] * Fj[2]; + a_cvatom(j, 6) += rjc[1] * Fj[0]; + a_cvatom(j, 7) += rjc[2] * Fj[0]; + a_cvatom(j, 8) += rjc[2] * Fj[1]; + + double rkc[3]; + rkc[0] = THIRD * (del_rki[0] + del_rkj[0]); + rkc[1] = THIRD * (del_rki[1] + del_rkj[1]); + rkc[2] = THIRD * (del_rki[2] + del_rkj[2]); + + a_cvatom(k, 0) += rkc[0] * Fk[0]; + a_cvatom(k, 1) += rkc[1] * Fk[1]; + a_cvatom(k, 2) += rkc[2] * Fk[2]; + a_cvatom(k, 3) += rkc[0] * Fk[1]; + a_cvatom(k, 4) += rkc[0] * Fk[2]; + a_cvatom(k, 5) += rkc[1] * Fk[2]; + a_cvatom(k, 6) += rkc[1] * Fk[0]; + a_cvatom(k, 7) += rkc[2] * Fk[0]; + a_cvatom(k, 8) += rkc[2] * Fk[1]; + } + } + } + } + a_f(j, 0) += fxtmpj; + a_f(j, 1) += fytmpj; + a_f(j, 2) += fztmpj; + } + + a_f(i, 0) += fxtmpi; + a_f(i, 1) += fytmpi; + a_f(i, 2) += fztmpi; +} + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::operator()(TagPairUF3ComputeFullA, + const int &ii) const +{ + EV_FLOAT ev; + this->template operator()(TagPairUF3ComputeFullA(), ii, ev); +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, + const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, + const F_FLOAT &delz) const +{ + + // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, + // and neither for Serial + + auto a_eatom = escatter.access(); + auto a_vatom = vscatter.access(); + auto a_cvatom = cvscatter.access(); + + if (eflag_atom) { + const E_FLOAT epairhalf = 0.5 * epair; + a_eatom[i] += epairhalf; + a_eatom[j] += epairhalf; + } + + if (vflag_either) { + const E_FLOAT v0 = delx * delx * fpair; + const E_FLOAT v1 = dely * dely * fpair; + const E_FLOAT v2 = delz * delz * fpair; + const E_FLOAT v3 = delx * dely * fpair; + const E_FLOAT v4 = delx * delz * fpair; + const E_FLOAT v5 = dely * delz * fpair; + + if (vflag_global) { + ev.v[0] += v0; + ev.v[1] += v1; + ev.v[2] += v2; + ev.v[3] += v3; + ev.v[4] += v4; + ev.v[5] += v5; + } + + if (vflag_atom) { + a_vatom(i, 0) += 0.5 * v0; + a_vatom(i, 1) += 0.5 * v1; + a_vatom(i, 2) += 0.5 * v2; + a_vatom(i, 3) += 0.5 * v3; + a_vatom(i, 4) += 0.5 * v4; + a_vatom(i, 5) += 0.5 * v5; + + a_vatom(j, 0) += 0.5 * v0; + a_vatom(j, 1) += 0.5 * v1; + a_vatom(j, 2) += 0.5 * v2; + a_vatom(j, 3) += 0.5 * v3; + a_vatom(j, 4) += 0.5 * v4; + a_vatom(j, 5) += 0.5 * v5; + } + + if (cvflag_atom) { + a_cvatom(i, 0) += 0.5 * v0; + a_cvatom(i, 1) += 0.5 * v1; + a_cvatom(i, 2) += 0.5 * v2; + a_cvatom(i, 3) += 0.5 * v3; + a_cvatom(i, 4) += 0.5 * v4; + a_cvatom(i, 5) += 0.5 * v5; + a_cvatom(i, 6) += 0.5 * v3; + a_cvatom(i, 7) += 0.5 * v4; + a_cvatom(i, 8) += 0.5 * v5; + a_cvatom(j, 0) += 0.5 * v0; + a_cvatom(j, 1) += 0.5 * v1; + a_cvatom(j, 2) += 0.5 * v2; + a_cvatom(j, 3) += 0.5 * v3; + a_cvatom(j, 4) += 0.5 * v4; + a_cvatom(j, 5) += 0.5 * v5; + a_cvatom(j, 6) += 0.5 * v3; + a_cvatom(j, 7) += 0.5 * v4; + a_cvatom(j, 8) += 0.5 * v5; + } + } +} + +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + called by SW and hbond potentials, newton_pair is always on + virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk + ------------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::ev_tally3(EV_FLOAT &ev, const int &i, const int &j, int &k, + const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, + F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const +{ + F_FLOAT epairthird, v[6]; + + // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, + // and neither for Serial + + auto a_eatom = escatter.access(); + auto a_vatom = vscatter.access(); + + if (eflag_atom) { + epairthird = THIRD * (evdwl + ecoul); + a_eatom[i] += epairthird; + a_eatom[j] += epairthird; + a_eatom[k] += epairthird; + } + + if (vflag_either) { + v[0] = drji[0] * fj[0] + drki[0] * fk[0]; + v[1] = drji[1] * fj[1] + drki[1] * fk[1]; + v[2] = drji[2] * fj[2] + drki[2] * fk[2]; + v[3] = drji[0] * fj[1] + drki[0] * fk[1]; + v[4] = drji[0] * fj[2] + drki[0] * fk[2]; + v[5] = drji[1] * fj[2] + drki[1] * fk[2]; + + if (vflag_global) { + ev.v[0] += v[0]; + ev.v[1] += v[1]; + ev.v[2] += v[2]; + ev.v[3] += v[3]; + ev.v[4] += v[4]; + ev.v[5] += v[5]; + } + + if (vflag_atom) { + a_vatom(i, 0) += THIRD * v[0]; + a_vatom(i, 1) += THIRD * v[1]; + a_vatom(i, 2) += THIRD * v[2]; + a_vatom(i, 3) += THIRD * v[3]; + a_vatom(i, 4) += THIRD * v[4]; + a_vatom(i, 5) += THIRD * v[5]; + + a_vatom(j, 0) += THIRD * v[0]; + a_vatom(j, 1) += THIRD * v[1]; + a_vatom(j, 2) += THIRD * v[2]; + a_vatom(j, 3) += THIRD * v[3]; + a_vatom(j, 4) += THIRD * v[4]; + a_vatom(j, 5) += THIRD * v[5]; + + a_vatom(k, 0) += THIRD * v[0]; + a_vatom(k, 1) += THIRD * v[1]; + a_vatom(k, 2) += THIRD * v[2]; + a_vatom(k, 3) += THIRD * v[3]; + a_vatom(k, 4) += THIRD * v[4]; + a_vatom(k, 5) += THIRD * v[5]; + } + } +} + +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + called by SW and hbond potentials, newton_pair is always on + virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk + ------------------------------------------------------------------------- */ + +template +template +void PairUF3Kokkos::copy_2d(V &d, T **h, int m, int n) +{ + Kokkos::View tmp("pair::tmp", m, n); //Create tmp view(array) on + //device memory + + //auto h_view = Kokkos::create_mirror_view(tmp); + auto h_view = Kokkos::create_mirror(tmp); //Create a mirror of the device + //view(array) tmp, as deep_copy is only possible for mirror views + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + h_view(i, j) = h[i][j]; //fill mirror + } + //views with data from normal array 'h' which always lives on host memory + } + + Kokkos::deep_copy(tmp, h_view); //Deepcopy data from h_view(host) to tmp(device) + + d = tmp; +} + +template +template +void PairUF3Kokkos::copy_3d(V &d, T ***h, int m, int n, int o) +{ + Kokkos::View tmp("pair::tmp", m, n, o); //Create tmp view(array) on + //device memory + + //auto h_view = Kokkos::create_mirror_view(tmp); //create_mirror always copies + //the data. create_mirror_view only copies data if the host cannot access the + //data + auto h_view = Kokkos::create_mirror(tmp); //Create a mirror of the device + //view(array) tmp, as deep_copy is only possible for mirror views + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + for (int k = 0; k < o; k++) { h_view(i, j, k) = h[i][j][k]; } //fill mirror + //views with data from normal array 'h' which always lives on host memory + } + } + + Kokkos::deep_copy(tmp, h_view); //Deepcopy data from h_view(host) to tmp(device) + + d = tmp; +} + +template +std::vector PairUF3Kokkos::get_constants(double *knots, double coefficient) +{ + + std::vector constants(16); + + constants[0] = coefficient * + (-cube(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[1] = coefficient * + (3 * square(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[2] = coefficient * + (-3 * knots[0] / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[3] = coefficient * + (1 / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[4] = coefficient * + (square(knots[1]) * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + square(knots[0]) * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] * knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[5] = coefficient * + (-square(knots[1]) / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 2 * knots[1] * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + square(knots[0]) / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 2 * knots[0] * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + knots[0] * knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[0] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[6] = coefficient * + (2 * knots[1] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + 2 * knots[0] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[7] = coefficient * + (-1 / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 1 / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 1 / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[8] = coefficient * + (-knots[0] * square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] * knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] * square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[9] = coefficient * + (2 * knots[0] * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + knots[1] * knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[1] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 2 * knots[2] * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) + + square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[10] = coefficient * + (-knots[0] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + 2 * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) - + 2 * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[11] = coefficient * + (1 / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + 1 / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 1 / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[12] = coefficient * + (cube(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + constants[13] = coefficient * + (-3 * square(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + constants[14] = coefficient * + (3 * knots[4] / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + constants[15] = coefficient * + (-1 / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + + return constants; +} + +template +std::vector PairUF3Kokkos::get_dnconstants(double *knots, double coefficient) +{ + std::vector constants(9); + + constants[0] = coefficient * + (square(knots[0]) / + (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + constants[1] = coefficient * + (-2 * knots[0] / + (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + constants[2] = coefficient * + (1 / (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + constants[3] = coefficient * + (-knots[1] * knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + knots[0] * knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + constants[4] = coefficient * + (knots[1] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[0] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2])) + + knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + constants[5] = coefficient * + (-1 / (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + 1 / (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + constants[6] = coefficient * + (square(knots[3]) / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + constants[7] = coefficient * + (-2 * knots[3] / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + constants[8] = coefficient * + (1 / (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + + return constants; +} + +template +double PairUF3Kokkos::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, + double /*factor_coul*/, double factor_lj, double &fforce) +{ + double value = 0.0; + double r = sqrt(rsq); + int interaction_id = map2b(itype, jtype); + int start_index = 3; + while (r > d_n2b_knot(interaction_id, start_index + 1)) start_index++; + + if (r < d_cutsq(itype, jtype)) { + F_FLOAT r_values[4]; + r_values[0] = 1; + r_values[1] = r; + r_values[2] = r_values[1] * r_values[1]; + r_values[3] = r_values[2] * r_values[1]; + + // Calculate energy + value = constants_2b(interaction_id, start_index, 0); + value += r_values[1] * constants_2b(interaction_id, start_index, 1); + value += r_values[2] * constants_2b(interaction_id, start_index, 2); + value += r_values[3] * constants_2b(interaction_id, start_index, 3); + value += constants_2b(interaction_id, start_index - 1, 4); + value += r_values[1] * constants_2b(interaction_id, start_index - 1, 5); + value += r_values[2] * constants_2b(interaction_id, start_index - 1, 6); + value += r_values[3] * constants_2b(interaction_id, start_index - 1, 7); + value += constants_2b(interaction_id, start_index - 2, 8); + value += r_values[1] * constants_2b(interaction_id, start_index - 2, 9); + value += r_values[2] * constants_2b(interaction_id, start_index - 2, 10); + value += r_values[3] * constants_2b(interaction_id, start_index - 2, 11); + value += constants_2b(interaction_id, start_index - 3, 12); + value += r_values[1] * constants_2b(interaction_id, start_index - 3, 13); + value += r_values[2] * constants_2b(interaction_id, start_index - 3, 14); + value += r_values[3] * constants_2b(interaction_id, start_index - 3, 15); + + // Calculate force + fforce = dnconstants_2b(interaction_id, start_index - 1, 0); + fforce += r_values[1] * dnconstants_2b(interaction_id, start_index - 1, 1); + fforce += r_values[2] * dnconstants_2b(interaction_id, start_index - 1, 2); + fforce += dnconstants_2b(interaction_id, start_index - 2, 3); + fforce += r_values[1] * dnconstants_2b(interaction_id, start_index - 2, 4); + fforce += r_values[2] * dnconstants_2b(interaction_id, start_index - 2, 5); + fforce += dnconstants_2b(interaction_id, start_index - 3, 6); + fforce += r_values[1] * dnconstants_2b(interaction_id, start_index - 3, 7); + fforce += r_values[2] * dnconstants_2b(interaction_id, start_index - 3, 8); + } + + return factor_lj * value; +} + +namespace LAMMPS_NS { +template class PairUF3Kokkos; +#ifdef KOKKOS_ENABLE_CUDA +template class PairUF3Kokkos; +#endif +} // namespace LAMMPS_NS diff --git a/src/KOKKOS/pair_uf3_kokkos.h b/src/KOKKOS/pair_uf3_kokkos.h new file mode 100644 index 0000000000..15c2832da1 --- /dev/null +++ b/src/KOKKOS/pair_uf3_kokkos.h @@ -0,0 +1,187 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(uf3/kk,PairUF3Kokkos) +PairStyle(uf3/kk/device,PairUF3Kokkos) +// clang-format on +#else + +#ifndef LMP_PAIR_UF3_KOKKOS_H +#define LMP_PAIR_UF3_KOKKOS_H + +#include "kokkos.h" +#include "pair_kokkos.h" +#include "pair_uf3.h" + +template struct TagPairUF3ComputeFullA {}; +struct TagPairUF3ComputeShortNeigh {}; + +namespace LAMMPS_NS { + +template class PairUF3Kokkos : public PairUF3 { + public: + PairUF3Kokkos(class LAMMPS *); + ~PairUF3Kokkos() override; + void compute(int, int) override; + void settings(int, char **) override; + void coeff(int, char **) override; + void allocate(); + void init_style() override; + void init_list(int, class NeighList *) override; // needed for ptr to full neigh list + double init_one(int, int) override; // needed for cutoff radius for neighbour list + double single(int, int, int, int, double, double, double, double &) override; + + template void copy_2d(V &d, T **h, int m, int n); + template void copy_3d(V &d, T ***h, int m, int n, int o); + + template + KOKKOS_INLINE_FUNCTION void operator()(TagPairUF3ComputeFullA, const int &, + EV_FLOAT &) const; + + template + KOKKOS_INLINE_FUNCTION void operator()(TagPairUF3ComputeFullA, + const int &) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairUF3ComputeShortNeigh, const int &) const; + + enum { EnabledNeighFlags = FULL }; + enum { COUL_FLAG = 0 }; + typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef EV_FLOAT value_type; + + protected: + typename AT::tdual_ffloat_2d k_cutsq;//Create a DualView, defination of tdual_ffloat_2d in kokkos_type.h + typename AT::t_ffloat_2d d_cutsq; //t_ffloat_2d = t_dev ==> Creates a new View d_cutsq + //the type of d_cutsq is decided by the Device(not host) type for the DualView k_cutsq + //Meaning the memory location of d_cutsq is the same as the Device(not host) memory location of + //k_cutsq + typedef Kokkos::DualView tdual_ffloat_3d; + typedef Kokkos::DualView tdual_ffloat_4d; + tdual_ffloat_3d k_cut_3b; + tdual_ffloat_4d k_min_cut_3b; + typename tdual_ffloat_3d::t_dev d_cut_3b; + typename tdual_ffloat_4d::t_dev d_min_cut_3b; + template void destroy_3d(TYPE data, typename TYPE::value_type*** &array); + template void destroy_4d(TYPE data, typename TYPE::value_type**** &array); + Kokkos::View /*d_cutsq,*/ d_cut_3b_list; + //Kokkos::View d_cut_3b; + + Kokkos::View d_coefficients_2b; + Kokkos::View d_dncoefficients_2b; + Kokkos::View d_n2b_knot; + Kokkos::View d_n2b_knot_spacings; + Kokkos::View map2b; + Kokkos::View constants; + Kokkos::View dnconstants; + Kokkos::View d_n3b_knot_matrix; + Kokkos::View d_coefficients_3b; + Kokkos::View d_dncoefficients_3b; + Kokkos::View d_n3b_knot_spacings; + Kokkos::View d_n3b_knot_matrix_spacings; + Kokkos::View map3b; + + Kokkos::View constants_2b; + Kokkos::View dnconstants_2b; + Kokkos::View constants_3b; + Kokkos::View dnconstants_3b; + + std::vector get_constants(double *knots, double coefficient); + std::vector get_dnconstants(double *knots, double coefficient); + + int coefficients_created = 0; + void create_coefficients(); + void create_3b_coefficients(); + void create_2b_coefficients(); + std::vector get_coefficients(const double *knots, const double coefficient) const; + std::vector get_dncoefficients(const double *knots, const double coefficient) const; + + template + void twobody(const int itype, const int jtype, const F_FLOAT r, F_FLOAT &evdwl, + F_FLOAT &fpair) const; + template + void threebody(const int itype, const int jtype, const int ktype, const F_FLOAT value_rij, + const F_FLOAT value_rik, const F_FLOAT value_rjk, F_FLOAT &evdwl3, + F_FLOAT (&fforce)[3]) const; + + template + KOKKOS_INLINE_FUNCTION void + ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, const F_FLOAT &fpair, + const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const; + + template + KOKKOS_INLINE_FUNCTION void ev_tally3(EV_FLOAT &ev, const int &i, const int &j, int &k, + const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, + F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const; + + typename AT::t_x_array_randomread x; + typename AT::t_f_array f; + typename AT::t_tagint_1d tag; + typename AT::t_int_1d_randomread type; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; + + using ScatterFType = Kokkos::Experimental::ScatterView; + ScatterFType fscatter; + using ScatterVType = Kokkos::Experimental::ScatterView; + ScatterVType vscatter; + using ScatterCVType = Kokkos::Experimental::ScatterView; + ScatterCVType cvscatter; + using ScatterEType = Kokkos::Experimental::ScatterView; + ScatterEType escatter; + + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist; + typename AT::t_int_1d_randomread d_numneigh; + + int neighflag, newton_pair; + int nlocal, nall, eflag, vflag; + + int inum; + Kokkos::View d_neighbors_short; + Kokkos::View d_numneigh_short; + + friend void pair_virial_fdotr_compute(PairUF3Kokkos *); +}; + +KOKKOS_INLINE_FUNCTION int min(int i, int j) +{ + return i < j ? i : j; +} +KOKKOS_INLINE_FUNCTION int max(int i, int j) +{ + return i > j ? i : j; +} + +} // namespace LAMMPS_NS + +#endif +#endif + diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index 18b642967c..74d1ae1871 100644 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -250,6 +250,7 @@ void PairSW::settings(int narg, char ** arg) // pair_coeff * * and can enable the single function. one_coeff = skip_threebody_flag ? 0 : 1; single_enable = skip_threebody_flag ? 1 : 0; + manybody_flag = skip_threebody_flag ? 0 : 1; iarg += 2; } else error->all(FLERR, "Illegal pair_style sw keyword: {}", arg[iarg]); } diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index bd7e46b3d1..acaaf8ea7e 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -2233,7 +2233,8 @@ void FixGCMC::attempt_molecule_insertion_full() } /* ---------------------------------------------------------------------- - compute particle's interaction energy with the rest of the system + compute particle's interaction energy with the rest of the system by + looping over all atoms in the sub-domain including ghosts. ------------------------------------------------------------------------- */ double FixGCMC::energy(int i, int itype, tagint imolecule, double *coord) diff --git a/src/MC/fix_widom.cpp b/src/MC/fix_widom.cpp index 9871dc8f60..63a43ae506 100644 --- a/src/MC/fix_widom.cpp +++ b/src/MC/fix_widom.cpp @@ -973,7 +973,8 @@ void FixWidom::attempt_molecule_insertion_full() } /* ---------------------------------------------------------------------- - compute particle's interaction energy with the rest of the system + compute particle's interaction energy with the rest of the system by + looping over all atoms in the sub-domain including ghosts. ------------------------------------------------------------------------- */ double FixWidom::energy(int i, int itype, tagint imolecule, double *coord) diff --git a/src/ML-IAP/mliap_descriptor_ace.cpp b/src/ML-IAP/mliap_descriptor_ace.cpp index aa30ac3f81..fd059b822b 100644 --- a/src/ML-IAP/mliap_descriptor_ace.cpp +++ b/src/ML-IAP/mliap_descriptor_ace.cpp @@ -136,7 +136,6 @@ void MLIAPDescriptorACE::compute_descriptors(class MLIAPData *data) int nei = 0; int jtmp = 0; for (int iitmp = 0; iitmp < data->nlistatoms; iitmp++) { - int itmp = data->iatoms[iitmp]; jtmp = data->numneighs[iitmp]; nei = nei + jtmp; if (jtmp > max_jnum) { max_jnum = jtmp; } @@ -144,7 +143,6 @@ void MLIAPDescriptorACE::compute_descriptors(class MLIAPData *data) for (int ii = 0; ii < data->nlistatoms; ii++) { const int i = data->iatoms[ii]; - const int ielemx = data->ielems[ii]; const int jnum = data->numneighs[ii]; delete acemlimpl->ace; @@ -184,7 +182,6 @@ void MLIAPDescriptorACE::compute_forces(class MLIAPData *data) int nei = 0; int jtmp = 0; for (int iitmp = 0; iitmp < data->nlistatoms; iitmp++) { - int itmp = data->iatoms[iitmp]; jtmp = data->numneighs[iitmp]; nei = nei + jtmp; if (jtmp > max_jnum) { max_jnum = jtmp; } @@ -193,7 +190,6 @@ void MLIAPDescriptorACE::compute_forces(class MLIAPData *data) // BEGIN force loop for (int ii = 0; ii < data->nlistatoms; ii++) { const int i = data->iatoms[ii]; - const int ielem = data->ielems[ii]; delete acemlimpl->ace; acemlimpl->ace = new ACECTildeEvaluator(*acemlimpl->basis_set); acemlimpl->ace->compute_projections = 1; @@ -268,7 +264,6 @@ void MLIAPDescriptorACE::compute_force_gradients(class MLIAPData *data) int nei = 0; int jtmp = 0; for (int iitmp = 0; iitmp < data->nlistatoms; iitmp++) { - int itmp = data->iatoms[iitmp]; jtmp = data->numneighs[iitmp]; nei = nei + jtmp; if (jtmp > max_jnum) { max_jnum = jtmp; } @@ -276,7 +271,6 @@ void MLIAPDescriptorACE::compute_force_gradients(class MLIAPData *data) for (int ii = 0; ii < data->nlistatoms; ii++) { const int i = data->iatoms[ii]; - const int ielem = data->ielems[ii]; delete acemlimpl->ace; acemlimpl->ace = new ACECTildeEvaluator(*acemlimpl->basis_set); acemlimpl->ace->compute_projections = 1; @@ -327,14 +321,12 @@ void MLIAPDescriptorACE::compute_descriptor_gradients(class MLIAPData *data) int nei = 0; int jtmp = 0; for (int iitmp = 0; iitmp < data->nlistatoms; iitmp++) { - int itmp = data->iatoms[iitmp]; jtmp = data->numneighs[iitmp]; nei = nei + jtmp; if (jtmp > max_jnum) { max_jnum = jtmp; } } for (int ii = 0; ii < data->nlistatoms; ii++) { const int i = data->iatoms[ii]; - const int ielem = data->ielems[ii]; delete acemlimpl->ace; acemlimpl->ace = new ACECTildeEvaluator(*acemlimpl->basis_set); acemlimpl->ace->compute_projections = 1; @@ -349,7 +341,6 @@ void MLIAPDescriptorACE::compute_descriptor_gradients(class MLIAPData *data) } } - const int *const jlist = data->lmp_firstneigh[ii]; const int jnum = data->numneighs[ii]; acemlimpl->ace->resize_neighbours_cache(jnum); acemlimpl->ace->compute_atom(i, atom->x, atom->type, data->numneighs[ii], @@ -363,11 +354,6 @@ void MLIAPDescriptorACE::compute_descriptor_gradients(class MLIAPData *data) ij = ij0; for (int jj = 0; jj < data->numneighs[ii]; jj++) { - const int jt = data->jatoms[ij]; - - const int j = jlist[jj]; - int yoffset = ndescriptors; - int zoffset = ndescriptors * 2; for (int iicoeff = 0; iicoeff < ndescriptors; iicoeff++) { DOUBLE_TYPE fx_dB = acemlimpl->ace->neighbours_dB(iicoeff, jj, 0); DOUBLE_TYPE fy_dB = acemlimpl->ace->neighbours_dB(iicoeff, jj, 1); diff --git a/src/ML-UF3/pair_uf3.cpp b/src/ML-UF3/pair_uf3.cpp new file mode 100644 index 0000000000..1f41ddd336 --- /dev/null +++ b/src/ML-UF3/pair_uf3.cpp @@ -0,0 +1,1984 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#include "pair_uf3.h" + +#include "uf3_bspline_basis2.h" +#include "uf3_bspline_basis3.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "math_const.h" +#include "memory.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "text_file_reader.h" + +#include +#include + +using namespace LAMMPS_NS; +using MathConst::THIRD; + +/* ---------------------------------------------------------------------- */ + +PairUF3::PairUF3(LAMMPS *lmp) : + Pair(lmp), setflag_3b(nullptr), knot_spacing_type_2b(nullptr), knot_spacing_type_3b(nullptr), + cut(nullptr), cut_3b(nullptr), cut_3b_list(nullptr), min_cut_3b(nullptr), + knot_spacing_2b(nullptr), knot_spacing_3b(nullptr), n2b_knots_array(nullptr), + n2b_coeff_array(nullptr), n2b_knots_array_size(nullptr), + n2b_coeff_array_size(nullptr), cached_constants_2b(nullptr), + cached_constants_2b_deri(nullptr), map_3b(nullptr), n3b_knots_array(nullptr), + n3b_coeff_array(nullptr), n3b_knots_array_size(nullptr), + n3b_coeff_array_size(nullptr), coeff_for_der_jk(nullptr), + coeff_for_der_ik(nullptr), coeff_for_der_ij(nullptr), + cached_constants_3b(nullptr), cached_constants_3b_deri(nullptr), + neighshort(nullptr) +{ + single_enable = 1; // 1 if single() routine exists + one_coeff = 1; // 1 if allows only one coeff * * call + restartinfo = 0; // 1 if pair style writes restart info + maxshort = 20; + centroidstressflag = CENTROID_AVAIL; + manybody_flag = 1; + bsplines_created = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairUF3::~PairUF3() +{ + if (copymode) return; + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(cut); + memory->destroy(knot_spacing_type_2b); + memory->destroy(knot_spacing_2b); + memory->destroy(n2b_knots_array_size); + memory->destroy(n2b_coeff_array_size); + memory->destroy(n2b_knots_array); + memory->destroy(n2b_coeff_array); + memory->destroy(cached_constants_2b); + memory->destroy(cached_constants_2b_deri); + + if (pot_3b) { + memory->destroy(setflag_3b); + memory->destroy(cut_3b); + memory->destroy(cut_3b_list); + memory->destroy(min_cut_3b); + memory->destroy(neighshort); + memory->destroy(knot_spacing_type_3b); + memory->destroy(knot_spacing_3b); + memory->destroy(map_3b); + memory->destroy(n3b_knots_array_size); + memory->destroy(n3b_coeff_array_size); + memory->destroy(n3b_knots_array); + memory->destroy(n3b_coeff_array); + memory->destroy(coeff_for_der_jk); + memory->destroy(coeff_for_der_ik); + memory->destroy(coeff_for_der_ij); + memory->destroy(cached_constants_3b); + memory->destroy(cached_constants_3b_deri); + } + } +} + +/* ---------------------------------------------------------------------- + * global settings + * ---------------------------------------------------------------------- */ + +void PairUF3::settings(int narg, char **arg) +{ + + if (narg != 1) + error->all(FLERR, + "Invalid number of arguments for pair_style uf3" + " Are you using a 2-body or 2 & 3-body UF potential?"); + nbody_flag = utils::numeric(FLERR, arg[0], true, lmp); + const int num_of_elements = atom->ntypes; + if (nbody_flag == 2) { + pot_3b = false; + manybody_flag = 0; + } else if (nbody_flag == 3) { + pot_3b = true; + single_enable = 0; + } else + error->all(FLERR, "Pair style uf3 not (yet) implemented for {}-body terms", nbody_flag); + +} + +/* ---------------------------------------------------------------------- + * set coeffs for one or more type pairs + * ---------------------------------------------------------------------- */ +void PairUF3::coeff(int narg, char **arg) +{ + if (narg != 3+atom->ntypes) + error->all(FLERR, "Invalid number of arguments uf3 in pair coeffs."); + + if (!allocated) allocate(); + + map_element2type(narg-3, arg+3, false); + + if (comm->me == 0) + uf3_read_unified_pot_file(arg[2]); + communicate(); + +} + +void PairUF3::allocate() +{ + allocated = 1; + const int num_of_elements = atom->ntypes; + + map = new int[num_of_elements+1]; //No need to delete map as ~Pair deletes map + + // Contains info about wether UF potential were found for type i and j + memory->create(setflag, num_of_elements + 1, num_of_elements + 1, "pair:setflag"); + + // Contains info about 2-body cutoff distance for type i and j + // cutsq is the global variable + // Even though we are making cutsq don't manually change the default values + // Lammps take care of setting the value + memory->create(cutsq, num_of_elements + 1, num_of_elements + 1, "pair:cutsq"); + // cut is specific to this pair style. We will set the values in cut + memory->create(cut, num_of_elements + 1, num_of_elements + 1, "pair:cut"); + //Contains info about type of knot_spacing--> 0 = uniform knot spacing (default) + //1 = non-uniform knot spacing + memory->create(knot_spacing_type_2b, num_of_elements + 1, num_of_elements + 1, + "pair:knot_spacing_type_2b"); + memory->create(knot_spacing_2b, num_of_elements + 1, num_of_elements + 1, + "pair:knot_spacing_2b"); + + //Contains size of 2b knots vectors and 2b coeff matrices + memory->create(n2b_knots_array_size, num_of_elements + 1, num_of_elements + 1, + "pair:n2b_knots_array_size"); + memory->create(n2b_coeff_array_size, num_of_elements + 1, num_of_elements + 1, + "pair:n2b_coeff_array_size"); + + if (pot_3b) { + // Contains info about wether UF potential were found for type i, j and k + memory->create(setflag_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:setflag_3b"); + // Contains info about 3-body cutoff distance for type i, j and k + memory->create(cut_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:cut_3b"); + // Contains info about 3-body cutoff distance for type i, j and k + // for constructing 3-body list + memory->create(cut_3b_list, num_of_elements + 1, num_of_elements + 1, + "pair:cut_3b_list"); + // Contains info about minimum 3-body cutoff distance for type i, j and k + memory->create(min_cut_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, 3, "pair:min_cut_3b"); + //Contains info about type of knot_spacing--> 0 = uniform knot spacing (default) + //1 = non-uniform knot spacing + memory->create(knot_spacing_type_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:knot_spacing_type_3b"); + memory->create(knot_spacing_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, 3, "pair:knot_spacing_3b"); + + tot_interaction_count_3b = 0; + //conatins map of I-J-K interaction + memory->create(map_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:map_3b"); + + // setting cut_3b, setflag = 0 and map_3b + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + cut_3b_list[i][j] = 0; + setflag[i][j] = 0; + n2b_coeff_array_size[i][j] = 0; + n2b_knots_array_size[i][j] = 0; + + for (int k = 1; k < num_of_elements + 1; k++) { + cut_3b[i][j][k] = 0; + min_cut_3b[i][j][k][0] = 0; + min_cut_3b[i][j][k][1] = 0; + min_cut_3b[i][j][k][2] = 0; + + setflag_3b[i][j][k] = 0; + + map_3b[i][j][k] = tot_interaction_count_3b; + tot_interaction_count_3b++; + } + } + } + + //contains sizes of 3b knots vectors and 3b coeff matrices + memory->create(n3b_knots_array_size, tot_interaction_count_3b, 3, + "pair:n3b_knots_array_size"); + memory->create(n3b_coeff_array_size, tot_interaction_count_3b, 3, + "pair:n3b_coeff_array_size"); + for (int i = 0; i < tot_interaction_count_3b; i++) { + n3b_coeff_array_size[i][0] = 0; + n3b_coeff_array_size[i][1] = 0; + n3b_coeff_array_size[i][2] = 0; + + n3b_knots_array_size[i][0] = 0; + n3b_knots_array_size[i][1] = 0; + n3b_knots_array_size[i][2] = 0; + } + + memory->create(neighshort, maxshort, "pair:neighshort"); + + } +} + +void PairUF3::uf3_read_unified_pot_file(char *potf_name) +{ + //Go through the entire file and get the sizes of knot vectors and + //coeff vectors/matrices + // + //Create arrays + // + //Go through the file again and read the knots and coefficients + // + + const int num_of_elements = atom->ntypes; + + //if (true) { + FILE *fp = utils::open_potential(potf_name, lmp, nullptr); + if (!fp) + error->all(FLERR, + "Cannot open UF3 potential file {}: {}", + potf_name, utils::getsyserror()); + + TextFileReader txtfilereader(fp, "UF3:POTFP"); + txtfilereader.ignore_comments = false; + + //while loop over the entire file, find blocks starting with #UF3 POT + //if block found read the very next line to determine 2B or 3B block + //if 2B read the knot vector and coeff vector size + //if 3B read the knot vectors and coeff matrix size + int line_counter = 1; + char *line; + while((line = txtfilereader.next_line(1))){ + Tokenizer line_token(line); + + //Detect start of a block + if (line_token.contains("#UF3 POT")) { + //Block start detected + if (line_token.contains("UNITS:") == 0) + error->all(FLERR, + "UF3: {} file does not contain the 'UNITS:' metadata in " + "the header", + potf_name); + + //Read the 2nd line of the block + std::string temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp2nd_line(temp_line); + + std::string nbody_on_file = fp2nd_line.next_string(); + if (nbody_on_file == "2B") { + //2B block + if (fp2nd_line.count() != 6) + error->all(FLERR, "UF3: Expected 6 words on line {} of {} file " + "but found {} word/s", + line_counter, potf_name, fp2nd_line.count()); + + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + for (int i=1; iall(FLERR, + "UF3: Current implementation is throughly tested only " + "for leading_trim=0"); + if (trailing_trim != 3) + error->all(FLERR, + "UF3: Current implementation is throughly tested only " + "for trailing_trim=3"); + + //read next line, should contain cutoff and size of knot vector + temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp3rd_line(temp_line); + if (fp3rd_line.count() != 2) + error->all(FLERR, + "UF3: Expected only 2 words on 3rd line => " + "Rij_CUTOFF NUM_OF_KNOTS. Found {} word/s", + fp3rd_line.count()); + + //cut is used in init_one which is called by pair.cpp at line 267 + //where the return of init_one is squared + cut[itype][jtype] = fp3rd_line.next_double(); + cut[jtype][itype] = cut[itype][jtype]; + + int num_knots_2b = fp3rd_line.next_int(); + n2b_knots_array_size[itype][jtype] = num_knots_2b; + n2b_knots_array_size[jtype][itype] = num_knots_2b; + max_num_knots_2b = std::max(max_num_knots_2b, num_knots_2b); + + //skip next line + txtfilereader.skip_line(); + line_counter++; + + //read number of coeff + temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp5th_line(temp_line); + + int num_coeff_2b = fp5th_line.next_int(); + if (num_coeff_2b <= 0) + error->all(FLERR, + "UF3: 0 or negative number found for num_coeff_2b" + " on line {} of the potential file",line_counter); + n2b_coeff_array_size[itype][jtype] = num_coeff_2b; + n2b_coeff_array_size[jtype][itype] = num_coeff_2b; + max_num_coeff_2b = std::max(max_num_coeff_2b, num_coeff_2b); + } + } + else if ((nbody_on_file == "3B") && (pot_3b)) { + //3B block + if (fp2nd_line.count() != 7) + error->all(FLERR, "UF3: Expected 7 words on line {} of {} file" + "but found {} word/s", + line_counter, potf_name, fp2nd_line.count()); + + if (nbody_on_file == "3B") { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + std::string element3 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + int ktype = 0; + for (int i=1; iall(FLERR, + "UF3: Current implementation is throughly tested " + "only for leading_trim=0"); + if (trailing_trim != 3) + error->all(FLERR, + "UF3: Current implementation is throughly tested " + "only for trailing_trim=3"); + + //read next line, should contain cutoffs and size of knot vectors + temp_line = txtfilereader.next_line(6); + line_counter++; + ValueTokenizer fp3rd_line(temp_line); + + if (fp3rd_line.count() != 6) + error->all(FLERR, + "UF3: Expected only 6 numbers on 3rd line => " + "Rjk_CUTOFF Rik_CUTOFF Rij_CUTOFF NUM_OF_KNOTS_JK " + "NUM_OF_KNOTS_IK NUM_OF_KNOTS_IJ Found {} number/s", + fp3rd_line.count()); + + double cut3b_rjk = fp3rd_line.next_double(); + double cut3b_rij = fp3rd_line.next_double(); + double cut3b_rik = fp3rd_line.next_double(); + + if (cut3b_rij != cut3b_rik) + error->all(FLERR, + "UF3: rij!=rik for {}-{}-{}. " + "Current implementation only works for rij=rik", + element1, element2, element3); + + if (2 * cut3b_rik != cut3b_rjk) + error->all(FLERR, + "UF3: 2rij=2rik!=rik for {}-{}-{}. " + "Current implementation only works for 2rij=2rik!=rik", + element1, element2, element3); + + cut_3b_list[itype][jtype] = + std::max(cut3b_rij, cut_3b_list[itype][jtype]); + cut_3b_list[itype][ktype] = + std::max(cut_3b_list[itype][ktype], cut3b_rik); + + cut_3b[itype][jtype][ktype] = cut3b_rij; + cut_3b[itype][ktype][jtype] = cut3b_rik; + + int num_knots_3b_jk = fp3rd_line.next_int(); + int num_knots_3b_ik = fp3rd_line.next_int(); + int num_knots_3b_ij = fp3rd_line.next_int(); + + n3b_knots_array_size[map_3b[itype][jtype][ktype]][0] = num_knots_3b_jk; + n3b_knots_array_size[map_3b[itype][jtype][ktype]][1] = num_knots_3b_ik; + n3b_knots_array_size[map_3b[itype][jtype][ktype]][2] = num_knots_3b_ij; + + n3b_knots_array_size[map_3b[itype][ktype][jtype]][0] = num_knots_3b_jk; + n3b_knots_array_size[map_3b[itype][ktype][jtype]][1] = num_knots_3b_ij; + n3b_knots_array_size[map_3b[itype][ktype][jtype]][2] = num_knots_3b_ik; + + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_jk); + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_ik); + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_ij); + + //skip next 3 line + txtfilereader.skip_line(); + line_counter++; + txtfilereader.skip_line(); + line_counter++; + txtfilereader.skip_line(); + line_counter++; + + //read number of coeff + temp_line = txtfilereader.next_line(3); + line_counter++; + ValueTokenizer fp7th_line(temp_line); + + if (fp7th_line.count() != 3) + error->all(FLERR, + "UF3: Expected 3 numbers on 7th line => " + "SHAPE_OF_COEFF_MATRIX[I][J][K] " + "found {} numbers", + fp7th_line.count()); + + int coeff_matrix_dim1 = fp7th_line.next_int(); + int coeff_matrix_dim2 = fp7th_line.next_int(); + int coeff_matrix_dim3 = fp7th_line.next_int(); + + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][0] = coeff_matrix_dim1; + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][1] = coeff_matrix_dim2; + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][2] = coeff_matrix_dim3; + + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][0] = coeff_matrix_dim2; + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][1] = coeff_matrix_dim1; + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][2] = coeff_matrix_dim3; + + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim1); + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim2); + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim3); + } + } + } + else { + if (!((nbody_on_file == "3B") && (!pot_3b))) + error->all(FLERR, + "UF3: Expected either '2B' or '3B' word on line {} of {} file", + line_counter, potf_name); + } + } //if of #UF3 POT + line_counter++; + } // while + + //Create knot and coeff arrays + if (max_num_knots_2b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 2B knot vector\n" + "Possibly no 2B UF3 potential block detected in {} file", + potf_name); + memory->destroy(n2b_knots_array); + memory->create(n2b_knots_array, num_of_elements + 1, num_of_elements + 1, + max_num_knots_2b, "pair:n2b_knots_array"); + + if (max_num_coeff_2b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 2B coeff vector\n" + "Possibly no 2B UF3 potential block detected in {} file", + potf_name); + + memory->destroy(n2b_coeff_array); + memory->create(n2b_coeff_array, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, "pair:n2b_coeff_array"); + + + if (pot_3b) { + if (max_num_knots_3b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 3B knot vector\n" + "Possibly no 3B UF3 potential block detected in {} file", + potf_name); + memory->destroy(n3b_knots_array); + memory->create(n3b_knots_array, tot_interaction_count_3b, 3, + max_num_knots_3b, "pair:n3b_knots_array"); + + if (max_num_coeff_3b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 3B coeff matrices\n" + "Possibly no 3B UF3 potential block detected in {} file", + potf_name); + memory->destroy(n3b_coeff_array); + memory->create(n3b_coeff_array, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:n3b_coeff_array"); + } + + //Go back to the begning of the file + txtfilereader.rewind(); + + //Go through the file again and fill knot and coeff arrays + //while loop to read the data + while((line = txtfilereader.next_line(1))){ + Tokenizer line_token(line); + + //Detect start of a block + if (line_token.contains("#UF3 POT")) { + //Block start detected + //Read the 2nd line of the block + std::string temp_line = txtfilereader.next_line(1); + ValueTokenizer fp2nd_line(temp_line); + std::string nbody_on_file = fp2nd_line.next_string(); + + if (nbody_on_file == "2B") { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + for (int i=1; iall(FLERR, + "UF3: Expected either 'uk'(uniform-knots) or 'nk'(non-uniform knots). " + "Found {} on the 2nd line of {}-{} interaction block", + knot_type, element1, element2); + + if ((itype != 0) && (jtype != 0)) { + //skip line containing info of cutoff and knot vect size + txtfilereader.skip_line(); + + int num_knots_2b = n2b_knots_array_size[itype][jtype]; + + temp_line = txtfilereader.next_line(num_knots_2b); + ValueTokenizer fp4th_line(temp_line); + + if (fp4th_line.count() != num_knots_2b) + error->all(FLERR, "UF3: Error readig the 2B potential block for {}-{}\n" + "Expecter {} numbers on 4th line of the block but found {} " + "numbers", num_knots_2b,fp4th_line.count()); + + for (int k = 0; k < num_knots_2b; k++) { + n2b_knots_array[itype][jtype][k] = fp4th_line.next_double(); + n2b_knots_array[jtype][itype][k] = n2b_knots_array[itype][jtype][k]; + } + + knot_spacing_2b[itype][jtype] = n2b_knots_array[itype][jtype][4] - + n2b_knots_array[itype][jtype][3]; + knot_spacing_2b[jtype][itype] = knot_spacing_2b[itype][jtype]; + + //skip next line + txtfilereader.skip_line(); + + int num_of_coeff_2b = n2b_coeff_array_size[itype][jtype]; + + temp_line = txtfilereader.next_line(num_of_coeff_2b); + ValueTokenizer fp6th_line(temp_line); + + if (fp6th_line.count() != num_of_coeff_2b) + error->all(FLERR, + "UF3: Error readig the 2B potential block for {}-{}\n" + "Expecter {} numbers on 6th line of the block but found {} " + "numbers", num_knots_2b,fp4th_line.count()); + + for (int k = 0; k < num_of_coeff_2b; k++) { + n2b_coeff_array[itype][jtype][k] = fp6th_line.next_double(); + n2b_coeff_array[jtype][itype][k] = n2b_coeff_array[itype][jtype][k]; + } + + if (num_knots_2b != num_of_coeff_2b + 4) + error->all(FLERR, + "UF3: {}-{} interaction block has incorrect knot and " + "coeff data nknots!=ncoeffs + 3 + 1", + element1, element2); + + setflag[itype][jtype] = 1; + setflag[jtype][itype] = 1; + } + } + + if ((nbody_on_file == "3B") && (pot_3b)) { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + std::string element3 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + int ktype = 0; + for (int i=1; iall(FLERR, + "UF3: Expected either 'uk'(uniform-knots) or 'nk'(non-uniform knots) " + "Found {} on the 2nd line of {}-{}-{} interaction block", + knot_type, element1, element2, element3); + + if ((itype != 0) && (jtype != 0) && (ktype!=0)) { + //skip line containing info of cutoffs and knot vector sizes + txtfilereader.skip_line(); + + int num_knots_3b_jk = n3b_knots_array_size[map_3b[itype][jtype][ktype]][0]; + int num_knots_3b_ik = n3b_knots_array_size[map_3b[itype][jtype][ktype]][1]; + int num_knots_3b_ij = n3b_knots_array_size[map_3b[itype][jtype][ktype]][2]; + + temp_line = txtfilereader.next_line(num_knots_3b_jk); + ValueTokenizer fp4th_line(temp_line); + if (fp4th_line.count() != num_knots_3b_jk) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 4th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_jk, fp4th_line.count()); + + for (int i = 0; i < num_knots_3b_jk; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][0][i] = + fp4th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][0][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][i]; + } + + min_cut_3b[itype][jtype][ktype][0] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][0]; + min_cut_3b[itype][ktype][jtype][0] = + n3b_knots_array[map_3b[itype][ktype][jtype]][0][0]; + + knot_spacing_3b[itype][jtype][ktype][0] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][4] - + n3b_knots_array[map_3b[itype][jtype][ktype]][0][3]; + knot_spacing_3b[itype][ktype][jtype][0] = + knot_spacing_3b[itype][jtype][ktype][0]; + + temp_line = txtfilereader.next_line(num_knots_3b_ik); + ValueTokenizer fp5th_line(temp_line); + if (fp5th_line.count() != num_knots_3b_ik) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 5th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_ik, fp5th_line.count()); + + for (int i = 0; i < num_knots_3b_ik; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][1][i] = + fp5th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][2][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][i]; + } + + min_cut_3b[itype][jtype][ktype][1] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][0]; + min_cut_3b[itype][ktype][jtype][2] = + n3b_knots_array[map_3b[itype][ktype][jtype]][2][0]; + + knot_spacing_3b[itype][jtype][ktype][1] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][4] - + n3b_knots_array[map_3b[itype][jtype][ktype]][1][3]; + knot_spacing_3b[itype][ktype][jtype][2] = + knot_spacing_3b[itype][jtype][ktype][1]; + + temp_line = txtfilereader.next_line(num_knots_3b_ij); + ValueTokenizer fp6th_line(temp_line); + if (fp6th_line.count() != num_knots_3b_ij) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 6th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_ij, fp6th_line.count()); + + for (int i = 0; i < num_knots_3b_ij; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][2][i] = + fp6th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][1][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][i]; + } + + min_cut_3b[itype][jtype][ktype][2] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][0]; + min_cut_3b[itype][ktype][jtype][1] = + n3b_knots_array[map_3b[itype][ktype][jtype]][1][0]; + + knot_spacing_3b[itype][jtype][ktype][2] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][4] - + n3b_knots_array[map_3b[itype][jtype][ktype]][2][3]; + knot_spacing_3b[itype][ktype][jtype][1] = + knot_spacing_3b[itype][jtype][ktype][2]; + + //skip next line + txtfilereader.skip_line(); + + int coeff_matrix_dim1 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][0]; + int coeff_matrix_dim2 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][1]; + int coeff_matrix_dim3 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][2]; + + if (num_knots_3b_jk != coeff_matrix_dim3 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_JK) and coeff (coeff_matrix_dim3) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + if (num_knots_3b_ik != coeff_matrix_dim2 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_IK) and coeff (coeff_matrix_dim2) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + if (num_knots_3b_ij != coeff_matrix_dim1 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_IJ) and coeff (coeff_matrix_dim1) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + int coeff_matrix_elements_len = coeff_matrix_dim3; + int key1 = map_3b[itype][jtype][ktype]; + int key2 = map_3b[itype][ktype][jtype]; + + int line_count = 0; + for (int i = 0; i < coeff_matrix_dim1; i++) { + for (int j = 0; j < coeff_matrix_dim2; j++) { + temp_line = txtfilereader.next_line(coeff_matrix_elements_len); + ValueTokenizer coeff_line(temp_line); + if (coeff_line.count() != coeff_matrix_elements_len) + error->all(FLERR, + "UF3: Error reading 3B potential block for {}-{}-{}\n" + "Expected {} numbers on {}th line of the block but found {} " + "numbers", element1, element2, element3, + coeff_matrix_elements_len, line_count + 8, + coeff_line.count()); + + for (int k = 0; k < coeff_matrix_dim3; k++) { + n3b_coeff_array[key1][i][j][k] = coeff_line.next_double(); + } + line_count += 1; + } + } + + for (int i = 0; i < coeff_matrix_dim1; i++) { + for (int j = 0; j < coeff_matrix_dim2; j++) { + for (int k = 0; k < coeff_matrix_dim3; k++) { + n3b_coeff_array[key2][j][i][k] = n3b_coeff_array[key1][i][j][k]; + } + } + } + + setflag_3b[itype][jtype][ktype] = 1; + setflag_3b[itype][ktype][jtype] = 1; + } + } + } // if #UF3 POT + } //while + fclose(fp); + + //Set interaction of atom types of the same elements + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + if (setflag[i][j] != 1){ + //i-j interaction not set + + //maybe i-j is mapped to some other atom type interaction? + int i_mapped_to = map[i]+1; //+1 as map starts from 0 + int j_mapped_to = map[j]+1; //+1 as map starts from 0 + + if ((i_mapped_to == i) && (j_mapped_to == j)) + //i-j is not mapped to some other atom type ie interaction is missing on file + error->all(FLERR, + "UF3: Potential for interaction {}-{} ie {}-{} not found " + "in {} file", + i, j, elements[i_mapped_to-1], elements[j_mapped_to-1], + potf_name); + + cut[i][j] = cut[i_mapped_to][j_mapped_to]; + + n2b_knots_array_size[i][j] = n2b_knots_array_size[i_mapped_to][j_mapped_to]; + n2b_coeff_array_size[i][j] = n2b_coeff_array_size[i_mapped_to][j_mapped_to]; + + knot_spacing_type_2b[i][j] = knot_spacing_type_2b[i_mapped_to][j_mapped_to]; + knot_spacing_2b[i][j] = knot_spacing_2b[i_mapped_to][j_mapped_to]; + + for (int knot_no = 0; knot_no < max_num_knots_2b; knot_no++) + n2b_knots_array[i][j][knot_no] = + n2b_knots_array[i_mapped_to][j_mapped_to][knot_no]; + + for (int coeff_no = 0; coeff_no < max_num_coeff_2b; coeff_no++) + n2b_coeff_array[i][j][coeff_no] = + n2b_coeff_array[i_mapped_to][j_mapped_to][coeff_no]; + + setflag[i][j] = 1; + } + } + } + + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + //for (int k = j; k < num_of_elements + 1; k++) { + for (int k = 1; k < num_of_elements + 1; k++) { + if (setflag_3b[i][j][k] != 1) { + //i-j-k interaction not set + + //maybe i-j-k is mapped to some other atom type interaction? + int i_mapped_to = map[i]+1; //+1 as map starts from 0 + int j_mapped_to = map[j]+1; //+1 as map starts from 0 + int k_mapped_to = map[k]+1; //+1 as map starts from 0 + + if ((i_mapped_to == i) && (j_mapped_to == j) && (k_mapped_to == k)) + error->all(FLERR, + "UF3: Potential for interaction {}-{}-{} ie {}-{}-{} " + " not found in {} file", + i, j, k, elements[i_mapped_to-1], elements[j_mapped_to-1], + elements[k_mapped_to-1], potf_name); + if (setflag_3b[i_mapped_to][j_mapped_to][k_mapped_to] != 1) + error->all(FLERR, + "UF3: Interaction {}-{}-{} was mapped to {}-{}-{}, but " + "potential interaction for {}-{}-{} was not found in " + "{} file", + i, j, k, i_mapped_to, j_mapped_to, k_mapped_to, + i_mapped_to, j_mapped_to, k_mapped_to, potf_name); + + + cut_3b_list[i][j] = std::max(cut_3b_list[i_mapped_to][j_mapped_to], + cut_3b_list[i][j]); + + + cut_3b[i][j][k] = cut_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + knot_spacing_type_3b[i][j][k] = + knot_spacing_type_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + knot_spacing_3b[i][j][k][0] = + knot_spacing_3b[i_mapped_to][j_mapped_to][k_mapped_to][0]; + knot_spacing_3b[i][j][k][1] = + knot_spacing_3b[i_mapped_to][j_mapped_to][k_mapped_to][1]; + knot_spacing_3b[i][j][k][2] = + knot_spacing_3b[i_mapped_to][j_mapped_to][k_mapped_to][2]; + + int key = map_3b[i][j][k]; + int mapped_to_key = map_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + n3b_knots_array_size[key][0] = n3b_knots_array_size[mapped_to_key][0]; + n3b_knots_array_size[key][1] = n3b_knots_array_size[mapped_to_key][1]; + n3b_knots_array_size[key][2] = n3b_knots_array_size[mapped_to_key][2]; + + n3b_coeff_array_size[key][0] = n3b_coeff_array_size[mapped_to_key][0]; + n3b_coeff_array_size[key][1] = n3b_coeff_array_size[mapped_to_key][1]; + n3b_coeff_array_size[key][2] = n3b_coeff_array_size[mapped_to_key][2]; + + min_cut_3b[i][j][k][0] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][0]; + + min_cut_3b[i][j][k][1] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][1]; + + min_cut_3b[i][j][k][2] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][2]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][0]; knot_no++) + n3b_knots_array[key][0][knot_no] = n3b_knots_array[mapped_to_key][0][knot_no]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][1]; knot_no++) + n3b_knots_array[key][1][knot_no] = n3b_knots_array[mapped_to_key][1][knot_no]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][2]; knot_no++) + n3b_knots_array[key][2][knot_no] = n3b_knots_array[mapped_to_key][2][knot_no]; + + for (int coeff1 = 0; coeff1 < n3b_coeff_array_size[key][0]; coeff1++) + for (int coeff2 = 0; coeff2 < n3b_coeff_array_size[key][1]; coeff2++) + for (int coeff3 = 0; coeff3 < n3b_coeff_array_size[key][2]; coeff3++) + n3b_coeff_array[key][coeff1][coeff2][coeff3] = + n3b_coeff_array[mapped_to_key][coeff1][coeff2][coeff3]; + setflag_3b[i][j][k] = 1; + } + } + } + } + } +} + +//Broadcast data read from potential file to all processors +void PairUF3::communicate() +{ + const int num_of_elements = atom->ntypes; + MPI_Bcast(&cut[0][0], (num_of_elements + 1)*(num_of_elements + 1), + MPI_DOUBLE, 0, world); + + MPI_Bcast(&n2b_knots_array_size[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + MPI_Bcast(&n2b_coeff_array_size[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + MPI_Bcast(&max_num_knots_2b, 1, MPI_INT, 0, world); + MPI_Bcast(&max_num_coeff_2b, 1, MPI_INT, 0, world); + + if (pot_3b){ + MPI_Bcast(&cut_3b_list[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_DOUBLE, 0, world); + + MPI_Bcast(&cut_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_DOUBLE, 0, world); + + MPI_Bcast(&n3b_knots_array_size[0][0], tot_interaction_count_3b*3, + MPI_INT, 0, world); + MPI_Bcast(&n3b_coeff_array_size[0][0], tot_interaction_count_3b*3, + MPI_INT, 0, world); + + MPI_Bcast(&max_num_knots_3b, 1, MPI_INT, 0, world); + MPI_Bcast(&max_num_coeff_3b, 1, MPI_INT, 0, world); + } + + if (comm->me != 0) { + memory->destroy(n2b_knots_array); + memory->destroy(n2b_coeff_array); + + memory->create(n2b_knots_array, num_of_elements + 1, num_of_elements + 1, + max_num_knots_2b, "pair:n2b_knots_array"); + memory->create(n2b_coeff_array, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, "pair:n2b_coeff_array"); + if (pot_3b) { + memory->destroy(n3b_knots_array); + memory->destroy(n3b_coeff_array); + + memory->create(n3b_knots_array, tot_interaction_count_3b, 3, + max_num_knots_3b, "pair:n3b_knots_array"); + + memory->create(n3b_coeff_array, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:n3b_coeff_array"); + } + } + + MPI_Bcast(&knot_spacing_type_2b[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + MPI_Bcast(&knot_spacing_2b[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_DOUBLE, 0, world); + + MPI_Bcast(&n2b_knots_array[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*max_num_knots_2b, MPI_DOUBLE, 0, world); + MPI_Bcast(&n2b_coeff_array[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*max_num_coeff_2b, MPI_DOUBLE, 0, world); + + MPI_Bcast(&setflag[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + if (pot_3b) { + MPI_Bcast(&knot_spacing_type_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_INT, 0, world); + + MPI_Bcast(&knot_spacing_3b[0][0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1)*3, + MPI_DOUBLE, 0, world); + MPI_Bcast(&n3b_knots_array[0][0][0], + tot_interaction_count_3b*3*max_num_knots_3b, MPI_DOUBLE, 0, world); + MPI_Bcast(&n3b_coeff_array[0][0][0][0], + tot_interaction_count_3b*max_num_coeff_3b*max_num_coeff_3b*max_num_coeff_3b, + MPI_DOUBLE, 0, world); + MPI_Bcast(&setflag_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_INT, 0, world); + MPI_Bcast(&min_cut_3b[0][0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1)*3, + MPI_DOUBLE, 0, world); + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ +void PairUF3::init_style() +{ + if (force->newton_pair == 0) error->all(FLERR, "UF3: Pair style requires newton pair on"); + // request a default neighbor list + neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- + init list sets the pointer to full neighbour list requested in previous function +------------------------------------------------------------------------- */ + +void PairUF3::init_list(int /*id*/, class NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ +double PairUF3::init_one(int i /*i*/, int /*j*/ j) +{ + + if (!bsplines_created) create_bsplines(); + + //init_one is called by pair.cpp at line 267 where it is squred + //at line 268 + return cut[i][j]; +} + +void PairUF3::create_bsplines() +{ + const int num_of_elements = atom->ntypes; + bsplines_created = 1; + int spacing_type = knot_spacing_type_2b[1][1]; + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + if (setflag[i][j] != 1) + error->all(FLERR, + "UF3: Not all 2-body UF potentials are set, " + "missing potential for {}-{} interaction", + i, j); + /*if (spacing_type != knot_spacing_type_2b[i][j]) + error->all(FLERR, + "UF3: In the current version the knot spacing type, " + "for all interactions needs to be same. For {}-{} " + "i.e. {}-{} interaction expected {}, but found {}", + i,j,elements[map[i]],elements[map[j]],spacing_type, + knot_spacing_type_2b[i][j]);*/ + } + } + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + if (setflag_3b[i][j][k] != 1) + error->all(FLERR, + "UF3: Not all 3-body UF potentials are set, " + "missing potential for {}-{}-{} interaction", + i, j, k); + if (spacing_type != knot_spacing_type_3b[i][j][k]) + error->all(FLERR, + "UF3: In the current version the knot spacing type, " + "for all interactions needs to be same. For {}-{}-{} " + "i.e. {}-{}-{} interaction expected{}, but found {}", + i,j,k,elements[map[i]],elements[map[j]],elements[map[k]], + spacing_type,knot_spacing_type_3b[i][j][k]); + } + } + } + } + + + if (spacing_type) { + get_starting_index_2b = &PairUF3::get_starting_index_nonuniform_2b; + if (pot_3b) + get_starting_index_3b = &PairUF3::get_starting_index_nonuniform_3b; + } + else { + get_starting_index_2b = &PairUF3::get_starting_index_uniform_2b; + if (pot_3b) + get_starting_index_3b = &PairUF3::get_starting_index_uniform_3b; + } + + create_cached_constants_2b(); + if (pot_3b) + create_cached_constants_3b(); +} + +int PairUF3::get_starting_index_uniform_2b(int i, int j, double r) +{ + return 3+(int)((r-n2b_knots_array[i][j][0])/(knot_spacing_2b[i][j])); +} + +int PairUF3::get_starting_index_uniform_3b(int i, int j, int k, double r, int knot_dim) +{ + return 3+(int)(((r-n3b_knots_array[map_3b[i][j][k]][knot_dim][0])/ + knot_spacing_3b[i][j][k][knot_dim])); +} + +int PairUF3::get_starting_index_nonuniform_2b(int i, int j, double r) +{ + for (int l = 3; l < n2b_knots_array_size[i][j]-1; ++l) { + if ((n2b_knots_array[i][j][l] <= r) && (r < n2b_knots_array[i][j][l+1])) + return l; + } + return -1; +} + +int PairUF3::get_starting_index_nonuniform_3b(int i, int j, int k, double r, int knot_dim) +{ + for (int l = 3; l < n3b_knots_array_size[map_3b[i][j][k]][knot_dim]-1; ++l) { + if ((n3b_knots_array[map_3b[i][j][k]][knot_dim][l] <= r) && + (r < n3b_knots_array[map_3b[i][j][k]][knot_dim][l+1])) + return l; + } + return -1; +} + +void PairUF3::create_cached_constants_2b() +{ + const int num_of_elements = atom->ntypes; + memory->destroy(cached_constants_2b); + memory->destroy(cached_constants_2b_deri); + memory->create(cached_constants_2b, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, 16, "pair:cached_constants_2b"); + + memory->create(cached_constants_2b_deri, num_of_elements + 1, + num_of_elements + 1, max_num_coeff_2b - 1, 9, + "pair:cached_constants_2b_deri"); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++ ) { + for (int l = 0; l < n2b_coeff_array_size[i][j]; l++) { + uf3_bspline_basis3 bspline_basis(lmp, &n2b_knots_array[i][j][l], + n2b_coeff_array[i][j][l]); + for (int cc = 0; cc < 16; cc++) { + cached_constants_2b[i][j][l][cc] = bspline_basis.constants[cc]; + } + } + } + } + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + //initialize coeff and knots for derivative + //double* knots_for_deri = new double[n2b_knots_array_size[i][j]-2]; + double *knots_for_deri = nullptr; + memory->create(knots_for_deri, n2b_knots_array_size[i][j]-2, "pair:knots_for_deri"); + + for (int l = 1; l < n2b_knots_array_size[i][j] - 1; l++) + knots_for_deri[l-1] = n2b_knots_array[i][j][l]; + + + //double* coeff_for_deri = new double[n2b_coeff_array_size[i][j]-1]; + double *coeff_for_deri = nullptr; + memory->create(coeff_for_deri, n2b_coeff_array_size[i][j]-1, "pair:coeff_for_deri"); + for (int l = 0; l < n2b_coeff_array_size[i][j] - 1; l++) { + double dntemp = 3 / (n2b_knots_array[i][j][l + 4] - + n2b_knots_array[i][j][l + 1]); + coeff_for_deri[l] = + (n2b_coeff_array[i][j][l+1] - n2b_coeff_array[i][j][l]) * dntemp; + } + + for (int l = 0; l < n2b_coeff_array_size[i][j] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri(lmp, &knots_for_deri[l], + coeff_for_deri[l]); + for (int cc = 0; cc < 9; cc++) { + cached_constants_2b_deri[i][j][l][cc] = bspline_basis_deri.constants[cc]; + } + } + memory->destroy(knots_for_deri); + memory->destroy(coeff_for_deri); + //delete[] knots_for_deri; + //delete[] coeff_for_deri; + } + } +} + +void PairUF3::create_cached_constants_3b() +{ + const int num_of_elements = atom->ntypes; + memory->destroy(coeff_for_der_jk); + memory->destroy(coeff_for_der_ik); + memory->destroy(coeff_for_der_ij); + memory->destroy(cached_constants_3b); + memory->destroy(cached_constants_3b_deri); + + memory->create(coeff_for_der_jk, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:coeff_for_der_jk"); + + memory->create(coeff_for_der_ik, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:coeff_for_der_ik"); + + memory->create(coeff_for_der_ij, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:coeff_for_der_ij"); + + memory->create(cached_constants_3b, tot_interaction_count_3b, 3, + max_num_coeff_3b, 16, "pair:cached_constants_3b"); + + memory->create(cached_constants_3b_deri, tot_interaction_count_3b, 3, + max_num_coeff_3b - 1, 9, "pair:cached_constants_3b_deri"); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++ ) { + for(int k = 1; k < num_of_elements + 1; k++) { + int map_to = map_3b[i][j][k]; + + for (int l = 0; l < n3b_knots_array_size[map_to][2] - 4; l++) { + uf3_bspline_basis3 bspline_basis_ij(lmp, &n3b_knots_array[map_to][2][l], 1); + for (int cc = 0; cc < 16; cc++) + cached_constants_3b[map_to][0][l][cc] = bspline_basis_ij.constants[cc]; + } + + for (int l = 0; l < n3b_knots_array_size[map_to][1] - 4; l++) { + uf3_bspline_basis3 bspline_basis_ik(lmp, &n3b_knots_array[map_to][1][l], 1); + for (int cc = 0; cc < 16; cc++) + cached_constants_3b[map_to][1][l][cc] = bspline_basis_ik.constants[cc]; + } + + for (int l = 0; l < n3b_knots_array_size[map_to][0] - 4; l++) { + uf3_bspline_basis3 bspline_basis_jk(lmp, &n3b_knots_array[map_to][0][l], 1); + for (int cc = 0; cc < 16; cc++) + cached_constants_3b[map_to][2][l][cc] = bspline_basis_jk.constants[cc]; + } + } + } + } + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++ ) { + for(int k = 1; k < num_of_elements + 1; k++) { + int map_to = map_3b[i][j][k]; + double **knots_for_der = nullptr;//new double*[3]; + + //n3b_knots_array_size[map_to][0] for jk knot vector --> always largest + memory->create(knots_for_der, 3, n3b_knots_array_size[map_to][0]-1, + "pair:knots_for_der"); + + //--deri_basis_jk + for (int l = 1; l < n3b_knots_array_size[map_to][0] - 1; l++) + knots_for_der[0][l-1] = n3b_knots_array[map_to][0][l]; + + for(int l = 0; l < n3b_coeff_array_size[map_to][0]; l++) { + for(int m = 0; m < n3b_coeff_array_size[map_to][1]; m++) { + for(int n = 0; n < n3b_coeff_array_size[map_to][2] - 1; n++) { + double dntemp = 3/(n3b_knots_array[map_to][0][n + 4] - + n3b_knots_array[map_to][0][n + 1]); + coeff_for_der_jk[map_to][l][m][n] = + ((n3b_coeff_array[map_to][l][m][n + 1] - + n3b_coeff_array[map_to][l][m][n])*dntemp); + } + } + } + + //--deri_basis_ik + for (int l = 1; l < n3b_knots_array_size[map_to][1] - 1; l++) + knots_for_der[1][l-1] = n3b_knots_array[map_to][1][l]; + + for (int l = 0; l < n3b_coeff_array_size[map_to][0]; l++) { + for (int m = 0; m < n3b_coeff_array_size[map_to][1] - 1; m++) { + double dntemp = 3/(n3b_knots_array[map_to][1][m + 4] - + n3b_knots_array[map_to][1][m + 1]); + for (int n = 0; n < n3b_coeff_array_size[map_to][2]; n++) { + coeff_for_der_ik[map_to][l][m][n] = + ((n3b_coeff_array[map_to][l][m + 1][n] - + n3b_coeff_array[map_to][l][m][n])*dntemp); + } + } + } + + //--deri_basis_ij + for (int l = 1; l < n3b_knots_array_size[map_to][2] - 1; l++) + knots_for_der[2][l-1] = n3b_knots_array[map_to][2][l]; + + for (int l = 0; l < n3b_coeff_array_size[map_to][0] - 1; l++) { + double dntemp = 3/(n3b_knots_array[map_to][2][l + 4] - + n3b_knots_array[map_to][2][l + 1]); + for(int m = 0; m < n3b_coeff_array_size[map_to][1]; m++) { + for(int n = 0; n < n3b_coeff_array_size[map_to][2]; n++) { + coeff_for_der_ij[map_to][l][m][n] = + ((n3b_coeff_array[map_to][l + 1][m][n] - + n3b_coeff_array[map_to][l][m][n]) * dntemp); + } + } + } + + for (int l = 0; l < n3b_coeff_array_size[map_to][0] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri_ij(lmp, &knots_for_der[2][l], 1); + for (int cc = 0; cc < 9; cc++) { + cached_constants_3b_deri[map_to][0][l][cc] = bspline_basis_deri_ij.constants[cc]; + } + } + + for (int l = 0; l < n3b_coeff_array_size[map_to][1] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri_ik(lmp, &knots_for_der[1][l], 1); + for (int cc = 0; cc < 9; cc++) { + cached_constants_3b_deri[map_to][1][l][cc] = bspline_basis_deri_ik.constants[cc]; + } + } + + for (int l = 0; l < n3b_coeff_array_size[map_to][2] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri_jk(lmp, &knots_for_der[0][l], 1); + for (int cc = 0; cc < 9; cc++) { + cached_constants_3b_deri[map_to][2][l][cc] = bspline_basis_deri_jk.constants[cc]; + } + } + + memory->destroy(knots_for_der); + } + } + } +} + +void PairUF3::compute(int eflag, int vflag) +{ + int i, j, k, ii, jj, kk, inum, jnum, itype, jtype, ktype; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair, fx, fy, fz; + double del_rji[3], del_rki[3], del_rkj[3]; + double fij[3], fik[3], fjk[3]; + double fji[3], fki[3], fkj[3]; + double Fi[3], Fj[3], Fk[3]; + double rsq, rij, rik, rjk; + double rij_sq, rik_sq, rjk_sq; + int *ilist, *jlist, *numneigh, **firstneigh; + + ev_init(eflag, vflag); + + double **x = atom->x; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms + for (ii = 0; ii < inum; ii++) { + evdwl = 0; + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + int numshort = 0; + for (jj = 0; jj < jnum; jj++) { + fx = 0; + fy = 0; + fz = 0; + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + if (rsq < cutsq[itype][jtype]) { + rij = sqrt(rsq); + + if (pot_3b) { + if (rij <= cut_3b_list[itype][jtype]) { + neighshort[numshort] = j; + if (numshort >= maxshort - 1) { + maxshort += maxshort / 2; + memory->grow(neighshort, maxshort, "pair:neighshort"); + } + numshort = numshort + 1; + } + } + + int knot_start_index = (this->*get_starting_index_2b)(itype,jtype,rij); + + double force_2b = cached_constants_2b_deri[itype][jtype][knot_start_index - 1][0]; + force_2b += rij*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][1]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][2]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 2][3]; + force_2b += rij*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][4]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][5]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 3][6]; + force_2b += rij*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][7]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][8]; + + fpair = -1 * force_2b / rij; + + fx = delx * fpair; + fy = dely * fpair; + fz = delz * fpair; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + + if (eflag) { + double rth = rsq*rij; + evdwl = cached_constants_2b[itype][jtype][knot_start_index][0]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index][1]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index][2]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index][3]; + evdwl += cached_constants_2b[itype][jtype][knot_start_index-1][4]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index-1][5]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index-1][6]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index-1][7]; + evdwl += cached_constants_2b[itype][jtype][knot_start_index-2][8]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index-2][9]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index-2][10]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index-2][11]; + evdwl += cached_constants_2b[itype][jtype][knot_start_index-3][12]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index-3][13]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index-3][14]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index-3][15]; + }; + + if (evflag) { + ev_tally_xyz(i, j, nlocal, newton_pair, evdwl, 0.0, fx, fy, fz, delx, dely, delz); + + // Centroid Stress + if (vflag_either && cvflag_atom) { + double v[6]; + + v[0] = delx * fx; + v[1] = dely * fy; + v[2] = delz * fz; + v[3] = delx * fy; + v[4] = delx * fz; + v[5] = dely * fz; + + cvatom[i][0] += 0.5 * v[0]; + cvatom[i][1] += 0.5 * v[1]; + cvatom[i][2] += 0.5 * v[2]; + cvatom[i][3] += 0.5 * v[3]; + cvatom[i][4] += 0.5 * v[4]; + cvatom[i][5] += 0.5 * v[5]; + cvatom[i][6] += 0.5 * v[3]; + cvatom[i][7] += 0.5 * v[4]; + cvatom[i][8] += 0.5 * v[5]; + + cvatom[j][0] += 0.5 * v[0]; + cvatom[j][1] += 0.5 * v[1]; + cvatom[j][2] += 0.5 * v[2]; + cvatom[j][3] += 0.5 * v[3]; + cvatom[j][4] += 0.5 * v[4]; + cvatom[j][5] += 0.5 * v[5]; + cvatom[j][6] += 0.5 * v[3]; + cvatom[j][7] += 0.5 * v[4]; + cvatom[j][8] += 0.5 * v[5]; + } + } + } + } + + // 3-body interaction + // jth atom + jnum = numshort - 1; + for (jj = 0; jj < jnum; jj++) { + fij[0] = fji[0] = 0; + fij[1] = fji[1] = 0; + fij[2] = fji[2] = 0; + j = neighshort[jj]; + jtype = type[j]; + del_rji[0] = x[j][0] - xtmp; + del_rji[1] = x[j][1] - ytmp; + del_rji[2] = x[j][2] - ztmp; + rij_sq = (del_rji[0] * del_rji[0]) + (del_rji[1] * del_rji[1]) + (del_rji[2] * del_rji[2]); + rij = sqrt(rij_sq); + + // kth atom + for (kk = jj + 1; kk < numshort; kk++) { + + fik[0] = fki[0] = 0; + fik[1] = fki[1] = 0; + fik[2] = fki[2] = 0; + + fjk[0] = fkj[0] = 0; + fjk[1] = fkj[1] = 0; + fjk[2] = fkj[2] = 0; + + k = neighshort[kk]; + ktype = type[k]; + del_rki[0] = x[k][0] - xtmp; + del_rki[1] = x[k][1] - ytmp; + del_rki[2] = x[k][2] - ztmp; + rik_sq = (del_rki[0] * del_rki[0]) + (del_rki[1] * del_rki[1]) + (del_rki[2] * del_rki[2]); + rik = sqrt(rik_sq); + + if ((rij <= cut_3b[itype][jtype][ktype]) && + (rik <= cut_3b[itype][ktype][jtype]) && + (rij >= min_cut_3b[itype][jtype][ktype][2]) && + (rik >= min_cut_3b[itype][jtype][ktype][1])) { + + del_rkj[0] = x[k][0] - x[j][0]; + del_rkj[1] = x[k][1] - x[j][1]; + del_rkj[2] = x[k][2] - x[j][2]; + + rjk_sq = (del_rkj[0] * del_rkj[0]) + (del_rkj[1] * del_rkj[1]) + (del_rkj[2] * del_rkj[2]); + rjk = sqrt(rjk_sq); + + if (rjk >= min_cut_3b[itype][jtype][ktype][0]) { + double rij_th = rij*rij_sq; + double rik_th = rik*rik_sq; + double rjk_th = rjk*rjk_sq; + + int map_to = map_3b[itype][jtype][ktype]; + int knot_start_index_ij = (this->*get_starting_index_3b)(itype,jtype,ktype,rij,2); + int knot_start_index_ik = (this->*get_starting_index_3b)(itype,jtype,ktype,rik,1); + int knot_start_index_jk = (this->*get_starting_index_3b)(itype,jtype,ktype,rjk,0); + double basis_ij[4]; + double basis_ik[4]; + double basis_jk[4]; + double basis_ij_der[3]; + double basis_ik_der[3]; + double basis_jk_der[3]; + + //--------------basis_ij + basis_ij[0] = cached_constants_3b[map_to][0][knot_start_index_ij - 3][12]; + basis_ij[0] += rij*cached_constants_3b[map_to][0][knot_start_index_ij - 3][13]; + basis_ij[0] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij - 3][14]; + basis_ij[0] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij - 3][15]; + + basis_ij[1] = cached_constants_3b[map_to][0][knot_start_index_ij - 2][8]; + basis_ij[1] += rij*cached_constants_3b[map_to][0][knot_start_index_ij - 2][9]; + basis_ij[1] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij - 2][10]; + basis_ij[1] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij - 2][11]; + + basis_ij[2] = cached_constants_3b[map_to][0][knot_start_index_ij - 1][4]; + basis_ij[2] += rij*cached_constants_3b[map_to][0][knot_start_index_ij - 1][5]; + basis_ij[2] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij - 1][6]; + basis_ij[2] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij - 1][7]; + + basis_ij[3] = cached_constants_3b[map_to][0][knot_start_index_ij][0]; + basis_ij[3] += rij*cached_constants_3b[map_to][0][knot_start_index_ij][1]; + basis_ij[3] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij][2]; + basis_ij[3] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij][3]; + + //--------------basis_ik + basis_ik[0] = cached_constants_3b[map_to][1][knot_start_index_ik - 3][12]; + basis_ik[0] += rik*cached_constants_3b[map_to][1][knot_start_index_ik - 3][13]; + basis_ik[0] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik - 3][14]; + basis_ik[0] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik - 3][15]; + + basis_ik[1] = cached_constants_3b[map_to][1][knot_start_index_ik - 2][8]; + basis_ik[1] += rik*cached_constants_3b[map_to][1][knot_start_index_ik - 2][9]; + basis_ik[1] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik - 2][10]; + basis_ik[1] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik - 2][11]; + + basis_ik[2] = cached_constants_3b[map_to][1][knot_start_index_ik - 1][4]; + basis_ik[2] += rik*cached_constants_3b[map_to][1][knot_start_index_ik - 1][5]; + basis_ik[2] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik - 1][6]; + basis_ik[2] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik - 1][7]; + + basis_ik[3] = cached_constants_3b[map_to][1][knot_start_index_ik][0]; + basis_ik[3] += rik*cached_constants_3b[map_to][1][knot_start_index_ik][1]; + basis_ik[3] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik][2]; + basis_ik[3] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik][3]; + + //--------------basis_jk + basis_jk[0] = cached_constants_3b[map_to][2][knot_start_index_jk - 3][12]; + basis_jk[0] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk - 3][13]; + basis_jk[0] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk - 3][14]; + basis_jk[0] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk - 3][15]; + + basis_jk[1] = cached_constants_3b[map_to][2][knot_start_index_jk - 2][8]; + basis_jk[1] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk - 2][9]; + basis_jk[1] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk - 2][10]; + basis_jk[1] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk - 2][11]; + + basis_jk[2] = cached_constants_3b[map_to][2][knot_start_index_jk - 1][4]; + basis_jk[2] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk - 1][5]; + basis_jk[2] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk - 1][6]; + basis_jk[2] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk - 1][7]; + + basis_jk[3] = cached_constants_3b[map_to][2][knot_start_index_jk][0]; + basis_jk[3] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk][1]; + basis_jk[3] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk][2]; + basis_jk[3] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk][3]; + + //----------------basis_ij_der + basis_ij_der[0] = cached_constants_3b_deri[map_to][0][knot_start_index_ij - 3][6]; + basis_ij_der[0] += rij*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 3][7]; + basis_ij_der[0] += rij_sq*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 3][8]; + + basis_ij_der[1] = cached_constants_3b_deri[map_to][0][knot_start_index_ij - 2][3]; + basis_ij_der[1] += rij*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 2][4]; + basis_ij_der[1] += rij_sq*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 2][5]; + + basis_ij_der[2] = cached_constants_3b_deri[map_to][0][knot_start_index_ij - 1][0]; + basis_ij_der[2] += rij*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 1][1]; + basis_ij_der[2] += rij_sq*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 1][2]; + + //----------------basis_ik_der + basis_ik_der[0] = cached_constants_3b_deri[map_to][1][knot_start_index_ik - 3][6]; + basis_ik_der[0] += rik*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 3][7]; + basis_ik_der[0] += rik_sq*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 3][8]; + + basis_ik_der[1] = cached_constants_3b_deri[map_to][1][knot_start_index_ik - 2][3]; + basis_ik_der[1] += rik*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 2][4]; + basis_ik_der[1] += rik_sq*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 2][5]; + + basis_ik_der[2] = cached_constants_3b_deri[map_to][1][knot_start_index_ik - 1][0]; + basis_ik_der[2] += rik*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 1][1]; + basis_ik_der[2] += rik_sq*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 1][2]; + + //----------------basis_jk_der + basis_jk_der[0] = cached_constants_3b_deri[map_to][2][knot_start_index_jk - 3][6]; + basis_jk_der[0] += rjk*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 3][7]; + basis_jk_der[0] += rjk_sq*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 3][8]; + + basis_jk_der[1] = cached_constants_3b_deri[map_to][2][knot_start_index_jk - 2][3]; + basis_jk_der[1] += rjk*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 2][4]; + basis_jk_der[1] += rjk_sq*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 2][5]; + + basis_jk_der[2] = cached_constants_3b_deri[map_to][2][knot_start_index_jk - 1][0]; + basis_jk_der[2] += rjk*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 1][1]; + basis_jk_der[2] += rjk_sq*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 1][2]; + + double triangle_eval[4] = {0,0,0,0}; + + int iknot_ij = knot_start_index_ij - 3; + int iknot_ik = knot_start_index_ik - 3; + int iknot_jk = knot_start_index_jk - 3; + + for (int l = 0; l < 3; l++) { + const double basis_ij_der_i = basis_ij_der[l]; + for (int m = 0; m < 4; m++) { + const double factor = basis_ij_der_i * basis_ik[m]; + const double* slice = + &coeff_for_der_ij[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[4]; + tmp[0] = slice[0] * basis_jk[0]; + tmp[1] = slice[1] * basis_jk[1]; + tmp[2] = slice[2] * basis_jk[2]; + tmp[3] = slice[3] * basis_jk[3]; + double sum = tmp[0] + tmp[1] + tmp[2] + tmp[3]; + triangle_eval[1] += factor * sum; + } + } + + for (int l = 0; l < 4; l++) { + const double basis_ij_i = basis_ij[l]; + for (int m = 0; m < 3; m++) { + const double factor = basis_ij_i * basis_ik_der[m]; + const double* slice = + &coeff_for_der_ik[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[4]; + tmp[0] = slice[0] * basis_jk[0]; + tmp[1] = slice[1] * basis_jk[1]; + tmp[2] = slice[2] * basis_jk[2]; + tmp[3] = slice[3] * basis_jk[3]; + double sum = tmp[0] + tmp[1] + tmp[2] + tmp[3]; + triangle_eval[2] += factor * sum; + } + } + + for (int l = 0; l < 4; l++) { + const double basis_ij_i = basis_ij[l]; + for (int m = 0; m < 4; m++) { + const double factor = basis_ij_i * basis_ik[m]; + const double* slice = + &coeff_for_der_jk[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[3]; + tmp[0] = slice[0] * basis_jk_der[0]; + tmp[1] = slice[1] * basis_jk_der[1]; + tmp[2] = slice[2] * basis_jk_der[2]; + double sum = tmp[0] + tmp[1] + tmp[2]; + triangle_eval[3] += factor * sum; + } + } + + fij[0] = *(triangle_eval + 1) * (del_rji[0] / rij); + fji[0] = -fij[0]; + fik[0] = *(triangle_eval + 2) * (del_rki[0] / rik); + fki[0] = -fik[0]; + fjk[0] = *(triangle_eval + 3) * (del_rkj[0] / rjk); + fkj[0] = -fjk[0]; + + fij[1] = *(triangle_eval + 1) * (del_rji[1] / rij); + fji[1] = -fij[1]; + fik[1] = *(triangle_eval + 2) * (del_rki[1] / rik); + fki[1] = -fik[1]; + fjk[1] = *(triangle_eval + 3) * (del_rkj[1] / rjk); + fkj[1] = -fjk[1]; + + fij[2] = *(triangle_eval + 1) * (del_rji[2] / rij); + fji[2] = -fij[2]; + fik[2] = *(triangle_eval + 2) * (del_rki[2] / rik); + fki[2] = -fik[2]; + fjk[2] = *(triangle_eval + 3) * (del_rkj[2] / rjk); + fkj[2] = -fjk[2]; + + Fi[0] = fij[0] + fik[0]; + Fi[1] = fij[1] + fik[1]; + Fi[2] = fij[2] + fik[2]; + f[i][0] += Fi[0]; + f[i][1] += Fi[1]; + f[i][2] += Fi[2]; + + Fj[0] = fji[0] + fjk[0]; + Fj[1] = fji[1] + fjk[1]; + Fj[2] = fji[2] + fjk[2]; + f[j][0] += Fj[0]; + f[j][1] += Fj[1]; + f[j][2] += Fj[2]; + + Fk[0] = fki[0] + fkj[0]; + Fk[1] = fki[1] + fkj[1]; + Fk[2] = fki[2] + fkj[2]; + f[k][0] += Fk[0]; + f[k][1] += Fk[1]; + f[k][2] += Fk[2]; + + if (eflag) { + for (int l = 0; l < 4; l++) { + const double basis_ij_i = basis_ij[l]; + for (int m = 0; m < 4; m++) { + const double factor = basis_ij_i * basis_ik[m]; + const double* slice = + &n3b_coeff_array[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[4]; + tmp[0] = slice[0] * basis_jk[0]; + tmp[1] = slice[1] * basis_jk[1]; + tmp[2] = slice[2] * basis_jk[2]; + tmp[3] = slice[3] * basis_jk[3]; + double sum = tmp[0] + tmp[1] + tmp[2] + tmp[3]; + triangle_eval[0] += factor * sum; + } + } + evdwl = *triangle_eval; + } + + if (evflag) { + ev_tally3(i, j, k, evdwl, 0, Fj, Fk, del_rji, del_rki); + // Centroid stress 3-body term + if (vflag_either && cvflag_atom) { + double ric[3]; + ric[0] = THIRD * (-del_rji[0] - del_rki[0]); + ric[1] = THIRD * (-del_rji[1] - del_rki[1]); + ric[2] = THIRD * (-del_rji[2] - del_rki[2]); + + cvatom[i][0] += ric[0] * Fi[0]; + cvatom[i][1] += ric[1] * Fi[1]; + cvatom[i][2] += ric[2] * Fi[2]; + cvatom[i][3] += ric[0] * Fi[1]; + cvatom[i][4] += ric[0] * Fi[2]; + cvatom[i][5] += ric[1] * Fi[2]; + cvatom[i][6] += ric[1] * Fi[0]; + cvatom[i][7] += ric[2] * Fi[0]; + cvatom[i][8] += ric[2] * Fi[1]; + + double rjc[3]; + rjc[0] = THIRD * (del_rji[0] - del_rkj[0]); + rjc[1] = THIRD * (del_rji[1] - del_rkj[1]); + rjc[2] = THIRD * (del_rji[2] - del_rkj[2]); + + cvatom[j][0] += rjc[0] * Fj[0]; + cvatom[j][1] += rjc[1] * Fj[1]; + cvatom[j][2] += rjc[2] * Fj[2]; + cvatom[j][3] += rjc[0] * Fj[1]; + cvatom[j][4] += rjc[0] * Fj[2]; + cvatom[j][5] += rjc[1] * Fj[2]; + cvatom[j][6] += rjc[1] * Fj[0]; + cvatom[j][7] += rjc[2] * Fj[0]; + cvatom[j][8] += rjc[2] * Fj[1]; + + double rkc[3]; + rkc[0] = THIRD * (del_rki[0] + del_rkj[0]); + rkc[1] = THIRD * (del_rki[1] + del_rkj[1]); + rkc[2] = THIRD * (del_rki[2] + del_rkj[2]); + + cvatom[k][0] += rkc[0] * Fk[0]; + cvatom[k][1] += rkc[1] * Fk[1]; + cvatom[k][2] += rkc[2] * Fk[2]; + cvatom[k][3] += rkc[0] * Fk[1]; + cvatom[k][4] += rkc[0] * Fk[2]; + cvatom[k][5] += rkc[1] * Fk[2]; + cvatom[k][6] += rkc[1] * Fk[0]; + cvatom[k][7] += rkc[2] * Fk[0]; + cvatom[k][8] += rkc[2] * Fk[1]; + } + } + } + } + } + } + } + if (vflag_fdotr) virial_fdotr_compute(); +} + +double PairUF3::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, + double /*factor_coul*/, double factor_lj, double &fforce) +{ + double value = 0.0; + double r = sqrt(rsq); + + if (r < cut[itype][jtype]) { + int knot_start_index = (this->*get_starting_index_2b)(itype,jtype,r); + + double force_2b = cached_constants_2b_deri[itype][jtype][knot_start_index - 1][0]; + force_2b += r*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][1]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][2]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 2][3]; + force_2b += r*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][4]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][5]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 3][6]; + force_2b += r*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][7]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][8]; + fforce = factor_lj * force_2b; + + double rth = rsq*r; + value = cached_constants_2b[itype][jtype][knot_start_index][0]; + value += r*cached_constants_2b[itype][jtype][knot_start_index][1]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index][2]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index][3]; + value += cached_constants_2b[itype][jtype][knot_start_index-1][4]; + value += r*cached_constants_2b[itype][jtype][knot_start_index-1][5]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index-1][6]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index-1][7]; + value += cached_constants_2b[itype][jtype][knot_start_index-2][8]; + value += r*cached_constants_2b[itype][jtype][knot_start_index-2][9]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index-2][10]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index-2][11]; + value += cached_constants_2b[itype][jtype][knot_start_index-3][12]; + value += r*cached_constants_2b[itype][jtype][knot_start_index-3][13]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index-3][14]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index-3][15]; + } + + return factor_lj * value; +} + +double PairUF3::memory_usage() +{ + const int num_of_elements = atom->ntypes; + double bytes = Pair::memory_usage(); + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(int); //***setflag_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(int); //knot_spacing_type_2b + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(int); //knot_spacing_type_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //cut + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(double); //***cut_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //cut_3b_list + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * 3 * + sizeof(double); //min_cut_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //knot_spacing_2b + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(double); //knot_spacing_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_knots_2b * + sizeof(double); //n2b_knots_array + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_coeff_2b * + sizeof(double); //n2b_coeff_array + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(int); //n2b_knots_array_size + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(int); //n2b_coeff_array_size + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_coeff_2b * + 16 * sizeof(double); //cached_constants_2b, + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (max_num_coeff_2b-1) * + 9 * sizeof(double); //cached_constants_2b_deri + + + if (pot_3b) { + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * + (num_of_elements + 1) * sizeof(int); //map_3b + + bytes += (double) tot_interaction_count_3b * 3 * max_num_knots_3b * sizeof(double); //n3b_knots_array + bytes += (double) tot_interaction_count_3b * max_num_coeff_3b * max_num_coeff_3b * + max_num_coeff_3b * sizeof(double); //n3b_coeff_array + + bytes += (double) tot_interaction_count_3b * 3 * sizeof(int); //n3b_knots_array_size + bytes += (double) tot_interaction_count_3b * 3 * sizeof(int); //n3b_coeff_array_size + + bytes += (double) tot_interaction_count_3b * max_num_coeff_3b * max_num_coeff_3b + * max_num_coeff_3b * 3 * sizeof(double); //coeff_for_der_jk coeff_for_der_ik coeff_for_der_ij + + bytes += (double) tot_interaction_count_3b * 3 * max_num_coeff_3b * 16 + * sizeof(double); //cached_constants_3b + bytes += (double) tot_interaction_count_3b * 3 * (max_num_coeff_3b - 1) * 16 + * sizeof(double); //cached_constants_3b_deri + + } + + bytes += (double) maxshort * sizeof(int); //neighshort + + bytes += (double) 6 * sizeof(int); //maxshort, bsplines_created, nbody_flag, + //max_num_knots_2b, max_num_coeff_2b, + //max_num_knots_3b, max_num_coeff_3b + bytes += (double) 1 * sizeof(bool); //pot_3b + + return bytes; +} diff --git a/src/ML-UF3/pair_uf3.h b/src/ML-UF3/pair_uf3.h new file mode 100644 index 0000000000..9c6ec5022f --- /dev/null +++ b/src/ML-UF3/pair_uf3.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(uf3,PairUF3); +// clang-format on +#else + +#ifndef LMP_PAIR_UF3_H +#define LMP_PAIR_UF3_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairUF3 : public Pair { + public: + PairUF3(class LAMMPS *); + ~PairUF3() override; + void compute(int, int) override; + void settings(int, char **) override; + void coeff(int, char **) override; + void init_style() override; + void init_list(int, class NeighList *) override; // needed for ptr to full neigh list + double init_one(int, int) override; // needed for cutoff radius for neighbour list + double single(int, int, int, int, double, double, double, double &) override; + + double memory_usage() override; + + protected: + int ***setflag_3b, **knot_spacing_type_2b, ***knot_spacing_type_3b; + double **cut, ***cut_3b, **cut_3b_list, ****min_cut_3b; + double **knot_spacing_2b, ****knot_spacing_3b; + + double ***n2b_knots_array, ***n2b_coeff_array; + int **n2b_knots_array_size, **n2b_coeff_array_size; + double ****cached_constants_2b, ****cached_constants_2b_deri; + + int ***map_3b; + double ***n3b_knots_array, ****n3b_coeff_array; + int **n3b_knots_array_size, **n3b_coeff_array_size; + double ****coeff_for_der_jk, ****coeff_for_der_ik,****coeff_for_der_ij; + double ****cached_constants_3b, ****cached_constants_3b_deri; + + int *neighshort, maxshort; // short neighbor list array for 3body interaction + + void uf3_read_unified_pot_file(char *potf_name); + void communicate(); + int bsplines_created; + bool pot_3b; + virtual void allocate(); + void create_bsplines(); + void create_cached_constants_2b(); + void create_cached_constants_3b(); + + int get_starting_index_uniform_2b(int i, int j, double r); + int get_starting_index_uniform_3b(int i, int j, int k, double r, int knot_dim); + + int get_starting_index_nonuniform_2b(int i, int j, double r); + int get_starting_index_nonuniform_3b(int i, int j, int k, double r, int knot_dim); + + int (PairUF3::*get_starting_index_2b)(int i, int j, double r); + int (PairUF3::*get_starting_index_3b)(int i, int j, int k, double r, int knot_dim); + + int nbody_flag = 3; + int max_num_knots_2b = 0; + int max_num_coeff_2b = 0; + int max_num_knots_3b = 0; + int max_num_coeff_3b = 0; + int tot_interaction_count_3b = 0; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + diff --git a/src/ML-UF3/uf3_bspline_basis2.cpp b/src/ML-UF3/uf3_bspline_basis2.cpp new file mode 100644 index 0000000000..bb73e07970 --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis2.cpp @@ -0,0 +1,111 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + copyright (2003) sandia corporation. under the terms of contract + de-ac04-94al85000 with sandia corporation, the u.s. government retains + certain rights in this software. this software is distributed under + the gnu general public license. + + see the readme file in the top-level lammps directory. +------------------------------------------------------------------------- */ + +#include "uf3_bspline_basis2.h" + +#include "math_special.h" + +using namespace LAMMPS_NS; +using MathSpecial::square; + +// Constructor +// Initializes coefficients and knots +// Requires [knots] to have length 4 +uf3_bspline_basis2::uf3_bspline_basis2(LAMMPS *ulmp, const double *knots, double coefficient) +{ + lmp = ulmp; + + double c0, c1, c2; + + c0 = coefficient + * (square(knots[0]) + / (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + c1 = coefficient * + (-2.0 * knots[0] / + (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + c2 = coefficient * + (1.0 / (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + constants[0] = c0; + constants[1] = c1; + constants[2] = c2; + c0 = coefficient * + (-knots[1] * knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + knots[0] * knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + c1 = coefficient * + (knots[1] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[0] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2])) + + knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + c2 = coefficient * + (-1.0 / (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + 1.0 / (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + constants[3] = c0; + constants[4] = c1; + constants[5] = c2; + c0 = coefficient * + (square(knots[3]) / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + c1 = coefficient * + (-2.0 * knots[3] / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + c2 = coefficient * + (1.0 / (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + constants[6] = c0; + constants[7] = c1; + constants[8] = c2; +} + +uf3_bspline_basis2::~uf3_bspline_basis2() {} + +// Evaluate outer-left part of spline +double uf3_bspline_basis2::eval0(double rsq, double r) +{ + return rsq * constants[2] + r * constants[1] + constants[0]; +} + +// Evaluate center-left part of spline +double uf3_bspline_basis2::eval1(double rsq, double r) +{ + return rsq * constants[5] + r * constants[4] + constants[3]; +} + +// Evaluate center-right part of spline +double uf3_bspline_basis2::eval2(double rsq, double r) +{ + return rsq * constants[8] + r * constants[7] + constants[6]; +} + +double uf3_bspline_basis2::memory_usage() +{ + double bytes = 0; + + bytes += (double)9*sizeof(double); + + return bytes; +} diff --git a/src/ML-UF3/uf3_bspline_basis2.h b/src/ML-UF3/uf3_bspline_basis2.h new file mode 100644 index 0000000000..b577e0c92a --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis2.h @@ -0,0 +1,41 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + copyright (2003) sandia corporation. under the terms of contract + de-ac04-94al85000 with sandia corporation, the u.s. government retains + certain rights in this software. this software is distributed under + the gnu general public license. + + see the readme file in the top-level lammps directory. +------------------------------------------------------------------------- */ +#include "pointers.h" + +#include + +#ifndef UF3_BSPLINE_BASIS2_H +#define UF3_BSPLINE_BASIS2_H + +namespace LAMMPS_NS { + +class uf3_bspline_basis2 { + private: + LAMMPS *lmp; + //std::vector constants; + + public: + uf3_bspline_basis2(LAMMPS *ulmp, const double *knots, double coefficient); + ~uf3_bspline_basis2(); + //std::vector constants; + double constants[9] = {}; + double eval0(double, double); + double eval1(double, double); + double eval2(double, double); + + double memory_usage(); +}; + +} // namespace LAMMPS_NS +#endif diff --git a/src/ML-UF3/uf3_bspline_basis3.cpp b/src/ML-UF3/uf3_bspline_basis3.cpp new file mode 100644 index 0000000000..b2c7aa2acb --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis3.cpp @@ -0,0 +1,355 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + copyright (2003) sandia corporation. under the terms of contract + de-ac04-94al85000 with sandia corporation, the u.s. government retains + certain rights in this software. this software is distributed under + the gnu general public license. + + see the readme file in the top-level lammps directory. +------------------------------------------------------------------------- */ + +#include "uf3_bspline_basis3.h" + +#include "math_special.h" + +using namespace LAMMPS_NS; +using MathSpecial::cube; +using MathSpecial::square; + +// Constructor +// Initializes coefficients and knots +// [knots] needs to have length 4 +uf3_bspline_basis3::uf3_bspline_basis3(LAMMPS *ulmp, const double *knots, double coefficient) +{ + lmp = ulmp; + + double c0, c1, c2, c3; + + c0 = coefficient * + (-cube(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + c1 = coefficient * + (3.0 * square(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + c2 = coefficient * + (-3.0 * knots[0] / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + c3 = coefficient * + (1.0 / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[0] = c0; + constants[1] = c1; + constants[2] = c2; + constants[3] = c3; + c0 = coefficient * + (square(knots[1]) * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + square(knots[0]) * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] * knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + c1 = coefficient * + (-square(knots[1]) / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 2.0 * knots[1] * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + square(knots[0]) / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 2.0 * knots[0] * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + knots[0] * knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[0] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + c2 = coefficient * + (2.0 * knots[1] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + 2.0 * knots[0] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + c3 = coefficient * + (-1.0 / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 1.0 / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 1.0 / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[4] = c0; + constants[5] = c1; + constants[6] = c2; + constants[7] = c3; + c0 = coefficient * + (-knots[0] * square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] * knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] * square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + c1 = coefficient * + (2.0 * knots[0] * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + knots[1] * knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[1] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 2.0 * knots[2] * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) + + square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + c2 = coefficient * + (-knots[0] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + 2.0 * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) - + 2.0 * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + c3 = coefficient * + (1.0 / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + 1.0 / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 1.0 / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[8] = c0; + constants[9] = c1; + constants[10] = c2; + constants[11] = c3; + c0 = coefficient * + (cube(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + c1 = coefficient * + (-3.0 * square(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + c2 = coefficient * + (3.0 * knots[4] / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + c3 = coefficient * + (-1.0 / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[12] = c0; + constants[13] = c1; + constants[14] = c2; + constants[15] = c3; +} + +uf3_bspline_basis3::~uf3_bspline_basis3() {} + +// Evaluate outer-left part of spline +double uf3_bspline_basis3::eval0(double rth, double rsq, double r) +{ + return rth * constants[3] + rsq * constants[2] + r * constants[1] + constants[0]; +} + +// Evaluate center-left part of spline +double uf3_bspline_basis3::eval1(double rth, double rsq, double r) +{ + return rth * constants[7] + rsq * constants[6] + r * constants[5] + constants[4]; +} + +// Evaluate center-right part of spline +double uf3_bspline_basis3::eval2(double rth, double rsq, double r) +{ + return rth * constants[11] + rsq * constants[10] + r * constants[9] + constants[8]; +} + +// Evaluate outer-right part of spline +double uf3_bspline_basis3::eval3(double rth, double rsq, double r) +{ + return rth * constants[15] + rsq * constants[14] + r * constants[13] + constants[12]; +} + +double uf3_bspline_basis3::memory_usage() +{ + double bytes = 0; + + bytes += (double)16*sizeof(double); + + return bytes; +} diff --git a/src/ML-UF3/uf3_bspline_basis3.h b/src/ML-UF3/uf3_bspline_basis3.h new file mode 100644 index 0000000000..70e1bbd2aa --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis3.h @@ -0,0 +1,42 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + copyright (2003) sandia corporation. under the terms of contract + de-ac04-94al85000 with sandia corporation, the u.s. government retains + certain rights in this software. this software is distributed under + the gnu general public license. + + see the readme file in the top-level lammps directory. +------------------------------------------------------------------------- */ + +#include "pointers.h" + +#include + +#ifndef UF3_BSPLINE_BASIS3_H +#define UF3_BSPLINE_BASIS3_H + +namespace LAMMPS_NS { + +class uf3_bspline_basis3 { + private: + LAMMPS *lmp; + //std::vector constants; + + public: + uf3_bspline_basis3(LAMMPS *ulmp, const double *knots, double coefficient); + ~uf3_bspline_basis3(); + double constants[16] = {}; + double eval0(double, double, double); + double eval1(double, double, double); + double eval2(double, double, double); + double eval3(double, double, double); + + double memory_usage(); +}; + +} // namespace LAMMPS_NS +#endif diff --git a/src/Makefile b/src/Makefile index b9f1bcbdef..805b950112 100644 --- a/src/Makefile +++ b/src/Makefile @@ -74,6 +74,7 @@ PACKAGE = \ dpd-smooth \ drude \ eff \ + extra-command \ extra-compute \ extra-dump \ extra-fix \ @@ -104,6 +105,7 @@ PACKAGE = \ ml-quip \ ml-rann \ ml-snap \ + ml-uf3 \ mofff \ molfile \ netcdf \ @@ -167,6 +169,7 @@ PACKMOST = \ dpd-smooth \ drude \ eff \ + extra-command \ extra-compute \ extra-dump \ extra-fix \ diff --git a/src/OPENMP/fix_omp.cpp b/src/OPENMP/fix_omp.cpp index f7828f43ee..59f0e9d534 100644 --- a/src/OPENMP/fix_omp.cpp +++ b/src/OPENMP/fix_omp.cpp @@ -229,7 +229,13 @@ void FixOMP::init() check_hybrid = 0; \ if (force->name) { \ if ( (strcmp(force->name ## _style,"hybrid") == 0) || \ - (strcmp(force->name ## _style,"hybrid/overlay") == 0) ) \ + (strcmp(force->name ## _style,"hybrid/overlay") == 0) || \ + (strcmp(force->name ## _style,"hybrid/scaled") == 0) || \ + (strcmp(force->name ## _style,"hybrid/molecular") == 0) || \ + (strcmp(force->name ## _style,"hybrid/omp") == 0) || \ + (strcmp(force->name ## _style,"hybrid/overlay/omp") == 0) || \ + (strcmp(force->name ## _style,"hybrid/scaled/omp") == 0) || \ + (strcmp(force->name ## _style,"hybrid/molecular/omp") == 0) ) \ check_hybrid=1; \ if (force->name->suffix_flag & Suffix::OMP) { \ last_force_name = (const char *) #name; \ diff --git a/src/OPENMP/npair_skip_omp.h b/src/OPENMP/npair_skip_omp.h index 937304ad3f..ddfdb9f055 100644 --- a/src/OPENMP/npair_skip_omp.h +++ b/src/OPENMP/npair_skip_omp.h @@ -19,14 +19,12 @@ NPairStyle(skip/omp, NPairSkip, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP); NPairStyle(skip/half/respa/omp, NPairSkipRespa, - NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP); NPairStyle(skip/half/size/omp, @@ -36,32 +34,27 @@ NPairStyle(skip/half/size/omp, NPairStyle(skip/size/off2on/omp, NPairSkipSizeOff2on, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_MULTI_OLD | + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP); NPairStyle(skip/size/off2on/oneside/omp, NPairSkipSizeOff2onOneside, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI | NP_OMP); + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | + NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP); NPairStyle(skip/ghost/omp, NPairSkip, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP | NP_GHOST); NPairStyle(skip/trim/omp, NPairSkipTrim, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); NPairStyle(skip/trim/half/respa/omp, NPairSkipTrimRespa, - NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); NPairStyle(skip/trim/half/size/omp, @@ -71,20 +64,17 @@ NPairStyle(skip/trim/half/size/omp, NPairStyle(skip/trim/size/off2on/omp, NPairSkipTrimSizeOff2on, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_MULTI_OLD | + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); NPairStyle(skip/trim/size/off2on/oneside/omp, NPairSkipTrimSizeOff2onOneside, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | + NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); NPairStyle(skip/trim/ghost/omp, NPairSkipTrim, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP | NP_GHOST); // clang-format off #endif diff --git a/src/PLUMED/fix_plumed.cpp b/src/PLUMED/fix_plumed.cpp index ad7f4f3995..2bf56acbbf 100644 --- a/src/PLUMED/fix_plumed.cpp +++ b/src/PLUMED/fix_plumed.cpp @@ -77,9 +77,9 @@ FixPlumed::FixPlumed(LAMMPS *lmp, int narg, char **arg) : int api_version=0; p->cmd("getApiVersion",&api_version); - if ((api_version < 5) || (api_version > 9)) + if ((api_version < 5) || (api_version > 10)) error->all(FLERR,"Incompatible API version for PLUMED in fix plumed. " - "Only Plumed 2.4.x, 2.5.x, 2.6.x, 2.7.x, 2.8.x are tested and supported."); + "Only Plumed 2.4.x, 2.5.x, 2.6.x, 2.7.x, 2.8.x, 2.9.x are tested and supported."); #if !defined(MPI_STUBS) // If the -partition option is activated then enable @@ -205,6 +205,7 @@ FixPlumed::FixPlumed(LAMMPS *lmp, int narg, char **arg) : double dt=update->dt; p->cmd("setTimestep",&dt); + extscalar = 1; scalar_flag = 1; energy_global_flag = virial_global_flag = 1; thermo_energy = thermo_virial = 1; diff --git a/src/QEQ/fix_qeq_shielded.cpp b/src/QEQ/fix_qeq_shielded.cpp index 6987732048..2e653b9226 100644 --- a/src/QEQ/fix_qeq_shielded.cpp +++ b/src/QEQ/fix_qeq_shielded.cpp @@ -55,29 +55,53 @@ void FixQEqShielded::init() neighbor->add_request(this, NeighConst::REQ_FULL); - int ntypes = atom->ntypes; + const int ntypes = atom->ntypes; memory->create(shld, ntypes + 1, ntypes + 1, "qeq:shielding"); init_shielding(); - int i; - for (i = 1; i <= ntypes; i++) { - if (gamma[i] == 0.0) error->all(FLERR, "Invalid param file for fix qeq/shielded"); + // check if valid parameters for all atom types in the fix group are provided + const int *type = atom->type; + const int *mask = atom->mask; + int tmp = 0, tmp_all = 0; + for (int i = 0; i < nlocal; ++i) { + if (mask[i] & groupbit) { + if (gamma[type[i]] == 0.0) + tmp = type[i]; + } } + MPI_Allreduce(&tmp, &tmp_all, 1, MPI_INT, MPI_MAX, world); + if (tmp_all) + error->all(FLERR, "Invalid QEq parameters for atom type {} provided", tmp_all); } /* ---------------------------------------------------------------------- */ void FixQEqShielded::extract_reax() { - Pair *pair = force->pair_match("^reax..", 0); - if (pair == nullptr) error->all(FLERR, "No pair reaxff for fix qeq/shielded"); - int tmp; + const int nlocal = atom->nlocal; + const int *mask = atom->mask; + const int *type = atom->type; + + Pair *pair = force->pair_match("^reaxff", 0); + if (pair == nullptr) error->all(FLERR, "No reaxff pair style for fix qeq/shielded"); + int tmp, tmp_all; chi = (double *) pair->extract("chi", tmp); eta = (double *) pair->extract("eta", tmp); gamma = (double *) pair->extract("gamma", tmp); - if (chi == nullptr || eta == nullptr || gamma == nullptr) - error->all(FLERR, "Fix qeq/shielded could not extract params from pair reaxff"); + if ((chi == nullptr) || (eta == nullptr) || (gamma == nullptr)) + error->all(FLERR, "Fix qeq/shielded could not extract all QEq parameters from pair reaxff"); + + tmp = tmp_all = 0; + for (int i = 0; i < nlocal; ++i) { + if (mask[i] & groupbit) { + if ((chi[type[i]] == 0.0) && (eta[type[i]] == 0.0) && (gamma[type[i]] == 0.0)) + tmp = type[i]; + } + } + MPI_Allreduce(&tmp, &tmp_all, 1, MPI_INT, MPI_MAX, world); + if (tmp_all) + error->all(FLERR, "No QEq parameters for atom type {} provided by pair reaxff", tmp_all); } // clang-format off diff --git a/src/REAXFF/fix_qeq_reaxff.cpp b/src/REAXFF/fix_qeq_reaxff.cpp index 2c3089b5e8..e6d5315823 100644 --- a/src/REAXFF/fix_qeq_reaxff.cpp +++ b/src/REAXFF/fix_qeq_reaxff.cpp @@ -205,25 +205,41 @@ int FixQEqReaxFF::setmask() void FixQEqReaxFF::pertype_parameters(char *arg) { + const int nlocal = atom->nlocal; + const int *mask = atom->mask; + const int *type = atom->type; + if (utils::strmatch(arg,"^reaxff")) { reaxflag = 1; Pair *pair = force->pair_match("^reaxff",0); if (!pair) error->all(FLERR,"No reaxff pair style for fix qeq/reaxff"); - int tmp; + int tmp, tmp_all; chi = (double *) pair->extract("chi",tmp); eta = (double *) pair->extract("eta",tmp); gamma = (double *) pair->extract("gamma",tmp); - if (chi == nullptr || eta == nullptr || gamma == nullptr) - error->all(FLERR, "Fix qeq/reaxff could not extract params from pair reaxff"); + if ((chi == nullptr) || (eta == nullptr) || (gamma == nullptr)) + error->all(FLERR, "Fix qeq/reaxff could not extract all QEq parameters from pair reaxff"); + tmp = tmp_all = 0; + for (int i = 0; i < nlocal; ++i) { + if (mask[i] & groupbit) { + if ((chi[type[i]] == 0.0) && (eta[type[i]] == 0.0) && (gamma[type[i]] == 0.0)) + tmp = type[i]; + } + } + MPI_Allreduce(&tmp, &tmp_all, 1, MPI_INT, MPI_MAX, world); + if (tmp_all) + error->all(FLERR, "No QEq parameters for atom type {} provided by pair reaxff", tmp_all); return; } else if (utils::strmatch(arg,"^reax/c")) { error->all(FLERR, "Fix qeq/reaxff keyword 'reax/c' is obsolete; please use 'reaxff'"); + } else { + error->all(FLERR, "Unknown fix qeq/reaxff keyword {}", arg); } reaxflag = 0; - const int ntypes = atom->ntypes; + const int ntypes = atom->ntypes; memory->create(chi,ntypes+1,"qeq/reaxff:chi"); memory->create(eta,ntypes+1,"qeq/reaxff:eta"); memory->create(gamma,ntypes+1,"qeq/reaxff:gamma"); diff --git a/src/REAXFF/pair_reaxff.cpp b/src/REAXFF/pair_reaxff.cpp index 99f7510a49..b9f4f6c838 100644 --- a/src/REAXFF/pair_reaxff.cpp +++ b/src/REAXFF/pair_reaxff.cpp @@ -694,24 +694,28 @@ void *PairReaxFF::extract(const char *str, int &dim) { dim = 1; if (strcmp(str,"chi") == 0 && chi) { + chi[0] = 0.0; for (int i = 1; i <= atom->ntypes; i++) if (map[i] >= 0) chi[i] = api->system->reax_param.sbp[map[i]].chi; else chi[i] = 0.0; return (void *) chi; } if (strcmp(str,"eta") == 0 && eta) { + eta[0] = 0.0; for (int i = 1; i <= atom->ntypes; i++) if (map[i] >= 0) eta[i] = api->system->reax_param.sbp[map[i]].eta; else eta[i] = 0.0; return (void *) eta; } if (strcmp(str,"gamma") == 0 && gamma) { + gamma[0] = 0.0; for (int i = 1; i <= atom->ntypes; i++) if (map[i] >= 0) gamma[i] = api->system->reax_param.sbp[map[i]].gamma; else gamma[i] = 0.0; return (void *) gamma; } if (strcmp(str,"bcut_acks2") == 0 && bcut_acks2) { + bcut_acks2[0] = 0.0; for (int i = 1; i <= atom->ntypes; i++) if (map[i] >= 0) bcut_acks2[i] = api->system->reax_param.sbp[map[i]].bcut_acks2; else bcut_acks2[i] = 0.0; diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index 6e14964a35..6f887a33e6 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -22,6 +22,7 @@ #include "comm.h" #include "domain.h" #include "error.h" +#include "fix_bond_history.h" #include "force.h" #include "group.h" #include "input.h" @@ -754,6 +755,10 @@ void DeleteAtoms::bondring(int nbuf, char *cbuf, void *ptr) int nlocal = daptr->atom->nlocal; + // find instances of bond history to delete data + auto histories = daptr->modify->get_fix_by_style("BOND_HISTORY"); + int n_histories = histories.size(); + // cbuf = list of N deleted atom IDs from other proc, put them in hash hash->clear(); @@ -771,6 +776,11 @@ void DeleteAtoms::bondring(int nbuf, char *cbuf, void *ptr) if (hash->find(bond_atom[i][m]) != hash->end()) { bond_type[i][m] = bond_type[i][n - 1]; bond_atom[i][m] = bond_atom[i][n - 1]; + if (n_histories > 0) + for (auto &ihistory: histories) { + dynamic_cast(ihistory)->shift_history(i,m,n-1); + dynamic_cast(ihistory)->delete_history(i,n-1); + } n--; } else m++; diff --git a/src/fix_bond_history.h b/src/fix_bond_history.h index fafcf52bd9..e19deee82f 100644 --- a/src/fix_bond_history.h +++ b/src/fix_bond_history.h @@ -44,6 +44,7 @@ class FixBondHistory : public Fix { void update_atom_value(int, int, int, double); double get_atom_value(int, int, int); + int get_ndata() const { return ndata; } // methods to reorder/delete elements of atom->bond_atom void delete_history(int, int); diff --git a/src/input.cpp b/src/input.cpp index c9a3cf5f52..826b1821d5 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -888,6 +888,7 @@ void Input::clear() lmp->destroy(); lmp->create(); lmp->post_create(); + variable->clear_in_progress(); } /* ---------------------------------------------------------------------- */ diff --git a/src/library.cpp b/src/library.cpp index e5c3021954..71cf01eff2 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -1198,14 +1198,31 @@ internally by the :doc:`Fortran interface ` and are not likely to be us * - triclinic - 1 if the the simulation box is triclinic, 0 if orthogonal. See :doc:`change_box`. + +**Communication status** + +.. list-table:: + :header-rows: 1 + :widths: auto + + * - Keyword + - Description / Return value * - universe_rank - MPI rank on LAMMPS' universe communicator (0 <= universe_rank < universe_size) * - universe_size - Number of ranks on LAMMPS' universe communicator (world_size <= universe_size) * - world_rank - - MPI rank on LAMMPS' world communicator (0 <= world_rank < world_size) + - MPI rank on LAMMPS' world communicator (0 <= world_rank < world_size, aka comm->me) * - world_size - - Number of ranks on LAMMPS' world communicator + - Number of ranks on LAMMPS' world communicator (aka comm->nprocs) + * - comm_style + - communication style (0 = BRICK, 1 = TILED) + * - comm_layout + - communication layout (0 = LAYOUT_UNIFORM, 1 = LAYOUT_NONUNIFORM, 2 = LAYOUT_TILED) + * - comm_mode + - communication mode (0 = SINGLE, 1 = MULTI, 2 = MULTIOLD) + * - ghost_velocity + - whether velocities are communicated for ghost atoms (0 = no, 1 = yes) .. _extract_system_sizes: @@ -1310,6 +1327,10 @@ int lammps_extract_setting(void *handle, const char *keyword) if (strcmp(keyword,"world_rank") == 0) return lmp->comm->me; if (strcmp(keyword,"world_size") == 0) return lmp->comm->nprocs; if (strcmp(keyword,"nthreads") == 0) return lmp->comm->nthreads; + if (strcmp(keyword,"comm_style") == 0) return lmp->comm->style; + if (strcmp(keyword,"comm_layout") == 0) return lmp->comm->layout; + if (strcmp(keyword,"comm_mode") == 0) return lmp->comm->mode; + if (strcmp(keyword,"ghost_velocity") == 0) return lmp->comm->ghost_velocity; if (strcmp(keyword,"nlocal") == 0) return lmp->atom->nlocal; if (strcmp(keyword,"nghost") == 0) return lmp->atom->nghost; @@ -1386,6 +1407,7 @@ int lammps_extract_global_datatype(void * /*handle*/, const char *name) if (strcmp(name,"xy") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"xz") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"yz") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"procgrid") == 0) return LAMMPS_INT; if (strcmp(name,"natoms") == 0) return LAMMPS_BIGINT; if (strcmp(name,"nbonds") == 0) return LAMMPS_BIGINT; @@ -1604,6 +1626,10 @@ report the "native" data type. The following tables are provided: - double - 1 - triclinic tilt factor. See :doc:`Howto_triclinic`. + * - procgrid + - int + - 3 + - processor count assigned to each dimension of 3d grid. See :doc:`processors`. .. _extract_system_settings: @@ -1861,6 +1887,9 @@ void *lammps_extract_global(void *handle, const char *name) if (strcmp(name,"xy") == 0) return (void *) &lmp->domain->xy; if (strcmp(name,"xz") == 0) return (void *) &lmp->domain->xz; if (strcmp(name,"yz") == 0) return (void *) &lmp->domain->yz; + if (((lmp->comm->layout == Comm::LAYOUT_UNIFORM) || + (lmp->comm->layout == Comm::LAYOUT_NONUNIFORM)) && (strcmp(name,"procgrid") == 0)) + return (void *) &lmp->comm->procgrid; if (strcmp(name,"natoms") == 0) return (void *) &lmp->atom->natoms; if (strcmp(name,"ntypes") == 0) return (void *) &lmp->atom->ntypes; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 4bdd58eead..878ee98917 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -148,6 +148,7 @@ void NeighList::post_constructor(NeighRequest *nq) copy = nq->copy; trim = nq->trim; id = nq->id; + molskip = nq->molskip; if (nq->copy) { listcopy = neighbor->lists[nq->copylist]; @@ -157,14 +158,16 @@ void NeighList::post_constructor(NeighRequest *nq) if (nq->skip) { listskip = neighbor->lists[nq->skiplist]; - int ntypes = atom->ntypes; - iskip = new int[ntypes+1]; - memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip"); - int i,j; - for (i = 1; i <= ntypes; i++) iskip[i] = nq->iskip[i]; - for (i = 1; i <= ntypes; i++) - for (j = 1; j <= ntypes; j++) - ijskip[i][j] = nq->ijskip[i][j]; + if (!molskip) { + int ntypes = atom->ntypes; + iskip = new int[ntypes+1]; + memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip"); + int i,j; + for (i = 1; i <= ntypes; i++) iskip[i] = nq->iskip[i]; + for (i = 1; i <= ntypes; i++) + for (j = 1; j <= ntypes; j++) + ijskip[i][j] = nq->ijskip[i][j]; + } } if (nq->halffull) diff --git a/src/neigh_list.h b/src/neigh_list.h index 01e9a1c6a7..4c592772ad 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -46,6 +46,7 @@ class NeighList : protected Pointers { int kk2cpu; // 1 if this list is copied from Kokkos to CPU int copymode; // 1 if this is a Kokkos on-device copy int id; // copied from neighbor list request + int molskip; // 1/2 if this is an intra-/inter-molecular skip list // data structs to store neighbor pairs I,J and associated values diff --git a/src/neigh_request.cpp b/src/neigh_request.cpp index 280b5c54ae..77e71c6860 100644 --- a/src/neigh_request.cpp +++ b/src/neigh_request.cpp @@ -76,6 +76,7 @@ NeighRequest::NeighRequest(LAMMPS *_lmp) : Pointers(_lmp) skip = 0; iskip = nullptr; ijskip = nullptr; + molskip = REGULAR; // only set when command = 1; @@ -183,6 +184,8 @@ int NeighRequest::identical(NeighRequest *other) int NeighRequest::same_skip(NeighRequest *other) { + if (molskip != other->molskip) return 0; + const int ntypes = atom->ntypes; int same = 1; @@ -307,6 +310,12 @@ void NeighRequest::set_skip(int *_iskip, int **_ijskip) ijskip = _ijskip; } +void NeighRequest::set_molskip(int _molskip) +{ + skip = 1; + molskip = _molskip; +} + void NeighRequest::enable_full() { half = 0; diff --git a/src/neigh_request.h b/src/neigh_request.h index fa57922c93..caa9e05ad6 100644 --- a/src/neigh_request.h +++ b/src/neigh_request.h @@ -29,6 +29,9 @@ class NeighRequest : protected Pointers { friend class NPairSkipTrimIntel; friend class FixIntel; + public: + enum { REGULAR, INTRA, INTER }; + protected: void *requestor; // class that made request int requestor_instance; // instance of that class (only Fix, Compute, Pair) @@ -88,6 +91,7 @@ class NeighRequest : protected Pointers { int skip; // 1 if this list skips atom types from another list int *iskip; // iskip[i] if atoms of type I are not in list int **ijskip; // ijskip[i][j] if pairs of type I,J are not in list + int molskip; // 0 reqular list, 1 keep only intra-molecular entries, 2 keep inter-molecular // command_style only set if command = 1 // allows print_pair_info() to access command name @@ -137,6 +141,7 @@ class NeighRequest : protected Pointers { void set_kokkos_device(int); void set_kokkos_host(int); void set_skip(int *, int **); + void set_molskip(int); void enable_full(); void enable_ghost(); void enable_intel(); diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 63d14acb9a..59ddf87698 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1800,10 +1800,17 @@ void Neighbor::print_pairwise_info() else out += fmt::format(", half/full from ({})",rq->halffulllist+1); } else if (rq->skip) { - if (rq->trim) - out += fmt::format(", skip trim from ({})",rq->skiplist+1); - else - out += fmt::format(", skip from ({})",rq->skiplist+1); + if (rq->molskip) { + if (rq->trim) + out += fmt::format(", molskip trim from ({})",rq->skiplist+1); + else + out += fmt::format(", molskip from ({})",rq->skiplist+1); + } else { + if (rq->trim) + out += fmt::format(", skip trim from ({})",rq->skiplist+1); + else + out += fmt::format(", skip from ({})",rq->skiplist+1); + } } out += "\n"; diff --git a/src/npair_skip.cpp b/src/npair_skip.cpp index 6afb43bc16..75802567b7 100644 --- a/src/npair_skip.cpp +++ b/src/npair_skip.cpp @@ -17,6 +17,7 @@ #include "error.h" #include "my_page.h" #include "neigh_list.h" +#include "neigh_request.h" using namespace LAMMPS_NS; @@ -41,11 +42,13 @@ void NPairSkipTemp::build(NeighList *list) int *type = atom->type; int nlocal = atom->nlocal; + tagint *molecule = atom->molecule; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; + int molskip = list->molskip; int *ilist_skip = list->listskip->ilist; int *numneigh_skip = list->listskip->numneigh; @@ -71,7 +74,8 @@ void NPairSkipTemp::build(NeighList *list) for (ii = 0; ii < num_skip; ii++) { i = ilist_skip[ii]; itype = type[i]; - if (iskip[itype]) continue; + + if (!molskip && iskip[itype]) continue; if (TRIM) { xtmp = x[i][0]; @@ -90,7 +94,9 @@ void NPairSkipTemp::build(NeighList *list) for (jj = 0; jj < jnum; jj++) { joriginal = jlist[jj]; j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; + if (!molskip && ijskip[itype][type[j]]) continue; + if ((molskip == NeighRequest::INTRA) && (molecule[i] != molecule[j])) continue; + if ((molskip == NeighRequest::INTER) && (molecule[i] == molecule[j])) continue; if (TRIM) { delx = xtmp - x[j][0]; diff --git a/src/npair_skip.h b/src/npair_skip.h index cb0d201555..72e86d3a3e 100644 --- a/src/npair_skip.h +++ b/src/npair_skip.h @@ -30,7 +30,8 @@ NPairStyle(skip/ghost, typedef NPairSkipTemp<0> NPairSkipSize; NPairStyle(skip/half/size, NPairSkipSize, - NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); typedef NPairSkipTemp<1> NPairSkipTrim; @@ -50,7 +51,8 @@ NPairStyle(skip/ghost/trim, typedef NPairSkipTemp<1> NPairSkipTrimSize; NPairStyle(skip/trim/half/size, NPairSkipTrimSize, - NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); // clang-format on diff --git a/src/npair_skip_respa.cpp b/src/npair_skip_respa.cpp index 4c3dda91eb..211aa6142a 100644 --- a/src/npair_skip_respa.cpp +++ b/src/npair_skip_respa.cpp @@ -18,6 +18,7 @@ #include "error.h" #include "my_page.h" #include "neigh_list.h" +#include "neigh_request.h" using namespace LAMMPS_NS; @@ -39,11 +40,13 @@ void NPairSkipRespaTemp::build(NeighList *list) int *neighptr, *jlist, *neighptr_inner, *neighptr_middle; int *type = atom->type; + tagint *molecule = atom->molecule; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; + int molskip = list->molskip; int *ilist_skip = list->listskip->ilist; int *numneigh_skip = list->listskip->numneigh; @@ -90,7 +93,7 @@ void NPairSkipRespaTemp::build(NeighList *list) for (ii = 0; ii < inum_skip; ii++) { i = ilist_skip[ii]; itype = type[i]; - if (iskip[itype]) continue; + if (!molskip && iskip[itype]) continue; if (TRIM) { xtmp = x[i][0]; @@ -114,7 +117,9 @@ void NPairSkipRespaTemp::build(NeighList *list) for (jj = 0; jj < jnum; jj++) { joriginal = jlist[jj]; j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; + if (!molskip && ijskip[itype][type[j]]) continue; + if ((molskip == NeighRequest::INTRA) && (molecule[i] != molecule[j])) continue; + if ((molskip == NeighRequest::INTER) && (molecule[i] == molecule[j])) continue; if (TRIM) { delx = xtmp - x[j][0]; @@ -135,7 +140,9 @@ void NPairSkipRespaTemp::build(NeighList *list) for (jj = 0; jj < jnum; jj++) { joriginal = jlist[jj]; j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; + if (!molskip && ijskip[itype][type[j]]) continue; + if ((molskip == NeighRequest::INTRA) && (molecule[i] != molecule[j])) continue; + if ((molskip == NeighRequest::INTER) && (molecule[i] == molecule[j])) continue; if (TRIM) { delx = xtmp - x[j][0]; @@ -157,7 +164,9 @@ void NPairSkipRespaTemp::build(NeighList *list) for (jj = 0; jj < jnum; jj++) { joriginal = jlist[jj]; j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; + if (!molskip && ijskip[itype][type[j]]) continue; + if ((molskip == NeighRequest::INTRA) && (molecule[i] != molecule[j])) continue; + if ((molskip == NeighRequest::INTER) && (molecule[i] == molecule[j])) continue; if (TRIM) { delx = xtmp - x[j][0]; diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index d257973617..09f233a4f6 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -321,11 +321,12 @@ void PairHybrid::settings(int narg, char **arg) iarg = 0; nstyles = 0; + const std::string mystyle = force->pair_style; while (iarg < narg) { if (utils::strmatch(arg[iarg],"^hybrid")) - error->all(FLERR,"Pair style hybrid cannot have hybrid as a sub-style"); + error->all(FLERR,"Pair style {} cannot have hybrid as a sub-style", mystyle); if (strcmp(arg[iarg],"none") == 0) - error->all(FLERR,"Pair style hybrid cannot have none as a sub-style"); + error->all(FLERR,"Pair style {} cannot have none as a sub-style", mystyle); styles[nstyles] = force->new_pair(arg[iarg],1,dummy); keywords[nstyles] = force->store_style(arg[iarg],0); @@ -345,6 +346,9 @@ void PairHybrid::settings(int narg, char **arg) nstyles++; } + if (utils::strmatch(mystyle,"^hybrid/molecular") && (nstyles != 2)) + error->all(FLERR, "Pair style {} must have exactly two sub-styles", mystyle); + delete[] cutmax_style; cutmax_style = new double[nstyles]; memset(cutmax_style, 0, nstyles*sizeof(double)); @@ -394,8 +398,7 @@ void PairHybrid::flags() for (m = 0; m < nstyles; m++) { if (styles[m]) comm_forward = MAX(comm_forward,styles[m]->comm_forward); if (styles[m]) comm_reverse = MAX(comm_reverse,styles[m]->comm_reverse); - if (styles[m]) comm_reverse_off = MAX(comm_reverse_off, - styles[m]->comm_reverse_off); + if (styles[m]) comm_reverse_off = MAX(comm_reverse_off,styles[m]->comm_reverse_off); } // single_enable = 1 if all sub-styles are set diff --git a/src/pair_hybrid.h b/src/pair_hybrid.h index d3a7693f9b..b59cc82cb4 100644 --- a/src/pair_hybrid.h +++ b/src/pair_hybrid.h @@ -14,6 +14,7 @@ #ifdef PAIR_CLASS // clang-format off PairStyle(hybrid,PairHybrid); +PairStyle(hybrid/omp,PairHybrid); // clang-format on #else diff --git a/src/pair_hybrid_molecular.cpp b/src/pair_hybrid_molecular.cpp new file mode 100644 index 0000000000..67b654da61 --- /dev/null +++ b/src/pair_hybrid_molecular.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "pair_hybrid_molecular.h" + +#include "atom.h" +#include "error.h" +#include "neigh_request.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairHybridMolecular::PairHybridMolecular(LAMMPS *lmp) : PairHybridOverlay(lmp) {} + +/* ---------------------------------------------------------------------- + modify neighbor list requests +------------------------------------------------------------------------- */ + +void PairHybridMolecular::init_style() +{ + if (!atom->molecule_flag) + error->all(FLERR, "Pair style hybrid/molecular requires atom attribute molecule"); + if (manybody_flag) + error->all(FLERR, "Pair style hybrid/molecular is not compatible with manybody potentials"); + + PairHybridOverlay::init_style(); + + // modify neighbor list requests + + bool first = true; + for (auto &request : neighbor->get_pair_requests()) { + if (first) { + request->set_molskip(NeighRequest::INTRA); + first = false; + } else { + request->set_molskip(NeighRequest::INTER); + } + } + born_matrix_enable = 0; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairHybridMolecular::init_one(int i, int j) +{ + // if I,J is not set explicitly: + // perform mixing only if I,I sub-style = J,J sub-style + // plus I,I and J,J need the same number of substyles + + if (setflag[i][j] == 0) { + if (nmap[i][i] != nmap[j][j]) + error->one(FLERR,"All pair coeffs are not set"); + int num = 0; + for (int k = 0; k < nmap[i][i]; ++k) { + for (int l = 0; l < nmap[j][j]; ++l) { + if (map[i][i][k] == map[j][j][l]) { + map[i][j][num] = map[i][i][k]; + ++num; + nmap[i][j] = num; + } + } + } + if (nmap[i][i] != nmap[i][j]) + error->one(FLERR,"All pair coeffs are not set"); + } + nmap[j][i] = nmap[i][j]; + + // call init/mixing for all sub-styles of I,J + // set cutsq in sub-style just as Pair::init() does via call to init_one() + // set cutghost for I,J and J,I just as sub-style does + // sum tail corrections for I,J + // return max cutoff of all sub-styles assigned to I,J + // if no sub-styles assigned to I,J (pair_coeff none), cutmax = 0.0 returned + + double cutmax = 0.0; + cutghost[i][j] = cutghost[j][i] = 0.0; + if (tail_flag) etail_ij = ptail_ij = 0.0; + + for (int k = 0; k < nmap[i][j]; k++) { + map[j][i][k] = map[i][j][k]; + double cut = styles[map[i][j][k]]->init_one(i,j); + if (styles[map[i][j][k]]->did_mix) did_mix = true; + styles[map[i][j][k]]->cutsq[i][j] = styles[map[i][j][k]]->cutsq[j][i] = cut*cut; + if (styles[map[i][j][k]]->ghostneigh) + cutghost[i][j] = cutghost[j][i] = MAX(cutghost[i][j],styles[map[i][j][k]]->cutghost[i][j]); + if (tail_flag) { + etail_ij += styles[map[i][j][k]]->etail_ij; + ptail_ij += styles[map[i][j][k]]->ptail_ij; + } + cutmax = MAX(cutmax,cut); + + int istyle; + for (istyle = 0; istyle < nstyles; istyle++) + if (styles[istyle] == styles[map[i][j][k]]) break; + + if (styles[istyle]->trim_flag) { + + if (cut > cutmax_style[istyle]) { + cutmax_style[istyle] = cut; + + for (auto &request : neighbor->get_pair_requests()) { + if (styles[istyle] == request->get_requestor()) { + request->set_cutoff(cutmax_style[istyle]); + break; + } + } + } + } + } + return cutmax; +} + +/* ---------------------------------------------------------------------- + call sub-style to compute single interaction + error if sub-style does not support single() call + since overlay could have multiple sub-styles, sum results explicitly +------------------------------------------------------------------------- */ + +double PairHybridMolecular::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_lj, double &fforce) +{ + if (nmap[itype][jtype] == 0) + error->one(FLERR,"Invoked pair single() on sub-style none"); + + double fone; + fforce = 0.0; + double esum = 0.0; + if (nmap[itype][jtype] == 2) { + int m = 0; + if (atom->molecule[i] != atom->molecule[j]) m = 1; + const int mystyle = map[itype][jtype][m]; + if (rsq < styles[mystyle]->cutsq[itype][jtype]) { + if (styles[mystyle]->single_enable == 0) + error->one(FLERR,"Pair hybrid/molecular sub-style {} does not support single() call", + keywords[mystyle]); + + if ((special_lj[mystyle] != nullptr) || (special_coul[mystyle] != nullptr)) + error->one(FLERR,"Pair hybrid/molecular single() calls do not support per sub-style " + "special bond values"); + + esum += styles[mystyle]->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fone); + fforce += fone; + } + } + + if (single_extra) copy_svector(itype,jtype); + return esum; +} diff --git a/src/pair_hybrid_molecular.h b/src/pair_hybrid_molecular.h new file mode 100644 index 0000000000..92f8bdc198 --- /dev/null +++ b/src/pair_hybrid_molecular.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(hybrid/molecular,PairHybridMolecular); +PairStyle(hybrid/molecular/omp,PairHybridMolecular); +// clang-format on +#else + +#ifndef LMP_PAIR_HYBRID_MOLECULAR_H +#define LMP_PAIR_HYBRID_MOLECULAR_H + +#include "pair_hybrid_overlay.h" + +namespace LAMMPS_NS { + +class PairHybridMolecular : public PairHybridOverlay { + public: + PairHybridMolecular(class LAMMPS *); + + void init_style() override; + double init_one(int, int) override; + + double single(int, int, int, int, double, double, double, double &) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/pair_hybrid_overlay.h b/src/pair_hybrid_overlay.h index ea0babbde5..f0e85b859f 100644 --- a/src/pair_hybrid_overlay.h +++ b/src/pair_hybrid_overlay.h @@ -14,6 +14,7 @@ #ifdef PAIR_CLASS // clang-format off PairStyle(hybrid/overlay,PairHybridOverlay); +PairStyle(hybrid/overlay/omp,PairHybridOverlay); // clang-format on #else diff --git a/src/pair_hybrid_scaled.h b/src/pair_hybrid_scaled.h index 64fd938822..2af5b61f8d 100644 --- a/src/pair_hybrid_scaled.h +++ b/src/pair_hybrid_scaled.h @@ -14,6 +14,7 @@ #ifdef PAIR_CLASS // clang-format off PairStyle(hybrid/scaled,PairHybridScaled); +PairStyle(hybrid/scaled/omp,PairHybridScaled); // clang-format on #else diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp index 66c4c1f9cd..cba6c742ab 100644 --- a/src/pair_soft.cpp +++ b/src/pair_soft.cpp @@ -39,6 +39,8 @@ PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) PairSoft::~PairSoft() { + if (copymode) return; + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); diff --git a/src/pair_soft.h b/src/pair_soft.h index 8fd1654609..d011b16322 100644 --- a/src/pair_soft.h +++ b/src/pair_soft.h @@ -49,7 +49,7 @@ class PairSoft : public Pair { double **prefactor; double **cut; - void allocate(); + virtual void allocate(); }; } // namespace LAMMPS_NS diff --git a/src/platform.cpp b/src/platform.cpp index 7e9fa820fa..7cc4815f51 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -248,6 +248,8 @@ std::string platform::os_info() buf = "Windows 11 22H2"; } else if (build == "22631") { buf = "Windows 11 23H2"; + } else if (build == "26100") { + buf = "Windows 11 24H2"; } else { buf = "Windows Build " + build; } diff --git a/src/update.cpp b/src/update.cpp index 13ff7c872a..c9e57f9621 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -328,7 +328,8 @@ void Update::create_integrate(int narg, char **arg, int trysuffix) delete[] integrate_style; delete integrate; - integrate_style = nullptr; + // temporarily assign the style name without suffix (for error messages during creation) + integrate_style = utils::strdup(arg[0]); integrate = nullptr; int sflag; @@ -349,6 +350,7 @@ void Update::create_integrate(int narg, char **arg, int trysuffix) else if ((sflag == 3) && lmp->non_pair_suffix()) estyle += lmp->non_pair_suffix(); } + delete[] integrate_style; integrate_style = utils::strdup(estyle); } @@ -398,11 +400,10 @@ void Update::create_minimize(int narg, char **arg, int trysuffix) delete[] minimize_style; delete minimize; - minimize_style = nullptr; + // temporarily assign the style name without suffix (for error messages during creation) + minimize_style = utils::strdup(arg[0]); minimize = nullptr; - // temporarily assign the style name without suffix (for error messages during creation) - minimize_style = arg[0]; int sflag; new_minimize(arg[0], narg - 1, &arg[1], trysuffix, sflag); @@ -417,6 +418,7 @@ void Update::create_minimize(int narg, char **arg, int trysuffix) else if ((sflag == 3) && lmp->non_pair_suffix()) estyle += lmp->non_pair_suffix(); } + delete[] minimize_style; minimize_style = utils::strdup(estyle); } diff --git a/src/variable.cpp b/src/variable.cpp index 1de4533267..f381eecde6 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -879,6 +879,17 @@ void Variable::purge_atomfile() if (style[i] == ATOMFILE) remove(i); } +/* ---------------------------------------------------------------------- + called by "clear" command to reset all "in_progress" state variables + to avoid spurious "variable has circular dependency" issues +------------------------------------------------------------------------- */ + +void Variable::clear_in_progress() +{ + for (int i = 0; i < nvar; ++i) + eval_in_progress[i] = 0; +} + /* ---------------------------------------------------------------------- called by python command in input script simply pass input script line args to Python class diff --git a/src/variable.h b/src/variable.h index f4a5e511c0..6aeba848a8 100644 --- a/src/variable.h +++ b/src/variable.h @@ -35,6 +35,7 @@ class Variable : protected Pointers { void set_arrays(int); void python_command(int, char **); void purge_atomfile(); + void clear_in_progress(); int equalstyle(int); int atomstyle(int); diff --git a/tools/fep/fep.py b/tools/fep/fep.py index c7656c5ef5..cdcf3f10c6 100755 --- a/tools/fep/fep.py +++ b/tools/fep/fep.py @@ -2,23 +2,40 @@ # fep.py - calculate free energy from compute fep results import sys +from argparse import ArgumentParser import math -if len(sys.argv) < 2: - print("Free Energy Perturbation") - print("usage: fep.py temperature < out.fep") - sys.exit() +def compute_fep(): -rt = 0.008314 / 4.184 * float(sys.argv[1]) # in kcal/mol + parser = ArgumentParser(description='A python script to calculate free energy from compute fep results') -v = 1.0 -sum = 0.0 -for line in sys.stdin: - if line.startswith("#"): - continue - tok = line.split() - if len(tok) == 4: - v = float(tok[3]) - sum += math.log(float(tok[2]) / v) + parser.add_argument("units", help="unit system can be lj, real or si") + parser.add_argument("Temperature", type=float, help="The temperature of the system") + parser.add_argument("InputFile", help="The name of the file with the data from compute fep.") + + args = parser.parse_args() + + r_value = {'lj': 1.0, 'real': 0.0019872036, 'si': 8.31446} + + if args.units in r_value: + rt = r_value[args.units] * args.Temperature + else: + sys.exit("The provided units keyword is not valid") + + v = 1.0 + mysum = 0.0 + + with open(args.InputFile, "r") as input_file: + for line in input_file: + if line.startswith("#"): + continue + tok = line.split() + if len(tok) == 4: + v = float(tok[3]) + mysum += math.log(float(tok[2]) / v) + + print(-rt * mysum) + +if __name__ == "__main__": + compute_fep() -print(-rt * sum) diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 4b0f7370dc..a78d891318 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -852,14 +852,19 @@ void LammpsGui::logupdate() } for (int i = 0; i < ncols; ++i) { - int datatype = *(int *)lammps.last_thermo("type", i); + int datatype = -1; double data = 0.0; - if (datatype == 0) // int - data = *(int *)lammps.last_thermo("data", i); - else if (datatype == 2) // double - data = *(double *)lammps.last_thermo("data", i); - else if (datatype == 4) // bigint - data = (double)*(int64_t *)lammps.last_thermo("data", i); + void *ptr = lammps.last_thermo("type", i); + if (ptr) datatype = *(int *)ptr; + ptr = lammps.last_thermo("data", i); + if (ptr) { + if (datatype == 0) // int + data = *(int *)ptr; + else if (datatype == 2) // double + data = *(double *)ptr; + else if (datatype == 4) // bigint + data = (double)*(int64_t *)ptr; + } chartwindow->add_data(step, data, i); } } diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index 010fabd6e2..6e823b32fc 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -138,8 +138,9 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton } command("run 0 post no"); + command("variable write_data_pair index ii"); command("write_restart " + cfg.basename + ".restart"); - command("write_data " + cfg.basename + ".data"); + command("write_data " + cfg.basename + ".data pair ${write_data_pair}"); command("write_coeff " + cfg.basename + "-coeffs.in"); return lmp; diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 185d28089e..eb6b0b488d 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -138,8 +138,9 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton } command("run 0 post no"); + command("variable write_data_pair index ii"); command("write_restart " + cfg.basename + ".restart"); - command("write_data " + cfg.basename + ".data nofix"); + command("write_data " + cfg.basename + ".data nofix pair ${write_data_pair}"); command("write_coeff " + cfg.basename + "-coeffs.in"); return lmp; diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index efc37b9e03..060dd040c2 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -136,8 +136,9 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton } command("run 0 post no"); + command("variable write_data_pair index ii"); command("write_restart " + cfg.basename + ".restart"); - command("write_data " + cfg.basename + ".data"); + command("write_data " + cfg.basename + ".data pair ${write_data_pair}"); command("write_coeff " + cfg.basename + "-coeffs.in"); return lmp; diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index ba3618d3dc..c90d30c21a 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -138,8 +138,9 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton } command("run 0 post no"); + command("variable write_data_pair index ii"); command("write_restart " + cfg.basename + ".restart"); - command("write_data " + cfg.basename + ".data"); + command("write_data " + cfg.basename + ".data pair ${write_data_pair}"); command("write_coeff " + cfg.basename + "-coeffs.in"); return lmp; diff --git a/unittest/force-styles/tests/manybody-pair-uf3.yaml b/unittest/force-styles/tests/manybody-pair-uf3.yaml new file mode 100644 index 0000000000..534b489c78 --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-uf3.yaml @@ -0,0 +1,158 @@ +--- +lammps_version: 24 Mar 2022 +tags: +date_generated: Tue Nov 28 14:51:03 2023 +epsilon: 1e-09 +skip_tests: +prerequisites: ! | + pair uf3 +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + variable newton_bond delete +post_commands: ! "" +input_file: in.manybody +pair_style: uf3 3 +pair_coeff: ! | + * * Nb.uf3 Nb Nb Nb Nb Nb Nb Nb Nb +extract: ! "" +natoms: 64 +init_vdwl: -76.14388662099438 +init_coul: 0 +init_stress: ! |2- + 3.1223073343802071e+02 3.1503555484293474e+02 3.2087032195384182e+02 -5.2677023646012433e+00 4.1046361968856566e+01 -2.2705704820012654e-01 +init_forces: ! |2 + 1 -1.0963106297354930e+00 1.9921565797217811e+00 2.0176595423650685e+00 + 2 -2.5744974244934786e+00 8.6065313692841872e-01 -1.3343920771683084e+00 + 3 -7.5762202587571881e-01 -5.1086473746213934e-01 1.7774798100697495e+00 + 4 -1.2651178900120015e+00 2.5481168050091734e+00 1.0332353551246649e+00 + 5 -3.3301075059618213e-02 -8.6936885426915711e-01 -8.0361144939346540e-01 + 6 5.9576544655966956e-02 -5.7569733665007693e-02 -2.5260577270195245e-01 + 7 -7.8223973805485159e-01 -1.5872724248886485e+00 -4.0690678808175756e-01 + 8 1.2837377243355602e-01 6.8616887866365453e-02 3.9279992110159728e-02 + 9 1.3013607224018784e+00 -2.2234802020121042e-01 -2.5820065882172409e+00 + 10 -3.5389541898719123e-01 1.0418734269769769e+00 -6.7534263859128518e-01 + 11 1.5048713773196754e+00 -1.1607474819622305e+00 -4.1343086960946002e-01 + 12 -3.8382036374205457e+00 -1.8953194768009614e+00 -1.5975045274049304e+00 + 13 -5.1243974635480005e-01 2.8005048190722506e+00 -8.5188627697957486e-01 + 14 -4.3260615266171099e-01 1.7104546503175775e+00 4.8896255947620082e-01 + 15 -2.1729171109783061e+00 1.9610148525080886e+00 -1.7550881080125238e+00 + 16 1.3063694982664014e+00 4.0801741093678640e-01 3.3816303090167859e+00 + 17 1.0103076935514768e+00 1.3062727533124225e+00 -3.0591856171743643e+00 + 18 6.6364797168941592e-01 1.3269858177825717e+00 1.0859880651465830e+00 + 19 -4.3237772669504843e-01 1.5179601478654310e+00 -8.9399081937433889e-01 + 20 -4.1109776137187977e+00 4.8942123015814726e-01 3.0324705210921541e-02 + 21 1.0443613152888414e+00 -2.7611218991110009e-01 -3.2334333893456133e+00 + 22 -3.8840635954358733e+00 1.8543888965122868e+00 -2.7044170995178298e+00 + 23 6.4824470795616951e-01 1.1930964693491897e+00 2.3472683895454201e+00 + 24 5.6518885203578750e-01 8.9024666222906623e-01 9.9558410495963645e-01 + 25 -2.3884920507811258e-01 -1.2236748552119361e-01 9.6166740424011798e-04 + 26 -9.4060753459907698e-01 -2.9688412181022056e-01 6.7007032584453752e-01 + 27 5.0390685311588923e-01 -5.8477364114704944e-01 1.6320689076693460e+00 + 28 -8.1564347181637331e-01 1.9951358496458818e-01 3.2879220126777038e+00 + 29 -1.6141037582891811e+00 3.7621933923780954e-01 5.6865013193370151e-01 + 30 -1.2051389982059610e+00 6.5471000907223187e-02 4.6548238063076404e-02 + 31 -8.3799333021355227e-01 -4.3387478264068147e-01 -3.4488785440063413e-01 + 32 -1.8712481645378094e+00 3.1431436055998407e-02 1.1920833582466677e+00 + 33 2.1132311819974756e+00 -7.8762333052322075e-01 2.9319369786200289e+00 + 34 -7.4212669325944880e-01 1.5089695276247311e-01 6.4837671979385259e-01 + 35 4.7876606586762549e-01 -5.2894027298845681e-01 6.5312176822087242e-01 + 36 9.4335406181387005e-01 -7.7270400013223828e-01 4.8506498341757304e-01 + 37 -6.9776523536821422e-01 1.5814045923629079e+00 -1.7145687025150753e+00 + 38 8.3390581678419395e-01 -2.3460369438656256e-01 -8.1845978792256724e-01 + 39 7.9082785819764490e-01 -1.4014821253885934e+00 -3.6171284136791626e+00 + 40 1.5528260681499937e+00 -1.9423308463414859e+00 2.7454733155675826e-01 + 41 1.6230449781222470e-01 4.0254440068393893e-01 -1.0728426614941826e+00 + 42 -2.5760797297848943e+00 -2.3727612877133377e+00 -7.3694736943877159e-01 + 43 -1.4658113294445060e-01 -3.7059450064886161e+00 -2.2611910919567893e-01 + 44 2.6125365540590240e+00 -2.0393457867642488e+00 -1.7353429519549574e-01 + 45 9.1508218547652620e-01 3.2090468646350390e-01 -1.3730810235354041e+00 + 46 -1.2861926535120600e+00 -1.8325412123528377e+00 2.7409156132103112e+00 + 47 5.2214882788544981e-01 9.0702150750152088e-02 1.3758849361839385e+00 + 48 8.7060691872545093e-01 1.0333012026994193e+00 -8.8450736609033931e-01 + 49 1.6921455867723978e-01 -3.2865843167979367e+00 -2.3941507623279072e+00 + 50 1.3029435213640246e+00 1.1566980491369294e+00 -7.8373321422495534e-02 + 51 1.7782167191801962e-01 3.5869618077998595e+00 2.1417753790319543e+00 + 52 3.4939214706481048e+00 -2.4127970289820255e+00 4.1443505260596725e+00 + 53 4.5955988135622799e-01 1.4913218496577223e+00 1.3076728090591363e+00 + 54 7.0400726037068106e-01 -9.4898269328552198e-01 -7.0340401843204670e-01 + 55 1.1319661424097816e+00 -2.3442414589969114e+00 -7.7166661047173946e-01 + 56 7.7292681497946214e-01 5.4202239892193216e-01 -1.0429033367200278e+00 + 57 1.1664627895682855e+00 1.9743121270468009e-01 -3.8302192241786348e-01 + 58 1.3342985230821185e+00 -2.6808564460978351e-01 -9.3875599645237040e-01 + 59 2.1547446695381884e+00 2.5922697594917221e-01 5.5883175680123842e-01 + 60 -1.1202730918333845e+00 -4.0836109063032069e+00 -3.1463158656990915e+00 + 61 7.5258775499505959e-01 1.4742795022217277e+00 -2.2056849646259416e-01 + 62 -2.1194607090574338e+00 9.6304617778841872e-01 -5.8648933450219842e-01 + 63 2.2116847362243819e+00 -6.9485816680348522e-01 -1.2888780585377166e+00 + 64 2.0946943533672595e+00 1.7817828615230797e+00 5.2222100516662051e+00 +run_vdwl: -76.1335425447406 +run_coul: 0 +run_stress: ! |2- + 3.1227357278065733e+02 3.1510436259931976e+02 3.2097655273455166e+02 -5.2932374901106582e+00 4.0956468170617640e+01 1.5018802669860862e-01 +run_forces: ! |2 + 1 -1.1136068191144672e+00 1.9868928531451695e+00 2.0284715885889444e+00 + 2 -2.5718148688418596e+00 8.3532761170683545e-01 -1.3404690568364115e+00 + 3 -7.6676194475345183e-01 -5.0716795928532021e-01 1.7997537336742999e+00 + 4 -1.2720923579033645e+00 2.5419855255447907e+00 1.0258862987566395e+00 + 5 -4.3524258688024453e-02 -8.8004954612209696e-01 -7.9382095260610019e-01 + 6 8.9678254474529928e-02 -5.0742940694548030e-02 -2.4348008365156723e-01 + 7 -7.7364435925734953e-01 -1.5558296160053275e+00 -4.2051790182009818e-01 + 8 1.1143851887986839e-01 7.2497057799814191e-02 3.6624183488660304e-02 + 9 1.2839141188983776e+00 -2.4381166390795905e-01 -2.5926851536420066e+00 + 10 -3.6606370803571597e-01 1.0472513106007628e+00 -6.5579353351390024e-01 + 11 1.4796344435746969e+00 -1.1469564140842350e+00 -4.2766370678100751e-01 + 12 -3.8341194520315707e+00 -1.8877013457658414e+00 -1.5901839974079914e+00 + 13 -4.6650968579193675e-01 2.7962961910932282e+00 -8.2237329615475063e-01 + 14 -4.5362402854231521e-01 1.7048830533652388e+00 4.9165017205992945e-01 + 15 -2.1790730324228798e+00 1.9552241266001966e+00 -1.7453842965710837e+00 + 16 1.3028733875052598e+00 4.1039519382071737e-01 3.3783851223727419e+00 + 17 1.0049330607671125e+00 1.3021263787131616e+00 -3.0544446010601831e+00 + 18 6.3052176771903379e-01 1.3324251901771336e+00 1.0977786571785106e+00 + 19 -4.5964705284123741e-01 1.4850585747490403e+00 -8.9955925151919691e-01 + 20 -4.0843338981113764e+00 4.6843741575982639e-01 4.6947857407657889e-03 + 21 1.0581909871649149e+00 -2.9084634536392007e-01 -3.2540160500533157e+00 + 22 -3.8927799316015426e+00 1.8587085622785937e+00 -2.7125312751977178e+00 + 23 6.6350903350923252e-01 1.1973095378961089e+00 2.3524290511459478e+00 + 24 5.7143336751982488e-01 8.7715571174154605e-01 9.9432218349388102e-01 + 25 -2.4703347062300032e-01 -1.2710986429222224e-01 -1.5749033311971992e-02 + 26 -9.3451713960198701e-01 -2.7778133649821901e-01 6.6713867661147919e-01 + 27 4.9808843860149610e-01 -5.8536464204160887e-01 1.6301914265685915e+00 + 28 -8.2771277475903027e-01 2.1570720428840873e-01 3.2880151472957344e+00 + 29 -1.6048620343875755e+00 3.8486480806372897e-01 5.6967398899129529e-01 + 30 -1.1973961350199096e+00 5.1593120685595580e-02 4.1293831832017062e-02 + 31 -8.4115448475027121e-01 -4.4444260925279200e-01 -3.3858426829044269e-01 + 32 -1.8597577591090164e+00 1.2810085646854485e-02 1.1797889462030640e+00 + 33 2.1159519472471811e+00 -7.8729199670032701e-01 2.9290939088097181e+00 + 34 -7.4188497270023746e-01 1.5645497560825464e-01 6.6033973957472436e-01 + 35 4.8203360935099837e-01 -5.2533146218590032e-01 6.5589135580856639e-01 + 36 9.4037223416537397e-01 -7.6094150822319195e-01 4.5734538655438040e-01 + 37 -6.9906373360474205e-01 1.5746536313295925e+00 -1.7263112595330459e+00 + 38 8.5615988284237132e-01 -2.2431722964535125e-01 -8.0332888328255958e-01 + 39 7.8065137836247200e-01 -1.3983715176027893e+00 -3.6344006191116991e+00 + 40 1.5756754145077525e+00 -1.9548680562354619e+00 2.4171639489710248e-01 + 41 1.7946227297557377e-01 4.1626928569421628e-01 -1.0542445180049111e+00 + 42 -2.5855819286639807e+00 -2.3809591696792194e+00 -7.5444018878363772e-01 + 43 -1.5651979567151933e-01 -3.7133196766462597e+00 -2.3417783002479109e-01 + 44 2.6088788324017109e+00 -2.0370826629544276e+00 -1.7748087222007777e-01 + 45 9.0750981150111454e-01 3.1320571808181447e-01 -1.3570279945304848e+00 + 46 -1.2844641842483453e+00 -1.8271514736854049e+00 2.7652384797305016e+00 + 47 5.2355177969578193e-01 9.5756521123463834e-02 1.3725765177085687e+00 + 48 8.7731662768264451e-01 1.0414860079651591e+00 -9.0032888888892382e-01 + 49 1.4644557239036082e-01 -3.3233388609839873e+00 -2.4250592659007468e+00 + 50 1.3159886335597091e+00 1.1534831728413786e+00 -7.9023436269654135e-02 + 51 1.5810961991408728e-01 3.6227053406802825e+00 2.1622129324293375e+00 + 52 3.5238822669377128e+00 -2.4112486219526210e+00 4.1691651240037055e+00 + 53 4.6279178075715538e-01 1.5349821135997805e+00 1.3624008261786760e+00 + 54 7.0473247201702627e-01 -9.3593778743269240e-01 -7.0089892988315006e-01 + 55 1.1161312397801737e+00 -2.3385526086116117e+00 -7.5151515336312336e-01 + 56 7.6996392118239054e-01 5.3225925152027631e-01 -1.0367667800909899e+00 + 57 1.1705705890031866e+00 1.9234764366836088e-01 -3.8394944778612211e-01 + 58 1.3292217712869172e+00 -2.6420177775466325e-01 -9.5699172084102668e-01 + 59 2.1842122534627268e+00 2.6220494593377625e-01 5.4393643560229021e-01 + 60 -1.1457317620961742e+00 -4.1194027577964150e+00 -3.1920012226137322e+00 + 61 7.5501968427331045e-01 1.4824037577796831e+00 -2.0845605296052469e-01 + 62 -2.1181153169676303e+00 9.6226604332888710e-01 -5.7042120154066434e-01 + 63 2.2161829432347631e+00 -7.0548049758710407e-01 -1.3062673143062038e+00 + 64 2.1263589729936818e+00 1.8281740261598369e+00 5.2543331430537403e+00 +... diff --git a/unittest/force-styles/tests/mol-pair-dpd_coul_slater_long.yaml b/unittest/force-styles/tests/mol-pair-dpd_coul_slater_long.yaml new file mode 100644 index 0000000000..e75defbf16 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-dpd_coul_slater_long.yaml @@ -0,0 +1,103 @@ +--- +lammps_version: 17 Apr 2024 +tags: +date_generated: Tue Jun 18 21:32:14 2024 +epsilon: 5e-13 +skip_tests: gpu intel kokkos_omp single +prerequisites: ! | + atom full + pair dpd/coul/slater/long + kspace ewald +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + comm_modify vel yes +post_commands: ! | + kspace_style ewald 1.0e-6 + kspace_modify gewald 0.3 + kspace_modify compute no +input_file: in.fourmol +pair_style: dpd/coul/slater/long 100.0 8.0 11223344 1.0 8.0 +pair_coeff: ! | + * * 0.4 4.0 yes + 1 1 0.4 4.0 yes + 2 2 0.1 2.0 no + 2 4 0.1 1.0 + 3 3 0.4 3.2 yes + 4 4 0.3 3.1 yes + 5 5 0.3 3.1 yes +extract: ! | + cut_coul 0 + lamda 0 + a0 2 + gamma 2 +natoms: 29 +init_vdwl: 50.81607024833933 +init_coul: 246.30486150616926 +init_stress: ! |2- + 3.8847917252197334e+01 6.0909421169945198e+01 1.3177337627459440e+01 -2.5125674673037557e-01 -2.6831071031318483e+01 -1.5576430133730318e+01 +init_forces: ! |2 + 1 1.7431218673076398e+00 -3.3508607597652662e-01 -2.4777022847678101e+00 + 2 4.3303449895107429e+00 -4.7270196423904629e+00 8.9179383719117788e-01 + 3 -3.0026241136767506e-01 1.4898682537669559e+00 -2.9373470062765152e+00 + 4 5.2673340332969785e+00 -4.7092409943919726e+00 -1.4235077704192447e+00 + 5 -6.8022719083087080e-01 5.7354131392205714e+00 -3.4748110565769061e+00 + 6 -3.8215670358728731e+00 2.7445299161598462e+00 -2.7043379570240411e+00 + 7 -3.3428118289029851e+00 2.6368994495618775e-01 4.1564102694578011e+00 + 8 -7.7861329310896457e+00 8.2082649420572917e-01 4.8567883896169803e+00 + 9 3.1057899939121918e+00 -3.9223414133714560e+00 8.4873882988538636e+00 + 10 -4.1521241974355734e+00 2.6307631121111197e-01 3.4593985187994503e+00 + 11 1.8308032335061764e+00 2.2688626790466668e+00 2.1488881927591183e-01 + 12 -3.8361154861853802e-01 9.7381188622448867e-01 -2.9002001998530074e+00 + 13 3.7110360694271507e+00 -6.0293319508894081e+00 -3.2353735026836565e+00 + 14 -7.1298424060686427e-01 2.4558730338472174e+00 -1.4114476204389881e+00 + 15 6.4421713828496296e-01 2.6560445474171779e+00 4.1805189129601663e+00 + 16 2.4609814411173456e+00 1.0005691236622609e+00 -1.3310794681660751e+00 + 17 4.3419008357709892e+00 3.5242769399360668e-01 -3.0595452598808506e+00 + 18 -8.6307586369950978e-02 8.2040370677288337e+00 -5.3929118878835798e+00 + 19 6.1879926571299937e-01 2.5540397129551908e+00 1.5642703712618800e+00 + 20 -3.0582098014826045e+00 -4.2726657137759743e+00 3.7804333126216734e+00 + 21 3.4138725239637657e+00 -2.8998556794986174e+00 -3.3216284249543198e+00 + 22 8.3753401659388671e-01 6.0848461632864803e-01 5.5206263511303710e-01 + 23 1.6137939864950199e+00 -1.9075657957633927e+00 -1.1740851854919403e+00 + 24 -9.2620994683392499e-01 -3.2450229700911435e+00 -8.0867271168075465e+00 + 25 -1.3940090389654722e+00 5.2843663545938764e+00 3.5772359574449069e+00 + 26 3.9218467465706744e-02 1.1015801783435457e+00 1.8824821245496248e+00 + 27 -2.4611420161719555e+00 -1.9453626284928394e+00 -3.3205056628962853e-01 + 28 1.4062959703817013e+00 -1.5914533664642678e+00 2.6909036096293515e+00 + 29 -6.2594440581983282e+00 -3.1925547225558533e+00 2.9681802507382837e+00 +run_vdwl: 50.80969849155796 +run_coul: 246.30257595743123 +run_stress: ! |2- + 2.5169432057277767e+01 1.3291837479686518e+02 7.8314082956801457e+01 1.4188397409481186e+00 4.7717966551748061e+00 -6.3215212489343497e-01 +run_forces: ! |2 + 1 -6.3863580151106092e-01 6.6929475226486339e+00 3.7704563748664892e+00 + 2 -4.3037556793948211e+00 9.5723509028532272e-02 -2.0030241717125286e+00 + 3 -1.2783833512172147e+00 1.7381921345191331e+00 -6.4662583653508925e+00 + 4 2.4827815076802873e+00 1.3730024199636431e-01 -2.0006851631917272e-01 + 5 4.7603332815631365e+00 -2.2528146831857900e+00 -3.4274535000597357e+00 + 6 -1.2817868583433294e+00 -5.9968609698691075e+00 -3.2762169423954415e+00 + 7 -6.6867815106826880e+00 -7.6943923258643654e-01 -2.6780134761760793e-01 + 8 -3.3343023480304996e+00 6.4339698400391008e+00 -6.4172530505932164e+00 + 9 -3.8353029345585190e+00 9.8394636146294001e+00 1.9174283216744969e+00 + 10 -2.7100348949081012e+00 1.4548533898989857e-01 -7.4888242419930628e-01 + 11 -3.5716272980494614e+00 -5.6333424874513238e-01 -1.7669409895579073e+00 + 12 8.7749889216756269e+00 -3.0182112894280873e+00 2.3328096163511405e+00 + 13 -7.1201394227081138e+00 8.5405234502858711e+00 4.5843737570467056e+00 + 14 -8.7413969567458588e-02 -3.7153733247848848e+00 -3.2874441379609167e+00 + 15 4.3120572612995609e+00 1.7256832039357071e+00 3.3428599179267393e-01 + 16 3.8021838909677803e+00 -1.3766365519719326e+01 2.2813835507927651e+00 + 17 4.9734505785815566e+00 -2.4146919042613795e+00 1.8287742974940246e+00 + 18 -1.7572559387593672e-03 3.8187261679342619e+00 -1.0584087358440382e+00 + 19 1.0838708527692988e+00 -6.6703633150528441e-01 -4.6973954164255893e-01 + 20 1.1923743451913014e+00 1.7419734493475330e+00 -3.6369159702300224e-01 + 21 2.3316248125417141e+00 -1.0849270685777668e+00 -3.2073997386907678e+00 + 22 2.6135216134985972e+00 -1.1025272637629011e+00 4.8873485142461329e-02 + 23 -1.2854577922712009e+00 -2.9253148869589518e+00 -4.6563146954583601e-01 + 24 -1.4021980080098731e-01 1.9672435672875048e+00 3.1379645935988041e+00 + 25 1.9085702323304496e+00 5.2270676739892066e+00 7.3556254244703823e+00 + 26 8.7357677171207004e-01 -1.1308292622526788e+00 -8.0741590972110988e-01 + 27 -1.1543680887940906e+00 -9.4513879574846338e-01 1.0062759048570287e+00 + 28 2.3730888896530073e+00 -1.9664779055036602e-01 1.0051483653476245e+00 + 29 -4.0524559526880868e+00 -7.5547871426945932e+00 4.6302307547994435e+00 +... diff --git a/unittest/force-styles/tests/mol-pair-hybrid_molecular.yaml b/unittest/force-styles/tests/mol-pair-hybrid_molecular.yaml new file mode 100644 index 0000000000..6bdf3b679d --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-hybrid_molecular.yaml @@ -0,0 +1,100 @@ +--- +lammps_version: 17 Apr 2024 +tags: +date_generated: Sun Jun 9 11:41:13 2024 +epsilon: 1e-13 +skip_tests: +prerequisites: ! | + atom full + pair lj/cut + pair hybrid/molecular +pre_commands: ! "" +post_commands: ! | + pair_modify mix arithmetic + pair_modify shift yes +input_file: in.fourmol +pair_style: hybrid/molecular lj/cut 8.0 lj/cut 8.0 +pair_coeff: ! | + 1 1 lj/cut 1 0.02 2.5 + 2 2 lj/cut 1 0.005 1.0 + 2 4 lj/cut 1 0.005 0.5 + 3 3 lj/cut 1 0.02 3.2 + 4 4 lj/cut 1 0.015 3.1 + 5 5 lj/cut 1 0.015 3.1 + 1 1 lj/cut 2 0.02 2.5 + 2 2 lj/cut 2 0.005 1.0 + 2 4 lj/cut 2 0.005 0.5 + 3 3 lj/cut 2 0.02 3.2 + 4 4 lj/cut 2 0.015 3.1 + 5 5 lj/cut 2 0.015 3.1 +extract: ! "" +natoms: 29 +init_vdwl: 749.2470096189497 +init_coul: 0 +init_stress: ! |2- + 2.1793857186503237e+03 2.1988957679770601e+03 4.6653994738862348e+03 -7.5956544622684351e+02 2.4751393539193327e+01 6.6652061873806679e+02 +init_forces: ! |2 + 1 -2.3333390274530565e+01 2.6994567613591136e+02 3.3272827850621587e+02 + 2 1.5828554630423909e+02 1.3025008843536872e+02 -1.8629682358915150e+02 + 3 -1.3528903744071786e+02 -3.8704313350789641e+02 -1.4568978426110147e+02 + 4 -7.8711096705734178e+00 2.1350518625352004e+00 -5.5954532185292400e+00 + 5 -2.5176757267276137e+00 -4.0521510680612876e+00 1.2152704057983799e+01 + 6 -8.3190665562047559e+02 9.6394165349388811e+02 1.1509101492424440e+03 + 7 5.8203416066164465e+01 -3.3609013622052356e+02 -1.7179626006587687e+03 + 8 1.4451392646293456e+02 -1.0927476052490437e+02 3.9990594285329479e+02 + 9 7.9156945283109025e+01 8.5273009784086469e+01 3.5032175698457496e+02 + 10 5.3118875219106917e+02 -6.1040990846582008e+02 -1.8355872692632028e+02 + 11 -2.3530157265571860e+00 -5.9077640075588906e+00 -9.6590723956614433e+00 + 12 1.7527155197359406e+01 1.0633119514682473e+01 -7.9254397903886158e+00 + 13 8.0986409580712841e+00 -3.2098088269317300e+00 -1.4896399871387667e-01 + 14 -3.3852721291218524e+00 6.8636181224987947e-01 -8.7507190862837803e+00 + 15 -2.0454999188607306e-01 8.4846165523012136e+00 3.0131615419840623e+00 + 16 4.6326331471561195e+02 -3.3087730492363477e+02 -1.1893030175606582e+03 + 17 -4.5334322060634048e+02 3.1554297967975305e+02 1.2058423415744451e+03 + 18 -1.8862629870158503e-02 -3.3402022492930034e-02 3.1000492146377390e-02 + 19 3.1843079948447594e-04 -2.3918628211596124e-04 1.7427252652160224e-03 + 20 -9.9760831169755002e-04 -1.0209184785886856e-03 3.6910973051849135e-04 + 21 -7.1566158640374354e+01 -8.1615716383825756e+01 2.2589571940670788e+02 + 22 -1.0808840769631149e+02 -2.6193799449067580e+01 -1.6957912849816358e+02 + 23 1.7964463850759611e+02 1.0782102722442450e+02 -5.6305812731665995e+01 + 24 3.6591423637378952e+01 -2.1181597497621908e+02 1.1218307103182993e+02 + 25 -1.4851496072162067e+02 2.3907129270267117e+01 -1.2485640694398953e+02 + 26 1.1191134671510581e+02 1.8789783424990625e+02 1.2650143102803206e+01 + 27 5.1810412832328005e+01 -2.2705468907750404e+02 9.0849153441059272e+01 + 28 -1.8041315533250560e+02 7.7534079082878250e+01 -1.2206962452216493e+02 + 29 1.2861063251415737e+02 1.4952718246094852e+02 3.1216040111076957e+01 +run_vdwl: 719.4532389988315 +run_coul: 0 +run_stress: ! |2- + 2.1330157554553725e+03 2.1547730555430494e+03 4.3976512412988704e+03 -7.3873325485023713e+02 4.1743707190785464e+01 6.2788040986774649e+02 +run_forces: ! |2 + 1 -2.0299419744961813e+01 2.6686193379336868e+02 3.2358785871037435e+02 + 2 1.5298617928501707e+02 1.2596516341411086e+02 -1.7961292655320207e+02 + 3 -1.3353630670276331e+02 -3.7923748676909099e+02 -1.4291839777232488e+02 + 4 -7.8374717836014449e+00 2.1276610789788282e+00 -5.5845014473593917e+00 + 5 -2.5014258629959465e+00 -4.0250131424457543e+00 1.2103512372172734e+01 + 6 -8.0681466162480240e+02 9.2165651041424792e+02 1.0270802401119468e+03 + 7 5.5780302775854636e+01 -3.1117544157318952e+02 -1.5746997989226002e+03 + 8 1.3452983973683914e+02 -1.0064660034658647e+02 3.8851792520911863e+02 + 9 7.6746213900459239e+01 8.2501469902247337e+01 3.3944351209160595e+02 + 10 5.2128033526109800e+02 -5.9920098832868109e+02 -1.8126029871233905e+02 + 11 -2.3573118088794365e+00 -5.8616944553482799e+00 -9.6049808813641686e+00 + 12 1.7503975897697526e+01 1.0626930302269722e+01 -8.0603160114673926e+00 + 13 8.0530313324242382e+00 -3.1756495175042607e+00 -1.4618315691984204e-01 + 14 -3.3416065166863160e+00 6.6492606318663194e-01 -8.6345131440736740e+00 + 15 -2.2253843262483208e-01 8.5025661635305205e+00 3.0369735873547175e+00 + 16 4.3476329769010198e+02 -3.1171099668258080e+02 -1.1135222104230593e+03 + 17 -4.2469864617016134e+02 2.9615424659116553e+02 1.1302578406458213e+03 + 18 -1.8849988250623853e-02 -3.3371648038832503e-02 3.0986306282264790e-02 + 19 3.0940278115793517e-04 -2.4634536779368854e-04 1.7433360016754921e-03 + 20 -9.8648131231171901e-04 -1.0112587092668940e-03 3.6932949186791977e-04 + 21 -7.0490777148272102e+01 -7.9749189729874402e+01 2.2171013458550721e+02 + 22 -1.0638722739944252e+02 -2.5949513934649758e+01 -1.6645597092015180e+02 + 23 1.7686805727889882e+02 1.0571023691370021e+02 -5.5243362166860535e+01 + 24 3.8206035227327128e+01 -2.1022829679057401e+02 1.1260716393332925e+02 + 25 -1.4918888258035886e+02 2.3762162241718102e+01 -1.2549193847418989e+02 + 26 1.1097064525776705e+02 1.8645512086371158e+02 1.2861565481437628e+01 + 27 5.0800867695850577e+01 -2.2296598219372004e+02 8.8607407764830413e+01 + 28 -1.7694198509380672e+02 7.6029979926844575e+01 -1.1950523558040683e+02 + 29 1.2614900659680345e+02 1.4694257504728049e+02 3.0893400701043564e+01 +... diff --git a/unittest/force-styles/tests/mol-pair-hybrid_molecular_lj_morse.yaml b/unittest/force-styles/tests/mol-pair-hybrid_molecular_lj_morse.yaml new file mode 100644 index 0000000000..17fb89dc4f --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-hybrid_molecular_lj_morse.yaml @@ -0,0 +1,119 @@ +--- +lammps_version: 17 Apr 2024 +tags: +date_generated: Sun Jun 9 11:41:13 2024 +epsilon: 1e-13 +skip_tests: +prerequisites: ! | + atom full + pair lj/cut + pair morse + pair hybrid/molecular +pre_commands: ! "" +post_commands: ! | + pair_modify mix arithmetic + pair_modify shift yes +input_file: in.fourmol +pair_style: hybrid/molecular lj/cut 8.0 morse 8.0 +pair_coeff: ! | + 1 1 lj/cut 0.02 2.5 + 1 2 lj/cut 0.01 1.75 + 1 3 lj/cut 0.02 2.85 + 1 4 lj/cut 0.01732050807568877293 2.8 + 1 5 lj/cut 0.01732050807568877293 2.8 + 2 2 lj/cut 0.005 1.0 + 2 3 lj/cut 0.01 2.1 + 2 4 lj/cut 0.005 0.5 + 2 5 lj/cut 0.00866025403784438646 2.05 + 3 3 lj/cut 0.02 3.2 + 3 4 lj/cut 0.01732050807568877293 3.15 + 3 5 lj/cut 0.01732050807568877293 3.15 + 4 4 lj/cut 0.015 3.1 + 4 5 lj/cut 0.015 3.1 + 5 5 lj/cut 0.015 3.1 + 1 1 morse 0.0202798941614106 2.78203488021395 2.725417159299 + 1 2 morse 0.0101167811264648 3.9793050302425 1.90749569018897 + 1 3 morse 0.0202934330695928 2.43948720203264 3.10711749999622 + 1 4 morse 0.0175731334238374 2.48316585521317 3.05258880102438 + 1 5 morse 0.0175731334238374 2.48316585521317 3.05258880102438 + 2 2 morse 0.00503064360487288 6.98433077606902 1.08960295117864 + 2 3 morse 0.0101296013842819 3.31380153807866 2.28919067558352 + 2 4 morse 0.00497405122588691 14.0508902925745 0.544416409093563 + 2 5 morse 0.00877114211614446 3.39491256196178 2.23466262511073 + 3 3 morse 0.0203039874239943 2.17204344301477 3.48881895084762 + 3 4 morse 0.0175825321440736 2.20660439192238 3.43428999287994 + 3 5 morse 0.0175825321440736 2.20660439192238 3.43428999287994 + 4 4 morse 0.0152259201379927 2.24227873774009 3.37976131582396 + 4 5 morse 0.0152259201379927 2.24227873774009 3.37976131582396 + 5 5 morse 0.0152259201379927 2.24227873774009 3.37976131582396 +extract: ! "" +natoms: 29 +init_vdwl: 642.2857035487534 +init_coul: 0 +init_stress: ! |2- + 1.5446101412530770e+03 1.7762864877230827e+03 4.3406629723991382e+03 -2.4168966825090698e+02 -4.2399281241000449e+02 1.0313398732648857e+03 +init_forces: ! |2 + 1 -2.3337658999820331e+01 2.6994849929388920e+02 3.3272731927204762e+02 + 2 1.5828475525620013e+02 1.3025198646645657e+02 -1.8629727921784635e+02 + 3 -1.3530883593401191e+02 -3.8702990176780906e+02 -1.4568955729804821e+02 + 4 -7.8720974048138279e+00 2.1357285334450031e+00 -5.5956697614574145e+00 + 5 -2.5179872246085657e+00 -4.0521698308193113e+00 1.2152426584580066e+01 + 6 -1.0627539753780246e+02 3.7096636535889553e+02 1.6577829288882351e+03 + 7 6.2545311732649182e+01 -3.3857732069504033e+02 -1.7085638850072914e+03 + 8 -5.8544805218664203e+02 4.8619364551174579e+02 -1.1637016110669298e+02 + 9 7.9157108381891348e+01 8.5271268694585373e+01 3.5031950365280102e+02 + 10 5.3119792393751504e+02 -6.1042010285634149e+02 -1.8355328074325874e+02 + 11 -2.3525975498215241e+00 -5.9087312467830966e+00 -9.6592450379633981e+00 + 12 1.7514418718210869e+01 1.0633490551535797e+01 -7.9269392455530774e+00 + 13 8.0989976759274995e+00 -3.2092537736156967e+00 -1.4857368826935238e-01 + 14 -3.3831155658252769e+00 6.8583230320825528e-01 -8.7521044176224088e+00 + 15 -2.0078689909299524e-01 8.4842702953333049e+00 3.0127255727602438e+00 + 16 4.6326713730462569e+02 -3.3088113342819690e+02 -1.1892994362776039e+03 + 17 -4.5333858978430715e+02 3.1553830929611308e+02 1.2058459850635415e+03 + 18 -2.0452760511035117e-02 -3.1643654311568722e-02 2.7038063904994043e-02 + 19 6.7683676563436612e-04 5.5257878746558435e-04 3.4368881128008698e-04 + 20 -7.2687428125721442e-04 -6.4369255876917293e-04 -7.3055429537143658e-05 + 21 -7.1559739956792001e+01 -8.1623086552077027e+01 2.2588907386171752e+02 + 22 -1.0808827580116072e+02 -2.6193999003846525e+01 -1.6957935616989226e+02 + 23 1.7964485683675787e+02 1.0782085824265097e+02 -5.6306005220676077e+01 + 24 3.6592705490564995e+01 -2.1181065162415683e+02 1.1218892889291895e+02 + 25 -1.4851386780240065e+02 2.3908077402265249e+01 -1.2485428291933182e+02 + 26 1.1191162087301427e+02 1.8789805761651786e+02 1.2650515090480996e+01 + 27 5.1805674347396028e+01 -2.2705907095144718e+02 9.0852216146745278e+01 + 28 -1.8041330407833553e+02 7.7533936594765862e+01 -1.2206953762508090e+02 + 29 1.2861029896870866e+02 1.4952683033680830e+02 3.1216382013473979e+01 +run_vdwl: 612.532027437114 +run_coul: 0 +run_stress: ! |2- + 1.5079612443981077e+03 1.7300922919292559e+03 4.0645404509935297e+03 -2.2501656863720930e+02 -3.8440649220519191e+02 9.6872117407090468e+02 +run_forces: ! |2 + 1 -2.0303664163328520e+01 2.6686344032747223e+02 3.2358595259116754e+02 + 2 1.5298537986232245e+02 1.2596704781215615e+02 -1.7961336269199933e+02 + 3 -1.3340899705451542e+02 -3.7937983996408559e+02 -1.4304731523709151e+02 + 4 -7.8384621494638589e+00 2.1283385602122546e+00 -5.5847156581558837e+00 + 5 -2.5017213737297879e+00 -4.0250398342732856e+00 1.2103221315331954e+01 + 6 -1.0069389067343234e+02 3.4070704568948952e+02 1.4995989516904360e+03 + 7 5.6637967265264535e+01 -3.0800622792471370e+02 -1.5506690902144287e+03 + 8 -5.6211472712331181e+02 4.6807109251305587e+02 -1.0712697415342610e+02 + 9 7.6069407842570087e+01 8.0619386602314336e+01 3.3418245682682038e+02 + 10 5.1153094792744940e+02 -5.8811350830044319e+02 -1.7678443640175220e+02 + 11 -2.3568347685072353e+00 -5.8621926046697821e+00 -9.6044928327397194e+00 + 12 1.7464493846680174e+01 1.0623724119993449e+01 -8.0428896399820058e+00 + 13 8.0533880511151636e+00 -3.1750913604087598e+00 -1.4579751155151741e-01 + 14 -3.3394709175794697e+00 6.6440083564233665e-01 -8.6358918170724337e+00 + 15 -2.1889102849274136e-01 8.5021207266300767e+00 3.0365920030191385e+00 + 16 4.3476429812120438e+02 -3.1171100998816553e+02 -1.1135203700101538e+03 + 17 -4.2469867717957146e+02 2.9615706504039451e+02 1.1302529422580635e+03 + 18 -2.0438484585882859e-02 -3.1629705308846789e-02 2.7018991453856001e-02 + 19 6.6852492737214141e-04 5.4625495751892833e-04 3.4152455215868423e-04 + 20 -7.1620896561888831e-04 -6.3500663583982407e-04 -7.1700429767679216e-05 + 21 -7.0484355349417541e+01 -7.9756579011007801e+01 2.2170349595393003e+02 + 22 -1.0638710558378827e+02 -2.5949713015442118e+01 -1.6645620880910886e+02 + 23 1.7686828769914484e+02 1.0571007956441812e+02 -5.5243556600722584e+01 + 24 3.8207315780355771e+01 -2.1022299522635379e+02 1.1261302962088173e+02 + 25 -1.4918780612527124e+02 2.3763111781582175e+01 -1.2548982817638399e+02 + 26 1.1097093258138914e+02 1.8645536456663984e+02 1.2861936841695268e+01 + 27 5.0796145560529055e+01 -2.2297034959629724e+02 8.8610475497234873e+01 + 28 -1.7694213444502824e+02 7.6029840540845129e+01 -1.1950515191029582e+02 + 29 1.2614865956603674e+02 1.4694220660200173e+02 3.0893738250707873e+01 +... diff --git a/unittest/python/python-commands.py b/unittest/python/python-commands.py index f11ac11da9..3a222dde5a 100644 --- a/unittest/python/python-commands.py +++ b/unittest/python/python-commands.py @@ -580,6 +580,37 @@ create_atoms 1 single & "Press" : 0.0} self.assertDictEqual(self.lmp.last_thermo(), ref) + def test_extract_setting(self): + self.assertEqual(self.lmp.extract_setting("dimension"), 3) + self.assertEqual(self.lmp.extract_setting("box_exist"), 0) + self.assertEqual(self.lmp.extract_setting("kokkos_active"), 0) + self.assertEqual(self.lmp.extract_setting("kokkos_nthreads"), 0) + self.assertEqual(self.lmp.extract_setting("kokkos_ngpus"), 0) + self.lmp.command("region box block -1 1 -2 2 -3 3") + self.lmp.command("create_box 1 box") + self.lmp.command("special_bonds lj 0.0 0.5 0.8 coul 0.1 0.5 1.0") + self.assertEqual(self.lmp.extract_setting("newton_bond"), 1) + self.assertEqual(self.lmp.extract_setting("newton_pair"), 1) + self.assertEqual(self.lmp.extract_setting("triclinic"), 0) + self.assertEqual(self.lmp.extract_setting("universe_rank"), 0) + self.assertEqual(self.lmp.extract_setting("universe_size"), 1) + self.assertEqual(self.lmp.extract_setting("world_rank"), 0) + self.assertEqual(self.lmp.extract_setting("world_size"), 1) + self.assertEqual(self.lmp.extract_setting("triclinic"), 0) + self.assertEqual(self.lmp.extract_setting("comm_style"), 0) + self.assertEqual(self.lmp.extract_setting("comm_layout"), 0) + self.assertEqual(self.lmp.extract_setting("comm_mode"), 0) + self.assertEqual(self.lmp.extract_setting("ghost_velocity"), 0) + self.lmp.command("comm_style tiled") + self.lmp.command("comm_modify vel yes") + self.lmp.command("mass 1 1.0") + self.lmp.command("run 0 post no") + self.lmp.command("balance 0.1 rcb") + self.assertEqual(self.lmp.extract_setting("comm_style"), 1) + self.assertEqual(self.lmp.extract_setting("comm_layout"), 2) + self.assertEqual(self.lmp.extract_setting("comm_mode"), 0) + self.assertEqual(self.lmp.extract_setting("ghost_velocity"), 1) + def test_extract_global(self): self.lmp.command("region box block -1 1 -2 2 -3 3") self.lmp.command("create_box 1 box") @@ -628,6 +659,13 @@ create_atoms 1 single & self.assertEqual(self.lmp.extract_global("sublo_lambda"), [0.0, 0.0, 0.0]) self.assertEqual(self.lmp.extract_global("subhi_lambda"), [1.0, 1.0, 1.0]) + # processor grid + self.assertEqual(self.lmp.extract_global("procgrid"), [1,1,1]) + self.lmp.command("comm_style tiled") + self.lmp.command("run 0 post no") + self.lmp.command("balance 0.1 rcb") + self.assertEqual(self.lmp.extract_global("procgrid"), None) + def test_create_atoms(self): self.lmp.command("boundary f p m") self.lmp.command("region box block 0 10 0 10 0 10") diff --git a/unittest/python/python-pylammps.py b/unittest/python/python-pylammps.py index 9e691b1b8c..3a7f0dc9cf 100644 --- a/unittest/python/python-pylammps.py +++ b/unittest/python/python-pylammps.py @@ -119,6 +119,10 @@ class PythonPyLammps(unittest.TestCase): self.assertEqual(self.pylmp.communication.comm_style,'brick') self.assertEqual(self.pylmp.communication.comm_layout,'uniform') self.assertEqual(self.pylmp.communication.nprocs,1) + self.assertEqual(self.pylmp.communication.nthreads,1) + self.assertEqual(self.pylmp.communication.procgrid,[1,1,1]) + self.assertEqual(self.pylmp.communication.proc_grid,[1,1,1]) + self.assertEqual(self.pylmp.communication.ghost_velocity,0) self.assertEqual(len(self.pylmp.computes),3) self.assertEqual(self.pylmp.computes[0]['name'], 'thermo_temp') self.assertEqual(self.pylmp.computes[0]['style'], 'temp') @@ -137,6 +141,11 @@ class PythonPyLammps(unittest.TestCase): self.assertEqual(self.pylmp.fixes[0]['group'], 'all') self.pylmp.group('none','empty') self.assertEqual(len(self.pylmp.groups),2) + self.pylmp.comm_style('tiled') + self.pylmp.mass('*',1.0) + self.pylmp.run('0','post','no') + self.pylmp.balance(0.1,'rcb') + self.assertEqual(self.pylmp.communication.procgrid,None) if __name__ == "__main__": unittest.main()