From d8ba3927171f81389356d30ef8c55f2991a4d4d8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 00:08:50 -0400 Subject: [PATCH 001/120] the TOUCH keyword requires CMake version 3.24 or later --- cmake/Modules/ExternalCMakeProject.cmake | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/Modules/ExternalCMakeProject.cmake b/cmake/Modules/ExternalCMakeProject.cmake index d7a3daf267f..1991e5bbf5e 100644 --- a/cmake/Modules/ExternalCMakeProject.cmake +++ b/cmake/Modules/ExternalCMakeProject.cmake @@ -36,8 +36,13 @@ function(ExternalCMakeProject target url hash basedir cmakedir cmakefile) # to a new archive version, compiled objects in an existing build directory appear # newer than the updated headers and are not recompiled, which leads to failed # links or subtly inconsistent binaries. - file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/_deps/${archive} - DESTINATION ${CMAKE_BINARY_DIR}/_deps/src TOUCH) + if(CMAKE_VERSION VERSION_LESS 3.24) + file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/_deps/${archive} + DESTINATION ${CMAKE_BINARY_DIR}/_deps/src) + else() + file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/_deps/${archive} + DESTINATION ${CMAKE_BINARY_DIR}/_deps/src TOUCH) + endif() file(GLOB TARGET_SOURCE "${CMAKE_BINARY_DIR}/_deps/src/${basedir}*") list(LENGTH TARGET_SOURCE _num) if(_num GREATER 1) From acdeab9d75838a140892abf362da77b9d4e36007 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 00:19:16 -0400 Subject: [PATCH 002/120] modernize --- src/ML-IAP/mliap_unified.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ML-IAP/mliap_unified.h b/src/ML-IAP/mliap_unified.h index 1ee8dfd60dc..3a271aca3fa 100644 --- a/src/ML-IAP/mliap_unified.h +++ b/src/ML-IAP/mliap_unified.h @@ -60,7 +60,7 @@ struct MLIAPBuildUnified_t { MLIAPDummyModel *model; }; -MLIAPBuildUnified_t build_unified(char *, MLIAPData *, LAMMPS *, char * = NULL); +MLIAPBuildUnified_t build_unified(char *, MLIAPData *, LAMMPS *, char * = nullptr); void update_pair_energy(MLIAPData *, double *); void update_pair_forces(MLIAPData *, double *); From 91bd3fcde3ee71aeb80885f98e130a86b7f318b1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 01:22:41 -0400 Subject: [PATCH 003/120] apply clang-format and use LAMMPS conventions for initializing pointers --- src/ML-PACE/pair_pace.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/ML-PACE/pair_pace.cpp b/src/ML-PACE/pair_pace.cpp index 067dcc1bf6d..6f419f25aa1 100644 --- a/src/ML-PACE/pair_pace.cpp +++ b/src/ML-PACE/pair_pace.cpp @@ -31,8 +31,8 @@ Copyright 2021 Yury Lysogorskiy^1, Cas van der Oord^2, Anton Bochkarev^1, #include "atom.h" #include "comm.h" #include "error.h" -#include "info.h" #include "force.h" +#include "info.h" #include "math_const.h" #include "memory.h" #include "neigh_list.h" @@ -82,7 +82,8 @@ static int AtomicNumberByName_pace(char *elname) } /* ---------------------------------------------------------------------- */ -PairPACE::PairPACE(LAMMPS *lmp) : Pair(lmp) +PairPACE::PairPACE(LAMMPS *lmp) : + Pair(lmp), aceimple(nullptr), corerep_factor(nullptr), scale(nullptr), { single_enable = 0; restartinfo = 0; @@ -91,14 +92,12 @@ PairPACE::PairPACE(LAMMPS *lmp) : Pair(lmp) nmax_corerep = 0; flag_corerep_factor = 0; - corerep_factor = nullptr; aceimpl = new ACEImpl; recursive = false; - scale = nullptr; - chunksize = 4096; + neigh_scratch_request = NEIGH_SCRATCH_AUTO; } /* ---------------------------------------------------------------------- @@ -128,8 +127,10 @@ void PairPACE::compute(int eflag, int vflag) double fij[3]; int *ilist, *jlist, *numneigh, **firstneigh; - if (copymode) ev_init(eflag, vflag, 0); - else ev_init(eflag, vflag, 1); + if (copymode) + ev_init(eflag, vflag, 0); + else + ev_init(eflag, vflag, 1); double **x = atom->x; double **f = atom->f; @@ -197,8 +198,7 @@ void PairPACE::compute(int eflag, int vflag) error->one(FLERR, e.what()); } - if (flag_corerep_factor) - corerep_factor[i] = 1 - aceimpl->ace->ace_fcut; + if (flag_corerep_factor) corerep_factor[i] = 1 - aceimpl->ace->ace_fcut; // 'compute_atom' will update the `aceimpl->ace->e_atom` and `aceimpl->ace->neighbours_forces(jj, alpha)` arrays @@ -282,15 +282,15 @@ void PairPACE::settings(int narg, char **arg) // KOKKOS-only: selects the team scratch memory level used to build the // short neighbor list. Parsed but ignored by this style, so that an // input written for pace/kk also runs without the KOKKOS package. - if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_style pace neigh", error); - if (strcmp(arg[iarg+1], "auto") == 0) + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "pair_style pace neigh", error); + if (strcmp(arg[iarg + 1], "auto") == 0) neigh_scratch_request = NEIGH_SCRATCH_AUTO; - else if (strcmp(arg[iarg+1], "shared") == 0) + else if (strcmp(arg[iarg + 1], "shared") == 0) neigh_scratch_request = NEIGH_SCRATCH_SHARED; - else if (strcmp(arg[iarg+1], "global") == 0) + else if (strcmp(arg[iarg + 1], "global") == 0) neigh_scratch_request = NEIGH_SCRATCH_GLOBAL; else - error->all(FLERR, "Unknown pair_style pace neigh keyword: {}", arg[iarg+1]); + error->all(FLERR, "Unknown pair_style pace neigh keyword: {}", arg[iarg + 1]); iarg += 2; } else error->all(FLERR, "Unknown pair_style pace keyword: {}", arg[iarg]); @@ -322,12 +322,12 @@ void PairPACE::coeff(int narg, char **arg) delete aceimpl->basis_set; if (comm->me == 0) utils::logmesg(lmp, "Loading {}\n", potential_file_name); // if potential is in ACEBBasisSet (YAML) format, then convert to ACECTildeBasisSet automatically - if (utils::strmatch(potential_file_name,".*\\.yaml$")) { + if (utils::strmatch(potential_file_name, ".*\\.yaml$")) { ACEBBasisSet bBasisSet = ACEBBasisSet(potential_file_name); ACECTildeBasisSet cTildeBasisSet = bBasisSet.to_ACECTildeBasisSet(); aceimpl->basis_set = new ACECTildeBasisSet(cTildeBasisSet); } else { - aceimpl->basis_set = new ACECTildeBasisSet(potential_file_name); + aceimpl->basis_set = new ACECTildeBasisSet(potential_file_name); } if (comm->me == 0) { @@ -449,6 +449,7 @@ void *PairPACE::extract_peratom(const char *str, int &ncol) double PairPACE::memory_usage() { double bytes = Pair::memory_usage(); - if (flag_corerep_factor) bytes += (double) nmax_corerep * sizeof(double); // corerep_factor[nmax_corerep] + if (flag_corerep_factor) + bytes += (double) nmax_corerep * sizeof(double); // corerep_factor[nmax_corerep] return bytes; } From f2363738c8578a2295695b339a465a962bc9b26c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 01:23:27 -0400 Subject: [PATCH 004/120] preferred dispatch not available on ubuntu 22.04LTS with GCC 11.x --- src/KOKKOS/pair_pace_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_pace_kokkos.cpp b/src/KOKKOS/pair_pace_kokkos.cpp index 3ed8d4ed838..fd45113f227 100644 --- a/src/KOKKOS/pair_pace_kokkos.cpp +++ b/src/KOKKOS/pair_pace_kokkos.cpp @@ -78,7 +78,7 @@ constexpr int PACE_BATCH_NRB_MAX = 64; // nradbase // compilers away from it. #if defined(__x86_64__) && defined(__gnu_linux__) && !defined(__AVX2__) && \ !defined(__CUDACC__) && !defined(__HIP_DEVICE_COMPILE__) && \ - defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) + (defined(__GNUC__) && (__GNUC__ > 11)) && !defined(__clang__) && !defined(__INTEL_COMPILER) #define PACE_VECTOR_CLONES __attribute__((target_clones("arch=x86-64-v3", "default"))) #else #define PACE_VECTOR_CLONES From 6007b421eb5cac4e35b052c5e2a35e7fd8439074 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 01:39:59 -0400 Subject: [PATCH 005/120] style registry: detect build-configuration guards wrapping whole style headers The generators for the style_*.cpp registration sources only parsed preprocessor directives inside the "#ifdef XXX_CLASS" marker block. A guard wrapping the entire header, like "#ifdef LAMMPS_ZSTD" in the zstd dump styles of the COMPRESS package, was invisible, so the styles were registered unconditionally and style_dump.cpp failed to compile when the package was enabled but libzstd was not available. Three other headers of this kind (snap/intel, netcdf, netcdf/mpiio) were handled through a hard-coded table duplicated in both generators. Both the CMake generator and the DEPEND/stylegen.c helper for the make build now collect the conditionals that are still open when the marker block starts and emit them around the #include and the registration calls of that header. The hard-coded tables are removed. --- cmake/Modules/StyleHeaderUtils.cmake | 76 +++++----- src/DEPEND/stylegen.c | 206 +++++++++++++++++---------- src/Make.sh | 4 +- 3 files changed, 176 insertions(+), 110 deletions(-) diff --git a/cmake/Modules/StyleHeaderUtils.cmake b/cmake/Modules/StyleHeaderUtils.cmake index 8bac8974937..5267176ce73 100644 --- a/cmake/Modules/StyleHeaderUtils.cmake +++ b/cmake/Modules/StyleHeaderUtils.cmake @@ -158,6 +158,22 @@ endfunction(GenerateStyleHeaders) # one_arg = TRUE selects the creator signature (LAMMPS*); FALSE selects # (LAMMPS*,int,char**). Generated files are accumulated in the global property # LAMMPS_STYLE_SOURCES for adding to the lammps target. +# +# Each header is walked with a small state machine: 0 = before the +# "#ifdef XXX_CLASS" marker block, 1 = inside it, 2 = after it. +# +# Some style headers wrap the *whole* file, marker block included, in one or +# more build-configuration guards (a compiler feature test or a library feature +# macro such as LAMMPS_ZSTD or LMP_HAS_NETCDF), so the class is only defined +# when that feature is available. Every conditional directive seen in state 0 +# is collected as such an outer guard and re-emitted around both the #include +# and the registration calls of that header, so a style whose class definition +# is compiled out is not registered either. (By LAMMPS convention the only +# conditionals allowed before the marker block are such guards; the include +# guard of the header lives inside the #else branch.) Inside the marker block +# (state 1) each XxxStyle(key,Class) marker becomes an explicit add_builtin() +# call and nested preprocessor directives are copied verbatim so +# build-config-dependent markers stay guarded. function(CreateStyleSource path property style macro base accessor regfunc one_arg includes) get_property(files GLOBAL PROPERTY ${property}) @@ -169,60 +185,45 @@ function(CreateStyleSource path property style macro base accessor regfunc one_a endforeach() list(SORT pairs) - # Some style headers wrap their class definition in a build-configuration - # guard (compiler or library feature macro) placed *outside* the - # "#ifdef XXX_CLASS" marker block, so the marker parser below cannot see it. - # Skip those headers during normal parsing and emit their #include and - # registration call by hand, wrapped in the same guard expression. - set(special_hdr "pair_snap_intel.h" "dump_netcdf.h" "dump_netcdf_mpiio.h") - set(special_guard "defined(__AVX512F__) && (defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER))" "defined(LMP_HAS_NETCDF)" "defined(LMP_HAS_PNETCDF)") - set(special_key "snap/intel" "netcdf" "netcdf/mpiio") - set(special_cls "PairSNAPIntel" "DumpNetCDF" "DumpNetCDFMPIIO") - set(include_block "") set(entry_block "") - set(present_specials "") foreach(entry ${pairs}) string(REGEX REPLACE "^[^|]*\\|" "" fname "${entry}") get_filename_component(bname ${fname} NAME) - list(FIND special_hdr "${bname}" spidx) - if(NOT spidx EQUAL -1) - list(APPEND present_specials ${spidx}) - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${fname}") - continue() - endif() - set(include_block "${include_block}#include \"${bname}\"\n") set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${fname}") - # walk the marker block (between "#ifdef XXX_CLASS" and the matching - # "#else"/"#endif"). Convert each XxxStyle(key,Class) marker into an - # explicit add_builtin() and copy any nested preprocessor directives - # verbatim so build-config-dependent markers stay guarded. file(STRINGS ${fname} all_lines) set(state 0) set(depth 0) + set(outer_guards "") + set(file_entries "") foreach(line IN LISTS all_lines) if(state EQUAL 0) if("${line}" MATCHES "^#ifdef[ \t]+[A-Z_]+_CLASS") set(state 1) set(depth 1) + elseif("${line}" MATCHES "^[ \t]*#[ \t]*if") + string(STRIP "${line}" dline) + list(APPEND outer_guards "${dline}") + elseif("${line}" MATCHES "^[ \t]*#[ \t]*endif") + list(POP_BACK outer_guards) endif() elseif(state EQUAL 1) if("${line}" MATCHES "^[ \t]*#[ \t]*if") math(EXPR depth "${depth} + 1") string(STRIP "${line}" dline) - set(entry_block "${entry_block}${dline}\n") + set(file_entries "${file_entries}${dline}\n") elseif("${line}" MATCHES "^[ \t]*#[ \t]*elif") if(depth GREATER 1) string(STRIP "${line}" dline) - set(entry_block "${entry_block}${dline}\n") + set(file_entries "${file_entries}${dline}\n") endif() elseif("${line}" MATCHES "^[ \t]*#[ \t]*else") if(depth EQUAL 1) set(state 2) else() string(STRIP "${line}" dline) - set(entry_block "${entry_block}${dline}\n") + set(file_entries "${file_entries}${dline}\n") endif() elseif("${line}" MATCHES "^[ \t]*#[ \t]*endif") math(EXPR depth "${depth} - 1") @@ -230,7 +231,7 @@ function(CreateStyleSource path property style macro base accessor regfunc one_a set(state 2) else() string(STRIP "${line}" dline) - set(entry_block "${entry_block}${dline}\n") + set(file_entries "${file_entries}${dline}\n") endif() elseif("${line}" MATCHES "${macro}\\(([^)]*)\\)") # the style keyword never contains a comma, so split on the @@ -244,21 +245,24 @@ function(CreateStyleSource path property style macro base accessor regfunc one_a string(SUBSTRING "${inner}" ${after} -1 cls) string(STRIP "${key}" key) string(STRIP "${cls}" cls) - set(entry_block "${entry_block} ${accessor}().add_builtin(\"${key}\", &creator<${cls}>);\n") + set(file_entries "${file_entries} ${accessor}().add_builtin(\"${key}\", &creator<${cls}>);\n") endif() endif() endif() endforeach() - endforeach() - # emit guarded #include + registration for the skipped special-case headers - foreach(spidx ${present_specials}) - list(GET special_hdr ${spidx} shdr) - list(GET special_guard ${spidx} sguard) - list(GET special_key ${spidx} skey) - list(GET special_cls ${spidx} scls) - set(include_block "${include_block}#if ${sguard}\n#include \"${shdr}\"\n#endif\n") - set(entry_block "${entry_block}#if ${sguard}\n ${accessor}().add_builtin(\"${skey}\", &creator<${scls}>);\n#endif\n") + # wrap the #include and the registration calls of this header in its + # outer build-configuration guards (usually none) + set(guard_open "") + set(guard_close "") + foreach(guard IN LISTS outer_guards) + set(guard_open "${guard_open}${guard}\n") + set(guard_close "${guard_close}#endif\n") + endforeach() + set(include_block "${include_block}${guard_open}#include \"${bname}\"\n${guard_close}") + if(NOT "${file_entries}" STREQUAL "") + set(entry_block "${entry_block}${guard_open}${file_entries}${guard_close}") + endif() endforeach() set(preamble "#include \"lammps.h\"\n#include \"creator_registry.h\"\n") diff --git a/src/DEPEND/stylegen.c b/src/DEPEND/stylegen.c index 7c6f21ed5ca..47c917b9775 100644 --- a/src/DEPEND/stylegen.c +++ b/src/DEPEND/stylegen.c @@ -41,7 +41,9 @@ * template (one-arg or three-arg signature), and a register function with * one add_builtin() call per parsed marker. Preprocessor directives * nested inside the marker block (e.g. "#ifdef LMP_KOKKOS_GPU") are copied - * through verbatim so build-config-dependent markers stay guarded. + * through verbatim so build-config-dependent markers stay guarded, and + * conditionals wrapping the whole header (e.g. "#ifdef LAMMPS_ZSTD") are + * re-emitted around its #include and registration calls. * * stylegen package -- file.h ... * Emit "package_styles().[\"key\"] = \"\";" lines, where the @@ -50,6 +52,7 @@ #include #include +#include #include #define MAXLINE 4096 @@ -118,27 +121,121 @@ static int starts_with(const char *s, const char *prefix) return strncmp(s, prefix, strlen(prefix)) == 0; } -/* print a directive line with leading whitespace removed and a single newline */ +/* copy a directive line into dst with leading whitespace and the trailing + * newline removed */ -static void emit_directive(const char *line) +static void strip_directive(char *dst, const char *line) { const char *p = line; size_t n; while ((*p == ' ') || (*p == '\t')) ++p; n = strlen(p); while ((n > 0) && ((p[n - 1] == '\n') || (p[n - 1] == '\r'))) --n; - printf("%.*s\n", (int) n, p); + memcpy(dst, p, n); + dst[n] = '\0'; +} + +/* print a directive line with leading whitespace removed and a single newline */ + +static void emit_directive(const char *line) +{ + char buf[MAXLINE]; + strip_directive(buf, line); + printf("%s\n", buf); +} + +/* Some style headers wrap the *whole* file, marker block included, in one or + * more build-configuration guards (a compiler feature test or a library feature + * macro such as LAMMPS_ZSTD or LMP_HAS_NETCDF), so the class is only defined + * when that feature is available. Those outer guards must be re-emitted + * around both the #include and the registration calls of the header, so a + * style whose class definition is compiled out is not registered either. (By + * LAMMPS convention the only conditionals allowed before the marker block are + * such guards; the include guard of the header lives inside the #else branch.) + * + * read_outer_guards() reads a header up to and including its "#ifdef + * XXX_CLASS" line and collects the conditional directives that are still open + * at that point into outer_guards[]. It returns their number, or -1 if the + * file has no marker block. On return the file is positioned on the first + * line inside the marker block. */ + +#define MAXGUARD 16 +static char outer_guards[MAXGUARD][MAXLINE]; + +static int read_outer_guards(FILE *fp, const char *path) +{ + char line[MAXLINE]; + int nguard = 0; + + while (fgets(line, sizeof(line), fp)) { + const char *kw; + if (is_class_ifdef(line)) return nguard; + kw = directive_kw(line); + if (!kw) continue; + if (starts_with(kw, "if")) { + if (nguard >= MAXGUARD) { + fprintf(stderr, "stylegen: too many nested conditionals before the style marker " + "block in %s\n", path); + exit(1); + } + strip_directive(outer_guards[nguard], line); + ++nguard; + } else if (starts_with(kw, "endif")) { + if (nguard > 0) --nguard; + } + } + return -1; +} + +/* print the outer guards once, the first time a registration line is emitted */ + +static void open_guards(int nguard, int *opened) +{ + int i; + if (*opened) return; + for (i = 0; i < nguard; ++i) printf("%s\n", outer_guards[i]); + *opened = 1; +} + +static void close_guards(int nguard) +{ + int i; + for (i = 0; i < nguard; ++i) printf("#endif\n"); +} + +/* print the #include line for one style header, wrapped in its outer guards */ + +static void print_include(const char *path) +{ + FILE *fp; + int nguard, opened = 0; + + fp = fopen(path, "r"); + if (!fp) { + fprintf(stderr, "stylegen: cannot open %s\n", path); + return; + } + nguard = read_outer_guards(fp, path); + fclose(fp); + if (nguard < 0) nguard = 0; + + open_guards(nguard, &opened); + printf("#include \"%s\"\n", path); + close_guards(nguard); } /* parse one style header and emit add_builtin() calls (source mode). Runs a - * small state machine over the "#ifdef XXX_CLASS" block: 0 = before block, - * 1 = inside block, 2 = after block (the #else class-definition branch). */ + * small state machine over the "#ifdef XXX_CLASS" block: 0 = before block + * (handled by read_outer_guards()), 1 = inside block, 2 = after block (the + * #else class-definition branch). The output is wrapped in the outer guards + * of the header, if any. */ static void process_source_file(const char *path, const char *macro, const char *accessor) { FILE *fp; char line[MAXLINE]; - int state = 0, depth = 0; + int state = 1, depth = 1; + int nguard, opened = 0; size_t maclen = strlen(macro); fp = fopen(path, "r"); @@ -146,35 +243,42 @@ static void process_source_file(const char *path, const char *macro, const char fprintf(stderr, "stylegen: cannot open %s\n", path); return; } + nguard = read_outer_guards(fp, path); + if (nguard < 0) { + fclose(fp); + return; + } - while (fgets(line, sizeof(line), fp)) { + while ((state == 1) && fgets(line, sizeof(line), fp)) { const char *kw; const char *q; - if (state == 0) { - if (is_class_ifdef(line)) { - state = 1; - depth = 1; - } - continue; - } - if (state == 2) continue; - - /* state == 1: inside the marker block */ kw = directive_kw(line); if (kw) { if (starts_with(kw, "if")) { ++depth; + open_guards(nguard, &opened); emit_directive(line); } else if (starts_with(kw, "elif")) { - if (depth > 1) emit_directive(line); + if (depth > 1) { + open_guards(nguard, &opened); + emit_directive(line); + } } else if (starts_with(kw, "else")) { - if (depth == 1) state = 2; - else emit_directive(line); + if (depth == 1) { + state = 2; + } else { + open_guards(nguard, &opened); + emit_directive(line); + } } else if (starts_with(kw, "endif")) { --depth; - if (depth == 0) state = 2; - else emit_directive(line); + if (depth == 0) { + state = 2; + } else { + open_guards(nguard, &opened); + emit_directive(line); + } } /* any other directive (#include, #define, ...) is ignored */ continue; @@ -185,10 +289,13 @@ static void process_source_file(const char *path, const char *macro, const char while ((*q == ' ') || (*q == '\t')) ++q; if ((strncmp(q, macro, maclen) == 0) && (q[maclen] == '(')) { char key[MAXTOK], cls[MAXTOK]; - if (parse_marker(q + maclen, key, cls)) + if (parse_marker(q + maclen, key, cls)) { + open_guards(nguard, &opened); printf(" %s().add_builtin(\"%s\", &creator<%s>);\n", accessor, key, cls); + } } } + if (opened) close_guards(nguard); fclose(fp); } @@ -259,38 +366,6 @@ static void print_includes(const char *s) } } -/* Style headers whose class definition is wrapped in a build-configuration - * guard (compiler or library feature macro) placed *outside* the - * "#ifdef XXX_CLASS" marker block. The marker parser cannot see such a guard, - * so these styles are skipped during normal parsing and their #include and - * registration call are emitted by hand, wrapped in the same guard. */ - -static const struct special_style { - const char *header; /* basename matched against the input file list */ - const char *guard; /* preprocessor condition for "#if " */ - const char *key; /* style keyword */ - const char *cls; /* C++ class name */ -} special_styles[] = { - {"pair_snap_intel.h", - "defined(__AVX512F__) && (defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER))", - "snap/intel", "PairSNAPIntel"}, - {"dump_netcdf.h", "defined(LMP_HAS_NETCDF)", "netcdf", "DumpNetCDF"}, - {"dump_netcdf_mpiio.h", "defined(LMP_HAS_PNETCDF)", "netcdf/mpiio", "DumpNetCDFMPIIO"}}; - -static const int num_special_styles = (int) (sizeof(special_styles) / sizeof(special_styles[0])); - -/* return the special_styles[] index matching path's basename, or -1 if none */ - -static int special_index(const char *path) -{ - const char *slash = strrchr(path, '/'); - const char *base = slash ? slash + 1 : path; - int i; - for (i = 0; i < num_special_styles; ++i) - if (strcmp(base, special_styles[i].header) == 0) return i; - return -1; -} - int main(int argc, char **argv) { int i, sep = -1; @@ -330,14 +405,7 @@ int main(int argc, char **argv) printf("#include \"creator_registry.h\"\n"); print_includes(includes); printf("\n"); - for (i = sep + 1; i < argc; ++i) - if (special_index(argv[i]) < 0) printf("#include \"%s\"\n", argv[i]); - for (i = sep + 1; i < argc; ++i) { - int s = special_index(argv[i]); - if (s >= 0) - printf("#if %s\n#include \"%s\"\n#endif\n", special_styles[s].guard, - special_styles[s].header); - } + for (i = sep + 1; i < argc; ++i) print_include(argv[i]); printf("\n"); printf("namespace LAMMPS_NS {\n\n"); if (strcmp(onearg, "1") == 0) { @@ -349,15 +417,7 @@ int main(int argc, char **argv) } printf("\n"); printf("void %s()\n{\n", regfunc); - for (i = sep + 1; i < argc; ++i) - if (special_index(argv[i]) < 0) process_source_file(argv[i], macro, accessor); - for (i = sep + 1; i < argc; ++i) { - int s = special_index(argv[i]); - if (s >= 0) - printf("#if %s\n %s().add_builtin(\"%s\", &creator<%s>);\n#endif\n", - special_styles[s].guard, accessor, special_styles[s].key, - special_styles[s].cls); - } + for (i = sep + 1; i < argc; ++i) process_source_file(argv[i], macro, accessor); printf("}\n\n"); printf("} // namespace LAMMPS_NS\n"); return 0; diff --git a/src/Make.sh b/src/Make.sh index 4dd62aa09cd..1cd876bf01f 100755 --- a/src/Make.sh +++ b/src/Make.sh @@ -40,7 +40,9 @@ style () { # 9=extra include headers (space separated) # the stylegen helper parses the XxxStyle(key,Class) markers into explicit # add_builtin() calls and copies preprocessor directives inside the marker block -# through verbatim so build-config-dependent markers stay guarded. +# through verbatim so build-config-dependent markers stay guarded; conditionals +# wrapping a whole header (e.g. "#ifdef LAMMPS_ZSTD") are re-emitted around its +# #include and registration calls. stylesource () { list=`grep -sl "$1" $2*.h | LC_ALL=C sort` From 978483b5dd3918dddc384034b7d9d449f753f04a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 01:40:00 -0400 Subject: [PATCH 006/120] fix typo and stray comma in the PairPACE constructor initializer list --- src/ML-PACE/pair_pace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ML-PACE/pair_pace.cpp b/src/ML-PACE/pair_pace.cpp index 6f419f25aa1..74950100860 100644 --- a/src/ML-PACE/pair_pace.cpp +++ b/src/ML-PACE/pair_pace.cpp @@ -83,7 +83,7 @@ static int AtomicNumberByName_pace(char *elname) /* ---------------------------------------------------------------------- */ PairPACE::PairPACE(LAMMPS *lmp) : - Pair(lmp), aceimple(nullptr), corerep_factor(nullptr), scale(nullptr), + Pair(lmp), aceimpl(nullptr), corerep_factor(nullptr), scale(nullptr) { single_enable = 0; restartinfo = 0; From ca906df1ce60df3af5815ee92e3bba47d320aa06 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 02:25:52 -0400 Subject: [PATCH 007/120] include more plugins. TLS support is crucial --- cmake/packaging/build_linux_tgz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/packaging/build_linux_tgz.sh b/cmake/packaging/build_linux_tgz.sh index d9f992956cf..7050b78655c 100755 --- a/cmake/packaging/build_linux_tgz.sh +++ b/cmake/packaging/build_linux_tgz.sh @@ -70,7 +70,7 @@ do \ done echo "Add additional plugins for Qt" -for dir in styles imageformats +for dir in styles imageformats tls iconengines do \ cp -r ${QTDIR}/plugins/${dir} ${DESTDIR}/qtplugins/ chmod +x ${DESTDIR}/qtplugins/*/*.so From 884f5c53e36d353287694fbced9af9d232bad6ac Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 05:23:57 -0400 Subject: [PATCH 008/120] add false positive --- doc/utils/sphinx-config/false_positives.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index fe63f4b1b54..04dfd2258a8 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2015,6 +2015,7 @@ Khersonskii Khrapak Khvostov Ki +KiB Kikkawa Kikugawa kim From 2fc8f4dd65bdcc421fbd7c12e28e235302950e19 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 06:22:22 -0400 Subject: [PATCH 009/120] modernize by replacing typedef with using --- src/BOCS/pair_ldd.h | 5 ++--- src/GRANULAR/granular_model.h | 32 ++++++++------------------------ 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/src/BOCS/pair_ldd.h b/src/BOCS/pair_ldd.h index 7b4351e19cb..facfb1830ea 100644 --- a/src/BOCS/pair_ldd.h +++ b/src/BOCS/pair_ldd.h @@ -38,7 +38,7 @@ class LddPotential; // except in a GPU-enabled Kokkos build where the host-only factory function // pointers must not be shadowed into device memory. -typedef LddIndicator *(*IndicatorCreator)(LAMMPS *); +using IndicatorCreator = LddIndicator *(*) (LAMMPS *); struct LddIndicatorInfo { const char *name; IndicatorCreator creator; @@ -46,7 +46,7 @@ struct LddIndicatorInfo { extern LMP_REGISTRY_CONST LddIndicatorInfo ldd_indicator_table[]; extern LMP_REGISTRY_CONST int num_ldd_indicator; -typedef LddPotential *(*PotentialCreator)(LAMMPS *); +using PotentialCreator = LddPotential *(*) (LAMMPS *); struct LddPotentialInfo { const char *name; PotentialCreator creator; @@ -109,7 +109,6 @@ class PairLdd : public Pair { void ErrorDoubleKeyword(const char *); void ErrorNumKeywordArgs(const char *, const char *); void read_file(char *filename); // reads ldd potential file, executes coeff_ldd per entry - }; } // namespace LAMMPS_NS diff --git a/src/GRANULAR/granular_model.h b/src/GRANULAR/granular_model.h index 39ba68f2ebe..9af6cc0751c 100644 --- a/src/GRANULAR/granular_model.h +++ b/src/GRANULAR/granular_model.h @@ -16,25 +16,11 @@ #include "pointers.h" // IWYU pragma: export - namespace LAMMPS_NS::Granular_NS { -enum SubModelType { - NORMAL = 0, - DAMPING, - TANGENTIAL, - ROLLING, - TWISTING, - HEAT, - NSUBMODELS -}; +enum SubModelType { NORMAL = 0, DAMPING, TANGENTIAL, ROLLING, TWISTING, HEAT, NSUBMODELS }; -enum ContactType { - PAIR = 0, - WALL = 1, - WALLREGION = 2, - SURFACE = 3 -}; +enum ContactType { PAIR = 0, WALL = 1, WALLREGION = 2, SURFACE = 3 }; // forward declarations class GranSubMod; @@ -50,8 +36,7 @@ class GranularModel; // the table has one entry per sub-model and is defined in the checked-in file // gran_sub_mod_register.cpp (which is also where new sub-models are registered). -typedef GranSubMod *(*GranSubModCreator)(GranularModel *, LAMMPS *); - +using GranSubModCreator = GranSubMod *(*) (GranularModel *, LAMMPS *); struct GranSubModInfo { const char *name; // keyword used in the input script GranSubModCreator creator; // factory function for the sub-model class @@ -76,7 +61,7 @@ class GranularModel : protected Pointers { int add_sub_model(char **, int, int, SubModelType); int define_classic_model(char **, int, int); void construct_sub_model(std::string, SubModelType); - int mix_coeffs(GranularModel*, GranularModel*); + int mix_coeffs(GranularModel *, GranularModel *); void write_restart(FILE *); void read_restart(FILE *); @@ -121,12 +106,11 @@ class GranularModel : protected Pointers { double *svector; protected: - int rolling_defined, twisting_defined, heat_defined; // Flag optional sub models - int classic_model; // Flag original pair/gran calculations - int contact_radius_flag; // Flag whether contact radius is needed + int rolling_defined, twisting_defined, heat_defined; // Flag optional sub models + int classic_model; // Flag original pair/gran calculations + int contact_radius_flag; // Flag whether contact radius is needed }; -} // namespace LAMMPS_NS::Granular_NS - +} // namespace LAMMPS_NS::Granular_NS #endif From ca77504413fe9b9b30d8f758b756bd1631ea4e37 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 06:22:45 -0400 Subject: [PATCH 010/120] use explicit scoping to indicate that virtual dispatch is not available --- src/ML-IAP/mliap_model_python.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ML-IAP/mliap_model_python.cpp b/src/ML-IAP/mliap_model_python.cpp index c1c534401af..856058db497 100644 --- a/src/ML-IAP/mliap_model_python.cpp +++ b/src/ML-IAP/mliap_model_python.cpp @@ -70,7 +70,7 @@ MLIAPModelPython::MLIAPModelPython(LAMMPS *lmp, char *coefffilename, bool is_chi PyList_Append(py_path, PyUnicode_FromString(potentials_path)); } PyGILState_Release(gstate); - if (coefffilename) read_coeffs(coefffilename); + if (coefffilename) MLIAPModelPython::read_coeffs(coefffilename); } From 8983f7b45c866f3cae5c6d309b954fa30147bedb Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 12:48:43 +0000 Subject: [PATCH 011/120] unittest: add KOKKOS variants to the compute/fix output and minimizer test drivers The test_output_style driver (compute-*.yaml and fix-output-*.yaml references) and the test_min_style driver (min-*.yaml references) only had a 'plain' test case, so none of the KOKKOS compute styles or minimizers was ever compared against the reference data. Add the kokkos_omp, kokkos_serial, and kokkos_gpu cases with the same guards, skip_tests qualifiers, and relaxed tolerances as the other force style drivers. The output driver keeps the prerequisites unsuffixed on purpose: there is no single tested style category, and running a compute or fix that has no KOKKOS variant inside a KOKKOS run still exercises the automatic host/device synchronization. The minimizer driver appends the suffix to the 'minimize' prerequisite so references for minimizers without a KOKKOS variant (hftn) skip instead of failing. The KOKKOS line search only supports 'min_modify line quadratic', so the backtrack and forcezero references skip the KOKKOS cases. --- unittest/force-styles/test_min_style.cpp | 132 +++++++++++++++++- unittest/force-styles/test_output_style.cpp | 126 ++++++++++++++++- .../force-styles/tests/min-cg-backtrack.yaml | 2 +- .../force-styles/tests/min-cg-forcezero.yaml | 2 +- 4 files changed, 247 insertions(+), 15 deletions(-) diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index aaa1a706590..a6ba6da1650 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -105,7 +105,18 @@ static LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg) Info *info = new Info(lmp); int nfail = 0; for (const auto &prerequisite : cfg.prerequisites) { - if (!info->has_style(prerequisite.first, prerequisite.second)) ++nfail; + std::string style = prerequisite.second; + + // this is a test for minimizer styles, so if the suffixed + // version is not available, there is no reason to test. + if (prerequisite.first == "minimize") { + if (lmp->suffix_enable) { + style += "/"; + style += lmp->suffix; + } + } + + if (!info->has_style(prerequisite.first, style)) ++nfail; } delete info; if (nfail > 0) { @@ -159,12 +170,8 @@ static void run_minimize(LAMMPS *lmp) lmp->input->one("run 0 post no"); } -TEST(MinStyle, plain) +static void run_min_test(LAMMPS::argv &args, double epsilon) { - if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - - LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite"}; - ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { @@ -192,7 +199,6 @@ TEST(MinStyle, plain) const int nlocal = lmp->atom->nlocal; ASSERT_EQ(lmp->atom->natoms, nlocal); - const double epsilon = test_config.epsilon; ErrorStats stats; const double init_pe = potential_energy(lmp); @@ -235,6 +241,118 @@ TEST(MinStyle, plain) cleanup_lammps(lmp); } +TEST(MinStyle, plain) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite"}; + + run_min_test(args, test_config.epsilon); +} + +// precision of the KOKKOS package as selected with -D KOKKOS_PREC at compile time +static std::string kokkos_precision() +{ + if (Info::has_accelerator_feature("KOKKOS", "precision", "mixed")) return "mixed"; + if (Info::has_accelerator_feature("KOKKOS", "precision", "single")) return "single"; + return "double"; +} + +// the KOKKOS minimizers descend along a different (but equally valid) path +// than their plain counterparts, so the tolerances have to be relaxed the +// same way as for the other KOKKOS force style tests + +static double kokkos_epsilon() +{ + // relax error a bit for KOKKOS package + double epsilon = 10.0 * test_config.epsilon; + // relax error a lot for reduced precision KOKKOS builds + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + return epsilon; +} + +TEST(MinStyle, kokkos_omp) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + } + + LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + + run_min_test(args, kokkos_epsilon()); +} + +TEST(MinStyle, kokkos_serial) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + } + + LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + + run_min_test(args, kokkos_epsilon()); +} + +TEST(MinStyle, kokkos_gpu) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires a GPU backend of the KOKKOS package + if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && + !Info::has_accelerator_feature("KOKKOS", "api", "hip") && + !Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "KOKKOS GPU backend not enabled"; + // transparently skip when no compatible GPU device is present + if (!Info::has_kokkos_gpu_device()) + GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list so the GPU kernels run with the input's default + // "newton on"; with the default "neigh full" the KOKKOS package requires + // newton off, which the force-style input templates do not use + LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", "-k", "on", + "g", "1", "-sf", "kk", "-pk", "kokkos", "neigh", + "half", "newton", "on"}; + + run_min_test(args, kokkos_epsilon()); +} + void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index f2a8eef7e47..40c7abbb442 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -50,6 +50,7 @@ #include #include +using ::testing::HasSubstr; using ::testing::StartsWith; using namespace LAMMPS_NS; @@ -257,12 +258,8 @@ static void compare_rows(const std::string &name, } } -TEST(OutputStyle, plain) +static void run_output_test(LAMMPS::argv &args, double epsilon, bool kokkos) { - if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - - LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite"}; - ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { @@ -286,6 +283,10 @@ TEST(OutputStyle, plain) EXPECT_THAT(output, StartsWith("LAMMPS (")); + // init_lammps() always runs the system for RUN_STEPS steps, so the + // timing summary of that run has to be part of the output + if (kokkos) EXPECT_THAT(output, HasSubstr("Loop time")); + // abort if running in parallel and not all atoms are local ASSERT_EQ(lmp->atom->natoms, lmp->atom->nlocal); @@ -295,7 +296,6 @@ TEST(OutputStyle, plain) FAIL() << "no compute or fix with ID 'test' defined"; } - const double epsilon = test_config.epsilon; ErrorStats stats; if (data.has_scalar) EXPECT_FP_LE_WITH_EPS(data.scalar, test_config.global_scalar, epsilon); @@ -316,6 +316,120 @@ TEST(OutputStyle, plain) cleanup_lammps(lmp); } +TEST(OutputStyle, plain) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite"}; + + run_output_test(args, test_config.epsilon, false); +} + +// precision of the KOKKOS package as selected with -D KOKKOS_PREC at compile time +static std::string kokkos_precision() +{ + if (Info::has_accelerator_feature("KOKKOS", "precision", "mixed")) return "mixed"; + if (Info::has_accelerator_feature("KOKKOS", "precision", "single")) return "single"; + return "double"; +} + +// the KOKKOS package accumulates in a different order and - depending on how it +// was compiled - with reduced precision, so the tolerance has to be relaxed +static double kokkos_epsilon() +{ + double epsilon = 5.0 * test_config.epsilon; + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + return epsilon; +} + +// the KOKKOS tests below use the same prerequisites as the plain test, i.e. no +// "/kk" suffix is appended to them. Unlike the other force style test drivers +// this one has no single tested style category, and a compute or fix without a +// KOKKOS variant is still worth running inside a KOKKOS enabled run: it +// exercises the automatic synchronization between the host and device copies +// of the atom data. + +TEST(OutputStyle, kokkos_omp) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + } + + LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + + run_output_test(args, kokkos_epsilon(), true); +} + +TEST(OutputStyle, kokkos_serial) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + } + + LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + + run_output_test(args, kokkos_epsilon(), true); +} + +TEST(OutputStyle, kokkos_gpu) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires a GPU backend of the KOKKOS package + if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && + !Info::has_accelerator_feature("KOKKOS", "api", "hip") && + !Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "KOKKOS GPU backend not enabled"; + // transparently skip when no compatible GPU device is present + if (!Info::has_kokkos_gpu_device()) GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list so the GPU kernels run with the input's default + // "newton on"; with the default "neigh full" the KOKKOS package requires + // newton off, which the force-style input templates do not use + LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "g", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "half", "newton", "on"}; + + run_output_test(args, kokkos_epsilon(), true); +} + static void write_rows(YamlWriter &writer, const std::string &key, const std::vector> &rows) { diff --git a/unittest/force-styles/tests/min-cg-backtrack.yaml b/unittest/force-styles/tests/min-cg-backtrack.yaml index 55c60f15ba5..1cc938fabc7 100644 --- a/unittest/force-styles/tests/min-cg-backtrack.yaml +++ b/unittest/force-styles/tests/min-cg-backtrack.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: date_generated: Thu Jul 9 18:25:59 2026 epsilon: 0.001 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full minimize cg diff --git a/unittest/force-styles/tests/min-cg-forcezero.yaml b/unittest/force-styles/tests/min-cg-forcezero.yaml index 46ddd077753..0dd2076202b 100644 --- a/unittest/force-styles/tests/min-cg-forcezero.yaml +++ b/unittest/force-styles/tests/min-cg-forcezero.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: date_generated: Thu Jul 9 18:26:00 2026 epsilon: 0.001 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full minimize cg From 4bd62e4d5e1b61b668f3db9fea4efe0dd33162fc Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 12:53:12 +0000 Subject: [PATCH 012/120] compute ti: accept pair styles with an accelerator suffix ComputeTI::init() looked up the pair style named in the compute command with an exact match, so with an active accelerator suffix (e.g. -sf kk or -sf omp, where the pair style is registered as lj/cut/kk) the command failed with 'Compute ti pair style does not exist'. Retry the lookup with the suffix appended, the same way compute pair does. Found by running the compute-ti.yaml reference with the KOKKOS package. --- src/EXTRA-COMPUTE/compute_ti.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/EXTRA-COMPUTE/compute_ti.cpp b/src/EXTRA-COMPUTE/compute_ti.cpp index f3a09b1abe1..30bcb7ac7f5 100644 --- a/src/EXTRA-COMPUTE/compute_ti.cpp +++ b/src/EXTRA-COMPUTE/compute_ti.cpp @@ -130,7 +130,10 @@ void ComputeTI::init() error->all(FLERR,"Variable for compute ti is invalid style"); if (which[m] == PAIR) { + // check for pair style with and without suffix pptr[m] = force->pair_match(pstyle[m],1); + if ((pptr[m] == nullptr) && lmp->suffix) + pptr[m] = force->pair_match(fmt::format("{}/{}",pstyle[m],lmp->suffix),1); if (pptr[m] == nullptr) error->all(FLERR,"Compute ti pair style does not exist"); From 3ecc108414f3c68c3af4c03a22894e051a99a65f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 12:53:12 +0000 Subject: [PATCH 013/120] compute gyration/shape: accept accelerated variants of compute gyration The check that the referenced compute is a compute gyration compared the style name with an exact string match, so an accelerated variant such as gyration/kk (which derives from ComputeGyration) was rejected with 'Compute gyration compute ID does not point to gyration compute'. Use a dynamic_cast to the ComputeGyration base class instead. Found by running the compute-gyration_shape.yaml reference with the KOKKOS package. --- src/EXTRA-COMPUTE/compute_gyration_shape.cpp | 12 ++++++++---- src/EXTRA-COMPUTE/compute_gyration_shape.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_gyration_shape.cpp b/src/EXTRA-COMPUTE/compute_gyration_shape.cpp index 34428a82876..aacece50433 100644 --- a/src/EXTRA-COMPUTE/compute_gyration_shape.cpp +++ b/src/EXTRA-COMPUTE/compute_gyration_shape.cpp @@ -18,6 +18,7 @@ #include "compute_gyration_shape.h" +#include "compute_gyration.h" #include "error.h" #include "math_eigen.h" #include "math_special.h" @@ -25,7 +26,6 @@ #include "update.h" #include -#include using namespace LAMMPS_NS; @@ -62,11 +62,15 @@ ComputeGyrationShape::~ComputeGyrationShape() void ComputeGyrationShape::init() { // check that the compute gyration command exist - c_gyration = modify->get_compute_by_id(id_gyration); - if (!c_gyration) + Compute *compute = modify->get_compute_by_id(id_gyration); + if (!compute) error->all(FLERR,"Compute gyration ID does not exist for " "compute gyration/shape"); - if (strcmp(c_gyration->style,"gyration") != 0) + + // accept compute gyration and any of its accelerated variants + + c_gyration = dynamic_cast(compute); + if (!c_gyration) error->all(FLERR,"Compute gyration compute ID does not point to " "gyration compute for compute gyration/shape"); } diff --git a/src/EXTRA-COMPUTE/compute_gyration_shape.h b/src/EXTRA-COMPUTE/compute_gyration_shape.h index 19e76def495..3556a49116f 100644 --- a/src/EXTRA-COMPUTE/compute_gyration_shape.h +++ b/src/EXTRA-COMPUTE/compute_gyration_shape.h @@ -34,7 +34,7 @@ class ComputeGyrationShape : public Compute { void compute_vector() override; private: - class Compute *c_gyration; + class ComputeGyration *c_gyration; }; } // namespace LAMMPS_NS From 38ee04b9fd027a393da3fab4e0264b778d1c4818 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 12:53:12 +0000 Subject: [PATCH 014/120] unittest: skip the KOKKOS cases of the compute centroid/stress/atom reference None of the KOKKOS angle, dihedral, or improper styles tallies the centroid stress (they all set centroidstressflag to CENTROID_NOTAVAIL), so compute centroid/stress/atom refuses to run with them. --- unittest/force-styles/tests/compute-centroid_stress_atom.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/force-styles/tests/compute-centroid_stress_atom.yaml b/unittest/force-styles/tests/compute-centroid_stress_atom.yaml index 0f92c2ca976..0f85aeddd7f 100644 --- a/unittest/force-styles/tests/compute-centroid_stress_atom.yaml +++ b/unittest/force-styles/tests/compute-centroid_stress_atom.yaml @@ -4,7 +4,7 @@ tags: date_generated: Wed Aug 5 09:48:25 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full compute centroid/stress/atom From a2b904f99412cf0a3cbc2cd2f4b0657899efd157 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 10:03:46 -0400 Subject: [PATCH 015/120] sync linux tgz package script with lammps-gui version --- cmake/packaging/build_linux_tgz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/packaging/build_linux_tgz.sh b/cmake/packaging/build_linux_tgz.sh index 7050b78655c..3669ec04b58 100755 --- a/cmake/packaging/build_linux_tgz.sh +++ b/cmake/packaging/build_linux_tgz.sh @@ -35,7 +35,7 @@ rm -rf ${DESTDIR}/lib64 rm -f ${DESTDIR}/lib/ld*.so ${DESTDIR}/lib/ld*.so.[0-9] rm -f ${DESTDIR}/lib/lib{c,dl,rt,m,pthread}.so.? rm -f ${DESTDIR}/lib/lib{c,dl,rt,m,pthread}-[0-9].[0-9]*.so -rm -f ${DESTDIR}/lib/libX* ${DESTDIR}/lib/libxcb* +rm -f ${DESTDIR}/lib/libX* ${DESTDIR}/lib/libxcb* ${DESTDIR}/lib/libxkb* rm -f ${DESTDIR}/lib/libgcc_s* rm -f ${DESTDIR}/lib/libstdc++* echo "Remove oversize potential files" From c034cd8c381be7d96b176318494e6806b2b3c9d2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 3 Sep 2026 11:21:46 -0400 Subject: [PATCH 016/120] update shared linker cache and symlinks on Linux -> fewer crashes --- cmake/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1bcb0d86779..a493b4054de 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -901,6 +901,13 @@ install( DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/profile.d ) +############################################################################### +# On Linux systems (any others, too?) we may need to update the shared linker cache +############################################################################### +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + install(CODE "execute_process(COMMAND ldconfig || exit 0)") +endif() + ############################################################################### # Install LAMMPS lib and python module into site-packages folder with # "install-python" target. Behaves exactly like "make install-python" for @@ -939,7 +946,6 @@ add_custom_target(tarball COMMAND ${LAMMPS_DIR}/cmake/packaging/build_tarball.sh ${LAMMPS_DIR}/doc ) - include(Testing) include(CodeCoverage) include(CodingStandard) From 89710e853023b4ad0139e40899c02eba5cae0fcf Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 22:35:32 +0000 Subject: [PATCH 017/120] compute temp/sphere, temp/asphere, temp/body: detect a temp/region bias by class, not by name These computes decide whether their bias compute is a compute temp/region (which needs the region-aware degree-of-freedom removal) with an exact comparison of the style name. An accelerated variant such as temp/region/kk therefore took the generic bias path, and with the KOKKOS package 'compute ID all temp/sphere bias ' crashed in ComputeTempRegion::dof_remove(-1), which dereferences atom->x[-1] and calls region->match() without prematch(). Use a dynamic_cast to the ComputeTempRegion base class instead; the eff variant derives from Compute and is unaffected either way. Add compute-temp_sphere.yaml, compute-temp_sphere_dof_rotate.yaml, and compute-temp_sphere_region_bias.yaml (the latter is the crash reproducer) to the output style tests; they also cover the 'dof rotate' option and the KOKKOS version of the compute. --- src/ASPHERE/compute_temp_asphere.cpp | 3 +- src/BODY/compute_temp_body.cpp | 3 +- src/compute_temp_sphere.cpp | 3 +- .../tests/compute-temp_sphere.yaml | 28 +++++++++++++++++ .../tests/compute-temp_sphere_dof_rotate.yaml | 28 +++++++++++++++++ .../compute-temp_sphere_region_bias.yaml | 31 +++++++++++++++++++ 6 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 unittest/force-styles/tests/compute-temp_sphere.yaml create mode 100644 unittest/force-styles/tests/compute-temp_sphere_dof_rotate.yaml create mode 100644 unittest/force-styles/tests/compute-temp_sphere_region_bias.yaml diff --git a/src/ASPHERE/compute_temp_asphere.cpp b/src/ASPHERE/compute_temp_asphere.cpp index 68e784059c0..dcca0a3b592 100644 --- a/src/ASPHERE/compute_temp_asphere.cpp +++ b/src/ASPHERE/compute_temp_asphere.cpp @@ -20,6 +20,7 @@ #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "compute_temp_region.h" #include "domain.h" #include "error.h" #include "force.h" @@ -119,7 +120,7 @@ void ComputeTempAsphere::init() error->all(FLERR,"Bias compute {} does not calculate a velocity bias", id_bias); if (tbias->igroup != igroup) error->all(FLERR,"Bias compute group does not match compute group"); - if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; + if (dynamic_cast(tbias) != nullptr) tempbias = 2; else tempbias = 1; // init and setup bias compute because diff --git a/src/BODY/compute_temp_body.cpp b/src/BODY/compute_temp_body.cpp index 920dd9db007..612775e8b2d 100644 --- a/src/BODY/compute_temp_body.cpp +++ b/src/BODY/compute_temp_body.cpp @@ -20,6 +20,7 @@ #include "atom.h" #include "atom_vec_body.h" +#include "compute_temp_region.h" #include "domain.h" #include "error.h" #include "force.h" @@ -110,7 +111,7 @@ void ComputeTempBody::init() error->all(FLERR,"Bias compute {} does not calculate a velocity bias", id_bias); if (tbias->igroup != igroup) error->all(FLERR,"Bias compute group does not match compute group"); - if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; + if (dynamic_cast(tbias) != nullptr) tempbias = 2; else tempbias = 1; // init and setup bias compute because diff --git a/src/compute_temp_sphere.cpp b/src/compute_temp_sphere.cpp index 0ca479acf5d..561fd01769b 100644 --- a/src/compute_temp_sphere.cpp +++ b/src/compute_temp_sphere.cpp @@ -15,6 +15,7 @@ #include "atom.h" #include "atom_masks.h" +#include "compute_temp_region.h" #include "domain.h" #include "error.h" #include "force.h" @@ -103,7 +104,7 @@ void ComputeTempSphere::init() if (tbias->tempbias == 0) error->all(FLERR, "Bias compute does not calculate a velocity bias"); if (tbias->igroup != igroup) error->all(FLERR, "Bias compute group does not match compute group"); - if (strcmp(tbias->style, "temp/region") == 0) + if (dynamic_cast(tbias) != nullptr) tempbias = 2; else tempbias = 1; diff --git a/unittest/force-styles/tests/compute-temp_sphere.yaml b/unittest/force-styles/tests/compute-temp_sphere.yaml new file mode 100644 index 00000000000..c76057feeb5 --- /dev/null +++ b/unittest/force-styles/tests/compute-temp_sphere.yaml @@ -0,0 +1,28 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Thu Sep 3 12:56:06 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: +prerequisites: | + atom sphere + pair zero + compute temp/sphere +pre_commands: | + variable atom_style delete + variable atom_style index sphere + variable pair_style delete + variable pair_style index 'zero 4.0' +post_commands: | + pair_coeff * * + set group all diameter 1.0 density 2.0 + set group all omega 0.4 -0.3 0.7 + set atom 1*8 omega -0.2 0.5 -0.9 + compute test all temp/sphere +input_file: in.colloid +natoms: 27 +global_scalar: 0.9030785937251846 +global_vector: |- + 6 4.6429613283360126e+01 5.2038904512285598e+01 4.5120978606658603e+01 4.2315245952666336e+00 -3.4536958155102457e+00 -3.6023972918251768e+00 +... diff --git a/unittest/force-styles/tests/compute-temp_sphere_dof_rotate.yaml b/unittest/force-styles/tests/compute-temp_sphere_dof_rotate.yaml new file mode 100644 index 00000000000..1e22a88c6cd --- /dev/null +++ b/unittest/force-styles/tests/compute-temp_sphere_dof_rotate.yaml @@ -0,0 +1,28 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Thu Sep 3 12:56:12 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: +prerequisites: | + atom sphere + pair zero + compute temp/sphere +pre_commands: | + variable atom_style delete + variable atom_style index sphere + variable pair_style delete + variable pair_style index 'zero 4.0' +post_commands: | + pair_coeff * * + set group all diameter 1.0 density 2.0 + set group all omega 0.4 -0.3 0.7 + set atom 1*8 omega -0.2 0.5 -0.9 + compute test all temp/sphere dof rotate +input_file: in.colloid +natoms: 27 +global_scalar: 0.029554242000437315 +global_vector: |- + 6 3.5185837720205698e-01 3.8851029149393784e-01 1.6535249333394275e+00 -3.2253684576855213e-01 7.0790554460889998e-01 -7.9482294135821741e-01 +... diff --git a/unittest/force-styles/tests/compute-temp_sphere_region_bias.yaml b/unittest/force-styles/tests/compute-temp_sphere_region_bias.yaml new file mode 100644 index 00000000000..a4dd0277367 --- /dev/null +++ b/unittest/force-styles/tests/compute-temp_sphere_region_bias.yaml @@ -0,0 +1,31 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Thu Sep 3 12:56:10 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: +prerequisites: | + atom sphere + pair zero + compute temp/sphere + compute temp/region +pre_commands: | + variable atom_style delete + variable atom_style index sphere + variable pair_style delete + variable pair_style index 'zero 4.0' +post_commands: | + pair_coeff * * + set group all diameter 1.0 density 2.0 + set group all omega 0.4 -0.3 0.7 + set atom 1*8 omega -0.2 0.5 -0.9 + region half block INF INF INF INF 6.75 INF units box + compute tbias all temp/region half + compute test all temp/sphere bias tbias +input_file: in.colloid +natoms: 27 +global_scalar: 0.9879111478197116 +global_vector: |- + 6 3.2762042542944300e+01 2.5094688884267381e+01 2.8091538433103207e+01 1.8860489288885243e+00 -1.4815358937769230e+00 -1.0846217647735578e+01 +... From 7b1ed2d820c7a87e3626101d9a60252790241eb7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 22:39:49 +0000 Subject: [PATCH 018/120] unittest: add KOKKOS full neighbor list cases to the force style test drivers All KOKKOS test cases run with the package defaults of the host backends, i.e. a half neighbor list with newton on, so the kernels instantiated for a full neighbor list (the ones the GPU backends use by default) are never executed in a CPU only test build. Add the kokkos_omp_full and kokkos_serial_full cases to the pair, bond, angle, dihedral, improper, fix timestep, output, and minimizer drivers. They pass '-pk kokkos neigh full newton off' and override the newton_pair and newton_bond index variables of the input templates on the command line, since the KOKKOS package requires newton off with a full neighbor list. The pair driver passes the newton setting on to the restart run and the angle driver to the data file run. A skip_tests entry for the plain kokkos_serial or kokkos_omp case also skips the corresponding full case. Reference data are unchanged: forces, energies, and the virial do not depend on the newton setting. Styles that cannot run with a full neighbor list under KOKKOS still need skip_tests entries. --- unittest/force-styles/test_angle_style.cpp | 94 ++++++++++++++++++- unittest/force-styles/test_bond_style.cpp | 79 ++++++++++++++++ unittest/force-styles/test_dihedral_style.cpp | 79 ++++++++++++++++ unittest/force-styles/test_fix_timestep.cpp | 81 ++++++++++++++++ unittest/force-styles/test_improper_style.cpp | 79 ++++++++++++++++ unittest/force-styles/test_min_style.cpp | 81 ++++++++++++++++ unittest/force-styles/test_output_style.cpp | 81 ++++++++++++++++ unittest/force-styles/test_pair_style.cpp | 94 ++++++++++++++++++- 8 files changed, 662 insertions(+), 6 deletions(-) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index b944017bd15..340c24ecc24 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -162,7 +162,7 @@ void restart_lammps(LAMMPS *lmp, const TestConfig &cfg) command("run 0 post no"); } -void data_lammps(LAMMPS *lmp, const TestConfig &cfg) +void data_lammps(LAMMPS *lmp, const TestConfig &cfg, const bool newton = true) { // utility lambdas to improve readability auto command = [&](const std::string &line) { @@ -176,7 +176,10 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) command("variable angle_style delete"); command("variable data_file delete"); command("variable newton_bond delete"); - command("variable newton_bond index on"); + if (newton) + command("variable newton_bond index on"); + else + command("variable newton_bond index off"); for (const auto &pre_command : cfg.pre_commands) { command(pre_command); @@ -541,7 +544,11 @@ static std::string kokkos_precision() return "double"; } -static void run_kokkos_test(LAMMPS::argv &args) +// the "newton" argument must match the newton setting the command line +// arguments select: with "-pk kokkos neigh full" the KOKKOS package rejects +// "newton on", so the run re-reading the data file must use newton off as well + +static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) { ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; @@ -655,7 +662,7 @@ static void run_kokkos_test(LAMMPS::argv &args) if (print_stats) std::cerr << "restart_energy stats:" << stats << std::endl; if (!verbose) ::testing::internal::CaptureStdout(); - data_lammps(lmp, test_config); + data_lammps(lmp, test_config, newton); if (!verbose) ::testing::internal::GetCapturedStdout(); angle = lmp->force->angle; @@ -694,6 +701,44 @@ TEST(AngleStyle, kokkos_omp) run_kokkos_test(args); }; +TEST(AngleStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args, false); +}; + TEST(AngleStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -720,6 +765,47 @@ TEST(AngleStyle, kokkos_serial) run_kokkos_test(args); }; +TEST(AngleStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args, false); +}; + TEST(AngleStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 05485ee8f14..b488d5763a7 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -683,6 +683,44 @@ TEST(BondStyle, kokkos_omp) run_kokkos_test(args); }; +TEST(BondStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(BondStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -709,6 +747,47 @@ TEST(BondStyle, kokkos_serial) run_kokkos_test(args); }; +TEST(BondStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(BondStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index ae7579b6bf9..7ac0a9a3c4a 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -700,6 +700,44 @@ TEST(DihedralStyle, kokkos_omp) run_kokkos_test(args); }; +TEST(DihedralStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(DihedralStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -727,6 +765,47 @@ TEST(DihedralStyle, kokkos_serial) run_kokkos_test(args); }; +TEST(DihedralStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(DihedralStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 4da777ddbaf..024e54f9274 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -1140,6 +1140,45 @@ TEST(FixTimestep, kokkos_omp) run_kokkos_test(args); }; +TEST(FixTimestep, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(FixTimestep, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -1167,6 +1206,48 @@ TEST(FixTimestep, kokkos_serial) run_kokkos_test(args); }; +TEST(FixTimestep, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(FixTimestep, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 72b343fee58..1275259c46e 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -675,6 +675,44 @@ TEST(ImproperStyle, kokkos_omp) run_kokkos_test(args); }; +TEST(ImproperStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(ImproperStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -702,6 +740,47 @@ TEST(ImproperStyle, kokkos_serial) run_kokkos_test(args); }; +TEST(ImproperStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args); +}; + TEST(ImproperStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index a6ba6da1650..dbfcd228f4a 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -299,6 +299,45 @@ TEST(MinStyle, kokkos_omp) run_min_test(args, kokkos_epsilon()); } +TEST(MinStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_min_test(args, kokkos_epsilon()); +} + TEST(MinStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -326,6 +365,48 @@ TEST(MinStyle, kokkos_serial) run_min_test(args, kokkos_epsilon()); } +TEST(MinStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_min_test(args, kokkos_epsilon()); +} + TEST(MinStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index 40c7abbb442..68af8bd93ac 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -377,6 +377,45 @@ TEST(OutputStyle, kokkos_omp) run_output_test(args, kokkos_epsilon(), true); } +TEST(OutputStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_output_test(args, kokkos_epsilon(), true); +} + TEST(OutputStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -404,6 +443,48 @@ TEST(OutputStyle, kokkos_serial) run_output_test(args, kokkos_epsilon(), true); } +TEST(OutputStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_output_test(args, kokkos_epsilon(), true); +} + TEST(OutputStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 5ec59bbad9f..cbdb2d8192f 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -705,7 +705,11 @@ static std::string kokkos_precision() return "double"; } -static void run_kokkos_test(LAMMPS::argv &args) +// the "newton" argument must match the newton setting the command line +// arguments select: with "-pk kokkos neigh full" the KOKKOS package rejects +// "newton on", so the restarted run has to be set up with newton off as well + +static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) { ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; @@ -824,7 +828,7 @@ static void run_kokkos_test(LAMMPS::argv &args) } if (!verbose) ::testing::internal::CaptureStdout(); - restart_lammps(lmp, test_config, true); + restart_lammps(lmp, test_config, true, newton); if (!verbose) ::testing::internal::GetCapturedStdout(); pair = lmp->force->pair; @@ -973,6 +977,50 @@ TEST(PairStyle, kokkos_omp) run_kokkos_test(args); }; +TEST(PairStyle, kokkos_omp_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_omp" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the OpenMP backend of KOKKOS + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) + GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; + // if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only. + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + // some styles cannot run with more than one thread in the test (dpd uses + // multiple pRNGs, snap and pace due to their implementation); these are + // flagged with the "single_thread" tag in their YAML file + if (test_config.has_tag("single_thread")) args[9] = "1"; + + run_kokkos_test(args, false); +}; + TEST(PairStyle, kokkos_serial) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -1000,6 +1048,48 @@ TEST(PairStyle, kokkos_serial) run_kokkos_test(args); }; +TEST(PairStyle, kokkos_serial_full) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // a style that cannot be tested with KOKKOS at all cannot be tested + // with a full neighbor list either, so the plain "kokkos_serial" + // skip entries apply here as well + if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); + if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) + GTEST_SKIP(); + // this test requires the KOKKOS package compiled with only the Serial backend: when the + // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial + if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) + GTEST_SKIP() << "KOKKOS Serial backend not enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads")) + GTEST_SKIP() << "Cannot test KOKKOS/Serial with threading support enabled"; + if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; + } + + // exercise the NEIGHFLAG == FULL kernels of the KOKKOS package. those are + // what the GPU backends select by default, but they are never reached in a + // CPU only test build, which always uses a half neighbor list with newton + // on. the KOKKOS package requires "newton off" with "neigh full", so the + // newton settings of the input template must be overridden as well: an + // index style variable defined with -var on the command line takes + // precedence over the "variable ... index" definition inside the template + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "full", "newton", "off", + "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + + run_kokkos_test(args, false); +}; + TEST(PairStyle, kokkos_gpu) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); From 344707742cf9633411c93ec51985cb61b91a2d8b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 3 Sep 2026 22:39:49 +0000 Subject: [PATCH 019/120] unittest: allow running the command and format tests with an accelerator package The LAMMPSTest fixture in unittest/testing/core.h now appends the words of the LAMMPS_ACCELERATOR_ARGS environment variable to the command line of every LAMMPS instance it creates. A new add_kokkos_test() CMake helper registers a second CTest entry (Kokkos, label 'kokkos') for 30 command and format tests that sets that variable to '-k on t 1 -sf kk' when the KOKKOS package is enabled, so the KOKKOS atom styles, regions, computes, and commands are exercised by the same test bodies. The test programs call lammps_kokkos_finalize() after the tests to avoid crashes during static destruction. Several of the new entries still fail and need per-test adjustments (exact style name checks, documented KOKKOS limitations such as label maps); those follow separately. --- unittest/CMakeLists.txt | 21 ++++++++++++++ unittest/commands/CMakeLists.txt | 28 ++++++++++++++++--- unittest/commands/test_compute_chunk.cpp | 7 +++++ unittest/commands/test_compute_frenkel.cpp | 7 +++++ unittest/commands/test_compute_global.cpp | 7 +++++ unittest/commands/test_delete_atoms.cpp | 8 ++++++ unittest/commands/test_fix_spring_chunk.cpp | 8 ++++++ unittest/commands/test_groups.cpp | 7 +++++ unittest/commands/test_info.cpp | 8 ++++++ unittest/commands/test_input_validation.cpp | 8 ++++++ unittest/commands/test_kspace_auto_slab.cpp | 8 ++++++ .../commands/test_kspace_group_group_slab.cpp | 8 ++++++ unittest/commands/test_labelmap.cpp | 8 ++++++ unittest/commands/test_lattice_region.cpp | 8 ++++++ unittest/commands/test_pair_ldd.cpp | 8 ++++++ unittest/commands/test_regions.cpp | 8 ++++++ unittest/commands/test_reset_atoms.cpp | 7 +++++ unittest/commands/test_restart_settings.cpp | 8 ++++++ unittest/commands/test_set_property.cpp | 8 ++++++ unittest/commands/test_simple_commands.cpp | 8 ++++++ unittest/commands/test_thermo.cpp | 8 ++++++ unittest/commands/test_variables.cpp | 8 ++++++ unittest/formats/CMakeLists.txt | 13 +++++++++ unittest/formats/test_atom_styles.cpp | 8 ++++++ unittest/formats/test_dump_atom.cpp | 8 ++++++ unittest/formats/test_dump_cfg.cpp | 8 ++++++ unittest/formats/test_dump_custom.cpp | 8 ++++++ unittest/formats/test_dump_grid.cpp | 8 ++++++ unittest/formats/test_dump_local.cpp | 8 ++++++ unittest/formats/test_file_operations.cpp | 8 ++++++ unittest/formats/test_image_flags.cpp | 8 ++++++ unittest/formats/test_molecule_file.cpp | 8 ++++++ unittest/testing/core.h | 12 ++++++++ 33 files changed, 297 insertions(+), 4 deletions(-) diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index cadfbfe1c75..3f80a8b53d6 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -113,6 +113,27 @@ else() endfunction() endif() +# environment setting that makes the LAMMPSTest fixture in unittest/testing/core.h +# append accelerator flags to the LAMMPS command line arguments, so that the very +# same test bodies also exercise the KOKKOS versions of styles and commands +set(KOKKOS_TEST_ENVIRONMENT "LAMMPS_ACCELERATOR_ARGS=-k on t 1 -sf kk") + +# convenience function for adding a second, KOKKOS enabled run of a test that is +# based on the LAMMPSTest fixture. The added test is called Kokkos and uses +# the same command. Environment settings of the original test are not inherited +# and thus must be repeated in the optional ENVIRONMENT argument. +function(add_kokkos_test) + if(NOT PKG_KOKKOS) + return() + endif() + cmake_parse_arguments(KKTEST "" "NAME" "COMMAND;ENVIRONMENT" ${ARGN}) + add_test(NAME ${KKTEST_NAME}Kokkos COMMAND ${KKTEST_COMMAND}) + set(KKTEST_ENV "${KOKKOS_TEST_ENVIRONMENT}") + list(APPEND KKTEST_ENV ${KKTEST_ENVIRONMENT}) + set_tests_properties(${KKTEST_NAME}Kokkos PROPERTIES LABELS "kokkos" + ENVIRONMENT "${KKTEST_ENV}") +endfunction() + # incorporate categories of specific tests from subdirectories add_subdirectory(utils) diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index b82e9899f5f..076fdf91017 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -36,34 +36,39 @@ target_link_libraries(test_geturl_command PRIVATE lammps GTest::GMock) add_test(NAME GeturlCommand COMMAND test_geturl_command) set_tests_properties(GeturlCommand PROPERTIES LABELS "slow") if(CMAKE_VERSION VERSION_LESS 3.20) - set_tests_properties(SimpleCommands PROPERTIES - ENVIRONMENT "LAMMPS_PLUGIN_DIR=${CMAKE_BINARY_DIR}") + set(LAMMPS_PLUGIN_BIN_DIR ${CMAKE_BINARY_DIR}) else() cmake_path(SET LAMMPS_PLUGIN_BIN_DIR NORMALIZE ${CMAKE_BINARY_DIR}) if(CMAKE_CONFIG_TYPE) cmake_path(APPEND LAMMPS_PLUGIN_BIN_DIR ${CMAKE_CONFIG_TYPE}) endif() - set_tests_properties(SimpleCommands PROPERTIES - ENVIRONMENT "LAMMPS_PLUGIN_DIR=${LAMMPS_PLUGIN_BIN_DIR}") endif() +set_tests_properties(SimpleCommands PROPERTIES + ENVIRONMENT "LAMMPS_PLUGIN_DIR=${LAMMPS_PLUGIN_BIN_DIR}") +add_kokkos_test(NAME SimpleCommands COMMAND test_simple_commands + ENVIRONMENT "LAMMPS_PLUGIN_DIR=${LAMMPS_PLUGIN_BIN_DIR}") add_executable(test_lattice_region test_lattice_region.cpp) target_link_libraries(test_lattice_region PRIVATE lammps GTest::GMock) add_test(NAME LatticeRegion COMMAND test_lattice_region) +add_kokkos_test(NAME LatticeRegion COMMAND test_lattice_region) add_executable(test_fix_spring_chunk test_fix_spring_chunk.cpp) target_link_libraries(test_fix_spring_chunk PRIVATE lammps GTest::GMock) add_test(NAME FixSpringChunk COMMAND test_fix_spring_chunk) +add_kokkos_test(NAME FixSpringChunk COMMAND test_fix_spring_chunk) add_executable(test_kspace_auto_slab test_kspace_auto_slab.cpp) target_compile_definitions(test_kspace_auto_slab PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_kspace_auto_slab PRIVATE lammps GTest::GMock) add_test(NAME KSpaceAutoSlab COMMAND test_kspace_auto_slab) +add_kokkos_test(NAME KSpaceAutoSlab COMMAND test_kspace_auto_slab) add_executable(test_kspace_group_group_slab test_kspace_group_group_slab.cpp) target_compile_definitions(test_kspace_group_group_slab PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_kspace_group_group_slab PRIVATE lammps GTest::GMock) add_test(NAME KSpaceGroupGroupSlab COMMAND test_kspace_group_group_slab) +add_kokkos_test(NAME KSpaceGroupGroupSlab COMMAND test_kspace_group_group_slab) if(PKG_QMMM-XTB) add_executable(test_kspace_group_potential test_kspace_group_potential.cpp) @@ -79,43 +84,53 @@ endif() add_executable(test_groups test_groups.cpp) target_link_libraries(test_groups PRIVATE lammps GTest::GMock) add_test(NAME Groups COMMAND test_groups) +add_kokkos_test(NAME Groups COMMAND test_groups) add_executable(test_regions test_regions.cpp) target_link_libraries(test_regions PRIVATE lammps GTest::GMock) add_test(NAME Regions COMMAND test_regions) +add_kokkos_test(NAME Regions COMMAND test_regions) add_executable(test_info test_info.cpp) target_link_libraries(test_info PRIVATE lammps GTest::GMock) add_test(NAME InfoCommand COMMAND test_info) +add_kokkos_test(NAME InfoCommand COMMAND test_info) add_executable(test_thermo test_thermo.cpp) target_link_libraries(test_thermo PRIVATE lammps GTest::GMock) add_test(NAME ThermoCommands COMMAND test_thermo) +add_kokkos_test(NAME ThermoCommands COMMAND test_thermo) add_executable(test_delete_atoms test_delete_atoms.cpp) target_link_libraries(test_delete_atoms PRIVATE lammps GTest::GMock) add_test(NAME DeleteAtoms COMMAND test_delete_atoms) +add_kokkos_test(NAME DeleteAtoms COMMAND test_delete_atoms) add_executable(test_set_property test_set_property.cpp) target_link_libraries(test_set_property PRIVATE lammps GTest::GMock) add_test(NAME SetProperty COMMAND test_set_property) +add_kokkos_test(NAME SetProperty COMMAND test_set_property) add_executable(test_pair_ldd test_pair_ldd.cpp) target_link_libraries(test_pair_ldd PRIVATE lammps GTest::GMock) add_test(NAME PairLDD COMMAND test_pair_ldd) +add_kokkos_test(NAME PairLDD COMMAND test_pair_ldd) add_executable(test_labelmap test_labelmap.cpp) target_compile_definitions(test_labelmap PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_labelmap PRIVATE lammps GTest::GMock) add_test(NAME Labelmap COMMAND test_labelmap) +add_kokkos_test(NAME Labelmap COMMAND test_labelmap) add_executable(test_compute_frenkel test_compute_frenkel.cpp) target_link_libraries(test_compute_frenkel PRIVATE lammps GTest::GMock) add_test(NAME ComputeFrenkel COMMAND test_compute_frenkel) +add_kokkos_test(NAME ComputeFrenkel COMMAND test_compute_frenkel) add_executable(test_variables test_variables.cpp) target_link_libraries(test_variables PRIVATE lammps GTest::GMock) add_test(NAME Variables COMMAND test_variables) +add_kokkos_test(NAME Variables COMMAND test_variables) add_executable(test_kim_commands test_kim_commands.cpp) if(KIM_EXTRA_UNITTESTS) @@ -132,17 +147,20 @@ add_executable(test_reset_atoms test_reset_atoms.cpp) target_compile_definitions(test_reset_atoms PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_reset_atoms PRIVATE lammps GTest::GMock) add_test(NAME ResetAtoms COMMAND test_reset_atoms) +add_kokkos_test(NAME ResetAtoms COMMAND test_reset_atoms) if(PKG_MOLECULE) add_executable(test_compute_global test_compute_global.cpp) target_compile_definitions(test_compute_global PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_compute_global PRIVATE lammps GTest::GMock) add_test(NAME ComputeGlobal COMMAND test_compute_global) + add_kokkos_test(NAME ComputeGlobal COMMAND test_compute_global) add_executable(test_compute_chunk test_compute_chunk.cpp) target_compile_definitions(test_compute_chunk PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(test_compute_chunk PRIVATE lammps GTest::GMock) add_test(NAME ComputeChunk COMMAND test_compute_chunk) + add_kokkos_test(NAME ComputeChunk COMMAND test_compute_chunk) endif() add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) @@ -152,7 +170,9 @@ add_mpi_test(NAME MPILoadBalancing NUM_PROCS 4 COMMAND $ 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_compute_frenkel.cpp b/unittest/commands/test_compute_frenkel.cpp index a48e9ddc32f..46caa6b3d4f 100644 --- a/unittest/commands/test_compute_frenkel.cpp +++ b/unittest/commands/test_compute_frenkel.cpp @@ -230,6 +230,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 9ad54bc664d..ff1023c35bb 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -616,6 +616,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_delete_atoms.cpp b/unittest/commands/test_delete_atoms.cpp index 0caefce4656..af30e5671cc 100644 --- a/unittest/commands/test_delete_atoms.cpp +++ b/unittest/commands/test_delete_atoms.cpp @@ -17,6 +17,7 @@ #include "group.h" #include "info.h" #include "input.h" +#include "library.h" #include "math_const.h" #include "region.h" #include "variable.h" @@ -227,6 +228,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_fix_spring_chunk.cpp b/unittest/commands/test_fix_spring_chunk.cpp index d9b613b735a..78aa742dc2b 100644 --- a/unittest/commands/test_fix_spring_chunk.cpp +++ b/unittest/commands/test_fix_spring_chunk.cpp @@ -14,6 +14,7 @@ #include "atom.h" #include "fix.h" +#include "library.h" #include "modify.h" #include "utils.h" @@ -131,6 +132,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index e4e18f1a739..c7a427d6835 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -852,6 +852,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_info.cpp b/unittest/commands/test_info.cpp index 2c86c9643ee..48ecb0406b0 100644 --- a/unittest/commands/test_info.cpp +++ b/unittest/commands/test_info.cpp @@ -17,6 +17,7 @@ #include "info.h" #include "input.h" +#include "library.h" #include "platform.h" #include "utils.h" @@ -507,6 +508,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_input_validation.cpp b/unittest/commands/test_input_validation.cpp index 3eaa4f6beb6..4784fe2c3a8 100644 --- a/unittest/commands/test_input_validation.cpp +++ b/unittest/commands/test_input_validation.cpp @@ -17,6 +17,7 @@ #include "lammps.h" #include "info.h" +#include "library.h" #include "utils.h" #include "../testing/core.h" @@ -160,6 +161,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_kspace_auto_slab.cpp b/unittest/commands/test_kspace_auto_slab.cpp index 7d59f5e371f..60046d77f9e 100644 --- a/unittest/commands/test_kspace_auto_slab.cpp +++ b/unittest/commands/test_kspace_auto_slab.cpp @@ -16,6 +16,7 @@ #include "atom.h" #include "comm.h" #include "domain.h" +#include "library.h" #include "gtest/gtest.h" #include "utils.h" @@ -211,6 +212,13 @@ int main(int argc, char **argv) if ((argc > 1) && (std::string(argv[1]) == "-v")) verbose = true; const int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_kspace_group_group_slab.cpp b/unittest/commands/test_kspace_group_group_slab.cpp index 3d77a1b0d04..a320fb9beb2 100644 --- a/unittest/commands/test_kspace_group_group_slab.cpp +++ b/unittest/commands/test_kspace_group_group_slab.cpp @@ -32,6 +32,7 @@ #include "comm.h" #include "compute.h" #include "domain.h" +#include "library.h" #include "gtest/gtest.h" #include "modify.h" #include "utils.h" @@ -177,6 +178,13 @@ int main(int argc, char **argv) if ((argc > 1) && (std::string(argv[1]) == "-v")) verbose = true; const int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_labelmap.cpp b/unittest/commands/test_labelmap.cpp index dad30dd5838..8cb73f9eed0 100644 --- a/unittest/commands/test_labelmap.cpp +++ b/unittest/commands/test_labelmap.cpp @@ -18,6 +18,7 @@ #include "domain.h" #include "info.h" #include "label_map.h" +#include "library.h" #include "math_const.h" #include "modify.h" @@ -390,6 +391,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_lattice_region.cpp b/unittest/commands/test_lattice_region.cpp index a76ec3ca1ab..4f9fa1ac86a 100644 --- a/unittest/commands/test_lattice_region.cpp +++ b/unittest/commands/test_lattice_region.cpp @@ -19,6 +19,7 @@ #include "input.h" #include "lammps.h" #include "lattice.h" +#include "library.h" #include "region.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -645,6 +646,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_pair_ldd.cpp b/unittest/commands/test_pair_ldd.cpp index dcf045cdaa2..d23b30358bd 100644 --- a/unittest/commands/test_pair_ldd.cpp +++ b/unittest/commands/test_pair_ldd.cpp @@ -16,6 +16,7 @@ #include "atom.h" #include "force.h" #include "info.h" +#include "library.h" #include "pair.h" #include "utils.h" @@ -177,6 +178,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_regions.cpp b/unittest/commands/test_regions.cpp index e74637e17ce..1977892b2fd 100644 --- a/unittest/commands/test_regions.cpp +++ b/unittest/commands/test_regions.cpp @@ -18,6 +18,7 @@ #include "group.h" #include "info.h" #include "input.h" +#include "library.h" #include "region.h" #include "../testing/core.h" @@ -298,6 +299,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_reset_atoms.cpp b/unittest/commands/test_reset_atoms.cpp index 90543333329..dcc59d0c9d4 100644 --- a/unittest/commands/test_reset_atoms.cpp +++ b/unittest/commands/test_reset_atoms.cpp @@ -819,6 +819,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_restart_settings.cpp b/unittest/commands/test_restart_settings.cpp index 6ada38858eb..9744513542e 100644 --- a/unittest/commands/test_restart_settings.cpp +++ b/unittest/commands/test_restart_settings.cpp @@ -21,6 +21,7 @@ #include "atom.h" #include "info.h" +#include "library.h" #include "utils.h" #include "../testing/core.h" @@ -187,6 +188,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index cb529903509..0caa828974f 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -16,6 +16,7 @@ #include "atom.h" #include "compute.h" #include "domain.h" +#include "library.h" #include "math_const.h" #include "modify.h" @@ -602,6 +603,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 1723bf76b6d..c5a4ba7b1a7 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -19,6 +19,7 @@ #include "force.h" #include "info.h" #include "input.h" +#include "library.h" #include "output.h" #include "platform.h" #include "update.h" @@ -668,6 +669,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_thermo.cpp b/unittest/commands/test_thermo.cpp index e3c9e28cde3..031576ea6cc 100644 --- a/unittest/commands/test_thermo.cpp +++ b/unittest/commands/test_thermo.cpp @@ -20,6 +20,7 @@ #include "error.h" #include "info.h" #include "input.h" +#include "library.h" #include "output.h" #include "thermo.h" #include "utils.h" @@ -750,6 +751,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index 6cb0ace076f..f33aa3bcf84 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -18,6 +18,7 @@ #include "group.h" #include "info.h" #include "input.h" +#include "library.h" #include "math_const.h" #include "region.h" #include "variable.h" @@ -1108,6 +1109,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/CMakeLists.txt b/unittest/formats/CMakeLists.txt index b52fafe808d..b2a0d6ee36d 100644 --- a/unittest/formats/CMakeLists.txt +++ b/unittest/formats/CMakeLists.txt @@ -3,10 +3,12 @@ add_executable(test_atom_styles test_atom_styles.cpp) target_link_libraries(test_atom_styles PRIVATE lammps GTest::GMock) add_test(NAME AtomStyles COMMAND test_atom_styles) +add_kokkos_test(NAME AtomStyles COMMAND test_atom_styles) add_executable(test_image_flags test_image_flags.cpp) target_link_libraries(test_image_flags PRIVATE lammps GTest::GMock) add_test(NAME ImageFlags COMMAND test_image_flags) +add_kokkos_test(NAME ImageFlags COMMAND test_image_flags) add_executable(test_input_convert test_input_convert.cpp) target_link_libraries(test_input_convert PRIVATE lammps GTest::GMockMain) @@ -15,6 +17,7 @@ add_test(NAME InputConvert COMMAND test_input_convert) add_executable(test_molecule_file test_molecule_file.cpp) target_link_libraries(test_molecule_file PRIVATE lammps GTest::GMock) add_test(NAME MoleculeFile COMMAND test_molecule_file) +add_kokkos_test(NAME MoleculeFile COMMAND test_molecule_file) add_executable(test_pair_unit_convert test_pair_unit_convert.cpp) target_link_libraries(test_pair_unit_convert PRIVATE lammps GTest::GMock) @@ -50,6 +53,7 @@ set_tests_properties(TextFileReader PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${ add_executable(test_file_operations test_file_operations.cpp) target_link_libraries(test_file_operations PRIVATE lammps GTest::GMock) add_test(NAME FileOperations COMMAND test_file_operations) +add_kokkos_test(NAME FileOperations COMMAND test_file_operations) # try to mitigate possible OpenMPI bug set_tests_properties(TextFileReader PROPERTIES ENVIRONMENT "OMPI_MCA_sharedfp=\"^sm\"") @@ -57,6 +61,7 @@ add_executable(test_dump_atom test_dump_atom.cpp) target_link_libraries(test_dump_atom PRIVATE lammps GTest::GMock) add_test(NAME DumpAtom COMMAND test_dump_atom) set_tests_properties(DumpAtom PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +add_kokkos_test(NAME DumpAtom COMMAND test_dump_atom ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") find_program(GZIP_EXECUTABLE NAMES gzip) if(PKG_COMPRESS AND GZIP_FOUND) @@ -116,6 +121,7 @@ add_executable(test_dump_custom test_dump_custom.cpp) target_link_libraries(test_dump_custom PRIVATE lammps GTest::GMock) add_test(NAME DumpCustom COMMAND test_dump_custom) set_tests_properties(DumpCustom PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +add_kokkos_test(NAME DumpCustom COMMAND test_dump_custom ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") if(PKG_KOKKOS) add_executable(test_dump_kokkos_triclinic_pbc test_dump_kokkos_triclinic_pbc.cpp) @@ -128,15 +134,18 @@ add_executable(test_dump_cfg test_dump_cfg.cpp) target_link_libraries(test_dump_cfg PRIVATE lammps GTest::GMock) add_test(NAME DumpCfg COMMAND test_dump_cfg) set_tests_properties(DumpCfg PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +add_kokkos_test(NAME DumpCfg COMMAND test_dump_cfg ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_dump_local test_dump_local.cpp) target_link_libraries(test_dump_local PRIVATE lammps GTest::GMock) add_test(NAME DumpLocal COMMAND test_dump_local) set_tests_properties(DumpLocal PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +add_kokkos_test(NAME DumpLocal COMMAND test_dump_local ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") add_executable(test_dump_grid test_dump_grid.cpp) target_link_libraries(test_dump_grid PRIVATE lammps GTest::GMock) add_test(NAME DumpGrid COMMAND test_dump_grid) +add_kokkos_test(NAME DumpGrid COMMAND test_dump_grid) if(PKG_EXTRA-DUMP) add_executable(test_dump_vtk test_dump_vtk.cpp) @@ -161,4 +170,8 @@ endif() if(BUILD_TOOLS) set_tests_properties(DumpAtom PROPERTIES ENVIRONMENT "BINARY2TXT_EXECUTABLE=$") set_tests_properties(DumpCustom PROPERTIES ENVIRONMENT "BINARY2TXT_EXECUTABLE=$") + if(PKG_KOKKOS) + set_tests_properties(DumpAtomKokkos DumpCustomKokkos PROPERTIES + ENVIRONMENT "${KOKKOS_TEST_ENVIRONMENT};BINARY2TXT_EXECUTABLE=$") + endif() endif() diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index 9b02dcdb64f..84239edcf3c 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -20,6 +20,7 @@ #include "atom_vec_tri.h" #include "body.h" #include "info.h" +#include "library.h" #include "math_const.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -5573,6 +5574,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 4ab283bac53..f1b6e94829f 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -15,6 +15,7 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "library.h" #include "output.h" #include "thermo.h" #include "utils.h" @@ -977,6 +978,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_dump_cfg.cpp b/unittest/formats/test_dump_cfg.cpp index 2e094c36912..3ca03781be3 100644 --- a/unittest/formats/test_dump_cfg.cpp +++ b/unittest/formats/test_dump_cfg.cpp @@ -15,6 +15,7 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "library.h" #include "utils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -164,6 +165,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_dump_custom.cpp b/unittest/formats/test_dump_custom.cpp index 99693ec0885..c55f002bb8e 100644 --- a/unittest/formats/test_dump_custom.cpp +++ b/unittest/formats/test_dump_custom.cpp @@ -15,6 +15,7 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "library.h" #include "output.h" #include "thermo.h" #include "utils.h" @@ -407,6 +408,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_dump_grid.cpp b/unittest/formats/test_dump_grid.cpp index b22c2b4212b..d30bb5d14f2 100644 --- a/unittest/formats/test_dump_grid.cpp +++ b/unittest/formats/test_dump_grid.cpp @@ -19,6 +19,7 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "library.h" #include "utils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -414,6 +415,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_dump_local.cpp b/unittest/formats/test_dump_local.cpp index 004a0590cd3..1de74e62cb8 100644 --- a/unittest/formats/test_dump_local.cpp +++ b/unittest/formats/test_dump_local.cpp @@ -15,6 +15,7 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "library.h" #include "output.h" #include "thermo.h" #include "utils.h" @@ -260,6 +261,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_file_operations.cpp b/unittest/formats/test_file_operations.cpp index efcad08834d..7a9a3a6b395 100644 --- a/unittest/formats/test_file_operations.cpp +++ b/unittest/formats/test_file_operations.cpp @@ -16,6 +16,7 @@ #include "atom.h" #include "domain.h" #include "error.h" +#include "library.h" #include "update.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -685,6 +686,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_image_flags.cpp b/unittest/formats/test_image_flags.cpp index a21910392d5..6e991e9fcb9 100644 --- a/unittest/formats/test_image_flags.cpp +++ b/unittest/formats/test_image_flags.cpp @@ -13,6 +13,7 @@ #include "../testing/core.h" #include "atom.h" +#include "library.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -266,6 +267,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/formats/test_molecule_file.cpp b/unittest/formats/test_molecule_file.cpp index e760d0baf61..6ab805a9219 100644 --- a/unittest/formats/test_molecule_file.cpp +++ b/unittest/formats/test_molecule_file.cpp @@ -15,6 +15,7 @@ #include "atom.h" #include "info.h" #include "lammps.h" +#include "library.h" #include "molecule.h" #include "platform.h" #include "gmock/gmock.h" @@ -862,6 +863,13 @@ int main(int argc, char **argv) if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + // same workaround as the force-style and FFT3d test drivers + + lammps_kokkos_finalize(); + MPI_Finalize(); return rv; } diff --git a/unittest/testing/core.h b/unittest/testing/core.h index a6687003b5d..0f72288b6ae 100644 --- a/unittest/testing/core.h +++ b/unittest/testing/core.h @@ -18,10 +18,12 @@ #include "input.h" #include "lammps.h" #include "platform.h" +#include "utils.h" #include "variable.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include #include #include @@ -123,6 +125,16 @@ class LAMMPSTest : public ::testing::Test { LAMMPS::argv full_args = {testbinary}; full_args.insert(full_args.end(), args.begin(), args.end()); + // append the accelerator command line flags given in the environment. + // this lets CTest run the very same fixtures a second time with, e.g., + // LAMMPS_ACCELERATOR_ARGS="-k on t 1 -sf kk" so that the KOKKOS styles + // and commands are exercised without duplicating any test bodies. + const char *accel_args = std::getenv("LAMMPS_ACCELERATOR_ARGS"); + if (accel_args && (accel_args[0] != '\0')) { + auto accel = LAMMPS_NS::utils::split_words(accel_args); + full_args.insert(full_args.end(), accel.begin(), accel.end()); + } + HIDE_OUTPUT([&] { lmp = new LAMMPS(full_args, MPI_COMM_WORLD); info = new Info(lmp); From a3f5834fe08c2d8d834db3c68ef95294e0bcd51f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 03:40:51 +0000 Subject: [PATCH 020/120] unittest: re-apply the full neighbor list newton setting after the pre_commands The kokkos_omp_full and kokkos_serial_full test cases select 'newton off' with -var newton_pair off -var newton_bond off on the command line, because the KOKKOS package requires it together with a full neighbor list. About 50 reference files redefine those index variables in their pre_commands (a convention taken over from the GPU package tests), which discards the command line setting and made those tests fail with 'Must use newton off with KOKKOS package option neigh full'. Re-apply the setting after the pre_commands have been processed. --- unittest/force-styles/test_angle_style.cpp | 24 +++++++++++++++++++ unittest/force-styles/test_bond_style.cpp | 24 +++++++++++++++++++ unittest/force-styles/test_dihedral_style.cpp | 24 +++++++++++++++++++ unittest/force-styles/test_fix_timestep.cpp | 23 ++++++++++++++++++ unittest/force-styles/test_improper_style.cpp | 24 +++++++++++++++++++ unittest/force-styles/test_min_style.cpp | 23 ++++++++++++++++++ unittest/force-styles/test_output_style.cpp | 23 ++++++++++++++++++ unittest/force-styles/test_pair_style.cpp | 24 +++++++++++++++++++ 8 files changed, 189 insertions(+) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index 340c24ecc24..2e0b6d9c533 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -40,6 +40,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -97,6 +115,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); parse_input_script(input_file); @@ -184,6 +203,7 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg, const bool newton = true) for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); command("variable angle_style index '" + cfg.angle_style + "'"); command("variable data_file index " + cfg.basename + ".data"); @@ -736,7 +756,9 @@ TEST(AngleStyle, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args, false); + kokkos_full_neigh = false; }; TEST(AngleStyle, kokkos_serial) @@ -803,7 +825,9 @@ TEST(AngleStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args, false); + kokkos_full_neigh = false; }; TEST(AngleStyle, kokkos_gpu) diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index b488d5763a7..872c458f62c 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -40,6 +40,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -97,6 +115,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); parse_input_script(input_file); @@ -181,6 +200,7 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); command("variable bond_style index '" + cfg.bond_style + "'"); command("variable data_file index " + cfg.basename + ".data"); @@ -718,7 +738,9 @@ TEST(BondStyle, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(BondStyle, kokkos_serial) @@ -785,7 +807,9 @@ TEST(BondStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(BondStyle, kokkos_gpu) diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 7ac0a9a3c4a..b8a6dda9665 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -40,6 +40,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -109,6 +127,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); parse_input_script(input_file); @@ -193,6 +212,7 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); command("variable dihedral_style index '" + cfg.dihedral_style + "'"); command("variable data_file index " + cfg.basename + ".data"); @@ -735,7 +755,9 @@ TEST(DihedralStyle, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(DihedralStyle, kokkos_serial) @@ -803,7 +825,9 @@ TEST(DihedralStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(DihedralStyle, kokkos_gpu) diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 024e54f9274..4cf80a44b59 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -42,6 +42,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -86,6 +104,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool use_re command("variable input_dir index " + INPUT_FOLDER); for (const auto &pre_command : cfg.pre_commands) command(pre_command); + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); lmp->input->file(input_file.c_str()); @@ -1176,7 +1195,9 @@ TEST(FixTimestep, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(FixTimestep, kokkos_serial) @@ -1245,7 +1266,9 @@ TEST(FixTimestep, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(FixTimestep, kokkos_gpu) diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 1275259c46e..158a42e1d0c 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -40,6 +40,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -97,6 +115,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); parse_input_script(input_file); @@ -181,6 +200,7 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); command("variable improper_style index '" + cfg.improper_style + "'"); command("variable data_file index " + cfg.basename + ".data"); @@ -710,7 +730,9 @@ TEST(ImproperStyle, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(ImproperStyle, kokkos_serial) @@ -778,7 +800,9 @@ TEST(ImproperStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args); + kokkos_full_neigh = false; }; TEST(ImproperStyle, kokkos_gpu) diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index dbfcd228f4a..cc5c9762dec 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -58,6 +58,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + // fixed iteration budget: enough to exercise the algorithms and the line // searches while keeping the tests fast and the reference deterministic static constexpr int MAX_ITER = 100; @@ -132,6 +150,7 @@ static LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg) command("variable input_dir index " + INPUT_FOLDER); for (const auto &pre_command : cfg.pre_commands) command(pre_command); + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); lmp->input->file(input_file.c_str()); @@ -335,7 +354,9 @@ TEST(MinStyle, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_min_test(args, kokkos_epsilon()); + kokkos_full_neigh = false; } TEST(MinStyle, kokkos_serial) @@ -404,7 +425,9 @@ TEST(MinStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_min_test(args, kokkos_epsilon()); + kokkos_full_neigh = false; } TEST(MinStyle, kokkos_gpu) diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index 68af8bd93ac..f0c665e984d 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -55,6 +55,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + // fixed number of MD steps before collecting the output, so that // history-dependent styles (msd, vacf, ave/time, ave/atom) have data static constexpr int RUN_STEPS = 10; @@ -187,6 +205,7 @@ static LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg) command("variable input_dir index " + INPUT_FOLDER); for (const auto &pre_command : cfg.pre_commands) command(pre_command); + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); lmp->input->file(input_file.c_str()); @@ -413,7 +432,9 @@ TEST(OutputStyle, kokkos_omp_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_output_test(args, kokkos_epsilon(), true); + kokkos_full_neigh = false; } TEST(OutputStyle, kokkos_serial) @@ -482,7 +503,9 @@ TEST(OutputStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_output_test(args, kokkos_epsilon(), true); + kokkos_full_neigh = false; } TEST(OutputStyle, kokkos_gpu) diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index cbdb2d8192f..a5a92563b4f 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -45,6 +45,24 @@ using ::testing::StartsWith; using namespace LAMMPS_NS; +// the "kokkos_omp_full" and "kokkos_serial_full" test cases select "newton off" +// through the newton_pair and newton_bond index variables on the command line. +// several YAML files redefine those variables in their pre_commands (a +// convention taken over from the GPU package tests), which discards the command +// line setting, so the override has to be re-applied after the pre_commands +// have been processed and before the input template is read. + +static bool kokkos_full_neigh = false; + +static void enforce_kokkos_full_neigh(LAMMPS *lmp) +{ + if (!kokkos_full_neigh) return; + lmp->input->one("variable newton_pair delete"); + lmp->input->one("variable newton_pair index off"); + lmp->input->one("variable newton_bond delete"); + lmp->input->one("variable newton_bond index off"); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -103,6 +121,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); std::string input_file = platform::path_join(INPUT_FOLDER, cfg.input_file); parse_input_script(input_file); @@ -210,6 +229,7 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) for (const auto &pre_command : cfg.pre_commands) { command(pre_command); } + enforce_kokkos_full_neigh(lmp); command("variable pair_style index '" + cfg.pair_style + "'"); command("variable data_file index " + cfg.basename + ".data"); @@ -1018,7 +1038,9 @@ TEST(PairStyle, kokkos_omp_full) // flagged with the "single_thread" tag in their YAML file if (test_config.has_tag("single_thread")) args[9] = "1"; + kokkos_full_neigh = true; run_kokkos_test(args, false); + kokkos_full_neigh = false; }; TEST(PairStyle, kokkos_serial) @@ -1087,7 +1109,9 @@ TEST(PairStyle, kokkos_serial_full) "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; + kokkos_full_neigh = true; run_kokkos_test(args, false); + kokkos_full_neigh = false; }; TEST(PairStyle, kokkos_gpu) From 6d7ff6d585ad9dd210243efda535e1093152cb2d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 03:40:52 +0000 Subject: [PATCH 021/120] KOKKOS: reject the superellipsoid option in atom style ellipsoid/kk The KOKKOS version of the ellipsoid atom style does not implement the superellipsoid extension: it neither allocates the per-atom radius array that the option adds nor handles the additional bonus data in its device pack and unpack routines. Requesting it therefore crashed in AtomVec::create_atom() when the first atom was created. Stop with an error message instead and document the restriction. --- doc/src/atom_style.rst | 4 +++- src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp | 14 ++++++++++++++ src/KOKKOS/atom_vec_ellipsoid_kokkos.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/src/atom_style.rst b/doc/src/atom_style.rst index cd94cc54645..dd410548602 100644 --- a/doc/src/atom_style.rst +++ b/doc/src/atom_style.rst @@ -361,7 +361,9 @@ By adding the flag *superellipsoid* to the *ellipsoid* atom_style command, the particles can be superellipsoids, which are a generalization of ellipsoids with two additional blockiness parameters that control the shape. Superellipsoids also store the principal -moments of inertia of the particle. +moments of inertia of the particle. The *superellipsoid* option is not +supported by the KOKKOS package version of the *ellipsoid* atom style, +which will stop with an error message when the option is used. For the *line* style, particles can be are idealized line segments which store a per-particle mass and length and orientation (i.e. the diff --git a/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp b/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp index 73f44921fc1..02e84d553b6 100644 --- a/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp +++ b/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp @@ -56,6 +56,20 @@ AtomVecEllipsoidKokkos::~AtomVecEllipsoidKokkos() } } +/* ---------------------------------------------------------------------- + process sub-style args + the KOKKOS version does not implement the superellipsoid extension +------------------------------------------------------------------------- */ + +void AtomVecEllipsoidKokkos::process_args(int narg, char **arg) +{ + for (int iarg = 0; iarg < narg; iarg++) + if (strcmp(arg[iarg], "superellipsoid") == 0) + error->all(FLERR, "Atom style ellipsoid/kk does not support the superellipsoid option"); + + AtomVecEllipsoid::process_args(narg, arg); +} + /* ---------------------------------------------------------------------- */ void AtomVecEllipsoidKokkos::init() diff --git a/src/KOKKOS/atom_vec_ellipsoid_kokkos.h b/src/KOKKOS/atom_vec_ellipsoid_kokkos.h index a87c9935091..9d7682450a9 100644 --- a/src/KOKKOS/atom_vec_ellipsoid_kokkos.h +++ b/src/KOKKOS/atom_vec_ellipsoid_kokkos.h @@ -63,6 +63,7 @@ class AtomVecEllipsoidKokkos : public AtomVecKokkos, public AtomVecEllipsoid { public: AtomVecEllipsoidKokkos(class LAMMPS *); ~AtomVecEllipsoidKokkos() override; + void process_args(int, char **) override; void init() override; void grow(int) override; From da67b03bb643d33ffb1e03bdb2dcecd2cf9f4c2f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 03:40:52 +0000 Subject: [PATCH 022/120] KOKKOS: add the finite size contribution of spheres in compute inertia/kk The KOKKOS version of compute inertia added the extended particle contribution only when one of the atom styles with bonus data was present, but Group::inertia_extended() also adds 0.4*m*r^2 for plain finite size spheres, which carry only a radius. With atom_style sphere the diagonal of the inertia tensor was therefore too small by that amount. Test with the atom flags that decide whether the extended contribution can be non-zero, and add a reference for the compute. --- src/KOKKOS/compute_inertia_kokkos.cpp | 19 ++++++------- .../force-styles/tests/compute-inertia.yaml | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 unittest/force-styles/tests/compute-inertia.yaml diff --git a/src/KOKKOS/compute_inertia_kokkos.cpp b/src/KOKKOS/compute_inertia_kokkos.cpp index a8915bab432..2bef823cb7d 100644 --- a/src/KOKKOS/compute_inertia_kokkos.cpp +++ b/src/KOKKOS/compute_inertia_kokkos.cpp @@ -48,15 +48,16 @@ void ComputeInertiaKokkos::compute_vector() groupKK->xcm_kk(igroup,masstotal,xcm); groupKK->inertia_kk(igroup,xcm,itensor); - // the extended-particle contribution reads the ellipsoid, line, tri and - // body bonus arrays, which have no device counterpart. when none of - // those atom styles is present it adds nothing, so skip it entirely and - // keep the whole compute on the device for the usual case - - if (atom->style_match("ellipsoid") || atom->style_match("line") || - atom->style_match("tri") || atom->style_match("body")) { - // inertia_extended() also reads the radius, the ellipsoid indices and the - // bonus data through the plain host pointers + // the extended-particle contribution reads the radius array and the + // ellipsoid, line, tri and body bonus arrays through the plain host + // pointers, none of which have a device counterpart. for point particles + // it adds nothing, so skip it entirely then and keep the whole compute on + // the device for the usual case. note that finite-size spheres carry only + // a radius and no bonus data, so testing the shape atom styles alone is + // not enough + + if ((atom->radius_flag) || (atom->ellipsoid_flag) || (atom->line_flag) || + (atom->tri_flag) || (atom->body_flag)) { atomKK->sync(Host,MASK_MASK|RMASS_MASK|TYPE_MASK|RADIUS_MASK|ELLIPSOID_MASK|BONUS_MASK); group->inertia_extended(igroup,itensor); } diff --git a/unittest/force-styles/tests/compute-inertia.yaml b/unittest/force-styles/tests/compute-inertia.yaml new file mode 100644 index 00000000000..b1a701ec5c5 --- /dev/null +++ b/unittest/force-styles/tests/compute-inertia.yaml @@ -0,0 +1,27 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Thu Sep 3 22:53:36 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: +prerequisites: | + atom sphere + compute inertia +pre_commands: | + variable atom_style delete + variable atom_style index sphere + variable pair_style delete + variable pair_style index 'zero 4.0' +post_commands: | + pair_coeff * * + set group all diameter 3.0 + set atom 1*8 diameter 5.0 + set atom 20*27 diameter 0.0 + set group all density 2.0 + compute test all inertia +input_file: in.colloid +natoms: 27 +global_vector: |- + 6 6.6570439741307418e+04 6.0263076187745297e+04 5.5798761902774473e+04 1.3819001881348519e+04 -3.3976932397737137e+03 1.6127390413375433e+03 +... From 04facf72f6a472b17686d2bb6ac79db625f4d35f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 04:03:06 +0000 Subject: [PATCH 023/120] unittest: skip the KOKKOS full neighbor list tests for styles that need newton on Many styles cannot run with a full neighbor list and 'newton off': the many-body pair styles, the tip4p styles, dihedral style charmm and the bonded interactions of angle style dipole all stop with an error that says so. Those are documented restrictions of the style, so turn such an error during the setup of the new kokkos_omp_full and kokkos_serial_full cases into a skipped test instead of a failure. The dihedral driver terminated the whole test program on a LAMMPS error, so it now rethrows for this case. --- unittest/force-styles/test_angle_style.cpp | 17 ++++++++++++++++ unittest/force-styles/test_bond_style.cpp | 17 ++++++++++++++++ unittest/force-styles/test_dihedral_style.cpp | 20 +++++++++++++++++++ unittest/force-styles/test_fix_timestep.cpp | 16 +++++++++++++++ unittest/force-styles/test_improper_style.cpp | 17 ++++++++++++++++ unittest/force-styles/test_min_style.cpp | 14 +++++++++++++ unittest/force-styles/test_output_style.cpp | 14 +++++++++++++ unittest/force-styles/test_pair_style.cpp | 20 +++++++++++++++++++ 8 files changed, 135 insertions(+) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index 2e0b6d9c533..d204cdfaac4 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -27,6 +27,7 @@ #include "fix.h" #include "force.h" #include "info.h" +#include "utils.h" #include "input.h" #include "modify.h" @@ -58,6 +59,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -329,6 +342,7 @@ TEST(AngleStyle, plain) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -458,6 +472,7 @@ TEST(AngleStyle, omp) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -577,6 +592,7 @@ static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -871,6 +887,7 @@ TEST(AngleStyle, numdiff) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 872c458f62c..8fc903eb700 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -27,6 +27,7 @@ #include "fix.h" #include "force.h" #include "info.h" +#include "utils.h" #include "input.h" #include "modify.h" @@ -58,6 +59,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -327,6 +340,7 @@ TEST(BondStyle, plain) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -458,6 +472,7 @@ TEST(BondStyle, omp) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -573,6 +588,7 @@ static void run_kokkos_test(LAMMPS::argv &args) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -853,6 +869,7 @@ TEST(BondStyle, numdiff) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index b8a6dda9665..230ef5d1615 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -28,6 +28,7 @@ #include "fix.h" #include "force.h" #include "info.h" +#include "utils.h" #include "input.h" #include "modify.h" @@ -58,6 +59,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -102,6 +115,9 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton fprintf(stderr, "LAMMPS Error: %s\n", ae.what()); exit(2); } catch (LAMMPSException &e) { + // let the caller turn a documented restriction of the style into a + // skipped test instead of terminating the whole test program + if (full_neigh_unsupported(e.what())) throw; fprintf(stderr, "LAMMPS Error: %s\n", e.what()); exit(3); } catch (fmt::format_error &fe) { @@ -342,6 +358,7 @@ TEST(DihedralStyle, plain) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -473,6 +490,7 @@ TEST(DihedralStyle, omp) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -589,6 +607,7 @@ static void run_kokkos_test(LAMMPS::argv &args) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -871,6 +890,7 @@ TEST(DihedralStyle, numdiff) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 4cf80a44b59..f8fc19ca187 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -25,6 +25,7 @@ #include "fix.h" #include "force.h" #include "info.h" +#include "utils.h" #include "input.h" #include "kspace.h" #include "modify.h" @@ -60,6 +61,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -323,6 +336,7 @@ TEST(FixTimestep, plain) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -646,6 +660,7 @@ TEST(FixTimestep, omp) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -958,6 +973,7 @@ static void run_kokkos_test(LAMMPS::argv &args) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 158a42e1d0c..3c885236284 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -27,6 +27,7 @@ #include "force.h" #include "improper.h" #include "info.h" +#include "utils.h" #include "input.h" #include "modify.h" @@ -58,6 +59,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -320,6 +333,7 @@ TEST(ImproperStyle, plain) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -451,6 +465,7 @@ TEST(ImproperStyle, omp) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -567,6 +582,7 @@ static void run_kokkos_test(LAMMPS::argv &args) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -846,6 +862,7 @@ TEST(ImproperStyle, numdiff) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index cc5c9762dec..b7fda063cf8 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -45,6 +45,7 @@ #include "compute.h" #include "domain.h" #include "info.h" +#include "utils.h" #include "input.h" #include "modify.h" @@ -76,6 +77,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + // fixed iteration budget: enough to exercise the algorithms and the line // searches while keeping the tests fast and the reference deterministic static constexpr int MAX_ITER = 100; @@ -198,6 +211,7 @@ static void run_min_test(LAMMPS::argv &args, double epsilon) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index f0c665e984d..57a60ea3a8a 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -42,6 +42,7 @@ #include "compute.h" #include "fix.h" #include "info.h" +#include "utils.h" #include "input.h" #include "modify.h" #include "update.h" @@ -73,6 +74,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + // fixed number of MD steps before collecting the output, so that // history-dependent styles (msd, vacf, ave/time, ave/atom) have data static constexpr int RUN_STEPS = 10; @@ -286,6 +299,7 @@ static void run_output_test(LAMMPS::argv &args, double epsilon, bool kokkos) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index a5a92563b4f..b7edd1906f7 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -26,6 +26,7 @@ #include "domain.h" #include "force.h" #include "info.h" +#include "utils.h" #include "input.h" #include "kspace.h" #include "modify.h" @@ -63,6 +64,18 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) lmp->input->one("variable newton_bond index off"); } +// styles that require "newton on" or a half neighbor list cannot run in the +// full neighbor list configuration of the KOKKOS package. those are +// documented restrictions of the style, so the corresponding test case is +// skipped instead of failed when the setup stops with such an error. + +static bool full_neigh_unsupported(const std::string &errmsg) +{ + if (!kokkos_full_neigh) return false; + return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || + LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); +} + void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg) { platform::unlink(cfg.basename + ".restart"); @@ -384,6 +397,7 @@ TEST(PairStyle, plain) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -594,6 +608,7 @@ TEST(PairStyle, omp) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -738,6 +753,7 @@ static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -916,6 +932,7 @@ void eatom_only_test(LAMMPS::argv args, const TestConfig &cfg) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -1184,6 +1201,7 @@ TEST(PairStyle, gpu) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -1275,6 +1293,7 @@ TEST(PairStyle, intel) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); @@ -1361,6 +1380,7 @@ TEST(PairStyle, opt) } catch (std::exception &e) { std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); FAIL() << e.what(); } std::string output = ::testing::internal::GetCapturedStdout(); From de859072ba2c9e32449098a109cadb2cb7c758ca Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 04:03:06 +0000 Subject: [PATCH 024/120] unittest: make the command and format tests pass with the KOKKOS package Running the fixtures with '-k on t 1 -sf kk' exposed several places that assume the plain styles: - an error thrown between BEGIN_HIDE_OUTPUT() and END_HIDE_OUTPUT() left the GoogleTest stdout capture active, so the next capture aborted the entire test program and hid the original error message. Track the capture state in the fixture and drop a capture left behind. - style names carry the accelerator suffix, e.g. 'atomic/kk'. Compare the atom style against the suffixed name when an accelerated variant exists, so the test also confirms it is in use, and make the compute and fix style patterns of the info command tolerate a suffix. - the sum over atoms of the total force on a group is zero only up to roundoff, and the accelerator packages sum in a different order. Compare against zero instead of pinning the roundoff values of the plain styles, and use a relative tolerance for the global scalars of the compute tests. - skip the tests of documented KOKKOS restrictions: label maps, atom styles without a KOKKOS version, the superellipsoid option, compute group/group with pppm/kk, granular pair styles that need newton off, and r-RESPA support of the pair styles. --- unittest/commands/test_compute_chunk.cpp | 2 + unittest/commands/test_compute_global.cpp | 29 +++- unittest/commands/test_groups.cpp | 33 ++-- unittest/commands/test_info.cpp | 26 +-- .../commands/test_kspace_group_group_slab.cpp | 2 + unittest/commands/test_labelmap.cpp | 4 + unittest/commands/test_restart_settings.cpp | 2 + unittest/commands/test_set_property.cpp | 4 + unittest/commands/test_simple_commands.cpp | 3 + unittest/commands/test_variables.cpp | 4 + unittest/formats/test_atom_styles.cpp | 153 +++++++++++------- unittest/formats/test_molecule_file.cpp | 6 + unittest/testing/core.h | 52 ++++-- 13 files changed, 223 insertions(+), 97 deletions(-) diff --git a/unittest/commands/test_compute_chunk.cpp b/unittest/commands/test_compute_chunk.cpp index d04f2d3e4c8..d32eac8e220 100644 --- a/unittest/commands/test_compute_chunk.cpp +++ b/unittest/commands/test_compute_chunk.cpp @@ -481,6 +481,8 @@ TEST_F(ComputeInertiaChunkTest, Sphere) TEST_F(ComputeInertiaChunkTest, Superellipsoid) { + // atom style ellipsoid/kk does not support the superellipsoid option + if (lmp->suffix_enable) GTEST_SKIP() << "superellipsoid is not supported with an accelerator suffix"; if (!info->has_style("atom", "ellipsoid")) GTEST_SKIP(); // same as Ellipsoid, but with atom_style "ellipsoid superellipsoid". diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index ff1023c35bb..c168c9385af 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -20,6 +20,8 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include + #include #include @@ -61,6 +63,17 @@ class ComputeGlobalTest : public LAMMPSTest { { return (double **)lammps_extract_compute(lmp, id, LMP_STYLE_GLOBAL, LMP_TYPE_ARRAY); } + + // compare a global scalar of a compute. an accelerator package sums the + // per-atom contributions in a different order, so the last digits of the + // result may differ from the reference value of the plain styles + void EXPECT_SCALAR_EQ(const char *id, double expected) + { + if (lmp->suffix_enable) + EXPECT_NEAR(get_scalar(id), expected, std::fabs(expected) * 1.0e-13); + else + EXPECT_SCALAR_EQ(id, expected); + } }; TEST_F(ComputeGlobalTest, Energy) @@ -95,14 +108,14 @@ TEST_F(ComputeGlobalTest, Energy) command("run 0 post no"); END_HIDE_OUTPUT(); - EXPECT_DOUBLE_EQ(get_scalar("ke1"), 2.3405256449146168); - EXPECT_DOUBLE_EQ(get_scalar("ke2"), 1.192924237073665); - EXPECT_DOUBLE_EQ(get_scalar("pe1"), 24155.155261642241); - EXPECT_DOUBLE_EQ(get_scalar("pe2"), 361.37528652881286); - EXPECT_DOUBLE_EQ(get_scalar("pe3"), 0.0); + EXPECT_SCALAR_EQ("ke1", 2.3405256449146168); + EXPECT_SCALAR_EQ("ke2", 1.192924237073665); + EXPECT_SCALAR_EQ("pe1", 24155.155261642241); + EXPECT_SCALAR_EQ("pe2", 361.37528652881286); + EXPECT_SCALAR_EQ("pe3", 0.0); EXPECT_NEAR(get_scalar("pr1"), 1956948.4735454607, 0.000000005); EXPECT_NEAR(get_scalar("pr2"), 1956916.7725807722, 0.000000005); - EXPECT_DOUBLE_EQ(get_scalar("pr3"), 0.0); + EXPECT_SCALAR_EQ("pr3", 0.0); auto *pr1 = get_vector("pr1"); auto *pr2 = get_vector("pr2"); auto *pr3 = get_vector("pr3"); @@ -269,7 +282,7 @@ TEST_F(ComputeGlobalTest, Reduction) auto *ave = get_vector("ave"); auto *rep = get_vector("rep"); - EXPECT_DOUBLE_EQ(get_scalar("chg"), 0.51000000000000001); + EXPECT_SCALAR_EQ("chg", 0.51000000000000001); EXPECT_DOUBLE_EQ(min[0], -2.7406520384725965); EXPECT_DOUBLE_EQ(min[1], -20385.448391361348); @@ -528,6 +541,8 @@ TEST_F(ComputeInertiaTest, Body) TEST_F(ComputeInertiaTest, Superellipsoid) { + // atom style ellipsoid/kk does not support the superellipsoid option + if (lmp->suffix_enable) GTEST_SKIP() << "superellipsoid is not supported with an accelerator suffix"; if (!info->has_style("atom", "ellipsoid")) GTEST_SKIP(); // same configuration as the Ellipsoid test, but with atom_style diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index c7a427d6835..5c70a1080fd 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -526,25 +526,32 @@ TEST_F(GroupTest, VariableFunctions) EXPECT_DOUBLE_EQ(center[1], 0); EXPECT_DOUBLE_EQ(center[2], 0); + // the total force on a group of this equilibrated system is zero up to the + // roundoff of the sum over its atoms. the individual values depend on the + // summation order and thus on the accelerator package in use, so only the + // magnitude is checked here + + constexpr double FORCE_EPSILON = 1.0e-06; + group->fcm(0, center); - EXPECT_NEAR(center[0], 1.9375372195540308e-08, EPSILON); - EXPECT_NEAR(center[1], -1.0289756668946382e-07, EPSILON); - EXPECT_NEAR(center[2], -1.3366961142124989e-07, EPSILON); + EXPECT_NEAR(center[0], 0, FORCE_EPSILON); + EXPECT_NEAR(center[1], 0, FORCE_EPSILON); + EXPECT_NEAR(center[2], 0, FORCE_EPSILON); group->fcm(two, center); - EXPECT_NEAR(center[0], 2.4316524016576579e-08, EPSILON); - EXPECT_NEAR(center[1], -6.0179227712175987e-08, EPSILON); - EXPECT_NEAR(center[2], -1.4393012942592875e-07, EPSILON); + EXPECT_NEAR(center[0], 0, FORCE_EPSILON); + EXPECT_NEAR(center[1], 0, FORCE_EPSILON); + EXPECT_NEAR(center[2], 0, FORCE_EPSILON); group->fcm(three, center); - EXPECT_NEAR(center[0], 0, EPSILON); - EXPECT_NEAR(center[1], 0, EPSILON); - EXPECT_NEAR(center[2], 0, EPSILON); + EXPECT_NEAR(center[0], 0, FORCE_EPSILON); + EXPECT_NEAR(center[1], 0, FORCE_EPSILON); + EXPECT_NEAR(center[2], 0, FORCE_EPSILON); group->fcm(one, center, top); - EXPECT_NEAR(center[0], -5.5879354476928711e-09, EPSILON); - EXPECT_NEAR(center[1], -1.6743454178680395e-08, EPSILON); - EXPECT_NEAR(center[2], 2.6166095290491853e-08, EPSILON); + EXPECT_NEAR(center[0], 0, FORCE_EPSILON); + EXPECT_NEAR(center[1], 0, FORCE_EPSILON); + EXPECT_NEAR(center[2], 0, FORCE_EPSILON); EXPECT_DOUBLE_EQ(group->ke(one), 0); EXPECT_DOUBLE_EQ(group->ke(one, top), 0); @@ -633,6 +640,8 @@ TEST_F(GroupTest, InertiaSphere) TEST_F(GroupTest, InertiaSuperellipsoid) { + // atom style ellipsoid/kk does not support the superellipsoid option + if (lmp->suffix_enable) GTEST_SKIP() << "superellipsoid is not supported with an accelerator suffix"; if (!info->has_style("atom", "ellipsoid")) GTEST_SKIP(); // same configuration as InertiaEllipsoid, but atom_style "ellipsoid diff --git a/unittest/commands/test_info.cpp b/unittest/commands/test_info.cpp index 48ecb0406b0..ebbb53b6fdd 100644 --- a/unittest/commands/test_info.cpp +++ b/unittest/commands/test_info.cpp @@ -180,14 +180,14 @@ TEST_F(InfoTest, Objects) ASSERT_THAT(output, HasSubstr(" Boundary: lo ")); ASSERT_THAT(output, HasSubstr(" No Boundary")); ASSERT_THAT(output, HasSubstr("Compute information:")); - ASSERT_MATCH(output, "Compute\\[ +[0-9]\\]: +ke, +style = ke, +group = all"); + ASSERT_MATCH(output, "Compute\\[ +[0-9]\\]: +ke, +style = ke[^,]*, +group = all"); ASSERT_THAT(output, HasSubstr("Dump information:")); ASSERT_MATCH(output, "Dump\\[ +0\\]: +d1, +file = info_test.dump, +style = atom, " "+group = all, +every = 100"); ASSERT_MATCH(output, "Dump\\[ +1\\]: +d2, +file = info_test2.dump, +style = atom, " "+group = all, +every = eq"); ASSERT_THAT(output, HasSubstr("Fix information:")); - ASSERT_MATCH(output, "Fix\\[ +0\\]: +nve, +style = nve, +group = all"); + ASSERT_MATCH(output, "Fix\\[ +0\\]: +nve, +style = nve[^,]*, +group = all"); ASSERT_THAT(output, HasSubstr("Variable information:")); ASSERT_MATCH(output, "Variable\\[ +[0-9]+\\]: +eq, +style = equal,"); ASSERT_MATCH(output, "Variable\\[ +[0-9]+\\]: +str, +style = string,"); @@ -214,14 +214,17 @@ TEST_F(InfoTest, Misc) ASSERT_THAT(output, HasSubstr("Communication cutoff = ")); ASSERT_THAT(output, HasSubstr("Processor grid = ")); - HIDE_OUTPUT([&] { - command("neighbor 0.3 multi"); - command("comm_modify mode multi"); - command("run 0 post no"); - }); - output = run_info("comm"); - ASSERT_THAT(output, HasSubstr("Communication mode = multi")); - ASSERT_THAT(output, HasSubstr("Communication cutoff for collection 1 = ")); + // the KOKKOS package supports only "bin" neighbor lists + if (!lmp->suffix_enable) { + HIDE_OUTPUT([&] { + command("neighbor 0.3 multi"); + command("comm_modify mode multi"); + command("run 0 post no"); + }); + output = run_info("comm"); + ASSERT_THAT(output, HasSubstr("Communication mode = multi")); + ASSERT_THAT(output, HasSubstr("Communication cutoff for collection 1 = ")); + } output = run_info("coeffs"); ASSERT_THAT(output, HasSubstr("Coeff status information:")); @@ -378,7 +381,8 @@ TEST_F(InfoTest, QueryAPI) ASSERT_FALSE(info->is_active("package", "intel")); ASSERT_FALSE(info->is_active("package", "omp")); ASSERT_TRUE(info->is_active("pair", "single")); - ASSERT_TRUE(info->is_active("pair", "respa")); + // the KOKKOS version of the pair styles does not support r-RESPA + if (!lmp->suffix_enable) ASSERT_TRUE(info->is_active("pair", "respa")); ASSERT_FALSE(info->is_active("pair", "manybody")); ASSERT_FALSE(info->is_active("pair", "tail")); ASSERT_FALSE(info->is_active("pair", "shift")); diff --git a/unittest/commands/test_kspace_group_group_slab.cpp b/unittest/commands/test_kspace_group_group_slab.cpp index a320fb9beb2..3098818d325 100644 --- a/unittest/commands/test_kspace_group_group_slab.cpp +++ b/unittest/commands/test_kspace_group_group_slab.cpp @@ -136,6 +136,8 @@ TEST_F(KSpaceGroupGroupSlabTest, EwaldTriclinicSlabMatchesOrthogonal) TEST_F(KSpaceGroupGroupSlabTest, PPPMTriclinicSlabMatchesOrthogonal) { + // the KOKKOS version of pppm does not support compute group/group + if (lmp->suffix_enable) GTEST_SKIP() << "pppm/kk does not support compute group/group"; if (!info->has_style("kspace", "pppm")) GTEST_SKIP(); if (!info->has_style("pair", "coul/long")) GTEST_SKIP(); if (!info->has_style("compute", "group/group")) GTEST_SKIP(); diff --git a/unittest/commands/test_labelmap.cpp b/unittest/commands/test_labelmap.cpp index 8cb73f9eed0..a16f0fa587d 100644 --- a/unittest/commands/test_labelmap.cpp +++ b/unittest/commands/test_labelmap.cpp @@ -55,6 +55,8 @@ class LabelMapTest : public LAMMPSTest { TEST_F(LabelMapTest, Atoms) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; EXPECT_EQ(atom->natoms, 0); EXPECT_EQ(domain->box_exist, 0); EXPECT_EQ(atom->labelmapflag, 0); @@ -189,6 +191,8 @@ TEST_F(LabelMapTest, Atoms) TEST_F(LabelMapTest, Topology) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; if (!info->has_style("atom", "full")) GTEST_SKIP(); EXPECT_EQ(atom->natoms, 0); diff --git a/unittest/commands/test_restart_settings.cpp b/unittest/commands/test_restart_settings.cpp index 9744513542e..87a22ddeddf 100644 --- a/unittest/commands/test_restart_settings.cpp +++ b/unittest/commands/test_restart_settings.cpp @@ -97,6 +97,8 @@ class RestartSettingsTest : public LAMMPSTest { TEST_F(RestartSettingsTest, granular_limit_damping) { if (!Info::has_package("GRANULAR")) GTEST_SKIP(); + // fix neigh/history/kk requires "newton off" for the exchange communication + if (lmp->suffix_enable) GTEST_SKIP() << "granular pair styles need newton off with KOKKOS"; BEGIN_HIDE_OUTPUT(); command("units si"); diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index 0caa828974f..05398665976 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -153,6 +153,8 @@ TEST_F(SetTest, velocity) TEST_F(SetTest, StylesTypes) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; if (!Info::has_package("MOLECULE")) GTEST_SKIP(); atomic_system("molecular"); ASSERT_EQ(atom->natoms, 8); @@ -326,6 +328,8 @@ TEST_F(SetTest, StylesTypes) TEST_F(SetTest, PosVelCharge) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; atomic_system("charge"); ASSERT_EQ(atom->natoms, 8); diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index c5a4ba7b1a7..b643717306c 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -263,6 +263,9 @@ TEST_F(SimpleCommandsTest, ResetTimestep) TEST_F(SimpleCommandsTest, Suffix) { + // this test enables suffixes from scratch, so it cannot run in a + // configuration that already has one active + if (lmp->suffix_enable) GTEST_SKIP() << "a suffix is already enabled"; ASSERT_EQ(lmp->suffix_enable, 0); ASSERT_EQ(lmp->suffix, nullptr); ASSERT_EQ(lmp->suffix2, nullptr); diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index f33aa3bcf84..ad43934af03 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -699,6 +699,8 @@ TEST_F(VariableTest, NextCommand) TEST_F(VariableTest, LabelMapAtomic) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; BEGIN_HIDE_OUTPUT(); command("region box block 0 2 0 2 0 2"); command("create_box 4 box"); @@ -730,6 +732,8 @@ TEST_F(VariableTest, LabelMapAtomic) TEST_F(VariableTest, LabelMapMolecular) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; if (!info->has_style("atom", "full")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index 84239edcf3c..3ceb12a22ba 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -89,6 +89,26 @@ static const double EPSILON = 5.0e-14; namespace LAMMPS_NS { using ::testing::Eq; +// with an accelerator suffix enabled (see LAMMPS_ACCELERATOR_ARGS in +// unittest/testing/core.h) Atom::create_avec() stores the suffixed style name, +// e.g. "atomic/kk", whenever an accelerated variant of the style exists. the +// helper below adapts the expected name accordingly, so the same expectations +// apply in either configuration and the test still confirms that the +// accelerated variant is the one in use. + +static LAMMPS *current_lmp = nullptr; + +static void ASSERT_ATOM_STYLE_EQ(const char *actual, const std::string &expected) +{ + std::string wanted = expected; + if (current_lmp && current_lmp->suffix_enable && current_lmp->suffix) { + std::string suffixed = expected + "/" + current_lmp->suffix; + Info info(current_lmp); + if (info.has_style("atom", suffixed)) wanted = suffixed; + } + ASSERT_THAT(std::string(actual), Eq(wanted)); +} + class AtomStyleTest : public LAMMPSTest { protected: static void SetUpTestSuite() { create_molecule_files("h2o.mol", "co2.mol"); } @@ -104,6 +124,7 @@ class AtomStyleTest : public LAMMPSTest { testbinary = "AtomStyleTest"; LAMMPSTest::SetUp(); ASSERT_NE(lmp, nullptr); + current_lmp = lmp; BEGIN_HIDE_OUTPUT(); command("units real"); command("dimension 3"); @@ -115,6 +136,7 @@ class AtomStyleTest : public LAMMPSTest { void TearDown() override { LAMMPSTest::TearDown(); + current_lmp = nullptr; remove("test_atom_styles.data"); remove("input_atom_styles.data"); remove("test_atom_styles.restart"); @@ -251,7 +273,7 @@ struct AtomState { void ASSERT_ATOM_STATE_EQ(Atom *atom, const AtomState &expected) { - ASSERT_THAT(std::string(atom->atom_style), Eq(expected.atom_style)); + ASSERT_ATOM_STYLE_EQ(atom->atom_style, expected.atom_style); ASSERT_NE(atom->avec, nullptr); ASSERT_EQ(atom->natoms, expected.natoms); @@ -463,6 +485,10 @@ TEST_F(AtomStyleTest, atomic_is_default) TEST_F(AtomStyleTest, atomic_after_charge) { + // the KOKKOS package keeps the per-atom arrays of its dual views + // allocated when the atom style is replaced, so the pointer of a field + // that is no longer part of the atom style is not reset to null + if (lmp->suffix_enable) GTEST_SKIP() << "arrays stay allocated with an accelerator suffix"; AtomState expected; expected.atom_style = "atomic"; expected.molecular = Atom::ATOMIC; @@ -496,7 +522,7 @@ TEST_F(AtomStyleTest, atomic) command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -522,7 +548,7 @@ TEST_F(AtomStyleTest, atomic) command("units real"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -577,7 +603,7 @@ TEST_F(AtomStyleTest, atomic) command("atom_modify map hash"); command("read_restart test_atom_styles.restart"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 2); ASSERT_EQ(lmp->atom->nlocal, 2); @@ -686,7 +712,7 @@ TEST_F(AtomStyleTest, no_tags) command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -714,7 +740,7 @@ TEST_F(AtomStyleTest, no_tags) command("units real"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -739,7 +765,7 @@ TEST_F(AtomStyleTest, no_tags) command("clear"); command("read_restart test_atom_styles.restart"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -811,7 +837,7 @@ TEST_F(AtomStyleTest, charge) command("set atom 4 charge 1.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("charge")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "charge"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -833,7 +859,7 @@ TEST_F(AtomStyleTest, charge) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("charge")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "charge"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -892,10 +918,10 @@ TEST_F(AtomStyleTest, charge) command("delete_atoms group two compress no"); command("write_restart test_atom_styles.restart"); command("clear"); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); command("read_restart test_atom_styles.restart"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("charge")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "charge"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 2); ASSERT_EQ(lmp->atom->nlocal, 2); @@ -994,7 +1020,7 @@ TEST_F(AtomStyleTest, sphere) command("set atom 4 omega 0.0 1.0 0.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("sphere")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "sphere"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -1017,7 +1043,7 @@ TEST_F(AtomStyleTest, sphere) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("sphere")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "sphere"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -1086,12 +1112,12 @@ TEST_F(AtomStyleTest, sphere) command("delete_atoms group two compress no"); command("write_restart test_atom_styles.restart"); command("clear"); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); command("read_restart test_atom_styles.restart"); command("replicate 1 1 2"); command("reset_atoms id"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("sphere")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "sphere"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -1167,7 +1193,7 @@ TEST_F(AtomStyleTest, ellipsoid) command("set atom 4 quat 1.0 1.0 1.0 60.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("ellipsoid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "ellipsoid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nellipsoids, 4); @@ -1204,7 +1230,7 @@ TEST_F(AtomStyleTest, ellipsoid) command("read_data test_atom_styles.data"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("ellipsoid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "ellipsoid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nlocal, 6); @@ -1322,7 +1348,7 @@ TEST_F(AtomStyleTest, ellipsoid) command("comm_style tiled"); command("replicate 1 1 2 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("ellipsoid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "ellipsoid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 8); ASSERT_EQ(lmp->atom->nlocal, 8); @@ -1462,6 +1488,9 @@ TEST_F(AtomStyleTest, ellipsoid) TEST_F(AtomStyleTest, superellipsoid) { + // this atom style has no KOKKOS variant, and the KOKKOS package + // requires a Kokkos-enabled atom style + if (lmp->suffix_enable) GTEST_SKIP() << "no KOKKOS version of this atom style"; if (!Info::has_package("ASPHERE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); @@ -1504,7 +1533,7 @@ TEST_F(AtomStyleTest, superellipsoid) command("set type 4 block 3.5 3.5"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("ellipsoid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "ellipsoid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nellipsoids, 3); @@ -1542,7 +1571,7 @@ TEST_F(AtomStyleTest, superellipsoid) command("read_data test_atom_styles.data"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("ellipsoid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "ellipsoid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -1605,7 +1634,7 @@ TEST_F(AtomStyleTest, superellipsoid) command("replicate 1 1 2 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("ellipsoid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "ellipsoid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 8); ASSERT_EQ(lmp->atom->nlocal, 8); @@ -1648,6 +1677,9 @@ TEST_F(AtomStyleTest, superellipsoid) TEST_F(AtomStyleTest, line) { + // this atom style has no KOKKOS variant, and the KOKKOS package + // requires a Kokkos-enabled atom style + if (lmp->suffix_enable) GTEST_SKIP() << "no KOKKOS version of this atom style"; if (!Info::has_package("ASPHERE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); @@ -1693,7 +1725,7 @@ TEST_F(AtomStyleTest, line) command("set atom 4 theta 60.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("line")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "line"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nlines, 4); @@ -1718,7 +1750,7 @@ TEST_F(AtomStyleTest, line) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("line")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "line"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nlocal, 6); @@ -1818,7 +1850,7 @@ TEST_F(AtomStyleTest, line) command("change_box all triclinic"); command("replicate 1 2 1 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("line")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "line"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 8); ASSERT_EQ(lmp->atom->nlocal, 8); @@ -1918,6 +1950,9 @@ TEST_F(AtomStyleTest, line) TEST_F(AtomStyleTest, tri) { + // this atom style has no KOKKOS variant, and the KOKKOS package + // requires a Kokkos-enabled atom style + if (lmp->suffix_enable) GTEST_SKIP() << "no KOKKOS version of this atom style"; if (!Info::has_package("ASPHERE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); @@ -1963,7 +1998,7 @@ TEST_F(AtomStyleTest, tri) command("set atom 4 quat 1.0 1.0 1.0 60.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("tri")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "tri"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->ntris, 4); @@ -2000,7 +2035,7 @@ TEST_F(AtomStyleTest, tri) command("read_data test_atom_styles.data"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("tri")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "tri"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nlocal, 6); @@ -2161,7 +2196,7 @@ TEST_F(AtomStyleTest, tri) command("change_box all triclinic"); command("replicate 1 1 2"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("tri")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "tri"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 8); ASSERT_EQ(lmp->atom->nlocal, 8); @@ -2400,7 +2435,7 @@ TEST_F(AtomStyleTest, body_nparticle) command("set atom 4 quat 1.0 1.0 1.0 60.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("body")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "body"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nbodies, 4); @@ -2575,7 +2610,7 @@ TEST_F(AtomStyleTest, body_nparticle) command("read_data test_atom_styles.data"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("body")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "body"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nlocal, 6); @@ -2747,7 +2782,7 @@ TEST_F(AtomStyleTest, body_nparticle) command("comm_style tiled"); command("replicate 1 1 2"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("body")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "body"); avec = dynamic_cast(lmp->atom->avec); ASSERT_THAT(std::string(avec->bptr->style), Eq("nparticle")); ASSERT_NE(lmp->atom->avec, nullptr); @@ -2889,6 +2924,9 @@ TEST_F(AtomStyleTest, body_nparticle) TEST_F(AtomStyleTest, template) { + // this atom style has no KOKKOS variant, and the KOKKOS package + // requires a Kokkos-enabled atom style + if (lmp->suffix_enable) GTEST_SKIP() << "no KOKKOS version of this atom style"; if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("molecule twomols h2o.mol co2.mol offset 2 1 1 0 0"); @@ -2935,7 +2973,7 @@ TEST_F(AtomStyleTest, template) command("angle_coeff * 109.0"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("template")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "template"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 12); ASSERT_EQ(lmp->atom->nbonds, 6); @@ -2977,7 +3015,7 @@ TEST_F(AtomStyleTest, template) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("template")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "template"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 12); @@ -3049,7 +3087,7 @@ TEST_F(AtomStyleTest, template) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("template")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "template"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 12); @@ -3169,7 +3207,7 @@ TEST_F(AtomStyleTest, template) command("read_restart test_atom_styles.restart"); command("replicate 1 1 2 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("template")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "template"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 16); ASSERT_EQ(lmp->atom->nbonds, 8); @@ -3284,6 +3322,9 @@ TEST_F(AtomStyleTest, template) TEST_F(AtomStyleTest, template_charge) { + // this atom style has no KOKKOS variant, and the KOKKOS package + // requires a Kokkos-enabled atom style + if (lmp->suffix_enable) GTEST_SKIP() << "no KOKKOS version of this atom style"; if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("molecule twomols h2o.mol co2.mol offset 2 1 1 0 0"); @@ -3313,7 +3354,7 @@ TEST_F(AtomStyleTest, template_charge) ASSERT_ATOM_STATE_EQ(lmp->atom, expected); auto *hybrid = dynamic_cast(lmp->atom->avec); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_EQ(hybrid->nstyles, 2); ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("template")); ASSERT_THAT(std::string(hybrid->keywords[1]), Eq("charge")); @@ -3344,7 +3385,7 @@ TEST_F(AtomStyleTest, template_charge) END_HIDE_OUTPUT(); ASSERT_NE(lmp->atom->avec, nullptr); hybrid = dynamic_cast(lmp->atom->avec); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_EQ(hybrid->nstyles, 2); ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("template")); ASSERT_THAT(std::string(hybrid->keywords[1]), Eq("charge")); @@ -3392,7 +3433,7 @@ TEST_F(AtomStyleTest, template_charge) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 12); @@ -3464,7 +3505,7 @@ TEST_F(AtomStyleTest, template_charge) command("atom_modify map array"); command("read_data test_atom_styles.data"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 12); @@ -3597,7 +3638,7 @@ TEST_F(AtomStyleTest, template_charge) command("read_restart test_atom_styles.restart"); command("replicate 1 1 2 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 16); @@ -3758,7 +3799,7 @@ TEST_F(AtomStyleTest, bond) command("create_bonds single/bond 2 3 6"); command("create_bonds single/bond 2 5 6"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("bond")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "bond"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nbonds, 5); @@ -3803,7 +3844,7 @@ TEST_F(AtomStyleTest, bond) command("pair_coeff * *"); command("bond_coeff * 4.0"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("bond")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "bond"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); @@ -3862,7 +3903,7 @@ TEST_F(AtomStyleTest, bond) command("pair_coeff * *"); command("bond_coeff * 4.0"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("bond")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "bond"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); @@ -3958,7 +3999,7 @@ TEST_F(AtomStyleTest, bond) command("read_restart test_atom_styles.restart"); command("replicate 1 1 2 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("bond")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "bond"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 8); ASSERT_EQ(lmp->atom->nlocal, 8); @@ -4112,7 +4153,7 @@ TEST_F(AtomStyleTest, angle) command("create_bonds single/angle 1 1 3 5"); command("create_bonds single/angle 2 3 5 6"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("angle")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "angle"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nbonds, 5); @@ -4161,7 +4202,7 @@ TEST_F(AtomStyleTest, angle) command("bond_coeff * 4.0"); command("angle_coeff * 90.0"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("angle")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "angle"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); @@ -4255,7 +4296,7 @@ TEST_F(AtomStyleTest, angle) command("pair_coeff * *"); command("bond_coeff * 4.0"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("angle")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "angle"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); @@ -4352,7 +4393,7 @@ TEST_F(AtomStyleTest, angle) command("read_restart test_atom_styles.restart"); command("replicate 1 1 2"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("angle")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "angle"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 8); ASSERT_EQ(lmp->atom->nlocal, 8); @@ -4454,7 +4495,7 @@ TEST_F(AtomStyleTest, full_ellipsoid) ASSERT_ATOM_STATE_EQ(lmp->atom, expected); auto *hybrid = dynamic_cast(lmp->atom->avec); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_EQ(hybrid->nstyles, 2); ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("full")); ASSERT_THAT(std::string(hybrid->keywords[1]), Eq("ellipsoid")); @@ -4497,7 +4538,7 @@ TEST_F(AtomStyleTest, full_ellipsoid) command("create_bonds single/bond 2 3 6"); command("create_bonds single/bond 2 5 6"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 6); ASSERT_EQ(lmp->atom->nbonds, 5); @@ -4538,7 +4579,7 @@ TEST_F(AtomStyleTest, full_ellipsoid) command("pair_coeff * *"); command("bond_coeff * 4.0"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); hybrid = dynamic_cast(lmp->atom->avec); ASSERT_EQ(hybrid->nstyles, 2); @@ -4671,7 +4712,7 @@ TEST_F(AtomStyleTest, full_ellipsoid) command("read_restart test_atom_styles.restart"); command("replicate 1 1 2 bbox"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); hybrid = dynamic_cast(lmp->atom->avec); ASSERT_EQ(hybrid->nstyles, 2); ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("full")); @@ -4915,7 +4956,7 @@ TEST_F(AtomStyleTest, property_atom) command("read_data test_atom_styles.data fix props NULL Properties"); command("pair_coeff * *"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 4); ASSERT_EQ(lmp->atom->nlocal, 4); @@ -4998,7 +5039,7 @@ TEST_F(AtomStyleTest, property_atom) command("delete_atoms group two compress no"); command("write_restart test_atom_styles.restart"); command("clear"); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "atomic"); command("read_restart test_atom_styles.restart"); command("fix props all property/atom i_one d_two mol d_three q rmass " "i2_four 2 d2_five 3 ghost yes"); @@ -5105,7 +5146,7 @@ TEST_F(AtomStyleTest, oxdna) ASSERT_ATOM_STATE_EQ(lmp->atom, expected); auto *hybrid = dynamic_cast(lmp->atom->avec); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_EQ(hybrid->nstyles, 3); ASSERT_THAT(std::string(hybrid->keywords[0]), Eq("bond")); ASSERT_THAT(std::string(hybrid->keywords[1]), Eq("ellipsoid")); @@ -5204,7 +5245,7 @@ TEST_F(AtomStyleTest, oxdna) command("pair_coeff * * oxdna2/dh 0.1 0.2 0.815"); END_HIDE_OUTPUT(); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); ASSERT_EQ(lmp->atom->natoms, 10); ASSERT_EQ(lmp->atom->nbonds, 8); @@ -5278,7 +5319,7 @@ TEST_F(AtomStyleTest, oxdna) "0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793"); command("pair_coeff * * oxdna2/dh 0.1 0.2 0.815"); - ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("hybrid")); + ASSERT_ATOM_STYLE_EQ(lmp->atom->atom_style, "hybrid"); ASSERT_NE(lmp->atom->avec, nullptr); hybrid = dynamic_cast(lmp->atom->avec); diff --git a/unittest/formats/test_molecule_file.cpp b/unittest/formats/test_molecule_file.cpp index 6ab805a9219..f617fd7411a 100644 --- a/unittest/formats/test_molecule_file.cpp +++ b/unittest/formats/test_molecule_file.cpp @@ -618,6 +618,8 @@ TEST_F(MoleculeFileTest, twofiles) TEST_F(MoleculeFileTest, labelmap) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; if (!info->has_style("atom", "full")) GTEST_SKIP(); BEGIN_CAPTURE_OUTPUT(); command("atom_style full"); @@ -789,6 +791,8 @@ TEST_F(MoleculeFileTest, auto_invalidopt) TEST_F(MoleculeFileTest, auto_angle_dihedral) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; if (!info->has_style("atom", "full")) GTEST_SKIP(); command("atom_style full"); command("region box block 0 2 0 2 0 2"); @@ -818,6 +822,8 @@ TEST_F(MoleculeFileTest, auto_angle_dihedral) TEST_F(MoleculeFileTest, auto_angle_improper) { + // label maps are currently not supported with the KOKKOS package + if (lmp->suffix_enable) GTEST_SKIP() << "label maps are not supported with an accelerator suffix"; if (!info->has_style("atom", "full")) GTEST_SKIP(); command("atom_style full"); command("region box block 0 2 0 2 0 2"); diff --git a/unittest/testing/core.h b/unittest/testing/core.h index 0f72288b6ae..df708884193 100644 --- a/unittest/testing/core.h +++ b/unittest/testing/core.h @@ -56,49 +56,75 @@ class LAMMPSTest : public ::testing::Test { public: void command(const std::string &line) { lmp->input->one(line); } + // GoogleTest supports only one active stdout capture at a time. When an + // error is thrown between BEGIN_HIDE_OUTPUT() and END_HIDE_OUTPUT(), the + // capture stays active and the next one aborts the entire test program + // with "Only one stdout capturer can exist at a time", which hides the + // original error message. Track the state so a capture left behind can + // be dropped when the test ends. + + void RESET_OUTPUT() + { + if (capturing) { + ::testing::internal::GetCapturedStdout(); + capturing = false; + } + } + void BEGIN_HIDE_OUTPUT() { - if (!verbose) ::testing::internal::CaptureStdout(); + if (!verbose) { + ::testing::internal::CaptureStdout(); + capturing = true; + } } void END_HIDE_OUTPUT() { - if (!verbose) ::testing::internal::GetCapturedStdout(); + if (!verbose) RESET_OUTPUT(); } - void BEGIN_CAPTURE_OUTPUT() { ::testing::internal::CaptureStdout(); } + void BEGIN_CAPTURE_OUTPUT() + { + ::testing::internal::CaptureStdout(); + capturing = true; + } std::string END_CAPTURE_OUTPUT() { auto output = ::testing::internal::GetCapturedStdout(); + capturing = false; if (verbose) std::cout << output; return output; } void HIDE_OUTPUT(std::function f) { - if (!verbose) ::testing::internal::CaptureStdout(); + BEGIN_HIDE_OUTPUT(); try { f(); } catch (LAMMPSException &e) { - if (!verbose) std::cout << ::testing::internal::GetCapturedStdout(); + if (!verbose) { + capturing = false; + std::cout << ::testing::internal::GetCapturedStdout(); + } throw e; } - if (!verbose) ::testing::internal::GetCapturedStdout(); + END_HIDE_OUTPUT(); } std::string CAPTURE_OUTPUT(std::function f) { - ::testing::internal::CaptureStdout(); + BEGIN_CAPTURE_OUTPUT(); try { f(); } catch (LAMMPSException &e) { - if (verbose) std::cout << ::testing::internal::GetCapturedStdout(); + capturing = false; + auto mesg = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << mesg; throw e; } - auto output = ::testing::internal::GetCapturedStdout(); - if (verbose) std::cout << output; - return output; + return END_CAPTURE_OUTPUT(); } double get_variable_value(const std::string &name) @@ -116,6 +142,7 @@ class LAMMPSTest : public ::testing::Test { protected: std::string testbinary = "LAMMPSTest"; + bool capturing = false; LAMMPS::argv args = {"-log", "none", "-echo", "screen", "-nocite"}; LAMMPS *lmp; Info *info; @@ -146,6 +173,9 @@ class LAMMPSTest : public ::testing::Test { void TearDown() override { + // an error thrown inside a captured block may have left a capture + // active. drop it, so the deletion below does not abort the program + RESET_OUTPUT(); HIDE_OUTPUT([&] { delete info; delete lmp; From 42defc1cce928a5e74cc3d301020b6fdbf937afb Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 04:04:47 +0000 Subject: [PATCH 025/120] compute fep: do not dereference the kspace style when there is none backup_qfev() and restore_qfev() test force->kspace->tip4pflag to decide whether the ghost atom forces have to be saved. With 'newton off' the first half of the condition is false, so the second one is evaluated and the command crashed for every input without a kspace style. Check the kspace pointer first. Found by running the compute-fep.yaml reference with a full neighbor list, which requires 'newton off' with the KOKKOS package. --- src/FEP/compute_fep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FEP/compute_fep.cpp b/src/FEP/compute_fep.cpp index 3c118d7a93e..c1614e0aa68 100644 --- a/src/FEP/compute_fep.cpp +++ b/src/FEP/compute_fep.cpp @@ -476,7 +476,7 @@ void ComputeFEP::backup_qfev() int nall = atom->nlocal + atom->nghost; int natom = atom->nlocal; - if (force->newton || force->kspace->tip4pflag) natom += atom->nghost; + if (force->newton || (force->kspace && force->kspace->tip4pflag)) natom += atom->nghost; double **f = atom->f; for (i = 0; i < natom; i++) { @@ -551,7 +551,7 @@ void ComputeFEP::restore_qfev() int nall = atom->nlocal + atom->nghost; int natom = atom->nlocal; - if (force->newton || force->kspace->tip4pflag) natom += atom->nghost; + if (force->newton || (force->kspace && force->kspace->tip4pflag)) natom += atom->nghost; double **f = atom->f; for (i = 0; i < natom; i++) { From 8b2b84c13f9483b224ba7db1c380404e420f386b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 04:09:21 +0000 Subject: [PATCH 026/120] comm: keep the reverse communication buffer size of fixes, computes, and dumps with newton off Comm::init() collects the largest per-atom reverse communication of all styles and then resets it to zero when newton is off, because the pair and bond styles do not communicate ghost forces in that case. Fixes, computes, and dumps, however, communicate their own per-atom data regardless of the newton setting, so the communication buffers were too small for them and their pack routine wrote past the end of the send buffer. With 'newton off' and 'compute snad/atom' this corrupted the heap; valgrind reports more than 20000 invalid accesses and the run aborts. Collect the requirements of those styles separately and apply them after the reset. Found by running the compute-snad_atom.yaml and compute-snav_atom.yaml references with a full neighbor list, which requires newton off with the KOKKOS package, but the bug is not specific to that package. --- src/comm.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/comm.cpp b/src/comm.cpp index 212b64dca63..dc971b135c6 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -218,24 +218,31 @@ void Comm::init() if (force->bond) maxforward = MAX(maxforward,force->bond->comm_forward); if (force->bond) maxreverse = MAX(maxreverse,force->bond->comm_reverse); + // fixes, computes, and dumps request a reverse communication of their own + // data and do so regardless of the newton setting, so their requirements + // are collected separately and are not discarded with newton off below + + int maxreverse_extra = 0; + for (const auto &fix : fix_list) { maxforward = MAX(maxforward, fix->comm_forward); - maxreverse = MAX(maxreverse, fix->comm_reverse); + maxreverse_extra = MAX(maxreverse_extra, fix->comm_reverse); } for (const auto &compute : modify->get_compute_list()) { maxforward = MAX(maxforward, compute->comm_forward); - maxreverse = MAX(maxreverse, compute->comm_reverse); + maxreverse_extra = MAX(maxreverse_extra, compute->comm_reverse); } for (const auto &dump: output->get_dump_list()) { maxforward = MAX(maxforward, dump->comm_forward); - maxreverse = MAX(maxreverse, dump->comm_reverse); + maxreverse_extra = MAX(maxreverse_extra, dump->comm_reverse); } if (force->newton == 0) maxreverse = 0; if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse_off); if (force->bond) maxreverse = MAX(maxreverse,force->bond->comm_reverse_off); + maxreverse = MAX(maxreverse,maxreverse_extra); // maxexchange_atom = size of an exchanged atom, set by AtomVec // only needs to be set if size > BUFEXTRA From 797fbf2ccdc28a0ebd396e412d6afe4b5b482712 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 04:11:03 +0000 Subject: [PATCH 027/120] unittest: skip the KOKKOS full neighbor list case of five compute references The new kokkos_omp_full and kokkos_serial_full cases run with a full neighbor list and 'newton off', which changes the output of these references: - compute pair/local and compute property/local list one row per pair, and both the order and the number of rows depend on how the pair list is built. - compute property/atom reports the number of bonds of an atom, and with 'newton_bond off' a bond is stored with both of its atoms. - compute stress/spherical and compute stress/cylinder build their own neighbor list and give results that differ by up to 2e-4 relative in this configuration, while the plain styles give identical results for 'newton on' and 'newton off'. This looks like a genuine difference of the neighbor lists handed to a non-KOKKOS compute with 'package kokkos neigh full' and needs a closer look before the case is enabled. --- unittest/force-styles/tests/compute-pair_local.yaml | 2 +- unittest/force-styles/tests/compute-property_atom_all.yaml | 2 +- .../force-styles/tests/compute-property_local_pair_radius.yaml | 2 +- unittest/force-styles/tests/compute-stress_cylinder.yaml | 2 +- unittest/force-styles/tests/compute-stress_spherical.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unittest/force-styles/tests/compute-pair_local.yaml b/unittest/force-styles/tests/compute-pair_local.yaml index 96a50aa1d93..077cd23a6a0 100644 --- a/unittest/force-styles/tests/compute-pair_local.yaml +++ b/unittest/force-styles/tests/compute-pair_local.yaml @@ -4,7 +4,7 @@ tags: date_generated: Thu Jul 9 16:21:48 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp_full kokkos_serial_full prerequisites: | atom full compute pair/local diff --git a/unittest/force-styles/tests/compute-property_atom_all.yaml b/unittest/force-styles/tests/compute-property_atom_all.yaml index 3d22e03f61e..e902d09d1bd 100644 --- a/unittest/force-styles/tests/compute-property_atom_all.yaml +++ b/unittest/force-styles/tests/compute-property_atom_all.yaml @@ -4,7 +4,7 @@ tags: date_generated: Sun Aug 23 12:37:01 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp_full kokkos_serial_full prerequisites: | atom full compute property/atom diff --git a/unittest/force-styles/tests/compute-property_local_pair_radius.yaml b/unittest/force-styles/tests/compute-property_local_pair_radius.yaml index 615e3feaccd..7a7f5c0485c 100644 --- a/unittest/force-styles/tests/compute-property_local_pair_radius.yaml +++ b/unittest/force-styles/tests/compute-property_local_pair_radius.yaml @@ -4,7 +4,7 @@ tags: date_generated: Sun Aug 23 12:40:39 2026 epsilon: 1e-08 timestep: 0.001 -skip_tests: +skip_tests: kokkos_omp_full kokkos_serial_full prerequisites: | atom sphere compute property/local diff --git a/unittest/force-styles/tests/compute-stress_cylinder.yaml b/unittest/force-styles/tests/compute-stress_cylinder.yaml index 1827ef072a6..ee53402ab42 100644 --- a/unittest/force-styles/tests/compute-stress_cylinder.yaml +++ b/unittest/force-styles/tests/compute-stress_cylinder.yaml @@ -4,7 +4,7 @@ tags: date_generated: Wed Aug 5 09:52:21 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp_full kokkos_serial_full prerequisites: | atom full compute stress/cylinder diff --git a/unittest/force-styles/tests/compute-stress_spherical.yaml b/unittest/force-styles/tests/compute-stress_spherical.yaml index 4c0ab2179b4..85af86ad854 100644 --- a/unittest/force-styles/tests/compute-stress_spherical.yaml +++ b/unittest/force-styles/tests/compute-stress_spherical.yaml @@ -4,7 +4,7 @@ tags: date_generated: Wed Aug 5 09:52:20 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp_full kokkos_serial_full prerequisites: | atom full compute stress/spherical From 246194bf915e8e7e901f8885bba39d81c57e9a65 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 04:40:32 +0000 Subject: [PATCH 028/120] unittest: fix the plain branch of the global scalar comparison A search and replace turned the fallback of the new helper into a call to itself, so the test looped forever without an accelerator suffix. --- unittest/commands/test_compute_global.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index c168c9385af..741e0ebc708 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -72,7 +72,7 @@ class ComputeGlobalTest : public LAMMPSTest { if (lmp->suffix_enable) EXPECT_NEAR(get_scalar(id), expected, std::fabs(expected) * 1.0e-13); else - EXPECT_SCALAR_EQ(id, expected); + EXPECT_DOUBLE_EQ(get_scalar(id), expected); } }; From a29b970483743c9f5eaa4eea1bd9018e53eadfa2 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 08:35:22 +0000 Subject: [PATCH 029/120] unittest: add references for fix store/force and fix viscous/sphere Both styles have a KOKKOS version but no reference so far, so the kokkos_serial cases of the output and timestep drivers now compare them against the result of the plain styles. --- .../tests/fix-output-store_force.yaml | 49 ++++++++ .../tests/fix-timestep-viscous_sphere.yaml | 118 ++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 unittest/force-styles/tests/fix-output-store_force.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml diff --git a/unittest/force-styles/tests/fix-output-store_force.yaml b/unittest/force-styles/tests/fix-output-store_force.yaml new file mode 100644 index 00000000000..db56ed79983 --- /dev/null +++ b/unittest/force-styles/tests/fix-output-store_force.yaml @@ -0,0 +1,49 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 04:44:12 2026 +epsilon: 1e-08 +timestep: 0.25 +skip_tests: +prerequisites: | + atom full + fix store/force + fix setforce +pre_commands: "" +post_commands: | + fix test all store/force + fix zap solute setforce 0.0 NULL NULL +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +peratom_data: |2 + 1.0000000000000000e+00 7.8591120304383494e+01 1.4706792519954141e+02 3.8520578628986087e+01 + 2.0000000000000000e+00 1.2978337342627329e+01 4.4617830236965510e+00 -2.1151572557699982e+01 + 3.0000000000000000e+00 -8.3322590639611889e+01 -5.5638752656092883e+01 1.6909538483125488e+01 + 4.0000000000000000e+00 -1.2191733710529961e+01 -3.0048642381748451e+01 1.1155661592537207e+01 + 5.0000000000000000e+00 -4.6750826654251732e+01 -5.1843866361982371e+01 -1.4229496550319746e+01 + 6.0000000000000000e+00 -3.0178749575510051e+02 3.1136234176148457e+02 -3.0751881076104638e+02 + 7.0000000000000000e+00 -1.9347362784718481e+01 1.1251963196529513e+01 -3.7977581822319330e+01 + 8.0000000000000000e+00 6.2078219484972962e+01 -8.7260089363996912e+01 3.6322009213592997e+02 + 9.0000000000000000e+00 1.7981308147060567e+01 3.7561826530270736e+01 1.0793959545808282e+02 + 1.0000000000000000e+01 2.6950728144848460e+02 -2.2494538112095950e+02 -1.7324813664550581e+02 + 1.1000000000000000e+01 -2.8539747186844203e+01 -1.9518465885833908e+01 -1.5170013599452615e+01 + 1.2000000000000000e+01 5.3424120565888789e+00 -1.3290209266704924e+01 -2.0090200762386420e+01 + 1.3000000000000000e+01 -7.6378255157072914e+00 1.0933504166337931e+01 -6.1408178755097342e-01 + 1.4000000000000000e+01 1.9241428159882926e+01 -4.4819099702085374e+00 1.1454738357693937e+00 + 1.5000000000000000e+01 9.9172954072584325e+00 -1.0892196461916793e+01 1.3075766336653290e+01 + 1.6000000000000000e+01 3.8219553830291311e+01 -3.4981062782289143e+01 -1.2618723864171651e+01 + 1.7000000000000000e+01 -1.4248372341628299e+01 1.0287340666589287e+01 5.0634159776359347e+01 + 1.8000000000000000e+01 4.7808470129837666e+00 7.4227005592532622e+00 -1.3521129646280130e+01 + 1.9000000000000000e+01 5.7515887187195114e+00 3.7593048091438788e+00 6.7773618088953222e+00 + 2.0000000000000000e+01 -1.0551292805634271e+01 -1.1214979070367052e+01 6.7752532954664204e+00 + 2.1000000000000000e+01 -7.2136818734558021e+00 -6.1536432080839267e+00 1.3078268202494506e+01 + 2.2000000000000000e+01 -1.3507767388724073e+01 -4.9433954450539854e+00 -1.2284639268530949e+01 + 2.3000000000000000e+01 2.0712185355424076e+01 1.1107337443962608e+01 -7.8353028964598703e-01 + 2.4000000000000000e+01 5.9012438049632072e+00 -2.5045323886840876e+01 1.4335231140998228e+01 + 2.5000000000000000e+01 -2.1144972965800733e+01 1.6459434459994458e+00 -1.7244549991013173e+01 + 2.6000000000000000e+01 1.5233342130062381e+01 2.3389793894550646e+01 2.8895104546957335e+00 + 2.7000000000000000e+01 8.7097490725472220e+00 -1.8716387222421634e+01 9.6687591258686467e+00 + 2.8000000000000000e+01 -2.0084842961570100e+01 7.1247448018757593e+00 -1.3052172502360030e+01 + 2.9000000000000000e+01 1.1382600307326776e+01 1.1597795585265230e+01 3.3793897724207609e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml b/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml new file mode 100644 index 00000000000..4c738e35534 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml @@ -0,0 +1,118 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 04:44:59 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom sphere + fix viscous/sphere + fix nve/sphere +pre_commands: "" +post_commands: | + fix move all nve/sphere + fix test solute viscous/sphere 0.05 scale 1 2.0 +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 4.5873663348591968e+01 5.4801063902264218e+01 1.9506138901465274e+01 + 2 -4.8584472040803931e+01 2.5844875851927739e+01 5.2592871753951265e+01 + 3 6.7347096375505913e+01 -6.1817590121654945e+01 -3.7159959400755640e+00 + 4 -4.4644978916933811e+00 7.1557420999354534e+01 -6.4952280686569338e+01 + 5 -2.9641779276086790e+01 -6.5315983893490113e+01 6.1204389320190550e+01 + 6 -1.4271704304863754e+01 -2.5491743333862331e+01 5.7547178511893202e+00 + 7 4.9335577700691388e+01 -1.9680679035400825e+01 8.0747044313338989e+00 + 8 -3.1424576833864542e+01 -6.6494876988484563e+01 4.4478029876122463e+01 + 9 7.2674448518984079e+01 7.2978248099728987e+01 5.8063620379984584e+01 + 10 -2.0749803823660834e+01 5.3458283874071327e+01 -1.2923661852210351e+01 + 11 3.7848447710355259e+01 -5.4471328086678255e+01 -2.2382878987946551e+01 + 12 -4.2279464114017713e+01 -2.5829482801981438e+01 6.0108695705995800e+01 + 13 -2.8245815756090138e+01 6.6795018542470359e+00 -5.5544459285198286e+01 + 14 -3.5454191268617443e+01 -5.1809503948285908e+01 -1.7253078625435077e+01 + 15 2.0614631025323519e+01 -4.9794765490810953e+01 -4.4281477405724090e+01 + 16 -2.6481335836068610e+01 -4.4180207822813500e+01 3.7840728265414924e+01 + 17 -7.2231222193996459e+01 -1.2728530419776050e+01 -2.6894949563482317e+01 + 18 -6.6659240656999941e+01 -1.0205683794269987e+01 -3.2011181305433610e+01 + 19 1.8542235098454679e+01 -4.7300706344060941e+01 5.9674527352030765e+01 + 20 -4.8635913615103341e+01 2.4564520646298526e+01 3.6322124585125408e+01 + 21 1.0585632673915486e+00 -3.5712774338144293e+01 3.3784920892188801e+01 + 22 -6.6875192587604644e+01 2.4410608482809199e+01 -3.5052770963734162e+01 + 23 6.1259314729498662e+01 5.3794318096633553e+01 3.6706208226847004e+01 + 24 1.0092596676290420e+01 -2.2403671982156325e+01 -6.4526051809229429e+01 + 25 2.0332027830210418e+01 5.1862045681009107e+01 3.5494695434586937e+01 + 26 -2.7348645729469759e+01 -2.1075294861328327e+01 1.6478988822477081e+01 + 27 1.8758462068665306e+01 4.5616299621318177e+01 4.8100182302648051e+01 + 28 -3.5693255694108728e+01 -6.6351379658073853e+01 1.3408217461985311e+01 + 29 -1.5889725634717150e+01 6.2005423836544686e+01 4.4493157054449682e+01 + 30 4.7765119886693526e+01 5.7077658400576865e+01 -1.2134013975542485e+01 + 31 1.0307017553088649e+01 -4.2872247808733803e+01 4.7646651160424199e+01 + 32 3.7044094382755958e+01 6.5682978407695359e+01 -3.7303988474404499e+00 +... From a66fe60d2fbb4bf02e77f5cab9656743a03b11bf Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 08:41:17 +0000 Subject: [PATCH 030/120] KOKKOS: replace non-ASCII characters in comments and the citation text LAMMPS sources are 7-bit US-ASCII only. Four files in the KOKKOS package contained typographic quotes, arrows and dashes. --- src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp | 2 +- src/KOKKOS/fix_gjf_kokkos.cpp | 2 +- src/KOKKOS/fix_rigid_small_kokkos.cpp | 6 +++--- src/KOKKOS/kokkos.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp b/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp index 02e84d553b6..a580c7072c5 100644 --- a/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp +++ b/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp @@ -737,7 +737,7 @@ struct AtomVecEllipsoidKokkos_BackfillEllipsoid { void operator() (const int &mysend) const { const int i = _sendlist(mysend); - // if atom J has bonus data, reset J’s bonus.ilocal to loc I + // if atom J has bonus data, reset J's bonus.ilocal to loc I int j = _copylist(mysend); if (j > -1) { diff --git a/src/KOKKOS/fix_gjf_kokkos.cpp b/src/KOKKOS/fix_gjf_kokkos.cpp index b335734b92a..d38de102efd 100644 --- a/src/KOKKOS/fix_gjf_kokkos.cpp +++ b/src/KOKKOS/fix_gjf_kokkos.cpp @@ -129,7 +129,7 @@ void FixGJFKokkos::initial_integrate(int /* vflag */) mass = atomKK->k_mass.view(); } - // vhalf mode: copy lv → v at start of step (all but the first step) + // vhalf mode: copy lv -> v at start of step (all but the first step) if (!osflag && lv_allocated) { k_lv.sync(); d_lv = k_lv.view(); diff --git a/src/KOKKOS/fix_rigid_small_kokkos.cpp b/src/KOKKOS/fix_rigid_small_kokkos.cpp index 6cab6b510f7..5c947991b6d 100644 --- a/src/KOKKOS/fix_rigid_small_kokkos.cpp +++ b/src/KOKKOS/fix_rigid_small_kokkos.cpp @@ -234,7 +234,7 @@ void FixRigidSmallKokkos::pre_exchange() // from the host arrays -- we must not skip the flush in that case. if (exchange_comm_device && !commKK->exchange_comm_legacy) return; - // Host exchange path: flush device→host so the base-class + // Host exchange path: flush device->host so the base-class // pack_exchange/copy_arrays/unpack_exchange see valid data. copy_body_host(); k_bodytag.sync_host(); @@ -685,11 +685,11 @@ void FixRigidSmallKokkos::pre_neighbor(){ if (extended_datamask) atomKK->sync(execution_space, extended_datamask); } refresh_atom_views(); - copy_body_device(); // push host body[] → d_body + copy_body_device(); // push host body[] -> d_body } else { // Device exchange path: pack/unpack_exchange_kokkos already updated all // per-atom DualViews and d_body on the device. Do NOT push stale host - // data to the device — just mark the device side as authoritative and + // data to the device -- just mark the device side as authoritative and // refresh the d_* view aliases. // // Clear any outstanding host claim first. comm->borders() runs between the diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index ec3dea33962..c5babf2b584 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -71,7 +71,7 @@ static const char cite_kokkos_package[] = " year = 2025,\n" " booktitle = {Proceedings of the SC '25 Workshops of the International Conference for High Performance Computing,\n" " Networking, Storage and Analysis},\n" - " pages = {1217–1232},\n" + " pages = {1217-1232},\n" "}\n\n"; int KokkosLMP::is_finalized = 0; From 99f9b93b04dde86fa3ae0ce19228ba027d95bb77 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 4 Sep 2026 05:28:34 -0400 Subject: [PATCH 031/120] import fixes to the examples tree from the preview branch --- examples/GRAPHICS/README | 4 +++- examples/GRAPHICS/in.bpm-fracture | 2 +- examples/PACKAGES/mbx/256h2o/{in.mbx_h2o => in.256h2o} | 0 .../mbx/256h2o_dipole/{in.mbx_h2o => in.256h2o_dipole} | 0 .../mof_ff_lammps+1_h2o_mbx/{in.mbx_mof_1h2o => in.mof_1h2o} | 0 .../{log.21Jul26.mof.g++.1 => log.21Jul26.mof_1h2o.g++.1} | 0 examples/PACKAGES/mbx/na+_slab/{in.slab => in.na+_slab} | 0 7 files changed, 4 insertions(+), 2 deletions(-) rename examples/PACKAGES/mbx/256h2o/{in.mbx_h2o => in.256h2o} (100%) rename examples/PACKAGES/mbx/256h2o_dipole/{in.mbx_h2o => in.256h2o_dipole} (100%) rename examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/{in.mbx_mof_1h2o => in.mof_1h2o} (100%) rename examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/{log.21Jul26.mof.g++.1 => log.21Jul26.mof_1h2o.g++.1} (100%) rename examples/PACKAGES/mbx/na+_slab/{in.slab => in.na+_slab} (100%) diff --git a/examples/GRAPHICS/README b/examples/GRAPHICS/README index ec0f6b42ab2..aade1dd0b80 100644 --- a/examples/GRAPHICS/README +++ b/examples/GRAPHICS/README @@ -18,7 +18,9 @@ Here is a list of the inputs and which graphics features they demonstrate - in.bpm-fracture: brittle disk (bonded particle model) shattered by a projectile, coloring each bond by the per-bond force - with "dump image ... bond c_ID" and a "bmap" color map + and also coloring atoms by their kinetic energy; + display colorscale labels for both maps + https://www.youtube.com/shorts/RcaNcNJ-xHI - in.water-arrows: box of water molecules, uses many kinds of arrows https://www.youtube.com/shorts/4Cm5p0SfgNU diff --git a/examples/GRAPHICS/in.bpm-fracture b/examples/GRAPHICS/in.bpm-fracture index 46208d29695..a4f4f8a1d11 100644 --- a/examples/GRAPHICS/in.bpm-fracture +++ b/examples/GRAPHICS/in.bpm-fracture @@ -51,7 +51,7 @@ velocity projectile set -0.05 0.0 0.0 # are run one the same steps and making this an index style variable lets you # override it from the command line with -var dumpfreq 100 -variable dumpfreq index 200 +variable dumpfreq index 100 # to add a color scale we have to reference a dump that has not been created. # the fix has to come *before* the dump image command so it can be enabled by it, diff --git a/examples/PACKAGES/mbx/256h2o/in.mbx_h2o b/examples/PACKAGES/mbx/256h2o/in.256h2o similarity index 100% rename from examples/PACKAGES/mbx/256h2o/in.mbx_h2o rename to examples/PACKAGES/mbx/256h2o/in.256h2o diff --git a/examples/PACKAGES/mbx/256h2o_dipole/in.mbx_h2o b/examples/PACKAGES/mbx/256h2o_dipole/in.256h2o_dipole similarity index 100% rename from examples/PACKAGES/mbx/256h2o_dipole/in.mbx_h2o rename to examples/PACKAGES/mbx/256h2o_dipole/in.256h2o_dipole diff --git a/examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/in.mbx_mof_1h2o b/examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/in.mof_1h2o similarity index 100% rename from examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/in.mbx_mof_1h2o rename to examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/in.mof_1h2o diff --git a/examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/log.21Jul26.mof.g++.1 b/examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/log.21Jul26.mof_1h2o.g++.1 similarity index 100% rename from examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/log.21Jul26.mof.g++.1 rename to examples/PACKAGES/mbx/mof_ff_lammps+1_h2o_mbx/log.21Jul26.mof_1h2o.g++.1 diff --git a/examples/PACKAGES/mbx/na+_slab/in.slab b/examples/PACKAGES/mbx/na+_slab/in.na+_slab similarity index 100% rename from examples/PACKAGES/mbx/na+_slab/in.slab rename to examples/PACKAGES/mbx/na+_slab/in.na+_slab From add7b93da98b9ee1857d851e2d7295b399749f7b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 4 Sep 2026 05:35:03 -0400 Subject: [PATCH 032/120] update logs --- ...sw.g++.1 => log.04Sep2026.charmmfsw.g++.1} | 86 ++++++++--------- ...sw.g++.4 => log.04Sep2026.charmmfsw.g++.4} | 92 +++++++++---------- 2 files changed, 81 insertions(+), 97 deletions(-) rename examples/charmmfsw/{log.26Jul24.charmmfsw.g++.1 => log.04Sep2026.charmmfsw.g++.1} (70%) rename examples/charmmfsw/{log.26Jul24.charmmfsw.g++.4 => log.04Sep2026.charmmfsw.g++.4} (68%) diff --git a/examples/charmmfsw/log.26Jul24.charmmfsw.g++.1 b/examples/charmmfsw/log.04Sep2026.charmmfsw.g++.1 similarity index 70% rename from examples/charmmfsw/log.26Jul24.charmmfsw.g++.1 rename to examples/charmmfsw/log.04Sep2026.charmmfsw.g++.1 index f56052b1404..d545762d24d 100644 --- a/examples/charmmfsw/log.26Jul24.charmmfsw.g++.1 +++ b/examples/charmmfsw/log.04Sep2026.charmmfsw.g++.1 @@ -1,6 +1,4 @@ -LAMMPS (27 Jun 2024) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) - using 1 OpenMP thread(s) per MPI task +LAMMPS (2 Sep 2026) # charmmfsw example generated by https://charmm-gui.org/ # from PDB structure 1HVN (https://www.rcsb.org/structure/1HVN) # @@ -12,7 +10,7 @@ boundary p p p newton off pair_style lj/charmmfsw/coul/long 10 12 -Switching to CHARMM coulomb energy conversion constant (src/KSPACE/pair_lj_charmmfsw_coul_long.cpp:63) +Switching to CHARMM coulomb energy conversion constant pair_modify mix arithmetic kspace_style pppm 1e-6 @@ -62,7 +60,7 @@ Finding 1-2 1-3 1-4 neighbors ... 17 = max # of 1-4 neighbors 21 = max # of special neighbors special bonds CPU = 0.002 seconds - read_data CPU = 0.072 seconds + read_data CPU = 0.068 seconds neighbor 2 bin neigh_modify delay 2 every 1 @@ -74,33 +72,27 @@ Finding SHAKE clusters ... 9 = # of size 4 clusters 3265 = # of frozen angles find clusters CPU = 0.003 seconds -fix 2 all nvt temp 303.15 303.15 100.0 +fix 2 all nvt temp 303.15 303.15 100.0 + +# for visualization with LAMMPS-GUI +group water type 18 60 +9795 atoms in group water +group nowater subtract all water +450 atoms in group nowater +group ions type 63 64 +19 atoms in group ions +group other subtract all water ions +431 atoms in group other + +# dump viz other image 10 myimage-*.ppm element type size 800 800 zoom 2.82954 shiny 0.5 fsaa yes bond none none view 20 10 box no 0.0 axes no 0.0 0.0 center s 0.521318 0.489856 0.489856 +# dump_modify viz pad 9 boxcolor darkblue backcolor darkgray element H H H H H H H H H H H H H H H H H H C C C C C C C C C C C C C C C C C C C N N N N N N N N N N N N N N O O O O O O O O O P S Cl K adiam 1 1.92 adiam 2 1.92 adiam 3 1.92 adiam 4 1.92 adiam 5 1.92 adiam 6 1.92 adiam 7 1.92 adiam 8 1.92 adiam 9 1.92 adiam 10 1.92 adiam 11 1.92 adiam 12 1.92 adiam 13 1.92 adiam 14 1.92 adiam 15 1.92 adiam 16 1.92 adiam 17 1.92 adiam 18 1.92 adiam 19 2.72 adiam 20 2.72 adiam 21 2.72 adiam 22 2.72 adiam 23 2.72 adiam 24 2.72 adiam 25 2.72 adiam 26 2.72 adiam 27 2.72 adiam 28 2.72 adiam 29 2.72 adiam 30 2.72 adiam 31 2.72 adiam 32 2.72 adiam 33 2.72 adiam 34 2.72 adiam 35 2.72 adiam 36 2.72 adiam 37 2.72 adiam 38 2.48 adiam 39 2.48 adiam 40 2.48 adiam 41 2.48 adiam 42 2.48 adiam 43 2.48 adiam 44 2.48 adiam 45 2.48 adiam 46 2.48 adiam 47 2.48 adiam 48 2.48 adiam 49 2.48 adiam 50 2.48 adiam 51 2.48 adiam 52 2.432 adiam 53 2.432 adiam 54 2.432 adiam 55 2.432 adiam 56 2.432 adiam 57 2.432 adiam 58 2.432 adiam 59 2.432 adiam 60 2.432 adiam 61 2.88 adiam 62 2.88 adiam 63 3.632 adiam 64 2.816 thermo 10 thermo_style custom step etotal evdwl ecoul elong edihed pe ke temp press run 100 - -CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE - -Your simulation uses code contributions which should be cited: - -- Type Label Framework: https://doi.org/10.1021/acs.jpcb.3c08419 - -@Article{Gissinger24, - author = {Jacob R. Gissinger, Ilia Nikiforov, Yaser Afshar, Brendon Waters, Moon-ki Choi, Daniel S. Karls, Alexander Stukowski, Wonpil Im, Hendrik Heinz, Axel Kohlmeyer, and Ellad B. Tadmor}, - title = {Type Label Framework for Bonded Force Fields in LAMMPS}, - journal = {J. Phys. Chem. B}, - year = 2024, - volume = 128, - number = 13, - pages = {3282–-3297} -} - -CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE - PPPM initialization ... - using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + using 12-bit tables for long-range coulomb G vector (1/distance) = 0.27938162 grid = 54 54 54 stencil order = 5 @@ -150,16 +142,16 @@ Bond: 97 1.325 4.3613e-08 3 Angle: 142 104.52 2.67611e-05 3265 Per MPI rank memory allocation (min/avg/max) = 143.6 | 143.6 | 143.6 Mbytes Step TotEng E_vdwl E_coul E_long E_dihed PotEng KinEng Temp Press - 0 -27877.652 3447.5013 144035.68 -182420.51 343.05623 -34213.5 6335.8474 307.44113 -989.27065 + 0 -27877.652 3447.5013 144035.68 -182420.51 343.05623 -34213.5 6335.8474 307.44113 -989.27063 10 -27879.086 3334.4154 144205.4 -182416.19 348.14696 -34133.566 6254.4808 303.49289 -1211.2863 - 20 -27882.193 3293.7931 144272.04 -182415.87 333.20456 -34116.91 6234.7164 302.53384 -1041.5231 - 30 -27886.779 3177.7183 144344.61 -182409.28 340.77044 -34166.241 6279.462 304.70508 -1538.0247 + 20 -27882.194 3293.7931 144272.04 -182415.87 333.20456 -34116.91 6234.7164 302.53384 -1041.5232 + 30 -27886.779 3177.7183 144344.61 -182409.28 340.77044 -34166.241 6279.462 304.70508 -1538.0248 40 -27892.698 3186.4294 144409.85 -182417.01 337.80177 -34097.62 6204.9214 301.08807 -1516.1201 - 50 -27898.215 3198.5531 144426.3 -182405.24 336.58074 -34049.909 6151.6947 298.50529 -1349.4431 - 60 -27900.589 3163.4592 144400.32 -182414.85 341.17705 -34110.926 6210.3369 301.35085 -1695.3697 - 70 -27900.487 3223.7183 144242.71 -182409.21 341.09496 -34188.493 6288.0059 305.11967 -1493.2031 - 80 -27901.07 3274.244 144265.07 -182417.68 344.0409 -34177.343 6276.2725 304.55032 -1273.0263 - 90 -27905.672 3237.6056 144288.71 -182418.22 342.15013 -34187.814 6282.1417 304.83511 -1268.0436 + 50 -27898.215 3198.5531 144426.3 -182405.24 336.58074 -34049.909 6151.6947 298.50529 -1349.4433 + 60 -27900.589 3163.4592 144400.32 -182414.85 341.17705 -34110.926 6210.3369 301.35085 -1695.37 + 70 -27900.487 3223.7183 144242.71 -182409.21 341.09496 -34188.493 6288.0059 305.11967 -1493.203 + 80 -27901.07 3274.244 144265.07 -182417.68 344.0409 -34177.342 6276.2726 304.55032 -1273.0261 + 90 -27905.671 3237.6057 144288.71 -182418.22 342.15014 -34187.813 6282.1417 304.83511 -1268.0434 SHAKE stats (type/ave/delta/count) on step 100 Bond: 16 1.09 3.78281e-07 6 Bond: 18 1.09 1.12288e-07 3 @@ -187,23 +179,23 @@ Bond: 87 1 0 1 Bond: 95 0.96 1.03526e-07 2 Bond: 97 1.325 3.64689e-08 3 Angle: 142 104.52 0.000130126 3265 - 100 -27913.241 3159.0677 144299.1 -182414.94 336.48839 -34254.412 6341.1706 307.69943 -1421.2905 -Loop time of 11.5304 on 1 procs for 100 steps with 10245 atoms + 100 -27913.241 3159.0677 144299.1 -182414.94 336.48837 -34254.411 6341.1705 307.69943 -1421.2901 +Loop time of 10.2273 on 1 procs for 100 steps with 10245 atoms -Performance: 1.499 ns/day, 16.014 hours/ns, 8.673 timesteps/s, 88.852 katom-step/s -99.7% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 1.690 ns/day, 14.205 hours/ns, 9.778 timesteps/s, 100.173 katom-step/s +99.6% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 8.6772 | 8.6772 | 8.6772 | 0.0 | 75.25 -Bond | 0.012444 | 0.012444 | 0.012444 | 0.0 | 0.11 -Kspace | 1.2286 | 1.2286 | 1.2286 | 0.0 | 10.66 -Neigh | 1.5276 | 1.5276 | 1.5276 | 0.0 | 13.25 -Comm | 0.010441 | 0.010441 | 0.010441 | 0.0 | 0.09 -Output | 0.00055001 | 0.00055001 | 0.00055001 | 0.0 | 0.00 -Modify | 0.07101 | 0.07101 | 0.07101 | 0.0 | 0.62 -Other | | 0.002628 | | | 0.02 +Pair | 7.747 | 7.747 | 7.747 | 0.0 | 75.75 +Bond | 0.012312 | 0.012312 | 0.012312 | 0.0 | 0.12 +Kspace | 0.98198 | 0.98198 | 0.98198 | 0.0 | 9.60 +Neigh | 1.4052 | 1.4052 | 1.4052 | 0.0 | 13.74 +Comm | 0.0099074 | 0.0099074 | 0.0099074 | 0.0 | 0.10 +Output | 0.00048764 | 0.00048764 | 0.00048764 | 0.0 | 0.00 +Modify | 0.067583 | 0.067583 | 0.067583 | 0.0 | 0.66 +Other | | 0.002754 | | | 0.03 Nlocal: 10245 ave 10245 max 10245 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -218,4 +210,4 @@ Ave special neighs/atom = 2.3664226 Neighbor list builds = 10 Dangerous builds = 0 -Total wall time: 0:00:11 +Total wall time: 0:00:10 diff --git a/examples/charmmfsw/log.26Jul24.charmmfsw.g++.4 b/examples/charmmfsw/log.04Sep2026.charmmfsw.g++.4 similarity index 68% rename from examples/charmmfsw/log.26Jul24.charmmfsw.g++.4 rename to examples/charmmfsw/log.04Sep2026.charmmfsw.g++.4 index b2dc69b0a52..bf3a330aab2 100644 --- a/examples/charmmfsw/log.26Jul24.charmmfsw.g++.4 +++ b/examples/charmmfsw/log.04Sep2026.charmmfsw.g++.4 @@ -1,6 +1,4 @@ -LAMMPS (27 Jun 2024) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) - using 1 OpenMP thread(s) per MPI task +LAMMPS (2 Sep 2026) # charmmfsw example generated by https://charmm-gui.org/ # from PDB structure 1HVN (https://www.rcsb.org/structure/1HVN) # @@ -12,7 +10,7 @@ boundary p p p newton off pair_style lj/charmmfsw/coul/long 10 12 -Switching to CHARMM coulomb energy conversion constant (src/KSPACE/pair_lj_charmmfsw_coul_long.cpp:63) +Switching to CHARMM coulomb energy conversion constant pair_modify mix arithmetic kspace_style pppm 1e-6 @@ -62,7 +60,7 @@ Finding 1-2 1-3 1-4 neighbors ... 17 = max # of 1-4 neighbors 21 = max # of special neighbors special bonds CPU = 0.001 seconds - read_data CPU = 0.068 seconds + read_data CPU = 0.065 seconds neighbor 2 bin neigh_modify delay 2 every 1 @@ -74,40 +72,34 @@ Finding SHAKE clusters ... 9 = # of size 4 clusters 3265 = # of frozen angles find clusters CPU = 0.001 seconds -fix 2 all nvt temp 303.15 303.15 100.0 +fix 2 all nvt temp 303.15 303.15 100.0 + +# for visualization with LAMMPS-GUI +group water type 18 60 +9795 atoms in group water +group nowater subtract all water +450 atoms in group nowater +group ions type 63 64 +19 atoms in group ions +group other subtract all water ions +431 atoms in group other + +# dump viz other image 10 myimage-*.ppm element type size 800 800 zoom 2.82954 shiny 0.5 fsaa yes bond none none view 20 10 box no 0.0 axes no 0.0 0.0 center s 0.521318 0.489856 0.489856 +# dump_modify viz pad 9 boxcolor darkblue backcolor darkgray element H H H H H H H H H H H H H H H H H H C C C C C C C C C C C C C C C C C C C N N N N N N N N N N N N N N O O O O O O O O O P S Cl K adiam 1 1.92 adiam 2 1.92 adiam 3 1.92 adiam 4 1.92 adiam 5 1.92 adiam 6 1.92 adiam 7 1.92 adiam 8 1.92 adiam 9 1.92 adiam 10 1.92 adiam 11 1.92 adiam 12 1.92 adiam 13 1.92 adiam 14 1.92 adiam 15 1.92 adiam 16 1.92 adiam 17 1.92 adiam 18 1.92 adiam 19 2.72 adiam 20 2.72 adiam 21 2.72 adiam 22 2.72 adiam 23 2.72 adiam 24 2.72 adiam 25 2.72 adiam 26 2.72 adiam 27 2.72 adiam 28 2.72 adiam 29 2.72 adiam 30 2.72 adiam 31 2.72 adiam 32 2.72 adiam 33 2.72 adiam 34 2.72 adiam 35 2.72 adiam 36 2.72 adiam 37 2.72 adiam 38 2.48 adiam 39 2.48 adiam 40 2.48 adiam 41 2.48 adiam 42 2.48 adiam 43 2.48 adiam 44 2.48 adiam 45 2.48 adiam 46 2.48 adiam 47 2.48 adiam 48 2.48 adiam 49 2.48 adiam 50 2.48 adiam 51 2.48 adiam 52 2.432 adiam 53 2.432 adiam 54 2.432 adiam 55 2.432 adiam 56 2.432 adiam 57 2.432 adiam 58 2.432 adiam 59 2.432 adiam 60 2.432 adiam 61 2.88 adiam 62 2.88 adiam 63 3.632 adiam 64 2.816 thermo 10 thermo_style custom step etotal evdwl ecoul elong edihed pe ke temp press run 100 - -CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE - -Your simulation uses code contributions which should be cited: - -- Type Label Framework: https://doi.org/10.1021/acs.jpcb.3c08419 - -@Article{Gissinger24, - author = {Jacob R. Gissinger, Ilia Nikiforov, Yaser Afshar, Brendon Waters, Moon-ki Choi, Daniel S. Karls, Alexander Stukowski, Wonpil Im, Hendrik Heinz, Axel Kohlmeyer, and Ellad B. Tadmor}, - title = {Type Label Framework for Bonded Force Fields in LAMMPS}, - journal = {J. Phys. Chem. B}, - year = 2024, - volume = 128, - number = 13, - pages = {3282–-3297} -} - -CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE - PPPM initialization ... - using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + using 12-bit tables for long-range coulomb G vector (1/distance) = 0.27938162 grid = 54 54 54 stencil order = 5 estimated absolute RMS force accuracy = 0.00036407395 estimated relative force accuracy = 1.0963718e-06 using double precision FFTW3 - 3d grid and FFT values/proc = 70516 40824 + 3d grid and FFT values/proc = 70516 39366 Generated 2016 of 2016 mixed pair_coeff terms from arithmetic mixing rule Neighbor list info ... update: every = 1 steps, delay = 2 steps, check = yes @@ -148,22 +140,22 @@ Bond: 87 1 0 1 Bond: 95 0.96 5.75241e-07 2 Bond: 97 1.325 4.3613e-08 3 Angle: 142 104.52 2.67611e-05 3265 -Per MPI rank memory allocation (min/avg/max) = 76.88 | 77.06 | 77.25 Mbytes +Per MPI rank memory allocation (min/avg/max) = 76.88 | 77 | 77.12 Mbytes Step TotEng E_vdwl E_coul E_long E_dihed PotEng KinEng Temp Press - 0 -27877.652 3447.5013 144035.68 -182420.51 343.05623 -34213.5 6335.8474 307.44113 -989.27065 + 0 -27877.652 3447.5013 144035.68 -182420.51 343.05623 -34213.5 6335.8474 307.44113 -989.27063 10 -27879.086 3334.4154 144205.4 -182416.19 348.14696 -34133.566 6254.4808 303.49289 -1211.2863 - 20 -27882.193 3293.7931 144272.04 -182415.87 333.20456 -34116.91 6234.7164 302.53384 -1041.5231 - 30 -27886.779 3177.7183 144344.61 -182409.28 340.77044 -34166.241 6279.462 304.70508 -1538.0247 + 20 -27882.194 3293.7931 144272.04 -182415.87 333.20456 -34116.91 6234.7164 302.53384 -1041.5232 + 30 -27886.779 3177.7183 144344.61 -182409.28 340.77044 -34166.241 6279.462 304.70508 -1538.0248 40 -27892.698 3186.4294 144409.85 -182417.01 337.80177 -34097.62 6204.9214 301.08807 -1516.1201 - 50 -27898.215 3198.5531 144426.3 -182405.24 336.58074 -34049.909 6151.6947 298.50529 -1349.4431 - 60 -27900.589 3163.4592 144400.32 -182414.85 341.17705 -34110.926 6210.3369 301.35085 -1695.3697 - 70 -27900.487 3223.7183 144242.71 -182409.21 341.09496 -34188.493 6288.0059 305.11967 -1493.2032 - 80 -27901.07 3274.244 144265.07 -182417.68 344.0409 -34177.343 6276.2725 304.55032 -1273.0263 - 90 -27905.672 3237.6056 144288.71 -182418.22 342.15013 -34187.814 6282.1417 304.83511 -1268.0436 + 50 -27898.215 3198.5531 144426.3 -182405.24 336.58074 -34049.909 6151.6947 298.50529 -1349.4433 + 60 -27900.589 3163.4592 144400.32 -182414.85 341.17705 -34110.926 6210.3369 301.35085 -1695.37 + 70 -27900.487 3223.7183 144242.71 -182409.21 341.09496 -34188.493 6288.0059 305.11967 -1493.2031 + 80 -27901.07 3274.244 144265.07 -182417.68 344.0409 -34177.342 6276.2726 304.55032 -1273.026 + 90 -27905.672 3237.6057 144288.71 -182418.22 342.15014 -34187.813 6282.1417 304.83511 -1268.0435 SHAKE stats (type/ave/delta/count) on step 100 Bond: 16 1.09 3.78281e-07 6 -Bond: 18 1.09 1.12288e-07 3 -Bond: 34 1.111 7.60709e-07 10 +Bond: 18 1.09 1.12287e-07 3 +Bond: 34 1.111 7.60708e-07 10 Bond: 39 1.111 2.37855e-07 5 Bond: 43 1.111 6.00872e-07 10 Bond: 44 1.111 3.75324e-07 10 @@ -187,23 +179,23 @@ Bond: 87 1 0 1 Bond: 95 0.96 1.03526e-07 2 Bond: 97 1.325 3.64689e-08 3 Angle: 142 104.52 0.000130126 3265 - 100 -27913.241 3159.0676 144299.1 -182414.94 336.48839 -34254.412 6341.1706 307.69943 -1421.2905 -Loop time of 3.49837 on 4 procs for 100 steps with 10245 atoms + 100 -27913.241 3159.0677 144299.1 -182414.94 336.48837 -34254.411 6341.1705 307.69943 -1421.2902 +Loop time of 3.22328 on 4 procs for 100 steps with 10245 atoms -Performance: 4.939 ns/day, 4.859 hours/ns, 28.585 timesteps/s, 292.851 katom-step/s -99.4% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 5.361 ns/day, 4.477 hours/ns, 31.024 timesteps/s, 317.844 katom-step/s +99.3% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.4572 | 2.5133 | 2.5634 | 2.6 | 71.84 -Bond | 0.0040264 | 0.0050718 | 0.0069286 | 1.6 | 0.14 -Kspace | 0.45979 | 0.50903 | 0.56364 | 5.6 | 14.55 -Neigh | 0.42029 | 0.42034 | 0.42036 | 0.0 | 12.02 -Comm | 0.013207 | 0.013292 | 0.013404 | 0.1 | 0.38 -Output | 0.00026525 | 0.00029549 | 0.00038249 | 0.0 | 0.01 -Modify | 0.035024 | 0.035546 | 0.03621 | 0.3 | 1.02 -Other | | 0.001504 | | | 0.04 +Pair | 2.251 | 2.2951 | 2.3427 | 2.4 | 71.21 +Bond | 0.0038074 | 0.004716 | 0.0061574 | 1.3 | 0.15 +Kspace | 0.4205 | 0.4693 | 0.51298 | 5.4 | 14.56 +Neigh | 0.39891 | 0.39898 | 0.39904 | 0.0 | 12.38 +Comm | 0.014307 | 0.014388 | 0.014467 | 0.1 | 0.45 +Output | 0.00027418 | 0.00029247 | 0.00034554 | 0.0 | 0.01 +Modify | 0.038003 | 0.038976 | 0.04042 | 0.5 | 1.21 +Other | | 0.001492 | | | 0.05 Nlocal: 2561.25 ave 2599 max 2520 min Histogram: 1 1 0 0 0 0 0 0 0 2 From d38b38274c805a89b7a9b32539466d37f9e986a9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 4 Sep 2026 06:44:18 -0400 Subject: [PATCH 033/120] reduce compiler warnings, improve errors --- src/atom_vec.cpp | 13 +++++++------ src/compute_count_type.cpp | 4 ++-- src/compute_msd.cpp | 2 +- src/compute_property_chunk.cpp | 2 +- src/compute_reduce.cpp | 2 +- src/compute_reduce_chunk.cpp | 2 +- src/compute_temp.cpp | 6 +++--- src/compute_temp_com.cpp | 8 ++++---- src/compute_temp_partial.cpp | 6 +++--- src/variable.h | 2 +- 10 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/atom_vec.cpp b/src/atom_vec.cpp index ad8f8d669b6..2ce4d31c57d 100644 --- a/src/atom_vec.cpp +++ b/src/atom_vec.cpp @@ -158,7 +158,8 @@ void AtomVec::init() error->all(FLERR, "KOKKOS package requires a kokkos enabled atom_style"); } -static constexpr bigint DELTA = 16384; +static constexpr int DELTA = 16384; +static constexpr bigint DELTABIG = DELTA; /* ---------------------------------------------------------------------- roundup N so it is a multiple of DELTA @@ -167,7 +168,7 @@ static constexpr bigint DELTA = 16384; bigint AtomVec::roundup(bigint n) { - if (n % DELTA) n = n / DELTA * DELTA + DELTA; + if (n % DELTABIG) n = n / DELTABIG * DELTABIG + DELTABIG; if (n > MAXSMALLINT) error->one(FLERR, "Too many atoms created on one or more procs"); return n; } @@ -182,7 +183,7 @@ void AtomVec::grow_nmax() nmax += DELTA; } -static constexpr bigint DELTA_BONUS = 8192; +static constexpr int DELTA_BONUS = DELTA/2; /* ---------------------------------------------------------------------- grow nmax_bonus so it is a multiple of DELTA_BONUS @@ -2545,13 +2546,13 @@ void AtomVec::setup_fields() int AtomVec::process_fields(const std::vector &words, const std::vector &def_words, Method *method) { - int nfield = words.size(); - int ndef = def_words.size(); + int nfield = (int) words.size(); + int ndef = (int) def_words.size(); // process fields one by one, add to index vector const auto &peratom = atom->peratom; - const int nperatom = peratom.size(); + const int nperatom = (int) peratom.size(); // allocate memory in method method->resize(nfield); diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 7b1651b61c3..27c278f712b 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -137,7 +137,7 @@ double ComputeCountType::compute_scalar() if (force->newton_bond == 0) bcount /= 2; if (bcount > MAXDOUBLEINT) error->all(FLERR, "Compute count/type overflow"); - scalar = bcount; + scalar = (double)bcount; return scalar; } @@ -179,7 +179,7 @@ void ComputeCountType::compute_vector() for (int m = 0; m < nvec; m++) if (bcount[m] > MAXDOUBLEINT) error->all(FLERR, "Compute count/type overflow"); - for (int m = 0; m < nvec; m++) vector[m] = bcount[m]; + for (int m = 0; m < nvec; m++) vector[m] = (double)bcount[m]; } /* ---------------------------------------------------------------------- diff --git a/src/compute_msd.cpp b/src/compute_msd.cpp index 8dd98c8fb10..2a96075c632 100644 --- a/src/compute_msd.cpp +++ b/src/compute_msd.cpp @@ -141,7 +141,7 @@ void ComputeMSD::compute_vector() { // check that nmsd is unchanged - int newnmsd = group->count(igroup); + bigint newnmsd = group->count(igroup); if (newnmsd != nmsd) error->all(FLERR, Error::NOLASTLINE, "Number of atoms in compute msd group must not change."); diff --git a/src/compute_property_chunk.cpp b/src/compute_property_chunk.cpp index 180fffd9061..504ba858fc4 100644 --- a/src/compute_property_chunk.cpp +++ b/src/compute_property_chunk.cpp @@ -148,7 +148,7 @@ void ComputePropertyChunk::allocate() double ComputePropertyChunk::memory_usage() { double bytes = ComputeChunk::memory_usage(); - bytes += (bigint) nchunk * nvalues * sizeof(double); + bytes += (double) nchunk * nvalues * sizeof(double); if (countflag) bytes += (double) nchunk * 2 * sizeof(int); return bytes; } diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp index e7f10569990..df1a835c4dc 100644 --- a/src/compute_reduce.cpp +++ b/src/compute_reduce.cpp @@ -198,7 +198,7 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : // optional args - nvalues = values.size(); + nvalues = (int)values.size(); replace = new int[nvalues]; for (int i = 0; i < nvalues; ++i) replace[i] = -1; input_mode = PERATOM; diff --git a/src/compute_reduce_chunk.cpp b/src/compute_reduce_chunk.cpp index 974cbba23f1..2214101ea5d 100644 --- a/src/compute_reduce_chunk.cpp +++ b/src/compute_reduce_chunk.cpp @@ -153,7 +153,7 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : } else { array_flag = 1; size_array_rows_variable = 1; - size_array_cols = values.size(); + size_array_cols = (int)values.size(); extarray = 0; } diff --git a/src/compute_temp.cpp b/src/compute_temp.cpp index 37300f648d9..e6e280ce2b2 100644 --- a/src/compute_temp.cpp +++ b/src/compute_temp.cpp @@ -58,7 +58,7 @@ void ComputeTemp::setup() void ComputeTemp::dof_compute() { adjust_dof_fix(); - natoms_temp = group->count(igroup); + natoms_temp = (double)group->count(igroup); dof = domain->dimension * natoms_temp; dof -= extra_dof + fix_dof; if (dof > 0.0) @@ -94,8 +94,8 @@ double ComputeTemp::compute_scalar() MPI_Allreduce(&t, &scalar, 1, MPI_DOUBLE, MPI_SUM, world); if (dynamic) dof_compute(); - if (dof < 0.0 && natoms_temp > 0.0) - error->all(FLERR, "Temperature compute degrees of freedom < 0"); + if ((dof < 0.0) && (natoms_temp > 0.0)) + error->all(FLERR, Error::NOLASTLINE, "Temperature compute {} degrees of freedom < 0", id); scalar *= tfactor; return scalar; } diff --git a/src/compute_temp_com.cpp b/src/compute_temp_com.cpp index 9bab3f9165a..c77e1326fec 100644 --- a/src/compute_temp_com.cpp +++ b/src/compute_temp_com.cpp @@ -69,10 +69,10 @@ void ComputeTempCOM::setup() void ComputeTempCOM::dof_compute() { adjust_dof_fix(); - natoms_temp = group->count(igroup); + natoms_temp = (double)group->count(igroup); dof = domain->dimension * natoms_temp; dof -= extra_dof + fix_dof; - if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz); + if (dof > 0.0) tfactor = force->mvv2e / (dof * force->boltz); else tfactor = 0.0; } @@ -110,8 +110,8 @@ double ComputeTempCOM::compute_scalar() MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world); if (dynamic) dof_compute(); - if (dof < 0.0 && natoms_temp > 0.0) - error->all(FLERR, Error::NOLASTLINE, "Temperature compute degrees of freedom < 0"); + if ((dof < 0.0) && (natoms_temp > 0.0)) + error->all(FLERR, Error::NOLASTLINE, "Temperature compute {} degrees of freedom < 0", id); scalar *= tfactor; return scalar; } diff --git a/src/compute_temp_partial.cpp b/src/compute_temp_partial.cpp index ec3c01fadfa..954ebf5914e 100644 --- a/src/compute_temp_partial.cpp +++ b/src/compute_temp_partial.cpp @@ -78,7 +78,7 @@ void ComputeTempPartial::setup() void ComputeTempPartial::dof_compute() { adjust_dof_fix(); - natoms_temp = group->count(igroup); + natoms_temp = (double)group->count(igroup); int nper = xflag+yflag+zflag; dof = nper * natoms_temp; @@ -126,8 +126,8 @@ double ComputeTempPartial::compute_scalar() MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world); if (dynamic) dof_compute(); - if (dof < 0.0 && natoms_temp > 0.0) - error->all(FLERR,"Temperature compute degrees of freedom < 0"); + if ((dof < 0.0) && (natoms_temp > 0.0)) + error->all(FLERR, Error::NOLASTLINE, "Temperature compute {} degrees of freedom < 0", id); scalar *= tfactor; return scalar; } diff --git a/src/variable.h b/src/variable.h index d3aea6ba899..d0cb8163438 100644 --- a/src/variable.h +++ b/src/variable.h @@ -37,7 +37,7 @@ class Variable : protected Pointers { void purge_atomfile(); void clear_in_progress(); - [[nodiscard]] int get_nvar() const { return variables.size(); } + [[nodiscard]] int get_nvar() const { return (int) variables.size(); } [[nodiscard]] const char *get_name(int i) const; [[nodiscard]] const char *get_style(int i) const; [[nodiscard]] std::string get_info(int i) const; From bd4c2d4d516e4bb8b93364cc4496040497894481 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 12:46:33 +0000 Subject: [PATCH 034/120] unittest: add a reference for fix freeze The GRANULAR package fix freeze has no reference so far. Add one on the sphere system of the brownian input: a constant force is added to all atoms, and the fix zeroes it again on a group of eight atoms whose velocity was set to zero. Its global vector reproduces the added force of exactly those eight atoms, so the reference fails if the fix stops seeing or stops zeroing the force. --- .../tests/fix-timestep-freeze.yaml | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 unittest/force-styles/tests/fix-timestep-freeze.yaml diff --git a/unittest/force-styles/tests/fix-timestep-freeze.yaml b/unittest/force-styles/tests/fix-timestep-freeze.yaml new file mode 100644 index 00000000000..f14bfc71e2f --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-freeze.yaml @@ -0,0 +1,124 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 12:46:18 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom sphere + fix freeze + fix addforce + fix nve/sphere +pre_commands: "" +post_commands: | + group frozen id 1:8 + velocity frozen set 0.0 0.0 0.0 + fix push all addforce 0.1 -0.2 0.3 + fix move all nve/sphere + fix test frozen freeze +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 7.9999999999999993e-01 -1.5999999999999999e+00 2.3999999999999999e+00 +run_pos: |2 + 1 8.1743856390593383e-01 -1.5010271964354949e+00 1.0637924298773633e+00 + 2 -1.5885878110813303e+00 2.2401728691740113e+00 4.7068930278928994e-01 + 3 -1.1818944957014061e+00 -2.6848623178033457e+00 -1.1800939297629425e+00 + 4 1.7205896211745580e-01 1.3643946759490944e+00 -1.1522506184595422e+00 + 5 -2.5038595242428823e+00 -1.6249307166302229e+00 -1.1484315973168586e+00 + 6 -1.2345478646498314e+00 -3.2244026715329771e-01 5.5339557736214073e-01 + 7 1.1946150666115714e+00 4.9213844242339227e-01 -5.1682952674245197e-01 + 8 1.8342027600045443e+00 1.5160950108325659e+00 4.3843911607852545e-02 + 9 -7.5879351833874142e-01 1.7789358484312321e+00 7.9565915576061874e-01 + 10 2.5972926660064748e+00 -1.8647583655455948e+00 4.8927967636252556e-01 + 11 -1.4181731160027302e+00 1.7723766139530115e+00 -9.4164886777057899e-01 + 12 -5.5181223811373514e-01 2.4297690153350042e+00 9.6441898135933779e-01 + 13 -2.4888426299257133e-01 1.3572542020980434e+00 2.1661324975171775e-01 + 14 6.2908491001815225e-01 -8.7237357202781940e-01 2.4755710818627219e-01 + 15 -1.3555712387728407e+00 -1.7492676919706331e+00 -5.7076540934712316e-02 + 16 -2.0176524035189671e+00 -1.7289555844515208e+00 -1.1193764627927547e+00 + 17 2.1665642331747668e+00 -2.5002391876471739e+00 1.0068596205776719e+00 + 18 -7.3487503383484076e-01 -1.3974921535932925e+00 -2.4284152250493188e-01 + 19 1.3444554998138287e+00 1.3907375166270164e+00 1.0988729503144357e+00 + 20 1.7387104803783953e+00 2.5247855562231298e+00 4.4339781390925603e-01 + 21 1.1849292759902565e+00 8.1872308152586926e-01 2.1520082405872876e-01 + 22 -8.4121322389017195e-01 1.6806678979994807e+00 7.4408570465480972e-01 + 23 -1.5739375460867937e+00 5.5886595879434398e-03 -9.1569143877619052e-01 + 24 8.1654581427533524e-01 -1.1331036627371471e+00 -7.7245370682111358e-01 + 25 2.3909276577752343e+00 -5.6765918727001374e-01 -6.2710447984532869e-01 + 26 -1.3191122943325966e+00 -2.0140424150453691e+00 5.9375533394837354e-01 + 27 1.3330088186881626e+00 -5.4123634740367121e-01 9.7152287142528393e-01 + 28 8.9848234847784358e-01 1.6985411068872214e+00 9.7076442954624298e-01 + 29 2.6221028339968835e+00 2.2590064206168212e+00 -1.3337125450851601e+00 + 30 -1.0569750846943260e+00 2.4716861283290110e+00 1.2581955403055073e-01 + 31 -1.5868776994651201e+00 -5.8129798638527219e-01 1.4821077503627395e-01 + 32 -2.6825458485801716e+00 -1.2824065299533078e+00 5.5512538869030470e-01 +run_vel: |2 + 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 9 -5.4530471918913896e+01 -1.1514822413917878e+02 -6.1072568392710423e+02 + 10 7.4863001092268973e+02 7.0186783579177677e+02 -4.9819744806233268e+02 + 11 -1.7494456085369347e+02 1.5340809830691131e+02 3.9081810049784451e+02 + 12 -3.9358374085589895e+02 5.6274787288343680e+02 -5.1224721431816056e+02 + 13 2.9404933154787409e+02 -4.1648188650753514e+02 -6.7895275020386930e+02 + 14 -7.6412797345353545e+02 7.3381541639404554e+02 7.2060532355867940e+02 + 15 -9.1188640318906081e+01 2.2490212260075899e+02 2.8443494063869281e+02 + 16 1.7907817196066165e+02 -5.3544191134126959e+02 -3.1855621738705094e+02 + 17 -4.2820380022951912e+02 -4.9151037524513259e+02 -2.7061522442093906e+02 + 18 3.9508033141307038e+02 3.0616664137582615e+02 -1.3214113879023644e+01 + 19 -2.0364023471521617e+02 -5.4703037084845690e+01 5.8106586403440929e+02 + 20 -1.1592425873891929e+02 -7.6200157158296918e+02 -2.2311450437244866e+02 + 21 6.5874258823272112e+02 5.8671439878439162e+02 -6.2485504650319012e+02 + 22 5.6131128662779027e+01 2.6141014759386150e+02 3.7386759316941522e+02 + 23 -2.5299318514427924e+02 -4.6609643365967321e+02 -6.7084435985796642e+02 + 24 -6.2705904704817578e+02 2.7853563755209211e+02 4.5718647265573276e+02 + 25 -5.4238795350865973e+02 -1.0531392332698724e+02 6.9119322533288823e+01 + 26 -2.1345976126842709e+02 -5.3434649237697761e+02 2.4411220197680274e+02 + 27 5.9521613712886767e+02 6.2653859854480550e+02 -7.3672167258298737e+02 + 28 -4.0055368220822896e+02 6.0663665596764770e+02 1.2166517500629433e+02 + 29 -3.4766165037948451e+02 -3.6579325072750822e+02 -5.4163496987380529e+02 + 30 -1.0498041107728554e+02 5.0013733349726215e+02 7.3143402433938309e+02 + 31 7.5485662237005886e+02 -3.4938864472681921e+01 -7.2609251663764019e+02 + 32 1.4002915910113560e+02 6.4308318310774314e+02 -5.3558703462098265e+02 +run_torque: |2 + 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +... From 1f50a583a1fce49adf7d787103d27eb599eac1ac Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 13:05:34 +0000 Subject: [PATCH 035/120] KOKKOS: fix the sign of the parallel drag force in pair dpd/ext/tstat/kk The parallel part of the dissipative force was added with the wrong sign, so the KOKKOS version of pair style dpd/ext/tstat pumped energy into the parallel component instead of damping it. The sibling style dpd/tstat/kk and the host version both negate the term. The ramp of the random force amplitude also updated only the parallel sigma and left the perpendicular sigmaT at its initial value, unlike the host version. The dissipative and conservative parts of the DPD pair styles are deterministic, and the amplitude of the random part is proportional to the target temperature, so at a temperature of zero the KOKKOS styles must reproduce the plain ones exactly. Add four references that use this to test them; so far every DPD reference skipped the KOKKOS tests because the device random number stream differs from the host one. --- src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp | 4 +- .../tests/mol-pair-dpd_ext_t0.yaml | 95 +++++++++++++++++++ .../tests/mol-pair-dpd_ext_tstat_t0.yaml | 95 +++++++++++++++++++ .../force-styles/tests/mol-pair-dpd_t0.yaml | 95 +++++++++++++++++++ .../tests/mol-pair-dpd_tstat_t0.yaml | 95 +++++++++++++++++++ 5 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml create mode 100644 unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml create mode 100644 unittest/force-styles/tests/mol-pair-dpd_t0.yaml create mode 100644 unittest/force-styles/tests/mol-pair-dpd_tstat_t0.yaml diff --git a/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp b/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp index 7b2c5f665d5..f0dc02bd5c1 100644 --- a/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp @@ -118,6 +118,8 @@ void PairDPDExtTstatKokkos::compute(int eflagin, int vflagin) for (int j = i; j <= atom->ntypes; j++) { k_params.view_host()(i,j).sigma = k_params.view_host()(j,i).sigma = static_cast(sqrt(2.0*boltz*temperature*gamma[i][j])); + k_params.view_host()(i,j).sigmaT = k_params.view_host()(j,i).sigmaT = + static_cast(sqrt(2.0*boltz*temperature*gammaT[i][j])); } } k_params.modify_host(); @@ -299,7 +301,7 @@ void PairDPDExtTstatKokkos::operator() (TagDPDExtTstatKokkos(rand_gen.normal()); // drag force - parallel - fpair = params(itype,jtype).gamma*wdPar*wdPar*dot*rinv; + fpair = -params(itype,jtype).gamma*wdPar*wdPar*dot*rinv; fpair *= factor_dpd; // random force - parallel diff --git a/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml b/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml new file mode 100644 index 00000000000..5e5088dd772 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml @@ -0,0 +1,95 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 12:52:23 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + pair dpd/ext +pre_commands: | + variable newton_pair delete + variable newton_pair index on + comm_modify vel yes +post_commands: "" +input_file: in.fourmol +pair_style: dpd/ext 0.0 8.0 55667788 +pair_coeff: | + * * 0.1 4.5 4.5 0.5 0.5 + 1 1 0.2 3.5 3.5 0.5 0.5 + 2 2 0.3 4.0 4.0 0.5 0.5 + 2 4 0.2 4.0 4.0 0.5 0.5 6.5 + 3 3 0.5 4.4 4.0 0.6 0.4 + 4 4 0.2 5.0 5.3 0.4 0.6 + 5 5 0.1 4.0 4.0 0.5 0.5 +extract: "" +natoms: 29 +init_vdwl: 30.80939222789883 +init_coul: 0 +init_stress: |2- + 2.2046196991243061e+01 2.8636262609476788e+01 2.3337819407743869e+01 -3.6989378975945955e+00 -7.1493227478737289e+00 -7.3474262592252604e-01 +init_forces: |2 + 1 -4.2835236279424493e-01 3.7792546783448100e-01 1.2512327915978214e-01 + 2 -6.8182165994908162e-01 7.2853620138562258e-01 -1.9205496943463171e-02 + 3 -4.6272893803301057e-01 1.4570445958959199e-01 6.3188134022620010e-02 + 4 -1.0735746566644133e+00 3.2168677928140560e-01 5.8856064013097682e-03 + 5 -9.5453153788409328e-01 2.1686084144328074e-01 3.7932751981063145e-01 + 6 -3.7202726906941314e-01 -3.8415740095932696e-02 -6.5761346328869541e-02 + 7 -5.9355365433863083e-01 -1.1596313989653834e-01 -3.4535469242293665e-01 + 8 -1.1885644325817287e-02 -2.4032389851799560e-01 4.9901996685576627e-02 + 9 -3.4356326874207116e-02 -2.5743421004797301e-01 6.3647661681528067e-01 + 10 1.3305107114102702e-01 -3.1119155319917202e-01 5.7281360970137869e-02 + 11 3.0091535776971608e-02 -7.5724495200576813e-01 -5.8717038848575258e-02 + 12 3.7549148087855683e-01 -1.3956357456289459e-01 6.2974537448275882e-03 + 13 7.4770810815684019e-01 -3.4936070430734500e-01 5.9032973384418604e-02 + 14 5.3823916767043456e-01 -1.5027796158703860e-01 -3.7800575116971280e-01 + 15 1.1439106531800662e+00 1.2917806307536961e-01 -1.3038460894054568e-01 + 16 2.4310119071707445e-01 -3.7986492876022965e-01 1.9124451831395134e-01 + 17 2.6270807597577395e-01 -5.0131811571033036e-01 4.9750368439356429e-01 + 18 2.2808897984512022e-01 6.0972558865515003e-01 -5.0944485835855202e-01 + 19 4.8039089826003065e-02 8.0485636295796437e-01 -1.1632567651952743e+00 + 20 2.4543488533300428e-01 6.0781194851874543e-01 -7.2674861482160558e-01 + 21 2.4110558226394682e-01 -2.8799595959606583e-01 -1.9348558432445281e-01 + 22 2.6863611567109547e-01 -4.5230415739657226e-01 -4.9821474348680284e-01 + 23 4.9432961171177803e-01 -3.2292827755295161e-01 -3.5469216334172321e-01 + 24 1.1866796133391443e-01 2.3321959512529969e-01 4.1637295544202813e-01 + 25 -1.1938096309509150e-02 7.3769262958342063e-01 8.2175481295227704e-01 + 26 3.0764494285942562e-01 4.5826321255915287e-01 4.7316075265681073e-01 + 27 -1.6326748362883889e-01 -2.1782737013515990e-01 1.4747912074092071e-01 + 28 -3.5827078957710556e-01 -3.3791825122465691e-01 1.1945991383083407e-01 + 29 -2.7994003289266678e-01 -5.1152835541285990e-01 3.9378096485754327e-01 +run_vdwl: 30.80374205817756 +run_coul: 0 +run_stress: |2- + 2.2024415989896553e+01 2.8619482916597910e+01 2.3320868868148928e+01 -3.6963953811512869e+00 -7.1409417245380791e+00 -7.2903052438278115e-01 +run_forces: |2 + 1 -4.2799816039445349e-01 3.7791664596095109e-01 1.2508337043350859e-01 + 2 -6.8020731084232233e-01 7.2788175305834402e-01 -1.8771156655721780e-02 + 3 -4.6235260628047936e-01 1.4574195686515323e-01 6.3110881995604856e-02 + 4 -1.0721541622589947e+00 3.2125641190111842e-01 5.5008165872513989e-03 + 5 -9.5321298553277711e-01 2.1673082416041223e-01 3.7864507119245511e-01 + 6 -3.7166402278445526e-01 -3.8242789436856744e-02 -6.5744516592555466e-02 + 7 -5.9328328631044347e-01 -1.1582267837105134e-01 -3.4520503419850723e-01 + 8 -1.1957564352801920e-02 -2.4012584184152766e-01 4.9835932899135064e-02 + 9 -3.4417209684488526e-02 -2.5714839070660866e-01 6.3545320129448502e-01 + 10 1.3286567053731080e-01 -3.1094600789322169e-01 5.7210068439798895e-02 + 11 2.9719271246457037e-02 -7.5603162239070265e-01 -5.8900125330474860e-02 + 12 3.7512677309088782e-01 -1.3936422111150285e-01 6.1377942755389964e-03 + 13 7.4698157791347208e-01 -3.4822677629234067e-01 5.8812791940842352e-02 + 14 5.3680051677304785e-01 -1.5015541729225346e-01 -3.7790686873051815e-01 + 15 1.1416094024286845e+00 1.2881021635291293e-01 -1.3022638784347343e-01 + 16 2.4292465289298457e-01 -3.7969655864459101e-01 1.9120617182085889e-01 + 17 2.6261887962849462e-01 -5.0126168976592722e-01 4.9745028816197212e-01 + 18 2.2799177665723203e-01 6.0951521930948238e-01 -5.0933582748803263e-01 + 19 4.8038016642205562e-02 8.0426369384393304e-01 -1.1622034877212817e+00 + 20 2.4538042594844631e-01 6.0686258589493047e-01 -7.2525042066619783e-01 + 21 2.4128893849901994e-01 -2.8808847492142087e-01 -1.9351350177099155e-01 + 22 2.6868029618113098e-01 -4.5235786163469260e-01 -4.9794860435522537e-01 + 23 4.9413979128361607e-01 -3.2297121476081087e-01 -3.5428528433385148e-01 + 24 1.1857372999988632e-01 2.3324019365873611e-01 4.1634747727328042e-01 + 25 -1.1715189145369544e-02 7.3657678051099262e-01 8.2110263829259000e-01 + 26 3.0727638889731274e-01 4.5791033817552806e-01 4.7304251566547723e-01 + 27 -1.6333424737074195e-01 -2.1786833150912424e-01 1.4750425916401930e-01 + 28 -3.5805540991985163e-01 -3.3763143840850257e-01 1.1943585121990399e-01 + 29 -2.7966395374300979e-01 -5.1076730471135878e-01 3.9341208503010966e-01 +... diff --git a/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml b/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml new file mode 100644 index 00000000000..416740a22e5 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml @@ -0,0 +1,95 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 12:52:28 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + pair dpd/ext/tstat +pre_commands: | + variable newton_pair delete + variable newton_pair index on + comm_modify vel yes +post_commands: "" +input_file: in.fourmol +pair_style: dpd/ext/tstat 0.0 0.0 8.0 55667788 +pair_coeff: | + * * 4.5 4.5 0.5 0.5 + 1 1 3.5 3.5 0.5 0.5 + 2 2 4.0 4.0 0.5 0.5 + 2 4 4.0 4.0 0.5 0.5 6.5 + 3 3 4.4 4.0 0.6 0.4 + 4 4 5.0 5.3 0.4 0.6 + 5 5 4.0 4.0 0.5 0.5 +extract: "" +natoms: 29 +init_vdwl: 0 +init_coul: 0 +init_stress: |- + -3.5313393365255075e-01 -5.3960916859929120e-01 -2.4419458171553152e-01 7.7880065024991840e-01 -4.1251648667416363e-01 -4.6329963652765127e-01 +init_forces: |2 + 1 -1.5746659343124005e-02 -5.8064320337767379e-02 2.9700467926992991e-02 + 2 -8.8328024843259620e-02 -2.0218739552622322e-01 -1.1685034600410460e-01 + 3 5.1778383656494946e-02 -8.3642499006150187e-02 3.1833175185354695e-02 + 4 3.8652749045540065e-02 1.7267950653481783e-02 1.4169563134665869e-01 + 5 5.3018331154195936e-02 -5.3838868069965150e-02 1.8460809667183123e-02 + 6 1.7414827423030962e-02 -7.3750309954607254e-02 -4.2795538622103068e-03 + 7 1.0817291605108465e-02 1.1382229546842766e-02 3.0197635983236156e-02 + 8 -8.3444438801833776e-03 1.2432755409277862e-02 2.4768400721885415e-02 + 9 -5.1003792525459501e-02 9.9674997185079037e-02 -2.8471081798701964e-02 + 10 -1.6370361264013943e-02 -3.2841296459684845e-02 3.3771156981353447e-02 + 11 8.4529150675940554e-03 3.6877898467490726e-02 1.2310365142084367e-01 + 12 -3.5447120062719273e-02 6.7609238359094739e-03 7.5866197707343153e-02 + 13 -1.3889344568742379e-01 -1.4129303130583770e-01 5.3069859717879163e-02 + 14 9.4445454321190406e-03 1.4675201383949912e-01 1.8332922740388574e-01 + 15 1.9442094571167756e-01 1.2092313726943019e-01 -1.0705424521756755e-01 + 16 -2.6269629429515337e-03 -5.5746497821208569e-03 -2.9489671395479290e-02 + 17 -2.1543297940801984e-02 -2.1652143127578610e-02 -2.3212872468015122e-02 + 18 2.2398640400394056e-02 2.4763812454601221e-02 8.3005651758156010e-03 + 19 2.8997912461561928e-02 1.0749701530885243e-01 -1.3638060796442661e-01 + 20 -1.1853873002248284e-01 -1.4064003944327810e-01 -4.1644364936222124e-02 + 21 2.6066602391341342e-02 -1.7670822406743995e-02 -2.1713751576573179e-03 + 22 5.9220120234175208e-02 3.3083430013098582e-02 -6.2992452933977483e-02 + 23 -5.3622215606495549e-04 5.7780826334723215e-02 -4.6487828675178790e-02 + 24 -1.5194901239512552e-03 -1.2823526653781619e-02 2.3850568153620574e-02 + 25 -1.1423179700707803e-01 1.2364945745462069e-01 -5.6216510882650131e-02 + 26 3.8153358745202752e-02 5.0030820520713330e-02 -4.5934132872974952e-02 + 27 2.7093598213696127e-03 -1.0256653402240421e-02 8.3601659965504352e-03 + 28 -3.6620909022030534e-04 8.2498422324890526e-03 -2.8561409226480105e-02 + 29 5.1950573739928591e-02 -2.8915550501301488e-03 -5.6561059992956540e-02 +run_vdwl: 0 +run_coul: 0 +run_stress: |- + -3.5354049068583787e-01 -5.3967000490646477e-01 -2.4470443418314641e-01 7.7739130325651795e-01 -4.1251076066659559e-01 -4.6240736851076103e-01 +run_forces: |2 + 1 -1.5753012652010231e-02 -5.8005365480871179e-02 2.9689677911605962e-02 + 2 -8.8182284177332301e-02 -2.0182471207409999e-01 -1.1663976568752815e-01 + 3 5.1732190127193302e-02 -8.3576232352476854e-02 3.1818954148334348e-02 + 4 3.8581517681715249e-02 1.7252630638740479e-02 1.4149921202820862e-01 + 5 5.2922209263976970e-02 -5.3747717576717702e-02 1.8439346031203351e-02 + 6 1.7393917214820104e-02 -7.3706579866621991e-02 -4.2758189073648662e-03 + 7 1.0792697044737839e-02 1.1359998838699384e-02 3.0191908154886656e-02 + 8 -8.3557642937932743e-03 1.2409773380984149e-02 2.4747780656589211e-02 + 9 -5.0926687152483746e-02 9.9492923651698456e-02 -2.8408729283009530e-02 + 10 -1.6367396359502299e-02 -3.2846749789476937e-02 3.3747601347310620e-02 + 11 8.4315469318436229e-03 3.6803087760825720e-02 1.2291564948236088e-01 + 12 -3.5434649103053703e-02 6.7411141784361230e-03 7.5807044160166717e-02 + 13 -1.3867532310071687e-01 -1.4108042218066522e-01 5.2984928475878205e-02 + 14 9.4111040376559704e-03 1.4647735271660525e-01 1.8299101085656669e-01 + 15 1.9414848583481925e-01 1.2075961350089685e-01 -1.0693049415509917e-01 + 16 -2.6280180687450229e-03 -5.5861606330864649e-03 -2.9472141961437374e-02 + 17 -2.1537734970142601e-02 -2.1655099255296410e-02 -2.3182441794557637e-02 + 18 2.2394453830442158e-02 2.4760537590466720e-02 8.3022731330033850e-03 + 19 2.8974450496389918e-02 1.0742380225794727e-01 -1.3628635994352842e-01 + 20 -1.1836350829933956e-01 -1.4041746889077730e-01 -4.1569242157957778e-02 + 21 2.6068900601512852e-02 -1.7662617330461521e-02 -2.1492259125069262e-03 + 22 5.9218572472683285e-02 3.3096281422435966e-02 -6.2969642179681248e-02 + 23 -5.4126557462153523e-04 5.7736295101022281e-02 -4.6445226749100239e-02 + 24 -1.5162220932292557e-03 -1.2815480142577405e-02 2.3854468842860497e-02 + 25 -1.1412472835998060e-01 1.2352802105384551e-01 -5.6149725318502458e-02 + 26 3.8131695659428186e-02 5.0006561099914075e-02 -4.5897693164547303e-02 + 27 2.7017088294150103e-03 -1.0262523543778452e-02 8.3753223000928509e-03 + 28 -3.6996192363449791e-04 8.2360486552853253e-03 -2.8522704799123180e-02 + 29 5.1873106101951678e-02 -2.8969127308961923e-03 -5.6465965515123714e-02 +... diff --git a/unittest/force-styles/tests/mol-pair-dpd_t0.yaml b/unittest/force-styles/tests/mol-pair-dpd_t0.yaml new file mode 100644 index 00000000000..8d4528f18ac --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-dpd_t0.yaml @@ -0,0 +1,95 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 12:52:03 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + pair dpd +pre_commands: | + variable newton_pair delete + variable newton_pair index on + comm_modify vel yes +post_commands: "" +input_file: in.fourmol +pair_style: dpd 0.0 8.0 11223344 +pair_coeff: | + * * 0.4 4.0 + 1 1 0.4 4.0 + 2 2 0.1 2.0 + 2 4 0.1 1.0 6.5 + 3 3 0.4 3.2 + 4 4 0.3 3.1 + 5 5 0.3 3.1 +extract: "" +natoms: 29 +init_vdwl: 49.27594449048496 +init_coul: 0 +init_stress: |2- + 3.5915734093326890e+01 4.7263177581789378e+01 3.6848730010982301e+01 -8.0696680228389308e+00 -1.0746221098316152e+01 8.0784993628064450e-01 +init_forces: |2 + 1 -1.4463927189033534e+00 1.3219106368052382e+00 3.1500676633351915e-01 + 2 -4.6307515772300123e-01 1.0361125406183451e+00 -1.1077787586901516e-01 + 3 -1.6814132934637289e+00 6.2362198974247385e-01 7.9068115548812684e-02 + 4 -9.5735080014676854e-01 4.1504433401871255e-01 -2.2048074672108584e-01 + 5 -9.4749544196633106e-01 3.8553027998684908e-01 2.9543291211957246e-01 + 6 -1.3321620017475480e+00 -2.7065536470427462e-03 -2.0079482466795445e-01 + 7 -8.0288927622090489e-01 4.9806172938088318e-02 -7.2422668481118713e-01 + 8 -2.2358381598775626e-01 -5.9303025553544275e-01 1.7125160398655628e-01 + 9 6.8634746252664469e-02 -1.8845471119185347e-01 4.3411205722459661e-01 + 10 5.0427495360104091e-01 -9.9527075823575550e-01 1.0462131875974789e-01 + 11 9.6085166814764950e-02 -6.1845891597792524e-01 -3.1957986927667037e-01 + 12 1.3085644366497300e+00 -5.4075058968591549e-01 -1.5187090883919768e-01 + 13 9.1359976430669532e-01 -6.7889298776545690e-02 -1.5173744856102572e-01 + 14 6.1817849294597649e-01 -9.1796970844383777e-02 -7.4834612618934893e-01 + 15 1.0930432626315054e+00 2.0971068477974519e-01 -2.3466515172900959e-01 + 16 8.0987536063080323e-01 -1.2380291356535731e+00 7.5376100837028004e-01 + 17 5.0121879385571777e-01 -7.3515398786254138e-01 8.0291896113230143e-01 + 18 4.2219384320712039e-01 1.0471746901141985e+00 -9.7066341397167111e-01 + 19 1.4036615690465515e-01 8.0696380921276445e-01 -1.1326411346166640e+00 + 20 3.8464220805365634e-01 7.3097034361709645e-01 -7.1330126729704912e-01 + 21 8.6448265227994647e-01 -1.0864514776006644e+00 -7.6663648023705766e-01 + 22 2.8036947000069368e-01 -4.8674395918678998e-01 -5.4590006471798280e-01 + 23 5.3453791472580514e-01 -3.5014186297577277e-01 -4.0889146928312303e-01 + 24 4.8221828728995997e-01 9.8225274212225344e-01 1.5741290250270623e+00 + 25 1.6657349442210911e-01 7.5408706129281677e-01 9.3777898536551318e-01 + 26 3.0751651366875582e-01 4.9338379498220220e-01 5.5956754665444586e-01 + 27 -6.6411673750164990e-01 -8.3119938983469033e-01 5.5692938041404549e-01 + 28 -4.9407486156942010e-01 -4.2640209214946878e-01 2.3491285385721261e-01 + 29 -4.8382141301113835e-01 -6.0408912107241819e-01 5.8102293199437693e-01 +run_vdwl: 49.269585028164144 +run_coul: 0 +run_stress: |2- + 3.5906293232248757e+01 4.7256435200606475e+01 3.6843455422352207e+01 -8.0689895218237719e+00 -1.0739255251699385e+01 8.1266712138472608e-01 +run_forces: |2 + 1 -1.4459288638045737e+00 1.3218297255914180e+00 3.1482832139445305e-01 + 2 -4.6235676839829970e-01 1.0357256595189910e+00 -1.1039678426976157e-01 + 3 -1.6809587742272902e+00 6.2372331512361379e-01 7.8874139183405925e-02 + 4 -9.5693049239420636e-01 4.1476408298457024e-01 -2.2078691695139949e-01 + 5 -9.4716969112211591e-01 3.8543891668639302e-01 2.9517244907178419e-01 + 6 -1.3317556711068874e+00 -2.3361768919097359e-03 -2.0063961175292944e-01 + 7 -8.0277490073399749e-01 4.9754976064363320e-02 -7.2401587019407976e-01 + 8 -2.2370993966472097e-01 -5.9283422369194672e-01 1.7110326115698016e-01 + 9 6.8536489618429133e-02 -1.8848081012845366e-01 4.3403419495577067e-01 + 10 5.0410426326827096e-01 -9.9487999756692047e-01 1.0454801726574200e-01 + 11 9.5737188445198906e-02 -6.1804264877845472e-01 -3.1961883541347252e-01 + 12 1.3080208628389349e+00 -5.4043226180799064e-01 -1.5207183907122812e-01 + 13 9.1336136797098966e-01 -6.7316985137494484e-02 -1.5162546166789576e-01 + 14 6.1724341246109282e-01 -9.2035076511423466e-02 -7.4826399709871072e-01 + 15 1.0925309825958118e+00 2.0929818902845362e-01 -2.3434009554556198e-01 + 16 8.0962436443688157e-01 -1.2376294779767849e+00 7.5370569380908736e-01 + 17 5.0115977089255004e-01 -7.3498108760520964e-01 8.0286652200263331e-01 + 18 4.2209647715438592e-01 1.0470055337255368e+00 -9.7067867093074001e-01 + 19 1.4037461151022756e-01 8.0714223255331985e-01 -1.1330070232430762e+00 + 20 3.8462155149599808e-01 7.3032613155894177e-01 -7.1246134800606631e-01 + 21 8.6459320443879917e-01 -1.0864819332230919e+00 -7.6673877970080051e-01 + 22 2.8027937864056229e-01 -4.8710422054477626e-01 -5.4584955878487096e-01 + 23 5.3443999785718344e-01 -3.5032711867504590e-01 -4.0860078828031460e-01 + 24 4.8218771693267970e-01 9.8212227281437736e-01 1.5740465118045135e+00 + 25 1.6683148591317337e-01 7.5342645202670733e-01 9.3775391671115682e-01 + 26 3.0736540776091725e-01 4.9316592808803372e-01 5.5974882745256338e-01 + 27 -6.6411999720413295e-01 -8.3118048503944209e-01 5.5681271741480454e-01 + 28 -4.9384540338845345e-01 -4.2615568484828775e-01 2.3484807461697238e-01 + 29 -4.8355803218740900e-01 -6.0350522733748757e-01 5.8075293407103956e-01 +... diff --git a/unittest/force-styles/tests/mol-pair-dpd_tstat_t0.yaml b/unittest/force-styles/tests/mol-pair-dpd_tstat_t0.yaml new file mode 100644 index 00000000000..514ba01850f --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-dpd_tstat_t0.yaml @@ -0,0 +1,95 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 12:52:19 2026 +epsilon: 2.5e-13 +skip_tests: +prerequisites: | + atom full + pair dpd/tstat +pre_commands: | + variable newton_pair delete + variable newton_pair index on + comm_modify vel yes +post_commands: "" +input_file: in.fourmol +pair_style: dpd/tstat 0.0 0.0 8.0 55667788 +pair_coeff: | + * * 4.0 + 1 1 4.0 + 2 2 2.0 + 2 4 1.0 6.5 + 3 3 3.2 + 4 4 3.1 + 5 5 3.1 +extract: "" +natoms: 29 +init_vdwl: 0 +init_coul: 0 +init_stress: |- + -1.4221138371383890e-01 -1.4324753055883854e-01 -2.8123467418587605e-02 5.1631542998017893e-02 2.3338244053621324e-02 2.2212084038899111e-04 +init_forces: |2 + 1 1.3804513881880561e-03 -7.1643313993628348e-03 4.1264465260940197e-03 + 2 1.3405449981966880e-03 -2.7896421606503886e-02 -7.8421176543063426e-03 + 3 1.4171760789709753e-02 -1.1677474241071881e-02 1.8934274700667141e-03 + 4 8.9114502296287600e-03 1.1171064747767655e-03 7.8949427455770275e-03 + 5 9.3912175088837826e-03 -4.8203135788670312e-03 -3.9298574586072565e-03 + 6 5.3998367000324936e-03 -1.0355600410170834e-02 6.4127148070355932e-04 + 7 1.7621511836904400e-03 2.4724467840089593e-04 5.5236690208588200e-03 + 8 -6.7693706922786912e-03 3.1121756892586033e-03 -9.3704991939610498e-05 + 9 -1.4296780380531518e-02 1.3854625500076899e-02 -6.4015716875226733e-03 + 10 -3.9641437397524961e-03 -2.5361074888715219e-03 3.1907614955669680e-03 + 11 -5.7854088672870899e-03 1.1448321043605728e-02 1.2116527916679163e-02 + 12 -1.3356689581690341e-02 4.6348141239483526e-03 7.8243972743521264e-03 + 13 -1.8200926337723893e-02 -4.8503496142581629e-03 5.5601581910320027e-03 + 14 -1.7648140894665071e-02 1.5322304635343009e-02 2.0364092162772480e-02 + 15 2.8544876421314855e-02 9.6813167440848360e-03 -1.3495179438125605e-02 + 16 -1.6663837955770611e-03 3.9333431842859751e-03 -6.9604129742234077e-03 + 17 -1.9277243598416816e-03 1.0774248075694440e-03 -3.1658112607365735e-03 + 18 1.9027196551919703e-03 1.7212841979783804e-03 -1.4494949447568005e-03 + 19 6.7292969656420881e-03 2.0589442922724861e-02 -2.4822338776798646e-02 + 20 -8.2894170029054748e-03 -1.6918717489398837e-02 1.1228769025360536e-02 + 21 4.3267327895244994e-03 -5.1509288433769949e-03 -1.3796435698757664e-03 + 22 4.1908666739434840e-03 -4.7527243558883525e-03 -5.1559070020428012e-03 + 23 -5.1470607559067052e-04 1.0081492272386056e-03 4.3281114565182812e-04 + 24 1.4684814584972369e-03 -1.9197449940717732e-03 4.0394758734327713e-03 + 25 -6.7909251799619765e-03 3.8690674117409780e-04 -4.0770091873822325e-03 + 26 2.2911504418478123e-03 1.8516119472635065e-03 1.5853569279039141e-03 + 27 -2.0936370081589228e-04 -9.1652290301258280e-04 4.5356143656413727e-04 + 28 9.3865509823309857e-04 2.2458552985064710e-03 -1.8023219612927719e-03 + 29 6.6697883060968461e-03 6.7273097086182482e-03 -6.3002977850055803e-03 +run_vdwl: 0 +run_coul: 0 +run_stress: |- + -1.4228602005556543e-01 -1.4332662687003542e-01 -2.8256824158476180e-02 5.1540047333382397e-02 2.3350997079446496e-02 7.6470774221434215e-05 +run_forces: |2 + 1 1.3861474899899433e-03 -7.1559262401433591e-03 4.1305475807535234e-03 + 2 1.3315258434090638e-03 -2.7890733587473387e-02 -7.8554988115374352e-03 + 3 1.4162187034249546e-02 -1.1664491495004970e-02 1.9006415306380183e-03 + 4 8.9077933553913021e-03 1.1136538773016535e-03 7.8988366585335916e-03 + 5 9.3857690961670261e-03 -4.8134062652545858e-03 -3.9226168670631664e-03 + 6 5.3963053448666219e-03 -1.0355001627400068e-02 6.3980201139914592e-04 + 7 1.7635157063113250e-03 2.4388646510834511e-04 5.5224699030825873e-03 + 8 -6.7689001348957747e-03 3.1073750157475225e-03 -9.0076061254800490e-05 + 9 -1.4285029459335095e-02 1.3848732731532509e-02 -6.3982240588811171e-03 + 10 -3.9587440328304581e-03 -2.5371524803236129e-03 3.1877882191923882e-03 + 11 -5.7803277287957902e-03 1.1445803683009967e-02 1.2115531935008379e-02 + 12 -1.3343034087174035e-02 4.6367657426235141e-03 7.8246364988988869e-03 + 13 -1.8201917168124662e-02 -4.8584568883622749e-03 5.5471378196822567e-03 + 14 -1.7632715403380048e-02 1.5327262128094208e-02 2.0372818644519758e-02 + 15 2.8535123081350842e-02 9.6718508701228566e-03 -1.3491905385507610e-02 + 16 -1.6619117177343263e-03 3.9268178801011525e-03 -6.9599172196641024e-03 + 17 -1.9261443958301728e-03 1.0748120460040876e-03 -3.1636027302888682e-03 + 18 1.9011971071406408e-03 1.7207931163588741e-03 -1.4475015369067926e-03 + 19 6.7307488183917163e-03 2.0598852618153515e-02 -2.4831269602445350e-02 + 20 -8.2911124295405713e-03 -1.6916349464265984e-02 1.1216638786423030e-02 + 21 4.3299604229938915e-03 -5.1459823330505102e-03 -1.3815566903028831e-03 + 22 4.1922864881818993e-03 -4.7504231107325023e-03 -5.1476174073772640e-03 + 23 -5.2335413339765790e-04 1.0123139228816753e-03 4.3955685831786960e-04 + 24 1.4710795677181994e-03 -1.9155929978848150e-03 4.0415912047860542e-03 + 25 -6.7956791657715404e-03 3.8059299306470124e-04 -4.0922134238179555e-03 + 26 2.2854228317869983e-03 1.8479104534328047e-03 1.5849069098057889e-03 + 27 -2.0865971290571789e-04 -9.1521964492436748e-04 4.5282636106565099e-04 + 28 9.3741554436544707e-04 2.2437257315209439e-03 -1.8010271347797752e-03 + 29 6.6610518374013855e-03 6.7175868597621098e-03 -6.2927039922798210e-03 +... From 0462e2b7054664f1f76edf987e3927eab98d7c3f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 13:08:22 +0000 Subject: [PATCH 036/120] KOKKOS: support the shift keyword in the tersoff pair styles The shift keyword of pair style tersoff and of its mod, mod/c and zbl variants was rejected for the KOKKOS package, so those simulations could not use an accelerated style at all. Implement it in the four KOKKOS kernels, following the CPU code: the squared distance of a pair becomes rsq + shift*shift + 2*sqrt(rsq)*shift wherever a cutoff function or a derivative with respect to the distance is evaluated, the two body force is corrected with sqrt(rsq_shifted/rsq), and the unit vectors and the angle keep using the unshifted geometry. Unlike the CPU side, where only pair_tersoff.cpp evaluates the shift and the variants inherit it, each of the four KOKKOS styles carries its own copy of the kernels, so all four need the change. The four references that were skipped for the KOKKOS package now run. --- doc/src/pair_tersoff.rst | 7 +- doc/src/pair_tersoff_mod.rst | 8 +- doc/src/pair_tersoff_zbl.rst | 9 ++- src/KOKKOS/pair_tersoff_kokkos.cpp | 69 +++++++++++++---- src/KOKKOS/pair_tersoff_kokkos.h | 1 + src/KOKKOS/pair_tersoff_mod_c_kokkos.cpp | 77 +++++++++++++++---- src/KOKKOS/pair_tersoff_mod_c_kokkos.h | 2 + src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 75 ++++++++++++++---- src/KOKKOS/pair_tersoff_mod_kokkos.h | 2 + src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 71 +++++++++++++---- src/KOKKOS/pair_tersoff_zbl_kokkos.h | 2 + src/MANYBODY/pair_tersoff.cpp | 2 +- .../manybody-pair-tersoff_mod_c_shift.yaml | 2 +- .../manybody-pair-tersoff_mod_shift.yaml | 2 +- .../tests/manybody-pair-tersoff_shift.yaml | 2 +- .../manybody-pair-tersoff_zbl_shift.yaml | 2 +- 16 files changed, 263 insertions(+), 70 deletions(-) diff --git a/doc/src/pair_tersoff.rst b/doc/src/pair_tersoff.rst index e1e373a6e30..ab53e3a84b8 100644 --- a/doc/src/pair_tersoff.rst +++ b/doc/src/pair_tersoff.rst @@ -303,8 +303,11 @@ This pair style requires the :doc:`newton ` setting to be "on" for pair interactions. The *shift* keyword is not supported by the *tersoff/gpu*, -*tersoff/intel*, *tersoff/kk*, *tersoff/table* or *tersoff/table/omp* -variants. +*tersoff/intel*, *tersoff/table* or *tersoff/table/omp* variants. + +.. versionchanged:: TBD + + The *shift* keyword is now also supported by the *tersoff/kk* variant. The *tersoff/intel* pair style is only available when compiling LAMMPS with the Intel compilers. diff --git a/doc/src/pair_tersoff_mod.rst b/doc/src/pair_tersoff_mod.rst index 1d6f443ef03..1e44ebe5c07 100644 --- a/doc/src/pair_tersoff_mod.rst +++ b/doc/src/pair_tersoff_mod.rst @@ -204,8 +204,12 @@ This pair style requires the :doc:`newton ` setting to be "on" for pair interactions. The *shift* keyword is not supported by the *tersoff/gpu*, -*tersoff/intel*, *tersoff/kk*, *tersoff/table* or *tersoff/table/omp* -variants. +*tersoff/intel*, *tersoff/table* or *tersoff/table/omp* variants. + +.. versionchanged:: TBD + + The *shift* keyword is now also supported by the *tersoff/mod/kk* and + *tersoff/mod/c/kk* variants. The *tersoff/mod* potential files provided with LAMMPS (see the potentials directory) are parameterized for metal :doc:`units `. You can diff --git a/doc/src/pair_tersoff_zbl.rst b/doc/src/pair_tersoff_zbl.rst index cb70f73bc3b..7beb812eb64 100644 --- a/doc/src/pair_tersoff_zbl.rst +++ b/doc/src/pair_tersoff_zbl.rst @@ -284,8 +284,13 @@ LAMMPS was built with that package. See the :doc:`Build package This pair style requires the :doc:`newton ` setting to be "on" for pair interactions. -The *shift* keyword is currently not supported for the *tersoff/gpu* and -*tersoff/kk* variants of this pair style. +The *shift* keyword is currently not supported for the *tersoff/gpu* +variant of this pair style. + +.. versionchanged:: TBD + + The *shift* keyword is now also supported by the *tersoff/zbl/kk* + variant. The tersoff/zbl potential files provided with LAMMPS (see the potentials directory) are parameterized for :doc:`"metal" units `. Also the diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 2c1f4098193..57c4e3d778b 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -230,6 +230,7 @@ void PairTersoffKokkos::compute(int eflag_in, int vflag_in) } cutmax_sq = static_cast(cutmax * cutmax); + shift_kk = shift_flag ? static_cast(shift) : static_cast(0.0); copymode = 1; @@ -353,7 +354,12 @@ void PairTersoffKokkos::operator()(TagPairTersoffComputeShortNeigh, const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq)*shift_kk; if (rsq < cutmax_sq) { d_neighbors_short(ii,inside) = j; @@ -404,14 +410,28 @@ void PairTersoffKokkos::tersoff_compute(const int &ii, EV_FLOAT& ev) const KK_FLOAT delx1 = xtmp - x(j,0); const KK_FLOAT dely1 = ytmp - x(j,1); const KK_FLOAT delz1 = ztmp - x(j,2); - const KK_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; + const KK_FLOAT rsq1_orig = delx1*delx1 + dely1*dely1 + delz1*delz1; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq1 = d_params(iparam_ij).cutsq; + // shift rsq and store correction for the repulsive force, + // as in PairTersoff::eval() + + KK_FLOAT rsq1 = rsq1_orig; + KK_FLOAT forceshiftfac = static_cast(1.0); + if (shift_flag) { + rsq1 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq1_orig)*shift_kk; + forceshiftfac = Kokkos::sqrt(rsq1/rsq1_orig); + } + KK_FLOAT bo_ij = 0; if (rsq1 > cutsq1) continue; const KK_FLOAT rij = Kokkos::sqrt(rsq1); + // distance without the shift, used for the 1/r factors and unit vectors + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + for (int kk = 0; kk < jnum; kk++) { if (jj == kk) continue; int k = d_neighbors_short(ii,kk); @@ -420,10 +440,15 @@ void PairTersoffKokkos::tersoff_compute(const int &ii, EV_FLOAT& ev) const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = d_params(iparam_ijk).cutsq; + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); bo_ij += bondorder(d_params(iparam_ijk),rij,delx1,dely1,delz1,rik,delx2,dely2,delz2); @@ -434,7 +459,7 @@ void PairTersoffKokkos::tersoff_compute(const int &ii, EV_FLOAT& ev) KK_FLOAT fa, dfa, bij, prefactor; ters_fa_k_and_ters_dfa(d_params(iparam_ij),rij,fa,dfa); ters_bij_k_and_ters_dbij(d_params(iparam_ij),bo_ij,bij,prefactor); - const KK_FLOAT fatt = -static_cast(0.5) * bij * dfa / rij; + const KK_FLOAT fatt = -static_cast(0.5) * bij * dfa / rij_orig; prefactor = static_cast(0.5) * fa * prefactor; f_x += static_cast(delx1*fatt); @@ -461,10 +486,15 @@ void PairTersoffKokkos::tersoff_compute(const int &ii, EV_FLOAT& ev) const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = d_params(iparam_ijk).cutsq; + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); ters_dthb(d_params(iparam_ijk),prefactor,rij,delx1,dely1,delz1, @@ -507,10 +537,14 @@ void PairTersoffKokkos::tersoff_compute(const int &ii, EV_FLOAT& ev) ters_fc_k_and_ters_dfc(d_params[iparam_ij],rij,tmp_fce,tmp_fcd); const KK_FLOAT tmp_exp = Kokkos::exp(-d_params[iparam_ij].lam1 * rij); - const KK_FLOAT frep = -d_params[iparam_ij].biga * tmp_exp * - (tmp_fcd - tmp_fce*d_params[iparam_ij].lam1) / rij; + KK_FLOAT frep = -d_params[iparam_ij].biga * tmp_exp * + (tmp_fcd - tmp_fce*d_params[iparam_ij].lam1) / rij; const KK_FLOAT eng = tmp_fce * d_params[iparam_ij].biga * tmp_exp; + // correct force for shift in rsq + + if (shift_flag) frep *= forceshiftfac; + f_x += static_cast(delx1*frep); fj_x -= static_cast(delx1*frep); @@ -666,7 +700,12 @@ KK_FLOAT PairTersoffKokkos::bondorder(const ParamKokkos& param, { KK_FLOAT arg, ex_delr; - const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij*rik); + // the unit vectors are built from the unshifted distances, as in PairTersoff::eval() + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + const KK_FLOAT rik_orig = shift_flag ? rik - shift_kk : rik; + + const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij_orig*rik_orig); const KK_FLOAT paramtmp = param.lam3 * (rij-rik); if (int(param.powerm) == 3) arg = paramtmp*paramtmp*paramtmp;//pow(param.lam3 * (rij-rik),3.0); @@ -867,7 +906,7 @@ void PairTersoffKokkos::ters_dthb( const KK_FLOAT &rik, const KK_FLOAT &dx2, const KK_FLOAT &dy2, const KK_FLOAT &dz2, KK_ACC_FLOAT *fi, KK_ACC_FLOAT *fj, KK_ACC_FLOAT *fk) const { - // from PairTersoff::attractive + // from PairTersoff::attractive, including the 1/r correction for the shift in rsq KK_FLOAT rij_hat[3],rik_hat[3]; KK_FLOAT rijinv,rikinv; KK_FLOAT delrij[3], delrik[3]; @@ -876,11 +915,11 @@ void PairTersoffKokkos::ters_dthb( delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; //rij = sqrt(rsq1); - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); //rik = sqrt(rsq2); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); // from PairTersoff::ters_zetaterm_d @@ -948,10 +987,10 @@ void PairTersoffKokkos::ters_dthbj( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; @@ -1011,10 +1050,10 @@ void PairTersoffKokkos::ters_dthbk( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; diff --git a/src/KOKKOS/pair_tersoff_kokkos.h b/src/KOKKOS/pair_tersoff_kokkos.h index 72f4428e2bf..492d6088071 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.h +++ b/src/KOKKOS/pair_tersoff_kokkos.h @@ -297,6 +297,7 @@ class PairTersoffKokkos : public PairTersoff { t_param_1d d_params; KK_FLOAT cutmax_sq; + KK_FLOAT shift_kk; // KK_FLOAT copy of PairTersoff::shift for device kernels int inum; typename AT::t_kkfloat_1d_3_lr_randomread x; diff --git a/src/KOKKOS/pair_tersoff_mod_c_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_c_kokkos.cpp index 4317c6ee52d..a3ee93c79b1 100644 --- a/src/KOKKOS/pair_tersoff_mod_c_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_c_kokkos.cpp @@ -206,6 +206,8 @@ void PairTersoffMODCKokkos::compute(int eflag_in, int vflag_in) ndup_vatom = Kokkos::Experimental::create_scatter_view(d_vatom); } + shift_kk = shift_flag ? static_cast(shift) : static_cast(0.0); + copymode = 1; EV_FLOAT ev; @@ -311,7 +313,12 @@ void PairTersoffMODCKokkos::operator()(TagPairTersoffMODCComputeShor const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq)*shift_kk; if (rsq < cutmax_sq) { d_neighbors_short(ii,inside) = j; @@ -371,10 +378,19 @@ void PairTersoffMODCKokkos::tersoff_mod_compute(const int &ii, EV_FL const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const KK_FLOAT rsq_orig = delx*delx + dely*dely + delz*delz; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq = static_cast(d_params(iparam_ij).cutsq); + // shift rsq and store correction for the force, as in PairTersoff::eval() + + KK_FLOAT rsq = rsq_orig; + KK_FLOAT forceshiftfac = static_cast(1.0); + if (shift_flag) { + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq_orig)*shift_kk; + forceshiftfac = Kokkos::sqrt(rsq/rsq_orig); + } + if (rsq >= cutsq) continue; const KK_FLOAT r = Kokkos::sqrt(rsq); @@ -384,12 +400,16 @@ void PairTersoffMODCKokkos::tersoff_mod_compute(const int &ii, EV_FL // tersoff/mod/c adds the constant c0 to the repulsive term const KK_FLOAT c0 = static_cast(d_params(iparam_ij).c0); - const KK_FLOAT frep = -static_cast(d_params(iparam_ij).biga) * tmp_exp * - (tmp_fcd - tmp_fce*static_cast(d_params(iparam_ij).lam1)) / r - - c0 * tmp_fcd / r; + KK_FLOAT frep = -static_cast(d_params(iparam_ij).biga) * tmp_exp * + (tmp_fcd - tmp_fce*static_cast(d_params(iparam_ij).lam1)) / r - + c0 * tmp_fcd / r; const KK_FLOAT eng = tmp_fce * static_cast(d_params(iparam_ij).biga) * tmp_exp + c0 * tmp_fce; + // correct force for shift in rsq + + if (shift_flag) frep *= forceshiftfac; + f_x += static_cast(delx*frep); f_y += static_cast(dely*frep); f_z += static_cast(delz*frep); @@ -412,14 +432,24 @@ void PairTersoffMODCKokkos::tersoff_mod_compute(const int &ii, EV_FL const KK_FLOAT delx1 = xtmp - x(j,0); const KK_FLOAT dely1 = ytmp - x(j,1); const KK_FLOAT delz1 = ztmp - x(j,2); - const KK_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; + const KK_FLOAT rsq1_orig = delx1*delx1 + dely1*dely1 + delz1*delz1; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq1 = static_cast(d_params(iparam_ij).cutsq); + // shift rsq, as in PairTersoff::eval() + + KK_FLOAT rsq1 = rsq1_orig; + if (shift_flag) + rsq1 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq1_orig)*shift_kk; + KK_FLOAT bo_ij = 0.0; if (rsq1 > cutsq1) continue; const KK_FLOAT rij = Kokkos::sqrt(rsq1); + // distance without the shift, used for the 1/r factors and unit vectors + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + for (int kk = 0; kk < jnum; kk++) { if (jj == kk) continue; int k = d_neighbors_short(ii,kk); @@ -428,10 +458,15 @@ void PairTersoffMODCKokkos::tersoff_mod_compute(const int &ii, EV_FL const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = static_cast(d_params(iparam_ijk).cutsq); + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); bo_ij += bondorder(d_params(iparam_ijk),rij,delx1,dely1,delz1,rik,delx2,dely2,delz2); @@ -442,7 +477,7 @@ void PairTersoffMODCKokkos::tersoff_mod_compute(const int &ii, EV_FL const KK_FLOAT fa = ters_fa_k(d_params(iparam_ij),rij); const KK_FLOAT dfa = ters_dfa(d_params(iparam_ij),rij); const KK_FLOAT bij = ters_bij_k(d_params(iparam_ij),bo_ij); - const KK_FLOAT fatt = -static_cast(0.5)*bij * dfa / rij; + const KK_FLOAT fatt = -static_cast(0.5)*bij * dfa / rij_orig; const KK_FLOAT prefactor = static_cast(0.5)*fa * ters_dbij(d_params(iparam_ij),bo_ij); f_x += static_cast(delx1*fatt); @@ -469,10 +504,15 @@ void PairTersoffMODCKokkos::tersoff_mod_compute(const int &ii, EV_FL const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = static_cast(d_params(iparam_ijk).cutsq); + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); ters_dthb(d_params(iparam_ijk),prefactor,rij,delx1,dely1,delz1, @@ -609,7 +649,12 @@ KK_FLOAT PairTersoffMODCKokkos::bondorder(const Param& param, { KK_FLOAT arg, ex_delr; - const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij*rik); + // the unit vectors are built from the unshifted distances, as in PairTersoff::eval() + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + const KK_FLOAT rik_orig = shift_flag ? rik - shift_kk : rik; + + const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij_orig*rik_orig); const KK_FLOAT paramtmp = static_cast(param.lam3) * (rij-rik); if (int(param.powerm) == 3) arg = paramtmp*paramtmp*paramtmp;//pow(param.lam3 * (rij-rik),3.0); @@ -744,11 +789,11 @@ void PairTersoffMODCKokkos::ters_dthb( delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; //rij = sqrt(rsq1); - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); //rik = sqrt(rsq2); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); // from PairTersoffMODC::ters_zetaterm_d @@ -817,10 +862,10 @@ void PairTersoffMODCKokkos::ters_dthbj( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; @@ -880,10 +925,10 @@ void PairTersoffMODCKokkos::ters_dthbk( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; diff --git a/src/KOKKOS/pair_tersoff_mod_c_kokkos.h b/src/KOKKOS/pair_tersoff_mod_c_kokkos.h index f767d03a202..d6beb5d4b8d 100644 --- a/src/KOKKOS/pair_tersoff_mod_c_kokkos.h +++ b/src/KOKKOS/pair_tersoff_mod_c_kokkos.h @@ -223,6 +223,8 @@ class PairTersoffMODCKokkos : public PairTersoffMODC { t_param_1d d_params; + KK_FLOAT shift_kk; // KK_FLOAT copy of PairTersoff::shift for device kernels + int inum; typename AT::t_kkfloat_1d_3_lr_randomread x; typename AT::t_kkacc_1d_3 f; diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 820958e9133..65778c6b336 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -206,6 +206,8 @@ void PairTersoffMODKokkos::compute(int eflag_in, int vflag_in) ndup_vatom = Kokkos::Experimental::create_scatter_view(d_vatom); } + shift_kk = shift_flag ? static_cast(shift) : static_cast(0.0); + copymode = 1; EV_FLOAT ev; @@ -311,7 +313,12 @@ void PairTersoffMODKokkos::operator()(TagPairTersoffMODComputeShortN const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq)*shift_kk; if (rsq < cutmax_sq) { d_neighbors_short(ii,inside) = j; @@ -371,20 +378,33 @@ void PairTersoffMODKokkos::tersoff_mod_compute(const int &ii, EV_FLO const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const KK_FLOAT rsq_orig = delx*delx + dely*dely + delz*delz; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq = static_cast(d_params(iparam_ij).cutsq); + // shift rsq and store correction for the force, as in PairTersoff::eval() + + KK_FLOAT rsq = rsq_orig; + KK_FLOAT forceshiftfac = static_cast(1.0); + if (shift_flag) { + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq_orig)*shift_kk; + forceshiftfac = Kokkos::sqrt(rsq/rsq_orig); + } + if (rsq >= cutsq) continue; const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT tmp_fce = ters_fc_k(d_params(iparam_ij),r); const KK_FLOAT tmp_fcd = ters_dfc(d_params(iparam_ij),r); const KK_FLOAT tmp_exp = Kokkos::exp(-static_cast(d_params(iparam_ij).lam1) * r); - const KK_FLOAT frep = -static_cast(d_params(iparam_ij).biga) * tmp_exp * - (tmp_fcd - tmp_fce*static_cast(d_params(iparam_ij).lam1)) / r; + KK_FLOAT frep = -static_cast(d_params(iparam_ij).biga) * tmp_exp * + (tmp_fcd - tmp_fce*static_cast(d_params(iparam_ij).lam1)) / r; const KK_FLOAT eng = tmp_fce * static_cast(d_params(iparam_ij).biga) * tmp_exp; + // correct force for shift in rsq + + if (shift_flag) frep *= forceshiftfac; + f_x += static_cast(delx*frep); f_y += static_cast(dely*frep); f_z += static_cast(delz*frep); @@ -407,14 +427,24 @@ void PairTersoffMODKokkos::tersoff_mod_compute(const int &ii, EV_FLO const KK_FLOAT delx1 = xtmp - x(j,0); const KK_FLOAT dely1 = ytmp - x(j,1); const KK_FLOAT delz1 = ztmp - x(j,2); - const KK_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; + const KK_FLOAT rsq1_orig = delx1*delx1 + dely1*dely1 + delz1*delz1; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq1 = static_cast(d_params(iparam_ij).cutsq); + // shift rsq, as in PairTersoff::eval() + + KK_FLOAT rsq1 = rsq1_orig; + if (shift_flag) + rsq1 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq1_orig)*shift_kk; + KK_FLOAT bo_ij = 0.0; if (rsq1 > cutsq1) continue; const KK_FLOAT rij = Kokkos::sqrt(rsq1); + // distance without the shift, used for the 1/r factors and unit vectors + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + for (int kk = 0; kk < jnum; kk++) { if (jj == kk) continue; int k = d_neighbors_short(ii,kk); @@ -423,10 +453,15 @@ void PairTersoffMODKokkos::tersoff_mod_compute(const int &ii, EV_FLO const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = static_cast(d_params(iparam_ijk).cutsq); + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); bo_ij += bondorder(d_params(iparam_ijk),rij,delx1,dely1,delz1,rik,delx2,dely2,delz2); @@ -437,7 +472,7 @@ void PairTersoffMODKokkos::tersoff_mod_compute(const int &ii, EV_FLO const KK_FLOAT fa = ters_fa_k(d_params(iparam_ij),rij); const KK_FLOAT dfa = ters_dfa(d_params(iparam_ij),rij); const KK_FLOAT bij = ters_bij_k(d_params(iparam_ij),bo_ij); - const KK_FLOAT fatt = -static_cast(0.5)*bij * dfa / rij; + const KK_FLOAT fatt = -static_cast(0.5)*bij * dfa / rij_orig; const KK_FLOAT prefactor = static_cast(0.5)*fa * ters_dbij(d_params(iparam_ij),bo_ij); f_x += static_cast(delx1*fatt); @@ -464,10 +499,15 @@ void PairTersoffMODKokkos::tersoff_mod_compute(const int &ii, EV_FLO const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = static_cast(d_params(iparam_ijk).cutsq); + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); ters_dthb(d_params(iparam_ijk),prefactor,rij,delx1,dely1,delz1, @@ -604,7 +644,12 @@ KK_FLOAT PairTersoffMODKokkos::bondorder(const Param& param, { KK_FLOAT arg, ex_delr; - const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij*rik); + // the unit vectors are built from the unshifted distances, as in PairTersoff::eval() + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + const KK_FLOAT rik_orig = shift_flag ? rik - shift_kk : rik; + + const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij_orig*rik_orig); const KK_FLOAT paramtmp = static_cast(param.lam3) * (rij-rik); if (int(param.powerm) == 3) arg = paramtmp*paramtmp*paramtmp;//pow(param.lam3 * (rij-rik),3.0); @@ -739,11 +784,11 @@ void PairTersoffMODKokkos::ters_dthb( delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; //rij = sqrt(rsq1); - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); //rik = sqrt(rsq2); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); // from PairTersoffMOD::ters_zetaterm_d @@ -812,10 +857,10 @@ void PairTersoffMODKokkos::ters_dthbj( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; @@ -875,10 +920,10 @@ void PairTersoffMODKokkos::ters_dthbk( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.h b/src/KOKKOS/pair_tersoff_mod_kokkos.h index 8478c31159d..50058e2e0b9 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.h +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.h @@ -223,6 +223,8 @@ class PairTersoffMODKokkos : public PairTersoffMOD { t_param_1d d_params; + KK_FLOAT shift_kk; // KK_FLOAT copy of PairTersoff::shift for device kernels + int inum; typename AT::t_kkfloat_1d_3_lr_randomread x; typename AT::t_kkacc_1d_3 f; diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index f5eba7086dc..672de94eafb 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -219,6 +219,8 @@ void PairTersoffZBLKokkos::compute(int eflag_in, int vflag_in) ndup_vatom = Kokkos::Experimental::create_scatter_view(d_vatom); } + shift_kk = shift_flag ? static_cast(shift) : static_cast(0.0); + copymode = 1; EV_FLOAT ev; @@ -324,7 +326,12 @@ void PairTersoffZBLKokkos::operator()(TagPairTersoffZBLComputeShortN const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq)*shift_kk; if (rsq < cutmax_sq) { d_neighbors_short(ii,inside) = j; @@ -384,10 +391,19 @@ void PairTersoffZBLKokkos::tersoff_zbl_compute(const int &ii, EV_FLO const KK_FLOAT delx = xtmp - x(j,0); const KK_FLOAT dely = ytmp - x(j,1); const KK_FLOAT delz = ztmp - x(j,2); - const KK_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const KK_FLOAT rsq_orig = delx*delx + dely*dely + delz*delz; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq = static_cast(d_params(iparam_ij).cutsq); + // shift rsq and store correction for the force, as in PairTersoff::eval() + + KK_FLOAT rsq = rsq_orig; + KK_FLOAT forceshiftfac = static_cast(1.0); + if (shift_flag) { + rsq += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq_orig)*shift_kk; + forceshiftfac = Kokkos::sqrt(rsq/rsq_orig); + } + if (rsq > cutsq) continue; // Tersoff repulsive portion @@ -428,6 +444,10 @@ void PairTersoffZBLKokkos::tersoff_zbl_compute(const int &ii, EV_FLO eng = (static_cast(1.0) - fermi_k(d_params(iparam_ij),r)) * eng_z + fermi_k(d_params(iparam_ij),r) * eng_t; + // correct force for shift in rsq + + if (shift_flag) frep *= forceshiftfac; + f_x += static_cast(delx*frep); f_y += static_cast(dely*frep); f_z += static_cast(delz*frep); @@ -450,14 +470,24 @@ void PairTersoffZBLKokkos::tersoff_zbl_compute(const int &ii, EV_FLO const KK_FLOAT delx1 = xtmp - x(j,0); const KK_FLOAT dely1 = ytmp - x(j,1); const KK_FLOAT delz1 = ztmp - x(j,2); - const KK_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; + const KK_FLOAT rsq1_orig = delx1*delx1 + dely1*dely1 + delz1*delz1; const int iparam_ij = d_elem3param(itype,jtype,jtype); const KK_FLOAT cutsq1 = static_cast(d_params(iparam_ij).cutsq); + // shift rsq, as in PairTersoff::eval() + + KK_FLOAT rsq1 = rsq1_orig; + if (shift_flag) + rsq1 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq1_orig)*shift_kk; + KK_FLOAT bo_ij = 0.0; if (rsq1 > cutsq1) continue; const KK_FLOAT rij = Kokkos::sqrt(rsq1); + // distance without the shift, used for the 1/r factors and unit vectors + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + for (int kk = 0; kk < jnum; kk++) { if (jj == kk) continue; int k = d_neighbors_short(ii,kk); @@ -466,10 +496,15 @@ void PairTersoffZBLKokkos::tersoff_zbl_compute(const int &ii, EV_FLO const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = static_cast(d_params(iparam_ijk).cutsq); + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); bo_ij += bondorder(d_params(iparam_ijk),rij,delx1,dely1,delz1,rik,delx2,dely2,delz2); @@ -480,7 +515,7 @@ void PairTersoffZBLKokkos::tersoff_zbl_compute(const int &ii, EV_FLO const KK_FLOAT fa = ters_fa_k(d_params(iparam_ij),rij); const KK_FLOAT dfa = ters_dfa(d_params(iparam_ij),rij); const KK_FLOAT bij = ters_bij_k(d_params(iparam_ij),bo_ij); - const KK_FLOAT fatt = -static_cast(0.5)*bij * dfa / rij; + const KK_FLOAT fatt = -static_cast(0.5)*bij * dfa / rij_orig; const KK_FLOAT prefactor = static_cast(0.5)*fa * ters_dbij(d_params(iparam_ij),bo_ij); f_x += static_cast(delx1*fatt); @@ -507,10 +542,15 @@ void PairTersoffZBLKokkos::tersoff_zbl_compute(const int &ii, EV_FLO const KK_FLOAT delx2 = xtmp - x(k,0); const KK_FLOAT dely2 = ytmp - x(k,1); const KK_FLOAT delz2 = ztmp - x(k,2); - const KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + KK_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; const int iparam_ijk = d_elem3param(itype,jtype,ktype); const KK_FLOAT cutsq2 = static_cast(d_params(iparam_ijk).cutsq); + // shift rsq, as in PairTersoff::eval() + + if (shift_flag) + rsq2 += shift_kk*shift_kk + static_cast(2.0)*Kokkos::sqrt(rsq2)*shift_kk; + if (rsq2 > cutsq2) continue; const KK_FLOAT rik = Kokkos::sqrt(rsq2); ters_dthb(d_params(iparam_ijk),prefactor,rij,delx1,dely1,delz1, @@ -645,7 +685,12 @@ KK_FLOAT PairTersoffZBLKokkos::bondorder(const Param& param, { KK_FLOAT arg, ex_delr; - const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij*rik); + // the unit vectors are built from the unshifted distances, as in PairTersoff::eval() + + const KK_FLOAT rij_orig = shift_flag ? rij - shift_kk : rij; + const KK_FLOAT rik_orig = shift_flag ? rik - shift_kk : rik; + + const KK_FLOAT costheta = (dx1*dx2 + dy1*dy2 + dz1*dz2)/(rij_orig*rik_orig); const KK_FLOAT paramtmp = static_cast(param.lam3) * (rij-rik); if (int(param.powerm) == 3) arg = paramtmp*paramtmp*paramtmp;//pow(param.lam3 * (rij-rik),3.0); @@ -778,11 +823,11 @@ void PairTersoffZBLKokkos::ters_dthb( delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; //rij = sqrt(rsq1); - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); //rik = sqrt(rsq2); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); // from PairTersoffZBL::ters_zetaterm_d @@ -851,10 +896,10 @@ void PairTersoffZBLKokkos::ters_dthbj( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; @@ -914,10 +959,10 @@ void PairTersoffZBLKokkos::ters_dthbk( delrij[0] = dx1; delrij[1] = dy1; delrij[2] = dz1; delrik[0] = dx2; delrik[1] = dy2; delrik[2] = dz2; - rijinv = static_cast(1.0)/rij; + rijinv = static_cast(1.0)/(shift_flag ? rij - shift_kk : rij); vec3_scale(rijinv,delrij,rij_hat); - rikinv = static_cast(1.0)/rik; + rikinv = static_cast(1.0)/(shift_flag ? rik - shift_kk : rik); vec3_scale(rikinv,delrik,rik_hat); KK_FLOAT gijk,dgijk,ex_delr,dex_delr,fc,dfc,cos,tmp; diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.h b/src/KOKKOS/pair_tersoff_zbl_kokkos.h index 48e9ca67a34..2a583549d8f 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.h +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.h @@ -230,6 +230,8 @@ class PairTersoffZBLKokkos : public PairTersoffZBL { t_param_1d d_params; + KK_FLOAT shift_kk; // KK_FLOAT copy of PairTersoff::shift for device kernels + int inum; typename AT::t_kkfloat_1d_3_lr_randomread x; typename AT::t_kkacc_1d_3 f; diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index f0d52d3075c..5568281d56b 100644 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -358,7 +358,7 @@ void PairTersoff::settings(int narg, char **arg) while (iarg < narg) { if (strcmp(arg[iarg],"shift") == 0) { - if (suffix_flag & (Suffix::INTEL|Suffix::GPU|Suffix::KOKKOS)) + if (suffix_flag & (Suffix::INTEL|Suffix::GPU)) error->all(FLERR,"Keyword 'shift' not supported for this style"); if (iarg+2 > narg) error->all(FLERR,"Illegal pair_style command"); shift = utils::numeric(FLERR,arg[iarg+1],false,lmp); diff --git a/unittest/force-styles/tests/manybody-pair-tersoff_mod_c_shift.yaml b/unittest/force-styles/tests/manybody-pair-tersoff_mod_c_shift.yaml index ff45ec3002d..ecaca86d500 100644 --- a/unittest/force-styles/tests/manybody-pair-tersoff_mod_c_shift.yaml +++ b/unittest/force-styles/tests/manybody-pair-tersoff_mod_c_shift.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:50 2022 epsilon: 2e-11 -skip_tests: gpu intel kokkos_omp kokkos_serial kokkos_gpu +skip_tests: gpu intel prerequisites: ! | pair tersoff/mod/c pre_commands: ! | diff --git a/unittest/force-styles/tests/manybody-pair-tersoff_mod_shift.yaml b/unittest/force-styles/tests/manybody-pair-tersoff_mod_shift.yaml index 452a851dbcf..454e76d8965 100644 --- a/unittest/force-styles/tests/manybody-pair-tersoff_mod_shift.yaml +++ b/unittest/force-styles/tests/manybody-pair-tersoff_mod_shift.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:50 2022 epsilon: 5e-11 -skip_tests: gpu intel kokkos_omp kokkos_serial kokkos_gpu +skip_tests: gpu intel prerequisites: ! | pair tersoff/mod diff --git a/unittest/force-styles/tests/manybody-pair-tersoff_shift.yaml b/unittest/force-styles/tests/manybody-pair-tersoff_shift.yaml index 059ae2e736e..c0d168543af 100644 --- a/unittest/force-styles/tests/manybody-pair-tersoff_shift.yaml +++ b/unittest/force-styles/tests/manybody-pair-tersoff_shift.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:50 2022 epsilon: 5e-13 -skip_tests: gpu intel kokkos_omp kokkos_serial kokkos_gpu +skip_tests: gpu intel prerequisites: ! | pair tersoff diff --git a/unittest/force-styles/tests/manybody-pair-tersoff_zbl_shift.yaml b/unittest/force-styles/tests/manybody-pair-tersoff_zbl_shift.yaml index 952eeedea2d..ecc6128500d 100644 --- a/unittest/force-styles/tests/manybody-pair-tersoff_zbl_shift.yaml +++ b/unittest/force-styles/tests/manybody-pair-tersoff_zbl_shift.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:50 2022 epsilon: 5e-11 -skip_tests: gpu intel kokkos_omp kokkos_serial kokkos_gpu +skip_tests: gpu intel prerequisites: ! | pair tersoff/zbl From 78a668ad6c4da428fa4c2bff019f9c46a89c97a7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 13:43:25 +0000 Subject: [PATCH 037/120] KOKKOS: add a build option to use the host random number generator Several KOKKOS fixes already select the host RanMars generator instead of the device pool when LMP_KOKKOS_DEBUG_RNG is defined, which makes a single threaded Serial run reproduce the trajectory of the plain style bit for bit. Nothing exposed that macro, so the references of all stochastic fixes had to skip the KOKKOS tests altogether. Add the CMake option KOKKOS_DEBUG_RNG, report the choice through Info::has_accelerator_feature() and the accelerator information, and let a reference skip a KOKKOS case only for builds that use the device generator, with the new 'devicerng' qualifier. The references of fix langevin, langevin with tally, gjf, baoab, brownian and temp/csld now use that qualifier and all pass in a build configured with -D KOKKOS_DEBUG_RNG=on, so those ports are compared against the plain styles for the first time. --- cmake/Modules/Packages/KOKKOS.cmake | 15 +++++++++ doc/src/Build_extras.rst | 14 +++++++++ src/info.cpp | 10 ++++++ unittest/force-styles/test_angle_style.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_bond_style.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_dihedral_style.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_fix_timestep.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_improper_style.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_min_style.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_output_style.cpp | 31 +++++++++++++++++++ unittest/force-styles/test_pair_style.cpp | 31 +++++++++++++++++++ .../tests/fix-timestep-baoab.yaml | 2 +- .../tests/fix-timestep-brownian_point.yaml | 2 +- .../force-styles/tests/fix-timestep-gjf.yaml | 2 +- .../tests/fix-timestep-langevin.yaml | 2 +- .../tests/fix-timestep-langevin_tally.yaml | 2 +- .../tests/fix-timestep-temp_csld.yaml | 2 +- 17 files changed, 293 insertions(+), 6 deletions(-) diff --git a/cmake/Modules/Packages/KOKKOS.cmake b/cmake/Modules/Packages/KOKKOS.cmake index aa657845ecc..8cd354d9b03 100644 --- a/cmake/Modules/Packages/KOKKOS.cmake +++ b/cmake/Modules/Packages/KOKKOS.cmake @@ -39,8 +39,23 @@ string(TOUPPER ${KOKKOS_LAYOUT} KOKKOS_LAYOUT) target_compile_definitions(lammps PRIVATE -DLMP_KOKKOS_LAYOUT_${KOKKOS_LAYOUT}) +# Use the host random number generator in KOKKOS styles. This makes runs with +# the KOKKOS package reproduce the results of the corresponding plain styles, +# which is required for validating them, but it is slow and not thread safe. +option(KOKKOS_DEBUG_RNG "Use the host random number generator in KOKKOS styles (for testing only)" OFF) +mark_as_advanced(KOKKOS_DEBUG_RNG) + +if(KOKKOS_DEBUG_RNG) + target_compile_definitions(lammps PRIVATE -DLMP_KOKKOS_DEBUG_RNG) +endif() + message(STATUS "Using " ${KOKKOS_PREC_LOWER} " precision for KOKKOS package") message(STATUS "Using " ${KOKKOS_LAYOUT_LOWER} " view layout for KOKKOS package") +if(KOKKOS_DEBUG_RNG) + message(STATUS "Using host random numbers for KOKKOS package") +else() + message(STATUS "Using device random numbers for KOKKOS package") +endif() ######################################################################## # consistency checks and Kokkos options/settings required by LAMMPS diff --git a/doc/src/Build_extras.rst b/doc/src/Build_extras.rst index 0804dd80cc9..e1627f8d074 100644 --- a/doc/src/Build_extras.rst +++ b/doc/src/Build_extras.rst @@ -976,6 +976,20 @@ speedup on GPUs for some models, but a slowdown for others. LayoutRight is always used for positions on GPUs since it has been found to be faster, and when compiling exclusively for CPUs. +.. versionadded:: TBD + +The CMake option ``-D KOKKOS_DEBUG_RNG=on`` makes those KOKKOS styles +that need random numbers (for example :doc:`fix langevin ` +or :doc:`fix brownian `) use the same random number +generator as the corresponding plain styles instead of the parallel +generator of the Kokkos library. A run on a single MPI process with the +Serial backend then follows the same trajectory as a run without the +KOKKOS package, which makes it possible to compare the two directly and +thus to validate the KOKKOS versions of those styles. This is a +validation and debugging aid only: the substitute generator is slower +and produces the same numbers only when there is no parallelism, so this +option must not be used for production simulations. + ---------- .. _lepton: diff --git a/src/info.cpp b/src/info.cpp index 2ce16ed3fd8..102fb73e21b 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -1109,6 +1109,13 @@ bool Info::has_accelerator_feature(const std::string &package, return setting == "double"; #elif defined(LMP_KOKKOS_SINGLE_DOUBLE) return setting == "mixed"; +#endif + } + if (category == "rng") { +#if defined(LMP_KOKKOS_DEBUG_RNG) + return setting == "host"; +#else + return setting == "device"; #endif } if (category == "layout") { @@ -1211,6 +1218,9 @@ std::string Info::get_accelerator_info(const std::string &package) if (has_accelerator_feature("KOKKOS","precision","single")) mesg += " single"; if (has_accelerator_feature("KOKKOS","precision","mixed")) mesg += " mixed"; if (has_accelerator_feature("KOKKOS","precision","double")) mesg += " double"; + mesg += "\nKOKKOS package random numbers:"; + if (has_accelerator_feature("KOKKOS","rng","host")) mesg += " host"; + if (has_accelerator_feature("KOKKOS","rng","device")) mesg += " device"; mesg += "\nKOKKOS package view layout:"; if (has_accelerator_feature("KOKKOS","layout","legacy")) mesg += " legacy"; if (has_accelerator_feature("KOKKOS","layout","default")) mesg += " default"; diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index d204cdfaac4..e7c57a47337 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -722,6 +722,11 @@ TEST(AngleStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -745,12 +750,20 @@ TEST(AngleStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -785,6 +798,11 @@ TEST(AngleStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -811,12 +829,20 @@ TEST(AngleStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -854,6 +880,11 @@ TEST(AngleStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 8fc903eb700..f3e921f6f84 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -704,6 +704,11 @@ TEST(BondStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -727,12 +732,20 @@ TEST(BondStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -767,6 +780,11 @@ TEST(BondStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -793,12 +811,20 @@ TEST(BondStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -836,6 +862,11 @@ TEST(BondStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 230ef5d1615..07930febcf7 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -723,6 +723,11 @@ TEST(DihedralStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -747,12 +752,20 @@ TEST(DihedralStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -787,6 +800,11 @@ TEST(DihedralStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -814,12 +832,20 @@ TEST(DihedralStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -857,6 +883,11 @@ TEST(DihedralStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index f8fc19ca187..5391bd04c14 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -1159,6 +1159,11 @@ TEST(FixTimestep, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -1183,12 +1188,20 @@ TEST(FixTimestep, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -1224,6 +1237,11 @@ TEST(FixTimestep, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -1251,12 +1269,20 @@ TEST(FixTimestep, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -1295,6 +1321,11 @@ TEST(FixTimestep, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 3c885236284..2d02fda4a82 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -695,6 +695,11 @@ TEST(ImproperStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -719,12 +724,20 @@ TEST(ImproperStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -759,6 +772,11 @@ TEST(ImproperStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -786,12 +804,20 @@ TEST(ImproperStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -829,6 +855,11 @@ TEST(ImproperStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index b7fda063cf8..811652967e6 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -316,6 +316,11 @@ TEST(MinStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -340,12 +345,20 @@ TEST(MinStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -381,6 +394,11 @@ TEST(MinStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -408,12 +426,20 @@ TEST(MinStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -452,6 +478,11 @@ TEST(MinStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index 57a60ea3a8a..58f55e60bda 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -394,6 +394,11 @@ TEST(OutputStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -418,12 +423,20 @@ TEST(OutputStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -459,6 +472,11 @@ TEST(OutputStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -486,12 +504,20 @@ TEST(OutputStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -530,6 +556,11 @@ TEST(OutputStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index b7edd1906f7..5a436afc451 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -993,6 +993,11 @@ TEST(PairStyle, kokkos_omp) // e.g. "kokkos_omp_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -1022,12 +1027,20 @@ TEST(PairStyle, kokkos_omp_full) // e.g. "kokkos_omp_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_omp" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_omp")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_omp_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_omp_devicerng")) + GTEST_SKIP(); // this test requires the OpenMP backend of KOKKOS if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP() << "KOKKOS OpenMP backend not enabled"; @@ -1068,6 +1081,11 @@ TEST(PairStyle, kokkos_serial) // e.g. "kokkos_serial_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -1095,12 +1113,20 @@ TEST(PairStyle, kokkos_serial_full) // e.g. "kokkos_serial_full_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // a style that cannot be tested with KOKKOS at all cannot be tested // with a full neighbor list either, so the plain "kokkos_serial" // skip entries apply here as well if (test_config.skip_tests.count("kokkos_serial")) GTEST_SKIP(); if (test_config.skip_tests.count("kokkos_serial_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count("kokkos_serial_devicerng")) + GTEST_SKIP(); // this test requires the KOKKOS package compiled with only the Serial backend: when the // OpenMP (or a GPU) backend is enabled, the host execution space is not Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial")) @@ -1139,6 +1165,11 @@ TEST(PairStyle, kokkos_gpu) // e.g. "kokkos_gpu_single" skips only single precision KOKKOS builds if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); // this test requires a GPU backend of the KOKKOS package if (!Info::has_accelerator_feature("KOKKOS", "api", "cuda") && !Info::has_accelerator_feature("KOKKOS", "api", "hip") && diff --git a/unittest/force-styles/tests/fix-timestep-baoab.yaml b/unittest/force-styles/tests/fix-timestep-baoab.yaml index a98d9985d01..a4ec72038ea 100644 --- a/unittest/force-styles/tests/fix-timestep-baoab.yaml +++ b/unittest/force-styles/tests/fix-timestep-baoab.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: no_respa no_restart date_generated: Fri Jul 10 18:23:09 2026 epsilon: 1e-13 -skip_tests: kokkos_gpu kokkos_omp kokkos_serial +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom full fix baoab diff --git a/unittest/force-styles/tests/fix-timestep-brownian_point.yaml b/unittest/force-styles/tests/fix-timestep-brownian_point.yaml index 4a80120b545..b9c2eccef27 100644 --- a/unittest/force-styles/tests/fix-timestep-brownian_point.yaml +++ b/unittest/force-styles/tests/fix-timestep-brownian_point.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: no_respa date_generated: Fri Jul 10 18:20:04 2026 epsilon: 5e-14 -skip_tests: kokkos_gpu kokkos_omp kokkos_serial +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom sphere fix brownian diff --git a/unittest/force-styles/tests/fix-timestep-gjf.yaml b/unittest/force-styles/tests/fix-timestep-gjf.yaml index 88bca95f2df..8be555f9740 100644 --- a/unittest/force-styles/tests/fix-timestep-gjf.yaml +++ b/unittest/force-styles/tests/fix-timestep-gjf.yaml @@ -3,7 +3,7 @@ lammps_version: 30 Mar 2026 tags: no_respa date_generated: Sat Jun 13 17:12:15 2026 epsilon: 1e-13 -skip_tests: kokkos_gpu kokkos_omp kokkos_serial +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom full fix gjf diff --git a/unittest/force-styles/tests/fix-timestep-langevin.yaml b/unittest/force-styles/tests/fix-timestep-langevin.yaml index 6c21195931b..0058b00ad36 100644 --- a/unittest/force-styles/tests/fix-timestep-langevin.yaml +++ b/unittest/force-styles/tests/fix-timestep-langevin.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: no_respa no_restart date_generated: Fri Jul 10 18:22:56 2026 epsilon: 5e-14 -skip_tests: kokkos_gpu kokkos_omp kokkos_serial +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom full fix langevin diff --git a/unittest/force-styles/tests/fix-timestep-langevin_tally.yaml b/unittest/force-styles/tests/fix-timestep-langevin_tally.yaml index 2642b947e3f..a20d21122ef 100644 --- a/unittest/force-styles/tests/fix-timestep-langevin_tally.yaml +++ b/unittest/force-styles/tests/fix-timestep-langevin_tally.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: no_respa no_restart date_generated: Fri Jul 10 18:22:58 2026 epsilon: 5e-14 -skip_tests: kokkos_gpu kokkos_omp kokkos_serial +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom full fix langevin diff --git a/unittest/force-styles/tests/fix-timestep-temp_csld.yaml b/unittest/force-styles/tests/fix-timestep-temp_csld.yaml index 570c3c12730..0dbdfa4e76e 100644 --- a/unittest/force-styles/tests/fix-timestep-temp_csld.yaml +++ b/unittest/force-styles/tests/fix-timestep-temp_csld.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:18:01 2022 epsilon: 5e-14 -skip_tests: kokkos_omp kokkos_serial kokkos_gpu +skip_tests: kokkos_omp_devicerng kokkos_serial_devicerng kokkos_gpu_devicerng prerequisites: ! | atom full fix temp/csld From b72d5219de4e98555ae20ed41a06aad0564a4866 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 13:59:42 +0000 Subject: [PATCH 038/120] KOKKOS: fix the grid computes of the ML-SNAP package on host backends Three defects, all of them only visible without a GPU backend, and none of them covered by a test so far: - compute sna/grid/kk and sna/grid/local/kk sized their per-element arrays with the number of elements but filled them with one entry per atom type. Without the chem keyword there is a single element, so a system with more than one type wrote past the end of the views and corrupted the heap; the inner cutoff arrays were additionally indexed from one instead of from zero. - the host fallback of compute sna/grid/local/kk called compute_array(), which the base class does not define, so the empty stub of the Compute base class ran and the local array stayed zero. - compute gaussian/grid/local/kk had no host fallback at all and also returned zeros. Add references for the three computes. The two styles with local output skip the KOKKOS cases because the KOKKOS version enumerates the grid points in a different order; the values themselves agree exactly. --- .../compute_gaussian_grid_local_kokkos.cpp | 1 + src/KOKKOS/compute_sna_grid_kokkos_impl.h | 16 ++++--- .../compute_sna_grid_local_kokkos_impl.h | 18 +++---- .../tests/compute-gaussian_grid_local.yaml | 47 +++++++++++++++++++ .../force-styles/tests/compute-sna_grid.yaml | 28 +++++++++++ .../tests/compute-sna_grid_local.yaml | 28 +++++++++++ 6 files changed, 123 insertions(+), 15 deletions(-) create mode 100644 unittest/force-styles/tests/compute-gaussian_grid_local.yaml create mode 100644 unittest/force-styles/tests/compute-sna_grid.yaml create mode 100644 unittest/force-styles/tests/compute-sna_grid_local.yaml diff --git a/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp b/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp index 564abe1f90b..ea64c6db943 100644 --- a/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp +++ b/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp @@ -128,6 +128,7 @@ template void ComputeGaussianGridLocalKokkos::compute_local() { if (host_flag) { + ComputeGaussianGridLocal::compute_local(); return; } diff --git a/src/KOKKOS/compute_sna_grid_kokkos_impl.h b/src/KOKKOS/compute_sna_grid_kokkos_impl.h index 5c3e047cb4d..30817248782 100644 --- a/src/KOKKOS/compute_sna_grid_kokkos_impl.h +++ b/src/KOKKOS/compute_sna_grid_kokkos_impl.h @@ -72,11 +72,13 @@ ComputeSNAGridKokkos::ComputeS } } - // Set up element lists - MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridKokkos::radelem",nelements); - MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridKokkos:wjelem",nelements); - MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridKokkos:sinnerelem",nelements); - MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridKokkos:dinnerelem",nelements); + // Set up element lists. the loop below fills these with one entry per + // atom type, which is not the same as the number of elements unless the + // chem keyword is used, so they have to be sized by the number of types + MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridKokkos::radelem",atom->ntypes); + MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridKokkos:wjelem",atom->ntypes); + MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridKokkos:sinnerelem",atom->ntypes); + MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridKokkos:dinnerelem",atom->ntypes); // test MemKK::realloc_kokkos(d_test, "ComputeSNAGridKokkos::test", nelements); @@ -97,8 +99,8 @@ ComputeSNAGridKokkos::ComputeS h_radelem(i-1) = static_cast(radelem[i]); h_wjelem(i-1) = static_cast(wjelem[i]); if (switchinnerflag){ - h_sinnerelem(i) = static_cast(sinnerelem[i]); - h_dinnerelem(i) = static_cast(dinnerelem[i]); + h_sinnerelem(i-1) = static_cast(sinnerelem[i]); + h_dinnerelem(i-1) = static_cast(dinnerelem[i]); } } diff --git a/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h b/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h index 34f613b9a08..88ee58510a1 100644 --- a/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h +++ b/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h @@ -71,11 +71,13 @@ ComputeSNAGridLocalKokkos::Com } } - // Set up element lists - MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridLocalKokkos::radelem",nelements); - MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridLocalKokkos:wjelem",nelements); - MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridLocalKokkos:sinnerelem",nelements); - MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridLocalKokkos:dinnerelem",nelements); + // Set up element lists. the loop below fills these with one entry per + // atom type, which is not the same as the number of elements unless the + // chem keyword is used, so they have to be sized by the number of types + MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridLocalKokkos::radelem",atom->ntypes); + MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridLocalKokkos:wjelem",atom->ntypes); + MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridLocalKokkos:sinnerelem",atom->ntypes); + MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridLocalKokkos:dinnerelem",atom->ntypes); // test MemKK::realloc_kokkos(d_test, "ComputeSNAGridLocalKokkos::test", nelements); @@ -96,8 +98,8 @@ ComputeSNAGridLocalKokkos::Com h_radelem(i-1) = static_cast(radelem[i]); h_wjelem(i-1) = static_cast(wjelem[i]); if (switchinnerflag){ - h_sinnerelem(i) = static_cast(sinnerelem[i]); - h_dinnerelem(i) = static_cast(dinnerelem[i]); + h_sinnerelem(i-1) = static_cast(sinnerelem[i]); + h_dinnerelem(i-1) = static_cast(dinnerelem[i]); } } @@ -157,7 +159,7 @@ template::compute_local() { if (host_flag) { - ComputeSNAGridLocal::compute_array(); + ComputeSNAGridLocal::compute_local(); return; } diff --git a/unittest/force-styles/tests/compute-gaussian_grid_local.yaml b/unittest/force-styles/tests/compute-gaussian_grid_local.yaml new file mode 100644 index 00000000000..3ddb4c70e1a --- /dev/null +++ b/unittest/force-styles/tests/compute-gaussian_grid_local.yaml @@ -0,0 +1,47 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 13:46:54 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: kokkos_omp kokkos_serial kokkos_gpu kokkos_omp_full kokkos_serial_full +prerequisites: | + atom atomic + pair lj/cut + compute gaussian/grid/local +pre_commands: "" +post_commands: | + pair_style lj/cut 4.0 + pair_coeff * * 0.4 2.3 + compute test all gaussian/grid/local grid 3 3 3 0.85 2.0 2.0 0.4 0.5 +input_file: in.metal +natoms: 32 +local_data: |2 + 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 8.9483165787237173e-01 1.8338421496140971e-05 + 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 0.0000000000000000e+00 0.0000000000000000e+00 2.6914507212179337e-02 8.4115070926503378e-04 + 2.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 0.0000000000000000e+00 0.0000000000000000e+00 6.3284626434567679e-03 4.4552688516960267e-04 + 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 0.0000000000000000e+00 4.1719591852214521e-03 2.0263317117725243e-03 + 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 2.3333333333333335e+00 0.0000000000000000e+00 1.1191705357642439e-04 1.8277974134546104e-01 + 2.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 2.3333333333333335e+00 0.0000000000000000e+00 7.5392335372406014e-02 1.6251809285465588e-04 + 0.0000000000000000e+00 2.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 0.0000000000000000e+00 3.8069848406061355e-02 5.2609182714223005e-04 + 1.0000000000000000e+00 2.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 4.6666666666666670e+00 0.0000000000000000e+00 4.9296915155156669e-02 1.3420879154977514e-07 + 2.0000000000000000e+00 2.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 4.6666666666666670e+00 0.0000000000000000e+00 3.1534862374487928e-04 1.9277729436871649e-01 + 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 5.6598023728506247e-03 2.5098004485298799e-03 + 1.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 2.3333333333333335e+00 0.0000000000000000e+00 2.3333333333333335e+00 1.2911784108264391e-03 9.2247760315127547e-02 + 2.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 4.6666666666666670e+00 0.0000000000000000e+00 2.3333333333333335e+00 1.0670243840662802e-01 1.3474257176921453e-04 + 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 2.3333333333333335e+00 3.4962812248527394e-08 1.5295423325091895e-01 + 1.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 2.3333333333333335e+00 2.3333333333333335e+00 2.3333333333333335e+00 5.9577059000864277e-04 1.5645386371790401e-02 + 2.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 4.6666666666666670e+00 2.3333333333333335e+00 2.3333333333333335e+00 2.7533888047806516e-09 2.9656521869305438e-02 + 0.0000000000000000e+00 2.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 2.3333333333333335e+00 1.2691950911691852e-01 1.1470817336657723e-03 + 1.0000000000000000e+00 2.0000000000000000e+00 1.0000000000000000e+00 2.3333333333333335e+00 4.6666666666666670e+00 2.3333333333333335e+00 8.6976681626411111e-03 1.5901256129536456e-04 + 2.0000000000000000e+00 2.0000000000000000e+00 1.0000000000000000e+00 4.6666666666666670e+00 4.6666666666666670e+00 2.3333333333333335e+00 5.9049208317735560e-04 1.7566470110896140e-02 + 0.0000000000000000e+00 0.0000000000000000e+00 2.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 2.9953715033177831e-02 1.5062789289625417e-03 + 1.0000000000000000e+00 0.0000000000000000e+00 2.0000000000000000e+00 2.3333333333333335e+00 0.0000000000000000e+00 4.6666666666666670e+00 1.3562703608312006e-04 1.8312962943132813e-01 + 2.0000000000000000e+00 0.0000000000000000e+00 2.0000000000000000e+00 4.6666666666666670e+00 0.0000000000000000e+00 4.6666666666666670e+00 8.1946070748127639e-02 2.0198940856083126e-04 + 0.0000000000000000e+00 1.0000000000000000e+00 2.0000000000000000e+00 0.0000000000000000e+00 2.3333333333333335e+00 4.6666666666666670e+00 7.0428810597671451e-08 8.4792695870721080e-02 + 1.0000000000000000e+00 1.0000000000000000e+00 2.0000000000000000e+00 2.3333333333333335e+00 2.3333333333333335e+00 4.6666666666666670e+00 7.2409783932922997e-04 2.0268301655037128e-02 + 2.0000000000000000e+00 1.0000000000000000e+00 2.0000000000000000e+00 4.6666666666666670e+00 2.3333333333333335e+00 4.6666666666666670e+00 8.6747245578870801e-09 2.9564950197958781e-02 + 0.0000000000000000e+00 2.0000000000000000e+00 2.0000000000000000e+00 0.0000000000000000e+00 4.6666666666666670e+00 4.6666666666666670e+00 4.2163579827604990e-07 2.0471894406694785e-01 + 1.0000000000000000e+00 2.0000000000000000e+00 2.0000000000000000e+00 2.3333333333333335e+00 4.6666666666666670e+00 4.6666666666666670e+00 5.7340121940448194e-03 1.2144057259890052e-04 + 2.0000000000000000e+00 2.0000000000000000e+00 2.0000000000000000e+00 4.6666666666666670e+00 4.6666666666666670e+00 4.6666666666666670e+00 3.6485975963578684e-03 2.4817000267706845e-02 +... diff --git a/unittest/force-styles/tests/compute-sna_grid.yaml b/unittest/force-styles/tests/compute-sna_grid.yaml new file mode 100644 index 00000000000..50e419285e6 --- /dev/null +++ b/unittest/force-styles/tests/compute-sna_grid.yaml @@ -0,0 +1,28 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 13:46:30 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: +prerequisites: | + atom atomic + pair lj/cut + compute sna/grid +pre_commands: "" +post_commands: | + pair_style lj/cut 4.0 + pair_coeff * * 0.4 2.3 + compute test all sna/grid grid 2 2 2 0.85 0.99363 6 2.0 2.0 1.0 1.0 bzeroflag 0 +input_file: in.metal +natoms: 32 +global_array: |2 + 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 6.5636756563453517e+01 3.9419166612265473e+00 3.4319044281371811e+00 7.0092446791777050e+01 1.4422835659331367e+01 4.1226812692305693e+01 4.2956866047751390e+01 7.6829584387998338e+01 1.1262684419398695e+01 4.5576068832616770e+01 6.9793184423932090e+01 3.5231256941128997e+01 6.1958768568438437e+01 4.5861591934049173e+01 1.3687487768297277e+01 2.6650253400129635e+01 4.6139545301836968e+01 4.3665340855498791e+01 1.6697483839939668e+01 2.8386166839042492e+01 1.2281502404363889e+02 1.9654194187260511e+01 7.1582991854880177e+01 6.2526201851742307e+01 4.4133454195336427e+01 6.4820103978883452e+01 1.0159849548597867e+02 5.8066868607017483e+01 3.5871949575595032e+01 4.2481775380544164e+01 + 3.5000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 6.9290002332882210e+01 3.6742564048755866e+00 3.0562715925678710e+00 7.0624834375136061e+01 1.3987175744008850e+01 4.0935898037267620e+01 4.1226740730181746e+01 8.1068175569748902e+01 1.0640977332463043e+01 4.7073821334295367e+01 7.1901246209285759e+01 3.5716130642981476e+01 6.4527588976044143e+01 4.3992098578966988e+01 1.2684233384151675e+01 2.4964266593792487e+01 4.5485111606366225e+01 4.3678220238943794e+01 1.5203252087722495e+01 2.6992017027998131e+01 1.2785455606853021e+02 1.9233395170115720e+01 7.3054860729002286e+01 6.5653501522299564e+01 4.3730669945818079e+01 6.7267574018244233e+01 1.0479101525750340e+02 5.8302465784358446e+01 3.5510350099999869e+01 4.4434235167437990e+01 + 0.0000000000000000e+00 3.5000000000000000e+00 0.0000000000000000e+00 6.1046506853063370e+01 4.0001718200086032e+00 3.5763005534521453e+00 7.1252044500710610e+01 1.4593969402850437e+01 4.4293117100638653e+01 4.4768400513101597e+01 7.0205219797862924e+01 1.1096166692184054e+01 4.3675729102355973e+01 7.0874557684320465e+01 3.3227839761268697e+01 5.4944955705419950e+01 4.4378686839536222e+01 1.4135958196181759e+01 2.7153913599150993e+01 4.5404683460250652e+01 4.3147195923067486e+01 1.6579190728509076e+01 2.7054809987332824e+01 1.2448120626705897e+02 1.9685130362823969e+01 7.6515180592849333e+01 5.9589906128047659e+01 4.5977631745598046e+01 6.4676221639906174e+01 8.8668058677181378e+01 5.3265260037104284e+01 3.2468429318341165e+01 3.7794911205526411e+01 + 3.5000000000000000e+00 3.5000000000000000e+00 0.0000000000000000e+00 6.5242713702966711e+01 3.9616682287773659e+00 3.5225082357130226e+00 7.0568351298599964e+01 1.4681480806535962e+01 4.2016214100253414e+01 4.3909293521530223e+01 7.7079813707139010e+01 1.1487676188680446e+01 4.6015172084900776e+01 7.1685160100118523e+01 3.6074751865767830e+01 6.2785380054570474e+01 4.6957291562823855e+01 1.4135514852247459e+01 2.7320798733302201e+01 4.7839237962376572e+01 4.4994739249751987e+01 1.7087774150948434e+01 2.9393702781684162e+01 1.2672502316831496e+02 2.0411080732378679e+01 7.4303983668344230e+01 6.5040661507341966e+01 4.6056717129631316e+01 6.8124064292280650e+01 1.0355209094506822e+02 5.9481156626781505e+01 3.7231720070777556e+01 4.4895504550170301e+01 + 0.0000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 6.8700677953771702e+01 3.6555483601875669e+00 3.0778547716599629e+00 7.1154478637437990e+01 1.4067382825598115e+01 4.1710717903003186e+01 4.1779218417367623e+01 8.0529268439057503e+01 1.0633974418851894e+01 4.7200390452978112e+01 7.3027950034363073e+01 3.5665455432656358e+01 6.4293082185226041e+01 4.3804488105766353e+01 1.2851977835953772e+01 2.5144967783452209e+01 4.5935460526861924e+01 4.4181109574303839e+01 1.5295478599514141e+01 2.7088868757445393e+01 1.3002320816176453e+02 1.9529391445414198e+01 7.5100979540140685e+01 6.6498736329129656e+01 4.4681225493649293e+01 6.8929144963995086e+01 1.0415835425878998e+02 5.8569410593312057e+01 3.5701337121006958e+01 4.4875585941273087e+01 + 3.5000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 6.9040906271555173e+01 3.5144885532352559e+00 3.0130635867191922e+00 7.0709404695127049e+01 1.3711594371511644e+01 4.1169121062401864e+01 4.0810352964344034e+01 8.0040807190381173e+01 1.0265216724147907e+01 4.6669740605299815e+01 7.1468478615190591e+01 3.4637888221590764e+01 6.2808020701083620e+01 4.2416073894451124e+01 1.2352808054059407e+01 2.4307626060722903e+01 4.4124775933195487e+01 4.2657671222114971e+01 1.4571535701828399e+01 2.5691857414645813e+01 1.2677850036051922e+02 1.8587988781526487e+01 7.2936673304882945e+01 6.4026174615207950e+01 4.2947049344234806e+01 6.5843765138990150e+01 1.0147703312000934e+02 5.6670372757056221e+01 3.3685375464914017e+01 4.2103338353800254e+01 + 0.0000000000000000e+00 3.5000000000000000e+00 3.5000000000000000e+00 6.7905100660016444e+01 3.8763493678442695e+00 3.3269167691360853e+00 7.1160407287774888e+01 1.4596625967781071e+01 4.1843722131542847e+01 4.3533420023603504e+01 8.0892253832690557e+01 1.1420159163287096e+01 4.7505610804324618e+01 7.3702400440408610e+01 3.7353361056335558e+01 6.6585368233067030e+01 4.7331128087631171e+01 1.3894416012686085e+01 2.7182675321217097e+01 4.8793214270650459e+01 4.6109328595917098e+01 1.6892367133488648e+01 3.0149436535167069e+01 1.3096825231938129e+02 2.0784270107704625e+01 7.5915519662995607e+01 6.8677433254304617e+01 4.7076284964900857e+01 7.1278713210694846e+01 1.0981682198292945e+02 6.2089863647835223e+01 3.9110259972337943e+01 4.8555970122555735e+01 + 3.5000000000000000e+00 3.5000000000000000e+00 3.5000000000000000e+00 6.7297257077713738e+01 3.7446696674110131e+00 3.3456824926128883e+00 7.2689608363933360e+01 1.4681415999963791e+01 4.3490799664779814e+01 4.4772655666155259e+01 8.0667182559519020e+01 1.1322691688211719e+01 4.8292214565676062e+01 7.6811230304367783e+01 3.7278695481590866e+01 6.6989611260779895e+01 4.6670938425697784e+01 1.4300267664682078e+01 2.7497349096080200e+01 4.9756132926189537e+01 4.7612964462472469e+01 1.7072278476710299e+01 3.0158861925364558e+01 1.3754190334558942e+02 2.1326201601360889e+01 8.1310667563734498e+01 7.1235090397110213e+01 4.9714255819348054e+01 7.6077483031076881e+01 1.0995954729095629e+02 6.3499482982705700e+01 3.9455361006304301e+01 4.9437283640788628e+01 +... diff --git a/unittest/force-styles/tests/compute-sna_grid_local.yaml b/unittest/force-styles/tests/compute-sna_grid_local.yaml new file mode 100644 index 00000000000..ee4f6a194ec --- /dev/null +++ b/unittest/force-styles/tests/compute-sna_grid_local.yaml @@ -0,0 +1,28 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 13:46:41 2026 +epsilon: 1e-08 +timestep: 0.001 +skip_tests: kokkos_omp kokkos_serial kokkos_gpu kokkos_omp_full kokkos_serial_full +prerequisites: | + atom atomic + pair lj/cut + compute sna/grid/local +pre_commands: "" +post_commands: | + pair_style lj/cut 4.0 + pair_coeff * * 0.4 2.3 + compute test all sna/grid/local grid 2 2 2 0.85 0.99363 6 2.0 2.0 1.0 1.0 rmin0 0.1 switchflag 0 +input_file: in.metal +natoms: 32 +local_data: |2 + 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 4.0950000000000000e+03 1.8251240269976167e+03 1.0960527570840395e+03 1.9840762808193108e+03 -2.5310756721863896e+02 7.8408669461433658e+02 2.5811123908456608e+02 1.3536212482713901e+02 -6.4788910546451717e+01 4.4096967715029471e+01 9.9390395102504726e+01 6.3711830900127158e+00 3.7590033249046499e+01 2.4058475119676766e+02 -4.5331733455122652e+01 5.0446355744253495e+01 2.5670268057768271e+02 1.7014889946970637e+01 6.9579147263392596e+00 2.4653204878994490e+01 7.1821211249798228e+02 -2.0376911255373503e+02 1.7004864306348148e+02 5.7635603869329898e+01 1.0983715750355607e+01 1.0027889950637606e+02 2.1656659536478010e+03 6.3696940507169222e+02 1.3379725269093856e+02 2.3528264148832957e+02 + 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 3.3740000000000000e+03 1.2274124046006605e+03 6.2653311370865822e+02 1.1844046525200681e+03 -3.4667909930995455e+02 4.0090765966320168e+02 1.7728060531923276e+01 4.3408165571031265e+02 -7.0467656381629169e+00 1.3983545452243979e+02 2.2752554514474403e+02 -2.1330525179065623e+00 1.3704547234669522e+02 9.8951417361176681e+01 2.1182476982844619e+01 -4.1985517809568655e+00 3.2893645983020605e+01 6.7179668884248471e+00 -4.8795472183249391e+00 -1.3171687735739571e+01 9.4686638898935291e+02 -2.8716548853636692e+02 2.3971635965594677e+02 1.5535427508189903e+02 -1.5767064957394545e+01 1.8248525423038919e+02 1.4457559241969718e+03 2.9800066485989299e+02 2.8080935224518790e+01 9.2625550745257613e+01 + 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 0.0000000000000000e+00 4.0950000000000000e+03 1.9247810137049601e+03 1.2067449131222447e+03 2.1567030818209787e+03 -2.4388091552755654e+02 8.9979291627916814e+02 2.6012860188179758e+02 1.2023254272124697e+02 -4.2223934502392346e+01 4.0935289868765402e+01 1.1673819588113058e+02 1.5297663862729634e+00 1.8844988261621442e+01 1.9812581783943560e+02 -7.0744032167301071e+01 4.3922463901316817e+01 2.1088125342063552e+02 1.4436852557158179e+01 6.6521935916286754e+00 1.5646672441008679e+01 7.2324819410258328e+02 -3.0728233823218090e+02 2.0551534704395604e+02 5.9150866205278703e+01 9.0770771798705958e+00 1.3693300035393469e+02 1.7847977322462666e+03 5.3740907751770374e+02 1.0985102604481715e+02 1.9640891368484210e+02 + 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 3.5000000000000000e+00 0.0000000000000000e+00 2.7430000000000000e+03 8.6895215394950901e+02 4.1396366083404109e+02 8.4218882163729836e+02 -3.2781566364713888e+02 2.6424355670756387e+02 -6.6606277826746407e+01 6.2099453602626795e+02 6.2614875552294748e+01 1.8716360617968309e+02 3.4029846933936682e+02 -3.9516287057480881e+01 1.2762632838896474e+02 1.3039990664390660e+02 1.1939018449999024e+02 1.1970384935129896e+00 -2.0145644188612312e+01 -4.7181194167662007e+01 -8.1011153697072888e+00 -1.0173864082903883e-02 1.5211235743084903e+03 -1.7005265944222947e+02 3.9922885390036032e+02 1.5014575286282323e+02 -7.1448506104004466e+01 2.1033763213815212e+02 8.1651663945479891e+02 8.9210880581726371e+01 -1.1932843801406641e+00 -2.9275744270531174e+01 + 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 4.0950000000000000e+03 1.7631376756578359e+03 1.0146921881144292e+03 1.8176642109330955e+03 -3.0169992345126872e+02 6.9698405379677570e+02 2.0970747584662371e+02 1.8601501449966267e+02 -6.2648391089931408e+01 6.4747683160798886e+01 1.1169928640828913e+02 8.6640831680345975e+00 6.5649357372498997e+01 1.8832821974008465e+02 -5.4476653709308742e+01 3.1983426542939966e+01 2.1048143438754795e+02 1.9726329658697811e+01 6.4994646417789159e+00 1.4687431430453437e+01 5.4871887617593291e+02 -2.9627226368193021e+02 1.2015364412377377e+02 8.4849879404767975e+01 -1.1046193882009474e+00 1.1323924651898318e+02 2.3010560444203675e+03 6.5780742463530760e+02 1.5035377513192498e+02 3.4065429862658243e+02 + 1.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 3.5000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 3.3740000000000000e+03 1.2296829856644890e+03 6.2683981504913504e+02 1.1780032250824206e+03 -3.5131952396925510e+02 3.9779651269630830e+02 7.0915952572569267e+00 4.3842290249975662e+02 -8.6481364979111799e+00 1.4360286275903408e+02 2.2812504885249891e+02 -2.3202557241295354e+00 1.4724038446141842e+02 6.5042942305833947e+01 1.7896665141009620e+01 -1.1282744154876768e+01 2.3214349027253693e+01 7.0431224213216890e+00 -5.6826095436231707e+00 -1.2777395550686956e+01 9.2537572673784518e+02 -3.0390742274977492e+02 2.3525799080412023e+02 1.6595195224684517e+02 -1.4686640788863709e+01 1.9055644990461315e+02 1.4572552751825388e+03 3.0519547428119836e+02 2.1168051947497734e+01 1.0692456123134164e+02 + 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 3.5000000000000000e+00 3.5000000000000000e+00 2.7430000000000000e+03 8.3538759112693742e+02 3.7923443210742357e+02 7.6561406773180624e+02 -3.2765364737970464e+02 2.2978468480255660e+02 -6.9314229905121294e+01 6.9012452285544316e+02 7.1072178579511586e+01 2.0116330473948619e+02 3.3586277808493406e+02 -4.8188835289516135e+01 1.6113152995823310e+02 1.1926013178838113e+02 1.1502276459604701e+02 3.6717981342396389e+00 -3.2844136602068289e+01 -5.3420145753656371e+01 -8.5301401959689152e+00 1.3438136258987914e+00 1.4370913593930659e+03 -2.0040447550895746e+02 3.6490261684756933e+02 1.7574610419482926e+02 -8.0834960475313963e+01 2.2197937195621378e+02 8.8143110895249811e+02 9.6457430803050883e+01 -1.1086863590823466e+00 -2.6371027535186471e+01 + 1.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 3.5000000000000000e+00 3.5000000000000000e+00 3.5000000000000000e+00 2.7430000000000000e+03 1.5700581271382412e+03 7.1651977511760970e+02 7.6657016452977928e+02 -2.0047985818969963e+02 2.3077083010565252e+02 -8.1742439510256702e+01 1.4715667598995901e+02 5.4818218955437217e+01 3.8507931881660213e+01 7.5345520214886648e+01 -1.6603448621481299e+01 2.5249455880068517e+01 1.2208121265044247e+02 1.1422641086471212e+02 7.4144142976528844e+00 -3.7267166652556085e+01 -1.6795295579908085e+01 -1.0857629838343668e+01 8.8237805748780342e+00 5.2328559597016056e+02 -9.4849421242594047e+01 9.0626412330671442e+01 4.0911438679777390e+01 -3.1438947245738280e+01 6.0430696570618522e+01 8.2397233759447465e+02 9.1782081069538322e+01 -8.0123239072285717e+00 -2.3736881798226189e+01 +... From 1232312e47e77cd7e53cc087a4a504a531fd00fb Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 13:59:43 +0000 Subject: [PATCH 039/120] unittest: add references for fix addtorque/atom, settorque/atom and electron/stopping The three fixes have no reference so far, so their KOKKOS versions were never compared against the plain ones. All three use non-default keywords: an atom style variable and 'every' for addtorque/atom, a NULL component, a variable and a region for settorque/atom, and 'minneigh' plus a region for electron/stopping. The stopping power table is copied from the electron_stopping example. --- unittest/force-styles/tests/Si.Si.elstop | 14 ++ .../tests/fix-timestep-addtorque_atom.yaml | 124 +++++++++++++++++ .../tests/fix-timestep-electron_stopping.yaml | 124 +++++++++++++++++ .../tests/fix-timestep-settorque_atom.yaml | 125 ++++++++++++++++++ 4 files changed, 387 insertions(+) create mode 100644 unittest/force-styles/tests/Si.Si.elstop create mode 100644 unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-electron_stopping.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-settorque_atom.yaml diff --git a/unittest/force-styles/tests/Si.Si.elstop b/unittest/force-styles/tests/Si.Si.elstop new file mode 100644 index 00000000000..1a6952e571c --- /dev/null +++ b/unittest/force-styles/tests/Si.Si.elstop @@ -0,0 +1,14 @@ +# Electronic stopping for Si in Si UNITS: metal DATE: 2019-02-19 CONTRIBUTOR: Risto Toijala risto.toijala@helsinki.fi +# Kinetic energy in eV, stopping power in eV/A +# For other atom types, add columns. + +# atom type 1 +# energy Si in Si + 3918.2 6.541 + 15672.9 13.091 + 35263.9 19.660 + 62691.5 26.257 + 97955.4 32.889 +141055.9 39.566 +191992.0 46.292 +250766.1 53.074 diff --git a/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml b/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml new file mode 100644 index 00000000000..b60732dcc7f --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml @@ -0,0 +1,124 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 13:47:35 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom sphere + fix addtorque/atom + fix nve/sphere + fix viscous/sphere +pre_commands: "" +post_commands: | + group sub id 1:16 + variable tz atom 20.0*z + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test sub addtorque/atom 12.0 -8.0 v_tz every 2 +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 5.7495240147335487e+00 -8.9892148479344968e+01 6.3535291951760044e+01 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 3.4999149888402286e+01 1.9512238074702505e+01 2.2053256741938966e+01 + 2 -1.2399457111986916e+01 4.9821716916501977e+00 4.0236528053073158e+01 + 3 4.5774408248055806e+01 -3.9006403312904624e+01 -1.7858050679933548e+01 + 4 9.7397192219531590e+00 2.7920491969711392e+01 -3.1467757182230265e+01 + 5 -2.8941112126358384e+00 -4.0761879332415788e+01 4.6054480800526505e+01 + 6 4.8185134345081551e+00 -2.0778280041648259e+01 -1.7615992401400558e+01 + 7 3.6736320722525988e+01 -1.7862317834673647e+01 1.1608861329177698e+01 + 8 -3.7887098668863004e+00 -4.1353441830180167e+01 1.2665337281532416e+01 + 9 4.8447646181034827e+01 2.8633455708287521e+01 4.5066581649966601e+01 + 10 1.5678363812816318e+00 1.8838437955931251e+01 3.3108301792866985e+00 + 11 3.0972137915721909e+01 -3.5320086769789512e+01 -3.0068130455068701e+01 + 12 -9.2356365302646637e+00 -2.0947755971401740e+01 4.9469862701878156e+01 + 13 -2.1936238909410548e+00 -4.6349145062372834e+00 -2.3534076784345835e+01 + 14 -5.8107496855697285e+00 -3.3984397093937901e+01 -3.6985610441988488e+00 + 15 2.2324297252732585e+01 -3.2973411687961459e+01 -2.3338254080956641e+01 + 16 -1.3082169331982954e+00 -3.0156055498477453e+01 -3.3862734923698632e+00 + 17 -3.6245256163667364e+01 -6.3871111638224605e+00 -1.3495747501256501e+01 + 18 -3.3449264457958030e+01 -5.1211596898529228e+00 -1.6063046301513040e+01 + 19 9.3043983000234061e+00 -2.3735251406356383e+01 2.9944371209876916e+01 + 20 -2.4405251554499323e+01 1.2326350244656219e+01 1.8226255489083119e+01 + 21 5.3118160854329755e-01 -1.7920486666067696e+01 1.6953099712445379e+01 + 22 -3.3557628027146755e+01 1.2249117911837695e+01 -1.7589300363970636e+01 + 23 3.0739609373049564e+01 2.6993712418787631e+01 1.8418986687028031e+01 + 24 5.0644131551068856e+00 -1.1242047487707133e+01 -3.2378841254744543e+01 + 25 1.0202507096633921e+01 2.6024108048890692e+01 1.7811055792779975e+01 + 26 -1.3723409906199922e+01 -1.0575474673847591e+01 8.2690719199617373e+00 + 27 9.4128998826732033e+00 2.2890024767581750e+01 2.4136424334565429e+01 + 28 -1.7910692310779947e+01 -3.3294781390526161e+01 6.7281746292838989e+00 + 29 -7.9733826800536098e+00 3.1114003089361034e+01 2.2326437598377652e+01 + 30 2.3968291735833084e+01 2.8641275713082941e+01 -6.0887858668077675e+00 + 31 5.1720084493622815e+00 -2.1513073667316927e+01 2.3908844737698647e+01 + 32 1.8588536223960755e+01 3.2959381077417568e+01 -1.8718949743780824e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml b/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml new file mode 100644 index 00000000000..925fc8a6461 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml @@ -0,0 +1,124 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 13:53:42 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom sphere + fix electron/stopping + fix nve/sphere + fix viscous/sphere +pre_commands: | + variable units index metal +post_commands: | + set group all mass 850.0 + region upper block INF INF INF INF 0.0 INF units box + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test all electron/stopping 10000.0 ${input_dir}/Si.Si.elstop minneigh 2 region upper +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_scalar: 515.5002586005972 +run_pos: |2 + 1 -1.2804284007003335e+00 -6.3968448273304890e-01 6.1489214262591174e-01 + 2 -2.3460040798724824e-02 2.4353261796863626e+00 6.9296279393330784e-01 + 3 -7.4259638885717627e-01 -2.3616040061148591e-02 -7.9858889806810940e-01 + 4 1.7655221776499568e+00 8.9461910437688408e-01 5.7568426112000470e-02 + 5 -1.6620166884113247e-01 -9.8574509639085295e-01 7.6738370875711936e-01 + 6 1.2025763191079151e+00 2.6294865854779785e+00 -1.0251470231648530e+00 + 7 1.0827531743269698e+00 -1.9275194099432504e+00 3.7754634402418469e-01 + 8 3.0284073821646579e-02 -1.5215368061314891e+00 -4.8300808654055954e-01 + 9 -7.5876809024254344e-01 1.7789958237388190e+00 7.9595646830636246e-01 + 10 2.5970122032255354e+00 -1.8650168222042307e+00 4.8946071901912458e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5161898155917166e-01 2.4294935671884215e+00 9.6466790928854729e-01 + 13 -2.4899477202981049e-01 1.3574116150552167e+00 2.1686030241506909e-01 + 14 6.2993828905737981e-01 -8.7319151035753972e-01 2.4674631413937731e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1666411761893087e+00 -2.5001460601032619e+00 1.0069046291017858e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3445295762087812e+00 1.3907608810253183e+00 1.0986526394915426e+00 + 20 1.7388938005687613e+00 2.5260036580693401e+00 4.4374900081267277e-01 + 21 1.1846833280420814e+00 8.1850844178314719e-01 2.1542808793199880e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5736887678345162e+00 6.0528584733189894e-03 -9.1503230286604287e-01 + 24 8.1743148040595714e-01 -1.1334946945798132e+00 -7.7310513638760658e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3190083424349843e+00 -2.0137753170455612e+00 5.9363012535627924e-01 + 27 1.3323053622976422e+00 -5.4197216094039624e-01 9.7238709521113931e-01 + 28 8.9911660032983221e-01 1.6975812766670484e+00 9.7056673656526604e-01 + 29 2.6224834068379632e+00 2.2594115022594385e+00 -1.3331218386506571e+00 + 30 -1.0568588660216853e+00 2.4711282299091701e+00 1.2499459880700725e-01 + 31 -1.5871590012326990e+00 -5.8128198170878520e-01 1.4847530548310039e-01 + 32 -2.6825733241663619e+00 -1.2825226397828080e+00 5.5522005140203790e-01 +run_vel: |2 + 1 -5.2422426304953467e+02 2.1523612170922226e+02 -1.1217318649721096e+02 + 2 3.9117443360577596e+02 4.8774922505002209e+01 -6.2286484544401640e+02 + 3 1.0980228524713830e+02 6.6517683174343506e+02 -5.8311003191886687e+02 + 4 3.9818936612842100e+02 -1.1739187653882787e+02 -3.7598304487468153e+02 + 5 5.8417150605034988e+02 1.5972997312593824e+02 -1.9956757717742377e+02 + 6 6.0915868496185897e+02 7.3783350542272160e+02 2.8391172500782938e+02 + 7 -2.7956056084213401e+01 7.5204102047198410e+02 2.2351867551020433e+02 + 8 -4.5092395342714912e+02 -7.5931413009524601e+02 5.4682383668771797e+02 + 9 -5.4514389562179922e+01 -1.1511112405514018e+02 -6.1053930394814370e+02 + 10 7.4830385056766954e+02 7.0156429174534640e+02 -4.9798319424274791e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9346277632504552e+02 5.6257535269406981e+02 -5.1209107676447502e+02 + 13 2.9392143413111955e+02 -4.1630029110650582e+02 -6.7866149218637486e+02 + 14 -7.6379628948415416e+02 7.3349768405767941e+02 7.2028952045334790e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2807378655785016e+02 -4.9135873603150105e+02 -2.7053486717170125e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0355279932040452e+02 -5.4677817323162195e+01 5.8081190665918507e+02 + 20 -1.1582550553755729e+02 -7.6134589615125401e+02 -2.2292525906983587e+02 + 21 6.5845669049642470e+02 5.8646196900411530e+02 -6.2458687130749445e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5288444414648779e+02 -4.6589316302073314e+02 -6.7055628496841837e+02 + 24 -6.2671266561460754e+02 2.7838296501449497e+02 4.5693107996852001e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1335505302443562e+02 -5.3408094128268021e+02 2.4398929390408915e+02 + 27 5.9488291604325696e+02 6.2619017287075314e+02 -7.3631246774489284e+02 + 28 -4.0021215514054813e+02 6.0611978542136762e+02 1.2155891700588776e+02 + 29 -3.4753504917001476e+02 -3.6565771606538402e+02 -5.4143883440893080e+02 + 30 -1.0493538740967504e+02 4.9992072547801376e+02 7.3111271805745696e+02 + 31 7.5452948102683138e+02 -3.4922230711791748e+01 -7.2578086649866327e+02 + 32 1.3998515186352287e+02 6.4288611483818295e+02 -5.3542392680861258e+02 +run_torque: |2 + 1 2.2614658043217627e+01 2.7015660622888987e+01 9.6160766069205028e+00 + 2 -2.3951024208899849e+01 1.2740927732746645e+01 2.5927072821467021e+01 + 3 3.3200565282136651e+01 -3.0474646226393482e+01 -1.8319002961722957e+00 + 4 -2.2008944955648655e+00 3.5276158218670624e+01 -3.2019976379299543e+01 + 5 -1.4612713552596896e+01 -3.2199273672197926e+01 3.0172352373566277e+01 + 6 -7.0356210729422095e+00 -1.2566841545661367e+01 2.8369431791594888e+00 + 7 2.4321301976419846e+01 -9.7021208675189090e+00 3.9806430571513318e+00 + 8 -1.5491591631791435e+01 -3.2780440779132896e+01 2.1926642928886558e+01 + 9 3.5826827023760977e+01 3.5976593210516391e+01 2.8624025721827522e+01 + 10 -1.0229174730828250e+01 2.6353701037623484e+01 -6.3710672337853325e+00 + 11 1.8658411819699559e+01 -2.6853108470526259e+01 -1.1034243123089679e+01 + 12 -2.0842800713851179e+01 -1.2733339314134140e+01 2.9632200691829880e+01 + 13 -1.3924535732446856e+01 3.2928403643061390e+00 -2.7382137401693626e+01 + 14 -1.7478098612833477e+01 -2.5540890560142739e+01 -8.5053698533308175e+00 + 15 1.0162537658748050e+01 -2.4547670966667337e+01 -2.1829747094084087e+01 + 16 -1.3054687826205129e+01 -2.1779823525296926e+01 1.8654606311378110e+01 + 17 -3.5608326667703068e+01 -6.2748719379256599e+00 -1.3258589854616581e+01 + 18 -3.2861468276979750e+01 -5.0311667361466021e+00 -1.5780774107373350e+01 + 19 9.1408942626198773e+00 -2.3318157327987304e+01 2.9418165706581494e+01 + 20 -2.3976383718628686e+01 1.2109742145296782e+01 1.7905969720662618e+01 + 21 5.2184727710231527e-01 -1.7605574102390051e+01 1.6655186815758398e+01 + 22 -3.2967927598252750e+01 1.2033866998383969e+01 -1.7280207660511742e+01 + 23 3.0199429333606453e+01 2.6519358159364913e+01 1.8095314097882376e+01 + 24 4.9754173951191136e+00 -1.1044493589684757e+01 -3.1809855372918591e+01 + 25 1.0023220801255352e+01 2.5566792422601502e+01 1.7498066232505909e+01 + 26 -1.3482251600820655e+01 -1.0389634305574823e+01 8.1237614333620254e+00 + 27 9.2474891720753600e+00 2.2487783661270019e+01 2.3712280537198502e+01 + 28 -1.7595951861040444e+01 -3.2709699904729796e+01 6.6099419740630756e+00 + 29 -7.8332682720161859e+00 3.0567243915811517e+01 2.1934100278922660e+01 + 30 2.3547102493701814e+01 2.8137969205292436e+01 -5.9817890422945572e+00 + 31 5.0811219421763445e+00 -2.1135029403932691e+01 2.3488700143903888e+01 + 32 1.8261884180052473e+01 3.2380193503679934e+01 -1.8390005973278851e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml b/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml new file mode 100644 index 00000000000..b301e9136de --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml @@ -0,0 +1,125 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 13:48:45 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom sphere + fix settorque/atom + fix nve/sphere + fix viscous/sphere +pre_commands: "" +post_commands: | + group sub id 1:16 + region upper block INF INF INF INF 0.0 INF units box + variable ty atom -15.0*x + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test sub settorque/atom NULL v_ty 5.0 region upper +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 -2.0842719284623900e+01 6.1684125183006103e+01 5.4603847158489835e+01 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 2.3019168563559930e+01 1.9219039527209908e+01 5.0000000000000000e+00 + 2 -2.4379438436829275e+01 3.4831636938470134e-01 5.0000000000000000e+00 + 3 3.3794426923213450e+01 -3.1130295103457946e+01 -1.8810507373697978e+00 + 4 -2.2402621028891989e+00 -2.6489770408086365e+01 5.0000000000000000e+00 + 5 -1.4874092537478198e+01 2.4860052550963943e+00 5.0000000000000000e+00 + 6 -7.1614678903341975e+00 -1.2841144130849308e+01 2.8821648673555007e+00 + 7 2.4756339397683632e+01 -1.6241143502769848e+01 5.0000000000000000e+00 + 8 -1.5768691191728664e+01 -3.3395672309308587e+01 2.2356134487210905e+01 + 9 3.6467664856192457e+01 1.1381925693392919e+01 5.0000000000000000e+00 + 10 -1.0412144943560724e+01 -3.8959367071785344e+01 5.0000000000000000e+00 + 11 1.8992156590879556e+01 -2.7442980153824085e+01 -1.1274271130589026e+01 + 12 -2.1215617855107027e+01 8.2772064900178446e+00 5.0000000000000000e+00 + 13 -1.4173605215783414e+01 3.7332868632003886e+00 5.0000000000000000e+00 + 14 -1.7790731010412081e+01 -9.4362507319604880e+00 5.0000000000000000e+00 + 15 1.0344315927890230e+01 -2.4986757471399887e+01 -2.2220217838284317e+01 + 16 -1.3288198258040664e+01 -2.2165077009142792e+01 1.8991627535856885e+01 + 17 -3.6245256163667364e+01 -6.3871111638224605e+00 -1.3495747501256501e+01 + 18 -3.3449264457958030e+01 -5.1211596898529228e+00 -1.6063046301513040e+01 + 19 9.3043983000234061e+00 -2.3735251406356383e+01 2.9944371209876916e+01 + 20 -2.4405251554499323e+01 1.2326350244656219e+01 1.8226255489083119e+01 + 21 5.3118160854329755e-01 -1.7920486666067696e+01 1.6953099712445379e+01 + 22 -3.3557628027146755e+01 1.2249117911837695e+01 -1.7589300363970636e+01 + 23 3.0739609373049564e+01 2.6993712418787631e+01 1.8418986687028031e+01 + 24 5.0644131551068856e+00 -1.1242047487707133e+01 -3.2378841254744543e+01 + 25 1.0202507096633921e+01 2.6024108048890692e+01 1.7811055792779975e+01 + 26 -1.3723409906199922e+01 -1.0575474673847591e+01 8.2690719199617373e+00 + 27 9.4128998826732033e+00 2.2890024767581750e+01 2.4136424334565429e+01 + 28 -1.7910692310779947e+01 -3.3294781390526161e+01 6.7281746292838989e+00 + 29 -7.9733826800536098e+00 3.1114003089361034e+01 2.2326437598377652e+01 + 30 2.3968291735833084e+01 2.8641275713082941e+01 -6.0887858668077675e+00 + 31 5.1720084493622815e+00 -2.1513073667316927e+01 2.3908844737698647e+01 + 32 1.8588536223960755e+01 3.2959381077417568e+01 -1.8718949743780824e+00 +... From 9406bd1dc7869cde852a9d3ab187dfbffc545d6a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 4 Sep 2026 10:08:02 -0400 Subject: [PATCH 040/120] fix memory leak --- src/KSPACE/msm.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/KSPACE/msm.cpp b/src/KSPACE/msm.cpp index 7b743c45e29..f9d192edd29 100644 --- a/src/KSPACE/msm.cpp +++ b/src/KSPACE/msm.cpp @@ -830,6 +830,10 @@ void MSM::allocate_levels() void MSM::deallocate_levels() { + // the per-atom virial grids are allocated per level, too, so they must be freed first + + if (peratom_allocate_flag) deallocate_peratom(); + if (world_levels) { for (int n=0; n < levels; ++n) { memory->destroy3d_offset(qgrid[n],nzlo_out[n],nylo_out[n],nxlo_out[n]); From 7f964d13721e52dde87531410b60bc353910ab8d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 4 Sep 2026 10:08:38 -0400 Subject: [PATCH 041/120] add suppressions false positives on thread storage --- tools/valgrind/MPICH.supp | 10 ++++++++++ tools/valgrind/README | 2 +- tools/valgrind/ROCm.supp | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/tools/valgrind/MPICH.supp b/tools/valgrind/MPICH.supp index 6c6d431040d..b94c8e5ae6e 100644 --- a/tools/valgrind/MPICH.supp +++ b/tools/valgrind/MPICH.supp @@ -425,3 +425,13 @@ fun:HYDT_dmxu_poll_wait_for_event ... } +{ + MPICH_psm3_rcvthread_tls + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + ... + fun:pthread_create@* + fun:psm3_ips_ptl_rcvthread_init + ... +} diff --git a/tools/valgrind/README b/tools/valgrind/README index 7f953218621..c42f9d4234a 100644 --- a/tools/valgrind/README +++ b/tools/valgrind/README @@ -51,4 +51,4 @@ The --max-stackframe option is needed because some Fortran libraries limit valgrind misreads the resulting stack pointer jump as a stack switch and reports millions of bogus invalid access errors. -Last update: 2026-08-22 +Last update: 2026-09-04 diff --git a/tools/valgrind/ROCm.supp b/tools/valgrind/ROCm.supp index 12fe0a8d51f..958f43a1a6d 100644 --- a/tools/valgrind/ROCm.supp +++ b/tools/valgrind/ROCm.supp @@ -66,3 +66,13 @@ fun:_ZN3amd*guessTlsSizeEv* ... } +{ + ROCm_amdocl_queue_thread_tls + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + ... + fun:pthread_create@* + fun:_ZN3amd2Os14createOsThreadE* + ... +} From c4eb7899ac46f91be98a3252bbd6f8d8d710dcb0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 14:10:30 +0000 Subject: [PATCH 042/120] unittest: add references for the granular KOKKOS styles without history pair gran/hooke, fix wall/gran and fix damping/cundall had no reference, so their KOKKOS versions were never compared against the plain ones. The pair style fixture builds an overlapping sphere system on the empty input template; the two fixes run on the sphere system of the brownian input. All three use the non-default limit_damping, shear or scale keyword. The wall fixture also covers the compatibility class kept for the old wall/gran API and the internal neighbor history fix. --- .../tests/atomic-pair-gran_hooke.yaml | 104 +++++++++++++++ .../tests/fix-timestep-damping_cundall.yaml | 122 ++++++++++++++++++ .../tests/fix-timestep-wall_gran.yaml | 119 +++++++++++++++++ 3 files changed, 345 insertions(+) create mode 100644 unittest/force-styles/tests/atomic-pair-gran_hooke.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-damping_cundall.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-wall_gran.yaml diff --git a/unittest/force-styles/tests/atomic-pair-gran_hooke.yaml b/unittest/force-styles/tests/atomic-pair-gran_hooke.yaml new file mode 100644 index 00000000000..a63e3855f4a --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-gran_hooke.yaml @@ -0,0 +1,104 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 12:51:34 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + pair gran/hooke + atom sphere +pre_commands: | + atom_modify map array + units lj + atom_style sphere + comm_modify vel yes + lattice fcc 0.8442 + region box block 0 2 0 2 0 2 + create_box 1 box + create_atoms 1 box + displace_atoms all random 0.05 0.05 0.05 623426 + set group all diameter 1.25 + set group all mass 1.0 + velocity all create 3.0 4534624 loop geom +post_commands: "" +input_file: in.empty +pair_style: gran/hooke 1000.0 350.0 50.0 30.0 0.5 1 limit_damping +pair_coeff: | + * * +extract: "" +natoms: 32 +init_vdwl: 0 +init_coul: 0 +init_stress: |2- + 5.3430856409575654e+03 5.3461832994424140e+03 4.9492032483456305e+03 -2.9298432281786290e+01 2.6160888391656226e+02 -2.2773453540487753e+02 +init_forces: |2 + 1 -6.4913202241618649e+02 -3.9480872470226899e+01 2.2052171467387697e+02 + 2 -1.1782065473257664e+01 6.3031455682989133e+02 2.0709095991399849e+01 + 3 3.9244173997741706e+02 -5.1560390292228271e+02 8.4789050324097303e+01 + 4 1.8707618517828092e+02 1.9964760782848177e+02 5.4374721640487337e+01 + 5 2.5444340534161972e+02 -2.5006803781581073e+02 -4.0247374143698687e+02 + 6 1.2312242659654596e+02 -1.5673932823197691e+02 -1.0612800926622796e+00 + 7 -6.8775645409517935e+01 -2.9576007516258068e+02 -1.8798358631303216e+01 + 8 -5.0857866337191467e+02 -3.6824400783603676e+02 2.6461342753397139e+02 + 9 8.6675593404451504e+01 -7.9404894872638167e+01 3.2436048373333040e+02 + 10 1.5620017378625292e+02 2.2199781162679508e+02 -1.8768855525748467e+02 + 11 -4.1246294396476560e+02 -3.8002598248619114e+02 6.9132792602710580e+01 + 12 7.9105546790104995e+01 3.4948235070753526e+02 -2.0226217146502776e+02 + 13 -1.5571819940018077e+02 -5.6394809611057568e+01 -1.1605348820723520e+01 + 14 1.6753551500515137e+01 1.7708840741624238e+02 -2.4087223022918087e+02 + 15 5.5983872413538722e+02 6.0246845000458870e+02 -1.6836953760080073e+02 + 16 2.5562454272151960e+01 8.9056952479366998e+01 -2.2748013481215654e+02 + 17 -4.1172132943178394e+02 2.2821587547834832e+02 -1.0017697960139060e+01 + 18 2.5621483384438551e+02 2.5426112527845581e+02 2.6904876249607572e+01 + 19 6.9441209992878782e+02 -2.4898123852739633e+02 4.3621503968874450e+01 + 20 1.3164636862270839e+01 6.4250962739846457e+01 -1.6833071866832461e+02 + 21 -5.2953153299410765e+01 4.8684565725251680e+01 2.1058123794242994e+02 + 22 4.5859508292047678e+02 2.6932307480858206e+01 6.1952278053008783e+01 + 23 -7.6403666017216807e+00 -1.6562528420872692e+02 1.9777003265700455e+02 + 24 -5.5985430282062555e+02 6.8501674223921057e+01 -3.9694514057714133e+02 + 25 -4.8512527365298223e+02 -2.1199412107392317e+02 8.6851526229184969e+01 + 26 3.0810087089991913e+02 2.1111887389564757e+02 5.2809160800843893e+02 + 27 -1.8020366060766224e+02 1.2702407250295229e+02 -3.3094436828445532e+02 + 28 7.4030643731744050e+01 -5.1066368279763134e+02 1.3813278591013173e+02 + 29 -3.3218925993024277e+02 -1.8768325202613721e+02 4.6435579158642577e+02 + 30 -1.4125188900246621e+02 -7.9516148999788683e+01 -1.9141082874057051e+02 + 31 2.4814910526295429e+02 -4.2957522791797402e+01 -2.7531251503154715e+02 + 32 4.3501700949452854e+01 2.9009756761601955e+02 3.6809700503524027e+01 +run_vdwl: 0 +run_coul: 0 +run_stress: |2- + 5.2539906176196100e+03 5.2773638627959726e+03 4.8952160375360363e+03 -4.4291321993969120e+01 2.6459741171942221e+02 -2.2036053867855566e+02 +run_forces: |2 + 1 -6.1688882717741387e+02 -4.0728713007187224e+01 2.1209155758040288e+02 + 2 -1.5307235207159952e+01 6.0439110131312270e+02 1.4420692947548446e+01 + 3 3.7729968607290544e+02 -4.9319179438424902e+02 7.6546148044181393e+01 + 4 1.8833904750721888e+02 1.8470325372781139e+02 5.5442955495363748e+01 + 5 2.4510335657595738e+02 -2.4176340972334060e+02 -3.9167181200509316e+02 + 6 1.1297407714530162e+02 -1.4227475674093094e+02 -3.3830097837680597e+00 + 7 -5.8748109377360720e+01 -2.8645797967908663e+02 -2.0825574449332692e+01 + 8 -4.8295938421407232e+02 -3.5133555319742288e+02 2.5810177283938600e+02 + 9 8.6162741594002767e+01 -7.1881353472715915e+01 3.0990109885462596e+02 + 10 1.4005291574802746e+02 2.1558612029124771e+02 -1.8140516562544451e+02 + 11 -4.0294523953565675e+02 -3.6173097891049383e+02 7.0611509254080786e+01 + 12 8.1506381905390356e+01 3.4064747955859906e+02 -1.9564801882076870e+02 + 13 -1.4828044856176319e+02 -5.3469013319528798e+01 -1.5865839819575342e+01 + 14 1.7592912289004353e+01 1.6814191923323224e+02 -2.4234676940210426e+02 + 15 5.3702250621641701e+02 5.7831364310430263e+02 -1.5875903737822892e+02 + 16 2.0757232440034560e+01 8.1751343076045885e+01 -2.1618844454090285e+02 + 17 -3.8441655671599756e+02 2.1525510699445886e+02 -6.0275180775926742e+00 + 18 2.5052427419010965e+02 2.4527350240119600e+02 2.5321024388888532e+01 + 19 6.6896125050126329e+02 -2.3728681744379941e+02 5.2496685167410419e+01 + 20 1.6822762204695081e+01 5.8061559079393959e+01 -1.5386866581091456e+02 + 21 -5.2645850414455118e+01 4.8404719602916543e+01 2.0811197833381587e+02 + 22 4.4214190374909873e+02 2.7535416436167182e+01 5.8647914405429830e+01 + 23 -6.9343701059928335e+00 -1.6684992991320561e+02 1.8984902961969505e+02 + 24 -5.4055625281973471e+02 6.6192035788515867e+01 -3.8872774566208199e+02 + 25 -4.7276785432521683e+02 -2.0409143620813643e+02 8.6542114343038449e+01 + 26 2.9099536974786605e+02 2.0168366757577172e+02 5.0881185800751700e+02 + 27 -1.8028630052442929e+02 1.3161148579928349e+02 -3.2034059907659980e+02 + 28 6.7759450526050671e+01 -4.9691127540156799e+02 1.3417116573284591e+02 + 29 -3.1930467331419044e+02 -1.8266672769251738e+02 4.4357163125313969e+02 + 30 -1.4280849379168848e+02 -7.9258819725320890e+01 -1.7958667299842693e+02 + 31 2.3613350813097466e+02 -4.0602293350330697e+01 -2.6293498920987406e+02 + 32 4.4700219540814352e+01 2.8294849818776902e+02 3.2940726393338863e+01 +... diff --git a/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml b/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml new file mode 100644 index 00000000000..edee9774ea9 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml @@ -0,0 +1,122 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 13:08:35 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom sphere + fix damping/cundall + fix addforce + fix addtorque/atom + fix nve/sphere +pre_commands: "" +post_commands: | + fix push all addforce 0.1 -0.2 0.3 + fix spin all addtorque/atom 0.05 -0.03 0.02 + fix move all nve/sphere + fix test solute damping/cundall 0.4 0.25 scale 1 2.0 +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +run_pos: |2 + 1 -1.2812665516165758e+00 -6.3934472575007140e-01 6.1472045771326989e-01 + 2 -2.3220785714823056e-02 2.4353504735282088e+00 6.9259056657354212e-01 + 3 -7.4243865838047629e-01 -2.2667868176229511e-02 -7.9941665956610064e-01 + 4 1.7659849994499153e+00 8.9448213687513922e-01 5.7139954198778597e-02 + 5 -1.6573337809560207e-01 -9.8562263563465446e-01 7.6723208392721476e-01 + 6 1.2034426689378903e+00 2.6305300670355285e+00 -1.0247424675715628e+00 + 7 1.0827456503820729e+00 -1.9272485274160238e+00 3.7762940620217211e-01 + 8 2.9729597575776090e-02 -1.5224757349536391e+00 -4.8233143568638936e-01 + 9 -7.5879229602877851e-01 1.7789382930511584e+00 7.9566282269050825e-01 + 10 2.5972914436965131e+00 -1.8647608101655193e+00 4.8928334329241319e-01 + 11 -1.4181718936927670e+00 1.7723741693330857e+00 -9.4165253470046850e-01 + 12 -5.5181101580377301e-01 2.4297665707150800e+00 9.6442264828922752e-01 + 13 -2.4888548530253521e-01 1.3572566467179694e+00 2.1661691668160749e-01 + 14 6.2908613232811761e-01 -8.7237601664774311e-01 2.4755344125638273e-01 + 15 -1.3555700164628781e+00 -1.7492701365905590e+00 -5.7080207864602106e-02 + 16 -2.0176536258289297e+00 -1.7289531398315932e+00 -1.1193727958628668e+00 + 17 2.1665654554847293e+00 -2.5002367430272474e+00 1.0068632875075600e+00 + 18 -7.3487625614480434e-01 -1.3974945982132181e+00 -2.4283785557504300e-01 + 19 1.3444567221237917e+00 1.3907399612469424e+00 1.0988692833845459e+00 + 20 1.7387117026883581e+00 2.5247880008430577e+00 4.4340148083914477e-01 + 21 1.1849280536802944e+00 8.1872063690594543e-01 2.1520449098861855e-01 + 22 -8.4121444620013486e-01 1.6806654533795546e+00 7.4408203772491999e-01 + 23 -1.5739363237768309e+00 5.5911042078695128e-03 -9.1568777184630068e-01 + 24 8.1654703658530103e-01 -1.1331061073570736e+00 -7.7245737375100343e-01 + 25 2.3909288800852000e+00 -5.6765674265008792e-01 -6.2710814677521753e-01 + 26 -1.3191110720226338e+00 -2.0140399704254408e+00 5.9375166701848470e-01 + 27 1.3330075963782002e+00 -5.4123879202359537e-01 9.7152653835517366e-01 + 28 8.9848357078780561e-01 1.6985386622672975e+00 9.7076076261635424e-01 + 29 2.6221040563068452e+00 2.2590088652367473e+00 -1.3337088781552704e+00 + 30 -1.0569738623843630e+00 2.4716836837090854e+00 1.2581588710066116e-01 + 31 -1.5868789217750825e+00 -5.8129554176534648e-01 1.4821444196616390e-01 + 32 -2.6825470708901351e+00 -1.2824089745732321e+00 5.5512905562019432e-01 +run_vel: |2 + 1 -5.2467559133127281e+02 2.1541924257264739e+02 -1.1226593039296084e+02 + 2 3.9134183273599945e+02 4.8793025989840984e+01 -6.2312702555460078e+02 + 3 1.0986403572460524e+02 6.6554723730807098e+02 -5.8343302395145338e+02 + 4 3.9848158572748753e+02 -1.1747828755723408e+02 -3.7625469833608406e+02 + 5 5.8453161293119263e+02 1.5982564515018370e+02 -1.9968642118964570e+02 + 6 6.0949770979130301e+02 7.3824120844849824e+02 2.8407012209841861e+02 + 7 -2.7966666508020417e+01 7.5236069073889087e+02 2.2361496241927412e+02 + 8 -4.5111760305783793e+02 -7.5964283923529649e+02 5.4706079650828394e+02 + 9 -5.4529860763932426e+01 -1.1514700182921584e+02 -6.1072385046215936e+02 + 10 7.4862939976770872e+02 7.0186661348181474e+02 -4.9819561459738873e+02 + 11 -1.7494394969871200e+02 1.5340687599694837e+02 3.9081626703289965e+02 + 12 -3.9358312970091794e+02 5.6274665057347477e+02 -5.1224538085321569e+02 + 13 2.9404872039289216e+02 -4.1648066419757220e+02 -6.7895091673892443e+02 + 14 -7.6412736229855261e+02 7.3381419408408351e+02 7.2060349009373454e+02 + 15 -9.1188029163924611e+01 2.2490090029079605e+02 2.8443310717374794e+02 + 16 1.7907756080568018e+02 -5.3544068903130574e+02 -3.1855438392210698e+02 + 17 -4.2820318907453810e+02 -4.9150915293516965e+02 -2.7061339095599510e+02 + 18 3.9507972025808846e+02 3.0616541906586320e+02 -1.3212280414079205e+01 + 19 -2.0363962356023470e+02 -5.4701814774882749e+01 5.8106403056946442e+02 + 20 -1.1592364758393782e+02 -7.6200034927300533e+02 -2.2311267090750425e+02 + 21 6.5874197707774010e+02 5.8671317647442959e+02 -6.2485321303824526e+02 + 22 5.6130517507797556e+01 2.6140892528389855e+02 3.7386575970447035e+02 + 23 -2.5299257398929777e+02 -4.6609521134971027e+02 -6.7084252639302156e+02 + 24 -6.2705843589319295e+02 2.7853441524212917e+02 4.5718463919078789e+02 + 25 -5.4238734235367690e+02 -1.0531270101702430e+02 6.9117489068344412e+01 + 26 -2.1345915011344562e+02 -5.3434527006701376e+02 2.4411036851185833e+02 + 27 5.9521552597388666e+02 6.2653737623484346e+02 -7.3671983911804250e+02 + 28 -4.0055307105324795e+02 6.0663543365768567e+02 1.2166334154134992e+02 + 29 -3.4766103922450350e+02 -3.6579202841754528e+02 -5.4163313640886042e+02 + 30 -1.0497979992230407e+02 5.0013611118729921e+02 7.3143219087443822e+02 + 31 7.5485601121507784e+02 -3.4937642162718980e+01 -7.2609068317269532e+02 + 32 1.4002854794615413e+02 6.4308196079778111e+02 -5.3558520115603778e+02 +run_torque: |2 + 1 7.5000000000000011e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 2 2.5000000000000001e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 3 7.5000000000000011e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 4 2.5000000000000001e-02 -1.4999999999999999e-02 1.0000000000000000e-02 + 5 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 6 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 7 7.5000000000000011e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 8 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 9 7.5000000000000011e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 10 2.5000000000000001e-02 -1.4999999999999999e-02 1.0000000000000000e-02 + 11 7.5000000000000011e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 12 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 13 2.5000000000000001e-02 -1.4999999999999999e-02 1.0000000000000000e-02 + 14 2.5000000000000001e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 15 7.5000000000000011e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 16 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 17 2.5000000000000001e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 18 2.5000000000000001e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 19 7.5000000000000011e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 20 2.5000000000000001e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 21 7.5000000000000011e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 22 2.5000000000000001e-02 -1.4999999999999999e-02 1.0000000000000000e-02 + 23 7.5000000000000011e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 24 7.5000000000000011e-02 -4.4999999999999998e-02 1.0000000000000000e-02 + 25 7.5000000000000011e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 26 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 27 7.5000000000000011e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 28 2.5000000000000001e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 29 2.5000000000000001e-02 -1.4999999999999999e-02 2.9999999999999999e-02 + 30 7.5000000000000011e-02 -1.4999999999999999e-02 1.0000000000000000e-02 + 31 7.5000000000000011e-02 -4.4999999999999998e-02 2.9999999999999999e-02 + 32 7.5000000000000011e-02 -1.4999999999999999e-02 1.0000000000000000e-02 +... diff --git a/unittest/force-styles/tests/fix-timestep-wall_gran.yaml b/unittest/force-styles/tests/fix-timestep-wall_gran.yaml new file mode 100644 index 00000000000..3347335903c --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-wall_gran.yaml @@ -0,0 +1,119 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 13:09:55 2026 +epsilon: 5e-14 +timestep: 1e-05 +skip_tests: +prerequisites: | + atom sphere + fix wall/gran + fix nve/sphere +pre_commands: | + boundary p p f +post_commands: | + fix move all nve/sphere + fix test all wall/gran hooke/history 1000.0 NULL 5.0 NULL 0.5 1 zplane -1.6 1.6 shear x 0.5 +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +run_pos: |2 + 1 7.7546440659153526e-01 -1.4837934370138892e+00 1.0548108254222370e+00 + 2 -1.5572804766855499e+00 2.2440765312689921e+00 4.2083881072123192e-01 + 3 -1.1731037605532570e+00 -2.6316209443970613e+00 -1.2267589847175293e+00 + 4 2.0393469515174925e-01 1.3549967858329008e+00 -1.1823449252284592e+00 + 5 -2.4570979896790890e+00 -1.6121456351707033e+00 -1.1644033183521219e+00 + 6 -1.1857880600896276e+00 -2.6338075046162474e-01 5.7612115046071499e-01 + 7 1.1923776232830339e+00 5.5232751769829702e-01 -4.9894036641820894e-01 + 8 1.7981132417520203e+00 1.4553236081399410e+00 8.7608738659216409e-02 + 9 -5.4503260164464351e-01 2.2303139535129022e+00 4.7529062047582760e-01 + 10 -3.3733551003851414e-01 8.1275201779654005e-01 -2.7219954351216979e-01 + 11 -7.3238897068429587e-01 1.1710139350460080e+00 2.4076619518864387e-01 + 12 9.9103749281334497e-01 2.2379442008801953e-01 2.5801484520748763e-01 + 13 -1.4015561758882811e+00 -2.4389749695261433e+00 1.6369481427184596e-01 + 14 -1.8043672004618472e+00 1.6799022953534217e+00 1.3720625674702208e-01 + 15 -9.9810864652318265e-01 -2.6308875314578106e+00 -1.1720611245812744e+00 + 16 2.7091978623570081e+00 3.6997377446234342e-01 1.2936830968035185e-01 + 17 -1.5837106363433748e+00 -5.7352145023016443e-01 -6.4674191597128683e-01 + 18 -2.2835884662021209e+00 -2.5976683213304415e+00 -1.9103779578329258e-01 + 19 2.1427302450132122e+00 1.6051716796458955e+00 -1.1789094593562743e+00 + 20 2.1931352615377353e+00 8.2994473157947335e-02 1.3180132353143812e+00 + 21 -1.3973402031100555e+00 -1.4812002952528573e+00 -4.9780609927805544e-02 + 22 -1.0612457814763101e+00 6.5593718588763295e-01 -7.2147086025343077e-01 + 23 -5.8220279354926419e-01 1.8326837459899510e+00 -1.0003947644120017e+00 + 24 -2.1542164877136747e+00 -2.2249662954852587e+00 1.4979733727918695e-01 + 25 -9.1174533088867826e-01 -1.5483154137213487e-01 -8.9804782385995452e-01 + 26 -4.8234856338840726e-01 8.0592901528471164e-02 -3.6316009748482631e-01 + 27 -1.0002391952997578e+00 2.4315602542195593e+00 1.1450698806088269e+00 + 28 2.4686542495060566e+00 -6.7947751804986989e-01 4.9384134383743583e-01 + 29 -1.4438972629333933e+00 -1.7359222032650703e+00 7.8950093713602354e-01 + 30 -6.4545040649941110e-01 5.1114484747583278e-01 -2.6979804469057810e-02 + 31 8.8292104080601597e-01 -4.4434057119627024e-01 2.8008022397678439e-01 + 32 2.1973765477051446e+00 1.6255396919102387e+00 -5.9786651874482809e-02 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0990461215728931e+02 6.6548415953906704e+02 -5.8318801588006818e+02 + 4 3.9840659188006333e+02 -1.1746860688104692e+02 -3.7609806608202183e+02 + 5 5.8450503632207892e+02 1.5979637817293187e+02 -1.9960206590564445e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1144889886041724e+01 2.2488791049789279e+02 2.8433164166942584e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0355178512433508e+02 -5.4671644098844922e+01 5.8084679195277215e+02 + 20 -1.1591907974839575e+02 -7.6197512349347926e+02 -2.2306223245151426e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9515564023746322e+02 6.2642213027136154e+02 -7.3644071253472839e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 3 -2.1721139577636569e+02 -1.3439350350070347e+02 0.0000000000000000e+00 + 4 3.3155605237739081e+01 2.6467994391185931e+02 0.0000000000000000e+00 + 5 -1.1317745444789655e+02 9.3405516165312406e+01 0.0000000000000000e+00 + 6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 15 -5.5570717282400196e+01 -1.5715993378914203e+02 0.0000000000000000e+00 + 16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 19 9.8545346197687138e+01 -2.9437634835171548e+02 0.0000000000000000e+00 + 20 -8.8997137922838036e+01 2.1223910560606949e+01 0.0000000000000000e+00 + 21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 27 4.1559462115008648e+02 -2.1038558857750255e+02 0.0000000000000000e+00 + 28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +... From afe6134ff1b2ae49ccc68a04f577ffe7e5ed6295 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 14:32:46 +0000 Subject: [PATCH 043/120] KOKKOS: refresh the partner views after growing them in fix neigh/history The harvest of the neighbor history retries when an atom has more partners than fit, and grows the two dual views before the retry. Growing a dual view reallocates it, but the device views cached in the class still pointed at the old, narrower allocation, so the retry wrote past the end of a row and into the next one. The history was then restored for the wrong partners, which changed the forces of the granular pair styles with history by order one at the first neighbor list rebuild in which any atom has more than eight contacts. Systems whose atoms never exceed the initial number of partners are not affected, which is why this went unnoticed. Also write the masked neighbor index back into the neighbor list rather than into the array of touch flags, as the plain version does. Add references for pair gran/hooke/history and gran/hertz/history, which reproduce the wrong forces without the fix. --- src/KOKKOS/fix_neigh_history_kokkos.cpp | 9 +- .../tests/atomic-pair-gran_hertz_history.yaml | 110 ++++++++++++++++++ .../tests/atomic-pair-gran_hooke_history.yaml | 110 ++++++++++++++++++ 3 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 unittest/force-styles/tests/atomic-pair-gran_hertz_history.yaml create mode 100644 unittest/force-styles/tests/atomic-pair-gran_hooke_history.yaml diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index ea9cf5324da..b8ed571545f 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -139,6 +139,13 @@ void FixNeighHistoryKokkos::pre_exchange_no_newton() maxpartner += 8; memoryKK->grow_kokkos(k_partner,partner,atom->nmax,maxpartner,"neighbor_history:partner"); memoryKK->grow_kokkos(k_valuepartner,valuepartner,atom->nmax,dnum*maxpartner,"neighbor_history:valuepartner"); + + // grow_kokkos() reallocates the dual views, so the device views cached in + // this class are stale and must be refreshed before the loop runs again, + // otherwise the retry writes past the end of the old, narrower rows + + d_partner = k_partner.template view(); + d_valuepartner = k_valuepartner.template view(); } } @@ -258,7 +265,7 @@ void FixNeighHistoryKokkos::operator()(TagFixNeighHistoryPostNeighbo if (use_bit_flag) { rflag = histmask(j) | beyond_contact; j &= HISTMASK; - d_firstflag(i,jj) = j; + d_neighbors(i,jj) = j; } else { rflag = 1; } diff --git a/unittest/force-styles/tests/atomic-pair-gran_hertz_history.yaml b/unittest/force-styles/tests/atomic-pair-gran_hertz_history.yaml new file mode 100644 index 00000000000..95ea47baa06 --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-gran_hertz_history.yaml @@ -0,0 +1,110 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 13:12:32 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + pair gran/hertz/history + atom sphere +pre_commands: | + variable newton_pair delete + variable newton_pair index off + variable newton_bond delete + variable newton_bond index off + newton off off + atom_modify map array + units lj + atom_style sphere + comm_modify vel yes + lattice fcc 0.8442 + region box block 0 2 0 2 0 2 + create_box 1 box + create_atoms 1 box + displace_atoms all random 0.05 0.05 0.05 623426 + set group all diameter 1.25 + set group all mass 1.0 + velocity all create 3.0 4534624 loop geom +post_commands: | + newton off off +input_file: in.empty +pair_style: gran/hertz/history 1000.0 350.0 50.0 30.0 0.5 1 limit_damping +pair_coeff: | + * * +extract: "" +natoms: 32 +init_vdwl: 0 +init_coul: 0 +init_stress: |2- + 9.6863922713684155e+02 9.3639928059597401e+02 9.1861558008771885e+02 3.6858050135871601e+01 4.7694326243056395e+01 -2.3275265498357545e+01 +init_forces: |2 + 1 -1.2707550735682150e+02 -3.3095381473400927e+01 5.2762060546400107e+01 + 2 3.3291371496586741e+01 9.5878979249923830e+01 2.9763507967177283e+00 + 3 4.5906190698232017e+01 -8.9565932660829986e+01 2.7966058684188980e+01 + 4 2.3537915930406736e+01 7.3324028177451893e+01 -6.9370392061428108e+00 + 5 2.9753810121605728e+01 -1.3922631582350908e+01 -6.8125013173850803e+01 + 6 2.4494950050957655e+01 -4.9347677526016334e+01 1.2764764429845101e+01 + 7 -3.7229318815914510e+01 -4.7777309336267209e+01 -8.1598794613999015e+00 + 8 -8.4237412625543314e+01 -9.5983075189087415e+01 4.7326366934836301e+01 + 9 1.4734143481863352e+01 -8.6011189871172551e+00 2.9523893156354330e+01 + 10 3.3391865695671733e+01 3.3308294746240598e+01 -2.0581394237094877e+01 + 11 -8.1369792424781792e+01 -6.2079016492958274e+01 -2.7359201743341401e+00 + 12 -1.9347316438296772e+01 5.0232447080687521e+01 -2.1209871465111661e+01 + 13 -4.3976708838885060e+01 6.5969797642465817e+00 -2.1816987182668345e+01 + 14 2.8348785467424342e+01 3.1889327093843441e+01 -3.2744369600869767e+01 + 15 1.3730493899992160e+02 1.2517650766874975e+02 -2.8361794140439965e+01 + 16 1.3711946084509098e+01 1.7859399347319883e+01 -2.6896489385320326e+01 + 17 -5.5127829142110762e+01 1.2805122284934132e+01 1.6490550763386533e+01 + 18 2.9900483379446509e+01 1.4766950804822201e+01 1.1135040658359896e+01 + 19 1.3946931061981013e+02 -4.0338747904246716e+01 -1.0627292067343861e+00 + 20 -1.5167822547361247e+01 4.5469895975864517e+01 -5.0981001108388810e+01 + 21 1.3382679547379109e+01 7.1586540224097375e+00 3.6937366581209261e+01 + 22 6.9270144120269478e+01 -2.7494527107266855e+01 2.3211276268211698e+01 + 23 -1.5320296939166784e+01 1.0024028715453856e+01 2.5970428454432842e+01 + 24 -7.4685062399785295e+01 -6.1492563222457655e+00 -6.8856554781668081e+01 + 25 -6.1959221710933924e+01 -2.0103354125160585e+01 2.0229272726462433e+01 + 26 4.6161479825314849e+01 4.3968472109474583e+01 8.8070129839162774e+01 + 27 -1.0563882605020696e+01 1.5277800026864334e+01 -5.0318108463328869e+01 + 28 2.4896180534744317e+01 -9.3589909112382827e+01 3.1638709427470076e+01 + 29 -6.7238345052340577e+01 -2.1483605978014211e+01 8.7256468666121407e+01 + 30 -3.6482359035549997e+01 -1.5070592889645031e+01 -5.3933460967879284e+01 + 31 3.1470777332449220e+01 6.7900395425274542e+00 -6.5119138392439297e+01 + 32 -9.2460974540798020e+00 3.4075210076176162e+01 1.3581013014511729e+01 +run_vdwl: 0 +run_coul: 0 +run_stress: |2- + 9.6654445683288588e+02 9.4653876205599556e+02 9.1118365598209539e+02 4.8265961305583609e+01 4.7017622337953668e+01 -4.7827205608374207e+01 +run_forces: |2 + 1 -1.3569117357535399e+02 -2.8556841404598554e+01 5.5800415731719475e+01 + 2 2.6093524529182183e+01 1.1661808629131475e+02 -2.5796005472043166e+00 + 3 6.2299560145913148e+01 -9.7268307632675928e+01 1.6215874223929863e+01 + 4 3.3329937979475567e+01 6.2696680103379251e+01 -1.8291643026509568e+00 + 5 3.6443027578301965e+01 -1.8058307010178318e+01 -7.0614120039656754e+01 + 6 2.2645380349159840e+01 -4.2033171190621005e+01 9.3164193573932828e+00 + 7 -2.6650259295032040e+01 -5.5836080303384009e+01 -1.2615477446929926e+01 + 8 -9.4833038087314847e+01 -9.8993196979197080e+01 5.5098669919706154e+01 + 9 1.7010947538784944e+01 -1.8870208829910055e+01 5.4227440312278908e+01 + 10 2.9376967775128119e+01 3.7677854439642289e+01 -2.8886557721186971e+01 + 11 -8.4296704864543486e+01 -6.8129683476419160e+01 5.0389922308898285e+00 + 12 7.7053948601306406e+00 6.5610407068643724e+01 -3.5422423563402212e+01 + 13 -4.2500405098019982e+01 5.2843048246411728e+00 -2.0601075684546636e+01 + 14 1.5732352160406364e+01 3.1098173551156847e+01 -4.1150344157991682e+01 + 15 1.4126301959976024e+02 1.2888992653760562e+02 -2.7203806489443007e+01 + 16 5.2630173875112840e+00 1.4985758436283207e+01 -3.5213380114502407e+01 + 17 -6.4167641944398696e+01 2.3254760083712267e+01 2.0302066060599852e+01 + 18 4.8228681429853381e+01 3.5708779121137944e+01 7.7611769060016078e+00 + 19 1.4253647857282212e+02 -4.3623448797132930e+01 2.7739948757002564e+00 + 20 -6.3023258275385157e+00 2.3962320022168193e+01 -4.1516969308919201e+01 + 21 2.0662813156354254e-01 8.1330255242050651e+00 4.6915578222477421e+01 + 22 8.0175165720064442e+01 -2.2027673272336024e+01 1.9212727822222803e+01 + 23 -1.2997337864060215e+01 4.5266023629635725e+00 2.5517664367827116e+01 + 24 -9.1889381257306823e+01 2.4370902618274535e+00 -7.5377794014985028e+01 + 25 -9.4424047395553885e+01 -3.4912689386240551e+01 1.4555527308163038e+01 + 26 5.4022433249209037e+01 4.6580884529114826e+01 9.5764506621592645e+01 + 27 -2.2523919012409291e+01 2.1746375085165063e+01 -5.9516814456454597e+01 + 28 2.4181965014933105e+01 -9.4156283002707752e+01 3.1666531941225575e+01 + 29 -7.4968221307411469e+01 -2.7810469600755155e+01 9.1779207241193021e+01 + 30 -3.6211121819465539e+01 -1.6827676208479474e+01 -5.1074230389653366e+01 + 31 4.0668169006082451e+01 -2.6704325846989985e+00 -5.8339624415752048e+01 + 32 2.7292632012680529e-01 4.0563441436373935e+01 9.9945895103586562e+00 +... diff --git a/unittest/force-styles/tests/atomic-pair-gran_hooke_history.yaml b/unittest/force-styles/tests/atomic-pair-gran_hooke_history.yaml new file mode 100644 index 00000000000..e64a214bb9b --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-gran_hooke_history.yaml @@ -0,0 +1,110 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 12:56:03 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + pair gran/hooke/history + atom sphere +pre_commands: | + variable newton_pair delete + variable newton_pair index off + variable newton_bond delete + variable newton_bond index off + newton off off + atom_modify map array + units lj + atom_style sphere + comm_modify vel yes + lattice fcc 0.8442 + region box block 0 2 0 2 0 2 + create_box 1 box + create_atoms 1 box + displace_atoms all random 0.05 0.05 0.05 623426 + set group all diameter 1.25 + set group all mass 1.0 + velocity all create 3.0 4534624 loop geom +post_commands: | + newton off off +input_file: in.empty +pair_style: gran/hooke/history 1000.0 NULL 50.0 NULL 0.5 1 limit_damping +pair_coeff: | + * * +extract: "" +natoms: 32 +init_vdwl: 0 +init_coul: 0 +init_stress: |2- + 5.3375876719083908e+03 5.2784836048321604e+03 5.0224009120050750e+03 1.3323417196060820e+01 2.3654044655962502e+02 -1.4541675602817094e+02 +init_forces: |2 + 1 -5.9545283279461671e+02 -5.2004044859781949e+01 2.2686066449098905e+02 + 2 3.0689575557511375e+01 4.9779235272267613e+02 4.3488409770844655e+01 + 3 3.1560729496086208e+02 -4.7146936282015702e+02 1.1142071653401075e+02 + 4 1.1506383417133189e+02 2.5895109280663422e+02 3.3669657218556161e+01 + 5 1.9604189714926198e+02 -2.2096288378670360e+02 -3.6420484564951687e+02 + 6 1.2511489713182307e+02 -1.7108457396512662e+02 -9.0077055658028939e+00 + 7 -9.7217450902554447e+01 -2.7416701859948296e+02 -2.7028407549846065e+01 + 8 -4.1985523144977526e+02 -3.4235141761279681e+02 2.0734836750627977e+02 + 9 8.6534619503281675e+01 -4.3690096667701070e+01 2.1536173541432822e+02 + 10 1.5402077378500201e+02 2.0303809078518557e+02 -1.7369188596376929e+02 + 11 -3.8180431357852473e+02 -3.4191953577333010e+02 1.9977647211923880e+01 + 12 6.8801405123919039e+00 2.8490640539220914e+02 -1.3733565647720249e+02 + 13 -1.6515665346321754e+02 -1.7689941718881812e+01 -2.9433245576211455e+01 + 14 6.4336125265260463e+01 1.4686584268263152e+02 -1.7920324163291616e+02 + 15 5.4627637650648808e+02 5.6804394301469449e+02 -1.5041049129658225e+02 + 16 8.2211757628876086e+01 1.0792012720170443e+02 -1.6425614076644425e+02 + 17 -3.6941434888323465e+02 1.7581990718007742e+02 1.9697400828549654e+00 + 18 2.0889752617458421e+02 1.9209267577167145e+02 5.6369086540872914e+01 + 19 6.5199306076112225e+02 -2.0042179082815827e+02 1.6417125979107148e+00 + 20 -3.2203651949808517e+01 1.4898119622302005e+02 -2.0938378663942311e+02 + 21 2.7239353671144620e+01 3.5316493711933063e+01 1.4390926697586329e+02 + 22 3.5297552243239494e+02 -2.2874734186086854e+01 8.9241932868323204e+01 + 23 -3.0763123936158621e+01 -1.1840825729470737e+02 2.0960478045862365e+02 + 24 -4.2221706863410395e+02 1.2334039949702415e+01 -3.2983493605400918e+02 + 25 -4.2442833491228492e+02 -2.0885637728961592e+02 1.2869788075732845e+02 + 26 2.5669953453439462e+02 1.9501665025735420e+02 4.6041809285845494e+02 + 27 -9.0065037528808475e+01 7.5079753603289106e+01 -2.6584821411587092e+02 + 28 7.2687713545948029e+01 -4.9467628789978448e+02 1.3927955228570335e+02 + 29 -3.1321957443716468e+02 -1.6045737009227537e+02 4.5112638612296627e+02 + 30 -1.4128249693704274e+02 -7.2974105268843317e+01 -2.1065612592507992e+02 + 31 1.8233092147290995e+02 2.3457836034782794e+01 -3.0887069983523617e+02 + 32 7.4791946427077871e+00 2.8839139132586831e+02 1.8779753352076280e+01 +run_vdwl: 0 +run_coul: 0 +run_stress: |2- + 5.2393833296160392e+03 5.2785208555942609e+03 4.9156440586580911e+03 -3.8361843258480960e+01 2.5953288826633826e+02 -1.9796810251060694e+02 +run_forces: |2 + 1 -5.9058367571986628e+02 -5.0122721500868984e+01 2.1308316817875499e+02 + 2 -9.0275605961204555e+00 5.8535918686491402e+02 3.0112572721086650e+00 + 3 3.4873317469487938e+02 -4.7019600752100826e+02 7.2985280175559808e+01 + 4 1.7530133526398572e+02 1.8954091181834218e+02 5.4111484540318202e+01 + 5 2.3376919963615802e+02 -2.3317768163732160e+02 -3.7340680660272608e+02 + 6 1.1299826259778298e+02 -1.5566361883407276e+02 -1.0337405874394072e+01 + 7 -6.4601546105707030e+01 -2.7814573914791185e+02 -1.6223551513012453e+01 + 8 -4.5828180133232820e+02 -3.5335244402477309e+02 2.5210713346236506e+02 + 9 8.8377608138549903e+01 -7.3403795502098617e+01 2.9896856520615194e+02 + 10 1.3492375220453360e+02 2.0881699868921990e+02 -1.7177989034870012e+02 + 11 -3.8226744496241594e+02 -3.5375556969451543e+02 6.2381263282148709e+01 + 12 5.4423747141022019e+01 3.3012034940388764e+02 -1.8759896181260180e+02 + 13 -1.5143568335935612e+02 -2.4397328948384597e+01 -2.4970109152246607e+01 + 14 2.2171836578390810e+01 1.6892764239756758e+02 -2.4052139732527132e+02 + 15 5.2739720349680306e+02 5.5056841582961965e+02 -1.4386283059857863e+02 + 16 2.5381489585179523e+01 8.2349235796156819e+01 -2.0286231500340244e+02 + 17 -3.6083083373546236e+02 1.9210076241443119e+02 -7.2677823841827021e+00 + 18 2.4018530987985633e+02 2.2853661755250653e+02 3.5782376999545392e+01 + 19 6.5297348205795265e+02 -2.1711454223678615e+02 3.7480800539279677e+01 + 20 8.3476010584013416e+00 6.2739218061456178e+01 -1.5588149396687152e+02 + 21 -4.6147645673601616e+01 5.0635090734151021e+01 2.0443682311011415e+02 + 22 4.2017079994512937e+02 1.4020620194454937e+01 6.4843566038303976e+01 + 23 -8.2960719013636890e+00 -1.6231984517279380e+02 1.8723815759247748e+02 + 24 -5.2757850199795917e+02 6.0387688294584763e+01 -3.7015611974823105e+02 + 25 -4.4550171854965294e+02 -1.9610602944534367e+02 9.4299540885877278e+01 + 26 2.8446221994270928e+02 1.9910585505555741e+02 4.8691906351304880e+02 + 27 -1.7294488334825428e+02 1.2780573432197014e+02 -3.1935505182545523e+02 + 28 6.7381143388374142e+01 -4.8272070042169076e+02 1.3527079804180431e+02 + 29 -3.0337421095631339e+02 -1.5980604581651576e+02 4.3111753388242590e+02 + 30 -1.4003096734516566e+02 -8.1060570230495642e+01 -1.8398182596346257e+02 + 31 2.3046506083888278e+02 -3.3850043333317153e+01 -2.6033123692435782e+02 + 32 3.3439319134976209e+01 2.7417835603907713e+02 3.4499966323211872e+01 +... From 22ebeb45220b477a36778b748a7257c838c3eaf3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 14:50:03 +0000 Subject: [PATCH 044/120] KOKKOS: fix special_bonds handling and self energy in the coul/dsf pair styles pair coul/dsf/kk and lj/cut/coul/dsf/kk scaled the complete damped shifted force interaction by the special_bonds coulomb factor. The CPU styles instead subtract only the excluded bare Coulomb part, forcecoul -= (1.0-factor_coul)*prefactor so that the damping and shifting terms are always applied in full. With any non-unit special_bonds coulomb factor -- the default 0.0 0.0 0.0 of a molecular system included -- the accelerated styles therefore produced different forces and energies than the styles they accelerate. pair born/coul/dsf/kk already used the correct convention; follow it in the other two. lj/cut/coul/dsf/kk additionally tallied the per-atom self energy in a host loop that ran even when no energy was requested, indexed the charge array with the neighbor list position instead of the atom index, and never added the self energy to the per-atom energy. Replace it with a device kernel that mirrors the ev_tally(i,i,...) call of the CPU style, giving both a correct total and a correct eatom. Both fixtures skipped all KOKKOS test cases; they now run and agree with the CPU reference data at the unchanged 1e-12 tolerance. --- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 6 +- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp | 55 +++++++++++++++---- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.h | 7 +++ .../force-styles/tests/mol-pair-coul_dsf.yaml | 2 +- .../tests/mol-pair-lj_cut_coul_dsf.yaml | 2 +- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index ddcb9eb21b0..2b1de2f3ca2 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -257,12 +257,13 @@ void PairCoulDSFKokkos::operator()(TagPairCoulDSFKernelA(1.0)/rsq; const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT prefactor = factor_coul * qqrd2e*qtmp*q[j]/r; + const KK_FLOAT prefactor = qqrd2e*qtmp*q[j]/r; const KK_FLOAT erfcd = Kokkos::exp(-alpha_kk*alpha_kk*rsq); const KK_FLOAT t = static_cast(1.0) / (static_cast(1.0) + static_cast(EWALD_P)*alpha_kk*r); const KK_FLOAT erfcc = t * (static_cast(A1)+t*(static_cast(A2)+t*(static_cast(A3)+t*(static_cast(A4)+t*static_cast(A5))))) * erfcd; - const KK_FLOAT forcecoul = prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + + KK_FLOAT forcecoul = prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + r*f_shift_kk) * r; + if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; const KK_FLOAT fpair = forcecoul * r2inv; fxtmp += static_cast(delx*fpair); @@ -279,6 +280,7 @@ void PairCoulDSFKokkos::operator()(TagPairCoulDSFKernelA(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; ev.ecoul += static_cast((((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(1.0):static_cast(0.5))*ecoul); } diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp index d0cede05b53..0f392d7e7f3 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp @@ -124,12 +124,15 @@ void PairLJCutCoulDSFKokkos::compute(int eflag_in, int vflag_in) copymode = 1; - int inum = list->inum; + // self energy of every local atom, tallied in a device kernel so that the + // charges and the per-atom energy stay resident on the device - for (int ii = 0; ii < inum; ii ++) { - //int i = list->ilist[ii]; - double qtmp = atom->q[ii]; - eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qtmp*qtmp*static_cast(qqrd2e); + if (eflag) { + d_ilist = ((NeighListKokkos*) list)->d_ilist; + KK_ACC_FLOAT e_self_sum = 0.0; + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,list->inum), + *this,e_self_sum); + if (eflag_global) eng_coul += static_cast(e_self_sum); } ev = pair_compute,void > @@ -220,13 +223,17 @@ compute_fcoul(const KK_FLOAT& rsq, const int& /*i*/, const int&j, const KK_FLOAT f_shift_kk = static_cast(f_shift); const KK_FLOAT r2inv = static_cast(1.0)/rsq; const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT prefactor = factor_coul * qqrd2e * qtmp * q(j); + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) / r; const KK_FLOAT erfcd = Kokkos::exp(-alpha_kk*alpha_kk*rsq); const KK_FLOAT t = static_cast(1.0) / (static_cast(1.0) + static_cast(EWALD_P)*alpha_kk*r); const KK_FLOAT erfcc = t * (static_cast(A1)+t*(static_cast(A2)+t*(static_cast(A3)+t*(static_cast(A4)+t*static_cast(A5))))) * erfcd; - return prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + r*f_shift_kk) * - r2inv; + KK_FLOAT forcecoul = prefactor * + (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + r*f_shift_kk) * r; + if (factor_coul < static_cast(1.0)) + forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + + return forcecoul * r2inv; } /* ---------------------------------------------------------------------- @@ -245,13 +252,41 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int&j, const KK_FLOAT e_shift_kk = static_cast(e_shift); const KK_FLOAT f_shift_kk = static_cast(f_shift); const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT prefactor = factor_coul * qqrd2e * qtmp * q(j); + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) / r; const KK_FLOAT erfcd = Kokkos::exp(-alpha_kk*alpha_kk*rsq); const KK_FLOAT t = static_cast(1.0) / (static_cast(1.0) + static_cast(EWALD_P)*alpha_kk*r); const KK_FLOAT erfcc = t * (static_cast(A1)+t*(static_cast(A2)+t*(static_cast(A3)+t*(static_cast(A4)+t*static_cast(A5))))) * erfcd; - return prefactor * (erfcc - r*e_shift_kk - rsq*f_shift_kk) / r; + KK_FLOAT ecoul = prefactor * (erfcc - r*e_shift_kk - rsq*f_shift_kk); + if (factor_coul < static_cast(1.0)) + ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + + return ecoul; + +} + +/* ---------------------------------------------------------------------- + self energy contribution of atom i (damped shifted force, see Fennell and + Gezelter, JCP 124, 234104 (2006)); mirrors the ev_tally(i,i,...) call in + PairLJCutCoulDSF::compute() + ---------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +void PairLJCutCoulDSFKokkos::operator()(TagPairLJCutCoulDSFSelfEnergy, + const int &ii, KK_ACC_FLOAT &e_self_sum) const +{ + const KK_FLOAT alpha_kk = static_cast(alpha); + const KK_FLOAT e_shift_kk = static_cast(e_shift); + + const int i = d_ilist[ii]; + const KK_FLOAT qtmp = q(i); + const KK_FLOAT e_self = -(e_shift_kk/static_cast(2.0) + + alpha_kk/static_cast(MY_PIS)) * qtmp*qtmp*qqrd2e; + if (eflag_global) e_self_sum += static_cast(e_self); + if (eflag_atom) d_eatom[i] += static_cast(e_self); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.h b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.h index b448018e24d..1d3271687c8 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.h +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.h @@ -29,6 +29,8 @@ PairStyle(lj/cut/coul/dsf/kk/host,PairLJCutCoulDSFKokkos); namespace LAMMPS_NS { +struct TagPairLJCutCoulDSFSelfEnergy{}; + template class PairLJCutCoulDSFKokkos : public PairLJCutCoulDSF { public: @@ -44,6 +46,10 @@ class PairLJCutCoulDSFKokkos : public PairLJCutCoulDSF { void init_style() override; double init_one(int, int) override; + // NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + void operator()(TagPairLJCutCoulDSFSelfEnergy, const int&, KK_ACC_FLOAT&) const; + protected: template // NOLINTNEXTLINE @@ -83,6 +89,7 @@ class PairLJCutCoulDSFKokkos : public PairLJCutCoulDSF { typename AT::t_kkacc_1d_3 f; typename AT::t_int_1d_randomread type; typename AT::t_kkfloat_1d_randomread q; + typename AT::t_int_1d_randomread d_ilist; DAT::ttransform_kkacc_1d k_eatom; DAT::ttransform_kkacc_1d_6 k_vatom; diff --git a/unittest/force-styles/tests/mol-pair-coul_dsf.yaml b/unittest/force-styles/tests/mol-pair-coul_dsf.yaml index 4a078c1671f..b6dfa5c1b1b 100644 --- a/unittest/force-styles/tests/mol-pair-coul_dsf.yaml +++ b/unittest/force-styles/tests/mol-pair-coul_dsf.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:29 2022 epsilon: 1e-12 -skip_tests: kokkos_omp kokkos_serial kokkos_gpu +skip_tests: ! "" prerequisites: ! | atom full diff --git a/unittest/force-styles/tests/mol-pair-lj_cut_coul_dsf.yaml b/unittest/force-styles/tests/mol-pair-lj_cut_coul_dsf.yaml index 1d041d09b4c..66e75f5e87e 100644 --- a/unittest/force-styles/tests/mol-pair-lj_cut_coul_dsf.yaml +++ b/unittest/force-styles/tests/mol-pair-lj_cut_coul_dsf.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:31 2022 epsilon: 8e-14 -skip_tests: kokkos_omp kokkos_serial kokkos_gpu +skip_tests: ! "" prerequisites: ! | atom full From 641a1d3b9ea7c2935d51800b309f652c6a6b893c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:00:34 +0000 Subject: [PATCH 045/120] test: check single() against compute() with a non-unit special_bonds factor TEST(PairStyle, single) compared the result of Pair::single() with the forces computed by the pair style, but only after resetting all special_bonds exclusion factors to 1.0. The exclusion factors are applied by compute() and by single() in two independent pieces of code, and a pair style may scale the whole interaction by the factor or -- as the damped shifted force and Wolf styles do -- subtract only the excluded bare Coulomb part. With a unit factor the two conventions cannot be told apart, so a style using different ones in compute() and single() passed the test. Repeat the last comparison with "special_bonds lj/coul 0.25 1.0 1.0" for molecular systems (skipped for styles that reject the setting). That uncovered five styles whose single() disagreed with their own compute(): * lj/cut/coul/dsf and buck6d/coul/gauss/dsf scaled the complete damped shifted force interaction by the factor instead of subtracting the excluded part. * born/coul/dsf applied both conventions at once, on an already scaled prefactor. * coul/slater/long subtracted the excluded part without the Slater correction that compute() applies, and left out the "scale" factor of fix adapt. * buck/long/coul/long applied the factor twice to the exponential repulsion term of the cut dispersion branch, and added the energy offset instead of subtracting it. Pair::single() feeds compute group/group, pair_write, fix bond/react and the tabulation of pair styles, so these were wrong results, not just an internal inconsistency. --- src/EXTRA-PAIR/pair_born_coul_dsf.cpp | 2 +- src/EXTRA-PAIR/pair_coul_slater_long.cpp | 9 ++-- src/EXTRA-PAIR/pair_lj_cut_coul_dsf.cpp | 4 +- src/KSPACE/pair_buck_long_coul_long.cpp | 6 ++- src/MOFFF/pair_buck6d_coul_gauss_dsf.cpp | 4 +- unittest/force-styles/test_pair_style.cpp | 59 +++++++++++++++++++++++ 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/EXTRA-PAIR/pair_born_coul_dsf.cpp b/src/EXTRA-PAIR/pair_born_coul_dsf.cpp index 3a500ac0313..ca4565454a4 100644 --- a/src/EXTRA-PAIR/pair_born_coul_dsf.cpp +++ b/src/EXTRA-PAIR/pair_born_coul_dsf.cpp @@ -464,7 +464,7 @@ double PairBornCoulDSF::single(int i, int j, int itype, int jtype, if (rsq < cut_coulsq) { r = sqrt(rsq); - prefactor = factor_coul * force->qqrd2e * atom->q[i]*atom->q[j]/r; + prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; arg = alpha * r ; erfcd = MathSpecial::expmsq(arg); diff --git a/src/EXTRA-PAIR/pair_coul_slater_long.cpp b/src/EXTRA-PAIR/pair_coul_slater_long.cpp index 142b07e6b3d..6f0a7ba2ece 100644 --- a/src/EXTRA-PAIR/pair_coul_slater_long.cpp +++ b/src/EXTRA-PAIR/pair_coul_slater_long.cpp @@ -305,7 +305,7 @@ void PairCoulSlaterLong::read_restart_settings(FILE *fp) /* ---------------------------------------------------------------------- */ -double PairCoulSlaterLong::single(int i, int j, int /*itype*/, int /*jtype*/, double rsq, +double PairCoulSlaterLong::single(int i, int j, int itype, int jtype, double rsq, double factor_coul, double /*factor_lj*/, double &fforce) { double r2inv,r,grij,expm2,t,erfc,prefactor; @@ -319,13 +319,14 @@ double PairCoulSlaterLong::single(int i, int j, int /*itype*/, int /*jtype*/, do 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; + prefactor = force->qqrd2e * scale[itype][jtype] * 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; + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor*(1.0-slater_term); fforce = forcecoul * r2inv; phicoul = prefactor*(erfc - (1 + r/lamda)*exp(-2*r/lamda)); - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; + if (factor_coul < 1.0) + phicoul -= (1.0-factor_coul)*prefactor*(1.0-(1 + r/lamda)*exp(-2*r/lamda)); return phicoul; } diff --git a/src/EXTRA-PAIR/pair_lj_cut_coul_dsf.cpp b/src/EXTRA-PAIR/pair_lj_cut_coul_dsf.cpp index cea0d087d11..28487040a58 100644 --- a/src/EXTRA-PAIR/pair_lj_cut_coul_dsf.cpp +++ b/src/EXTRA-PAIR/pair_lj_cut_coul_dsf.cpp @@ -441,11 +441,12 @@ double PairLJCutCoulDSF::single(int i, int j, int itype, int jtype, double rsq, if (rsq < cut_coulsq) { r = sqrt(rsq); - prefactor = factor_coul * force->qqrd2e * atom->q[i]*atom->q[j]/r; + prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; erfcc = erfc(alpha*r); erfcd = exp(-alpha*alpha*r*r); forcecoul = prefactor * (erfcc/r + 2.0*alpha/MY_PIS * erfcd + r*f_shift) * r; + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; } else forcecoul = 0.0; fforce = (forcecoul + factor_lj*forcelj) * r2inv; @@ -459,6 +460,7 @@ double PairLJCutCoulDSF::single(int i, int j, int itype, int jtype, double rsq, if (rsq < cut_coulsq) { phicoul = prefactor * (erfcc - r*e_shift - rsq*f_shift); + if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; eng += phicoul; } diff --git a/src/KSPACE/pair_buck_long_coul_long.cpp b/src/KSPACE/pair_buck_long_coul_long.cpp index 02a42a8241e..de97c37003e 100644 --- a/src/KSPACE/pair_buck_long_coul_long.cpp +++ b/src/KSPACE/pair_buck_long_coul_long.cpp @@ -1062,10 +1062,12 @@ double PairBuckLongCoulLong::single(int i, int j, int itype, int jtype, force_buck = buck1[itype][jtype]*r*expr-g8term+t*buck2[itype][jtype]; eng += buck_a[itype][jtype]*expr-g6term+t*buck_c[itype][jtype]; } else { // cut + // expr already carries factor_buck, so the exponential term must not be + // scaled a second time (compare with the special case in compute()) force_buck = - factor_buck*(buck1[itype][jtype]*r*expr-buck2[itype][jtype]*r6inv); + buck1[itype][jtype]*r*expr-factor_buck*buck2[itype][jtype]*r6inv; eng += buck_a[itype][jtype]*expr- - factor_buck*(buck_c[itype][jtype]*r6inv-offset[itype][jtype]); + factor_buck*(buck_c[itype][jtype]*r6inv+offset[itype][jtype]); } } else force_buck = 0.0; diff --git a/src/MOFFF/pair_buck6d_coul_gauss_dsf.cpp b/src/MOFFF/pair_buck6d_coul_gauss_dsf.cpp index 81f284d7ce5..3a99b2ff916 100644 --- a/src/MOFFF/pair_buck6d_coul_gauss_dsf.cpp +++ b/src/MOFFF/pair_buck6d_coul_gauss_dsf.cpp @@ -546,12 +546,13 @@ double PairBuck6dCoulGaussDSF::single(int i, int j, int itype, int jtype, double } else forcebuck6d = 0.0; if (rsq < cut_coulsq) { - prefactor = factor_coul * force->qqrd2e * atom->q[i] * atom->q[j] / r; + prefactor = force->qqrd2e * atom->q[i] * atom->q[j] / r; arg = alpha_ij[itype][jtype]*r; erfcd = MathSpecial::expmsq(arg); erfcc = 1 - (MathSpecial::my_erfcx(arg) * erfcd); forcecoul = prefactor * ((erfcc/r) - (2.0/MY_PIS*alpha_ij[itype][jtype]*erfcd) + r*f_shift_ij[itype][jtype]) * r; + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; } else forcecoul = 0.0; fforce = (forcecoul + factor_lj*forcebuck6d) * r2inv; @@ -565,6 +566,7 @@ double PairBuck6dCoulGaussDSF::single(int i, int j, int itype, int jtype, double if (rsq < cut_coulsq) { phicoul = prefactor * (erfcc - r*e_shift_ij[itype][jtype] - rsq*f_shift_ij[itype][jtype]); + if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; eng += phicoul; } diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 5a436afc451..a23116c0252 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -1801,6 +1801,65 @@ TEST(PairStyle, single) } if (print_stats) std::cerr << "single_force stats:" << stats << std::endl; + // repeat the comparison with a non-unit special_bonds exclusion factor. + // the factors are applied by compute() and by single() independently, and + // the two implementations must agree. styles that subtract only the + // excluded part of the interaction instead of scaling the whole term (the + // coul/dsf and coul/wolf families, tabulated coulomb, ...) are easy to get + // wrong in one of the two places, and the unit factor used above cannot + // tell the two conventions apart. + + if (molecular == Atom::MOLECULAR) { + stats.reset(); + bool special_supported = true; + if (!verbose) ::testing::internal::CaptureStdout(); + try { + command("special_bonds lj/coul 0.25 1.0 1.0"); + command("run 0 post no"); + } catch (std::exception &) { + special_supported = false; + } + if (!verbose) ::testing::internal::GetCapturedStdout(); + + if (special_supported) { + splj = lmp->force->special_lj[1]; + spcl = lmp->force->special_coul[1]; + f = lmp->atom->f; + x = lmp->atom->x; + if (is_ellipsoid) tor = lmp->atom->torque; + idx1 = lmp->atom->map(1); + idx2 = lmp->atom->map(2); + delx = x[idx2][0] - x[idx1][0]; + dely = x[idx2][1] - x[idx1][1]; + delz = x[idx2][2] - x[idx1][2]; + rsq = delx * delx + dely * dely + delz * delz; + fsingle = 0.0; + + pair->single(idx1, idx2, 1, 2, rsq, spcl, splj, fsingle); + if (is_ellipsoid) { + EXPECT_NE(pair->svector, nullptr); + EXPECT_GE(pair->single_extra, 6); + if (pair->svector != nullptr && pair->single_extra >= 6) { + EXPECT_FP_LE_WITH_EPS(pair->svector[0], f[idx1][0], epsilon); + EXPECT_FP_LE_WITH_EPS(pair->svector[1], f[idx1][1], epsilon); + EXPECT_FP_LE_WITH_EPS(pair->svector[2], f[idx1][2], epsilon); + EXPECT_FP_LE_WITH_EPS(pair->svector[3], tor[idx1][0], epsilon); + EXPECT_FP_LE_WITH_EPS(pair->svector[4], tor[idx1][1], epsilon); + EXPECT_FP_LE_WITH_EPS(pair->svector[5], tor[idx1][2], epsilon); + } + } else { + EXPECT_FP_LE_WITH_EPS(f[idx1][0], -fsingle * delx, epsilon); + EXPECT_FP_LE_WITH_EPS(f[idx1][1], -fsingle * dely, epsilon); + EXPECT_FP_LE_WITH_EPS(f[idx1][2], -fsingle * delz, epsilon); + EXPECT_FP_LE_WITH_EPS(f[idx2][0], fsingle * delx, epsilon); + EXPECT_FP_LE_WITH_EPS(f[idx2][1], fsingle * dely, epsilon); + EXPECT_FP_LE_WITH_EPS(f[idx2][2], fsingle * delz, epsilon); + } + if (print_stats) std::cerr << "single_special stats:" << stats << std::endl; + } else if (print_stats) + std::cerr << "skipping single_special test: style rejects the factor\n"; + } + if ((test_config.pair_style.find("coul/dsf") != std::string::npos) && (test_config.pair_style.find("coul/wolf") != std::string::npos)) { stats.reset(); From 28c75ef7e931f8d198f5f15999d976c97d6ea2b0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:03:00 +0000 Subject: [PATCH 046/120] test: add fix halt, PHONON command and 2d enforce2d tests Three styles that the existing test suite never reached, each also run with the KOKKOS variants through the LAMMPS_ACCELERATOR_ARGS ctest entries: * fix halt stops a run when a criterion is met and therefore cannot be tested by the fixed step count force-style drivers. test_fix_halt checks the bondmax criterion in both directions and an equal-style variable criterion, including the step the run actually stops on. * dynamical_matrix and third_order write the second and third derivatives of the potential energy to a file. test_phonon_commands runs both on a two atom group of a Lennard-Jones fcc lattice, checks the size and symmetry of the force constant matrix and compares the largest matrix elements. * fix enforce2d needs a two dimensional system, which none of the existing input templates provides. Add in.2d/data.2d/coeffs.2d and a fixture that uses them. --- unittest/commands/CMakeLists.txt | 13 ++ unittest/commands/test_fix_halt.cpp | 142 +++++++++++++ unittest/commands/test_phonon_commands.cpp | 196 ++++++++++++++++++ unittest/force-styles/tests/coeffs.2d | 7 + unittest/force-styles/tests/data.2d | 91 ++++++++ .../tests/fix-timestep-enforce2d.yaml | 93 +++++++++ unittest/force-styles/tests/in.2d | 17 ++ 7 files changed, 559 insertions(+) create mode 100644 unittest/commands/test_fix_halt.cpp create mode 100644 unittest/commands/test_phonon_commands.cpp create mode 100644 unittest/force-styles/tests/coeffs.2d create mode 100644 unittest/force-styles/tests/data.2d create mode 100644 unittest/force-styles/tests/fix-timestep-enforce2d.yaml create mode 100644 unittest/force-styles/tests/in.2d diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index 076fdf91017..7966f5411aa 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -161,6 +161,19 @@ if(PKG_MOLECULE) target_link_libraries(test_compute_chunk PRIVATE lammps GTest::GMock) add_test(NAME ComputeChunk COMMAND test_compute_chunk) add_kokkos_test(NAME ComputeChunk COMMAND test_compute_chunk) + + add_executable(test_fix_halt test_fix_halt.cpp) + target_compile_definitions(test_fix_halt PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(test_fix_halt PRIVATE lammps GTest::GMock) + add_test(NAME FixHalt COMMAND test_fix_halt) + add_kokkos_test(NAME FixHalt COMMAND test_fix_halt) +endif() + +if(PKG_PHONON) + add_executable(test_phonon_commands test_phonon_commands.cpp) + target_link_libraries(test_phonon_commands PRIVATE lammps GTest::GMock) + add_test(NAME PhononCommands COMMAND test_phonon_commands) + add_kokkos_test(NAME PhononCommands COMMAND test_phonon_commands) endif() add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) diff --git a/unittest/commands/test_fix_halt.cpp b/unittest/commands/test_fix_halt.cpp new file mode 100644 index 00000000000..67d2772c753 --- /dev/null +++ b/unittest/commands/test_fix_halt.cpp @@ -0,0 +1,142 @@ +/* ---------------------------------------------------------------------- + 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 "../testing/core.h" + +#include "info.h" +#include "lammps.h" +#include "library.h" +#include "update.h" +#include "utils.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include + +// whether to print verbose output (i.e. not capturing LAMMPS screen output). +bool verbose = false; + +namespace LAMMPS_NS { + +using ::testing::ContainsRegex; + +#define STRINGIFY(val) XSTR(val) +#define XSTR(val) #val + +// fix halt stops a run when a criterion is met, so it cannot be checked with +// the fixed step count drivers in unittest/force-styles. the tests below run +// the same input with the plain and - through the LAMMPS_ACCELERATOR_ARGS +// setting of the FixHaltKokkos ctest entry - with the KOKKOS version of the +// fix and confirm that the run stops on the expected timestep. + +class FixHaltTest : public LAMMPSTest { +protected: + void SetUp() override + { + testbinary = "FixHaltTest"; + LAMMPSTest::SetUp(); + if (info->has_style("atom", "full")) { + BEGIN_HIDE_OUTPUT(); + command("variable input_dir index \"" STRINGIFY(TEST_INPUT_FOLDER) "\""); + command("include \"${input_dir}/in.fourmol\""); + command("fix move all nve"); + END_HIDE_OUTPUT(); + } + } +}; + +// the longest bond of the fourmol system is about 1.565 angstrom and the pair +// and bond styles of the input template are "zero", so the geometry hardly +// changes during the short run below. a limit of 1.5 angstrom is thus already +// exceeded at the first end-of-step check. + +TEST_F(FixHaltTest, BondmaxTriggers) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("fix stop all halt 1 bondmax > 1.5"); + END_HIDE_OUTPUT(); + auto output = CAPTURE_OUTPUT([&] { + command("run 10 post no"); + }); + + EXPECT_EQ(lmp->update->ntimestep, 1); + EXPECT_THAT(output, ContainsRegex("Fix halt condition for fix-id stop met on step 1")); +} + +// with a limit well above the longest bond the run must not be stopped early + +TEST_F(FixHaltTest, BondmaxDoesNotTrigger) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("fix stop all halt 1 bondmax > 2.0"); + command("run 10 post no"); + END_HIDE_OUTPUT(); + + EXPECT_EQ(lmp->update->ntimestep, 10); +} + +// an equal-style variable is only checked every "nevery" steps, so the run +// stops on step 6 and not on step 5, where the condition first becomes true + +TEST_F(FixHaltTest, VariableHalt) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("variable steps equal step"); + command("fix stop all halt 2 v_steps >= 5"); + END_HIDE_OUTPUT(); + auto output = CAPTURE_OUTPUT([&] { + command("run 20 post no"); + }); + + EXPECT_EQ(lmp->update->ntimestep, 6); + EXPECT_THAT(output, ContainsRegex("Fix halt condition for fix-id stop met on step 6")); +} + +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = LAMMPS_NS::utils::split_words(var); + for (auto arg : env) { + if (arg == "-v") verbose = true; + } + } + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + + lammps_kokkos_finalize(); + + MPI_Finalize(); + return rv; +} diff --git a/unittest/commands/test_phonon_commands.cpp b/unittest/commands/test_phonon_commands.cpp new file mode 100644 index 00000000000..99170decbb4 --- /dev/null +++ b/unittest/commands/test_phonon_commands.cpp @@ -0,0 +1,196 @@ +/* ---------------------------------------------------------------------- + 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 "../testing/core.h" +#include "../testing/utils.h" + +#include "info.h" +#include "lammps.h" +#include "library.h" +#include "utils.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include + +// whether to print verbose output (i.e. not capturing LAMMPS screen output). +bool verbose = false; + +namespace LAMMPS_NS { + +// the dynamical_matrix and third_order commands of the PHONON package compute +// the second and third derivatives of the potential energy by finite +// differences of the forces and write them to a file. the tests below use a +// two atom group of a perfect fcc lattice of Lennard-Jones particles, which +// keeps the output small, and are run a second time with the KOKKOS versions +// of the two commands through the LAMMPS_ACCELERATOR_ARGS setting of the +// PhononCommandsKokkos ctest entry. + +class PhononCommandsTest : public LAMMPSTest { +protected: + void SetUp() override + { + testbinary = "PhononCommandsTest"; + LAMMPSTest::SetUp(); + if (info->has_style("command", "dynamical_matrix")) { + BEGIN_HIDE_OUTPUT(); + command("units lj"); + command("atom_style atomic"); + command("atom_modify map array"); + command("boundary p p p"); + command("lattice fcc 0.8442"); + command("region box block 0 2 0 2 0 2"); + command("create_box 1 box"); + command("create_atoms 1 box"); + command("mass 1 1.0"); + command("pair_style lj/cut 1.2"); + command("pair_coeff 1 1 1.0 1.0"); + command("neighbor 0.3 bin"); + command("neigh_modify delay 0 every 1 check no"); + command("group two id 1 2"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + } + } + + // split a line of numbers into doubles + static std::vector numbers(const std::string &line) + { + std::vector values; + for (const auto &word : utils::split_words(line)) + values.push_back(std::stod(word)); + return values; + } +}; + +TEST_F(PhononCommandsTest, DynamicalMatrix) +{ + if (!info->has_style("command", "dynamical_matrix")) GTEST_SKIP(); + + const std::string outfile = "test_dynmat.dat"; + delete_file(outfile); + + BEGIN_HIDE_OUTPUT(); + command("dynamical_matrix two regular 1.0e-6 file " + outfile); + END_HIDE_OUTPUT(); + + ASSERT_FILE_EXISTS(outfile); + auto lines = read_lines(outfile); + + // one line of three columns for each degree of freedom of the group (3*2) + // and each atom of the group (2) + ASSERT_EQ((int)lines.size(), 12); + + // assemble the 6x6 force constant matrix of the group + double matrix[6][6]; + for (std::size_t n = 0; n < lines.size(); ++n) { + auto values = numbers(lines[n]); + ASSERT_EQ((int)values.size(), 3); + const int row = (int)n / 2; + const int col = ((int)n % 2) * 3; + for (int k = 0; k < 3; ++k) + matrix[row][col + k] = values[k]; + } + + // the force constant matrix must be symmetric + for (int i = 0; i < 6; ++i) + for (int j = 0; j < 6; ++j) + EXPECT_NEAR(matrix[i][j], matrix[j][i], 1.0e-6); + + // reference values of the perfect fcc lattice + EXPECT_NEAR(matrix[0][0], 68.86210274, 1.0e-6); + EXPECT_NEAR(matrix[1][1], 68.86210274, 1.0e-6); + EXPECT_NEAR(matrix[2][2], 68.86210274, 1.0e-6); + EXPECT_NEAR(matrix[0][3], -7.73672374, 1.0e-6); + EXPECT_NEAR(matrix[0][4], -5.99464554, 1.0e-6); + EXPECT_NEAR(matrix[2][5], -1.74207820, 1.0e-6); + EXPECT_NEAR(matrix[0][5], 0.0, 1.0e-6); + + delete_file(outfile); +} + +TEST_F(PhononCommandsTest, ThirdOrder) +{ + if (!info->has_style("command", "third_order")) GTEST_SKIP(); + + const std::string outfile = "test_thirdorder.dat"; + delete_file(outfile); + + BEGIN_HIDE_OUTPUT(); + command("third_order two regular 1.0e-6 file " + outfile); + END_HIDE_OUTPUT(); + + ASSERT_FILE_EXISTS(outfile); + auto lines = read_lines(outfile); + + // atom i, direction alpha, atom j, direction beta, atom k plus three values + // for the three directions of atom k, for all group atoms and directions + ASSERT_EQ((int)lines.size(), 72); + + std::map> entries; + for (const auto &line : lines) { + auto words = utils::split_words(line); + ASSERT_EQ((int)words.size(), 8); + const std::string key = words[0] + " " + words[1] + " " + words[2] + " " + words[3] + " " + + words[4]; + entries[key] = {std::stod(words[5]), std::stod(words[6]), std::stod(words[7])}; + } + ASSERT_EQ((int)entries.size(), 72); + + // the third derivatives of a Lennard-Jones fcc lattice are large along the + // lattice directions that connect the two atoms of the group. the finite + // difference noise of the vanishing components is of order 1e-3, so the + // reference values are compared with a matching tolerance. + EXPECT_NEAR(entries["1 1 1 1 2"][0], 122.32675983, 1.0e-2); + EXPECT_NEAR(entries["1 1 1 1 2"][1], 136.60317322, 1.0e-2); + EXPECT_NEAR(entries["1 1 1 2 2"][0], 136.60367282, 1.0e-2); + EXPECT_NEAR(entries["1 1 1 3 2"][2], -7.13828996, 1.0e-2); + EXPECT_NEAR(entries["1 1 2 1 2"][0], -122.32675983, 1.0e-2); + EXPECT_NEAR(entries["1 1 2 2 1"][0], 136.60383935, 1.0e-2); + + delete_file(outfile); +} + +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = LAMMPS_NS::utils::split_words(var); + for (auto arg : env) { + if (arg == "-v") verbose = true; + } + } + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + + lammps_kokkos_finalize(); + + MPI_Finalize(); + return rv; +} diff --git a/unittest/force-styles/tests/coeffs.2d b/unittest/force-styles/tests/coeffs.2d new file mode 100644 index 00000000000..7a0625e41c7 --- /dev/null +++ b/unittest/force-styles/tests/coeffs.2d @@ -0,0 +1,7 @@ +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 +pair_coeff 1 2 0.8 1.05 +pair_coeff 2 2 0.6 1.1 + +group solute type 1 +group solvent type 2 diff --git a/unittest/force-styles/tests/data.2d b/unittest/force-styles/tests/data.2d new file mode 100644 index 00000000000..4b67383f3fc --- /dev/null +++ b/unittest/force-styles/tests/data.2d @@ -0,0 +1,91 @@ +LAMMPS data file for 2d unit tests. 6x6 square lattice of LJ particles. + +36 atoms +2 atom types + +0.0 6.9000 xlo xhi +0.0 6.9000 ylo yhi +-0.1 0.1 zlo zhi + +Masses + +1 1.0 +2 1.4 + +Atoms # atomic + + 1 1 0.483604017852 0.550366426613 0.000000000000 + 2 2 1.722254646657 0.456969694086 0.000000000000 + 3 1 2.879156358717 0.508756682035 0.000000000000 + 4 2 3.926254515099 0.682446095938 0.000000000000 + 5 1 5.221030559998 0.553432818329 0.000000000000 + 6 2 6.414810752729 0.594108268872 0.000000000000 + 7 2 0.547410445027 1.797770416331 0.000000000000 + 8 1 1.808151792053 1.815858969404 0.000000000000 + 9 2 2.859505362045 1.665247407012 0.000000000000 +10 1 3.971246679798 1.686306061724 0.000000000000 +11 2 5.280141919642 1.708867638814 0.000000000000 +12 1 6.338311656260 1.663334613573 0.000000000000 +13 1 0.548250149705 2.761857942124 0.000000000000 +14 2 1.739941051490 2.876025448955 0.000000000000 +15 1 2.787163221208 2.951860692155 0.000000000000 +16 2 4.135678127324 2.889788247388 0.000000000000 +17 1 5.160272585899 2.865810222601 0.000000000000 +18 2 6.217392301713 2.799548823077 0.000000000000 +19 2 0.482643133211 4.105131517365 0.000000000000 +20 1 1.781880202858 4.136183841044 0.000000000000 +21 2 2.796114323359 4.064548173475 0.000000000000 +22 1 3.913463932106 3.993616887357 0.000000000000 +23 2 5.103538013717 4.114602961326 0.000000000000 +24 1 6.327742845677 3.908150263738 0.000000000000 +25 1 0.679403948190 5.134718886163 0.000000000000 +26 2 1.664664702114 5.267762392675 0.000000000000 +27 1 2.815839369835 5.241074567538 0.000000000000 +28 2 4.120670318822 5.074002950813 0.000000000000 +29 1 5.081145051308 5.172775777685 0.000000000000 +30 2 6.301890523760 5.155367313498 0.000000000000 +31 2 0.469959143533 6.356143484469 0.000000000000 +32 1 1.840741930861 6.343698709152 0.000000000000 +33 2 2.840719015745 6.377496214069 0.000000000000 +34 1 3.981083958772 6.302721240568 0.000000000000 +35 2 5.235451027915 6.431425109646 0.000000000000 +36 1 6.407705315589 6.375378766543 0.000000000000 + +Velocities + + 1 0.291507992166 -0.201478410658 -0.152230070021 + 2 0.243787266437 0.139707507879 0.145901063721 + 3 -0.179954058477 -0.353930396119 0.107870154677 + 4 -0.154418042358 0.299845151214 -0.267913550754 + 5 -0.186971163586 -0.257165559700 0.087140312568 + 6 0.399473251502 -0.328293644654 0.150917310688 + 7 -0.390043785403 0.243567915991 -0.270570402896 + 8 0.015358514665 0.241198746134 0.179713324306 + 9 -0.179089284805 0.361233712011 -0.241807470661 +10 -0.028933962950 0.000075787677 -0.096041571297 +11 0.153432884441 -0.114348592735 -0.180833524669 +12 -0.302042081442 -0.341674136327 -0.125538415181 +13 0.348526130027 0.138490763356 0.230057174941 +14 0.213590408193 0.202764696717 0.210244552072 +15 -0.046241333145 -0.374897219699 -0.119891455043 +16 0.213205109471 0.284676211059 -0.187964543741 +17 0.261257658063 -0.267600824862 -0.251064447202 +18 -0.384508492508 -0.216868412641 0.228979786788 +19 -0.084025448971 -0.109793592436 -0.294579533831 +20 -0.298068742192 -0.212152450370 0.247286574666 +21 -0.005469346046 -0.172875615984 0.226742779664 +22 0.360964541665 0.197650622297 0.088702215046 +23 -0.144821347564 0.095437431601 0.108186343474 +24 0.212476424790 0.277228190651 0.041666728545 +25 0.140249671822 0.304520715106 0.118032552428 +26 0.018614611818 0.331420689281 -0.229158457239 +27 -0.372092796775 -0.057999659180 -0.289083083906 +28 0.061845041117 -0.065718807569 0.293878336220 +29 0.038649416905 -0.037362590537 0.172059973872 +30 0.250061287754 0.076086543586 0.188652309968 +31 -0.097279231878 0.309905057650 -0.122277563739 +32 0.172206595065 -0.287151715354 -0.078262618927 +33 0.232488298717 0.204778416085 -0.044610774382 +34 -0.339975797829 0.099447371081 -0.197080038203 +35 -0.090815582699 -0.375751318286 -0.253629791685 +36 -0.148274925478 -0.072494601594 -0.228089362544 diff --git a/unittest/force-styles/tests/fix-timestep-enforce2d.yaml b/unittest/force-styles/tests/fix-timestep-enforce2d.yaml new file mode 100644 index 00000000000..60504f783dd --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-enforce2d.yaml @@ -0,0 +1,93 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 14:15:45 2026 +epsilon: 5e-12 +timestep: 0.005 +skip_tests: +prerequisites: | + atom atomic + pair lj/cut + fix nve + fix enforce2d +pre_commands: "" +post_commands: | + fix move all nve + fix test all enforce2d +input_file: in.2d +input_coeffs: coeffs.2d +natoms: 36 +run_pos: |2 + 1 5.4258474493290032e-01 5.4805743862952938e-01 0.0000000000000000e+00 + 2 1.7289984445227686e+00 4.7801881713871880e-01 0.0000000000000000e+00 + 3 2.8627086830389503e+00 5.1277617518388030e-01 0.0000000000000000e+00 + 4 3.9276200952476441e+00 6.7374983451080639e-01 0.0000000000000000e+00 + 5 5.2126175884442558e+00 5.6342347025613615e-01 0.0000000000000000e+00 + 6 6.3975299192403217e+00 5.7826623477083072e-01 0.0000000000000000e+00 + 7 5.3489706539078541e-01 1.7710243842060935e+00 0.0000000000000000e+00 + 8 1.7966289195902732e+00 1.8152143045496378e+00 0.0000000000000000e+00 + 9 2.8579579701890454e+00 1.6795954507570010e+00 0.0000000000000000e+00 + 10 3.9768608195308222e+00 1.7166079913271910e+00 0.0000000000000000e+00 + 11 5.2763930848851528e+00 1.7051630398806839e+00 0.0000000000000000e+00 + 12 6.3351969207601613e+00 1.6560589391871883e+00 0.0000000000000000e+00 + 13 5.6152602413066866e-01 2.8189665382279845e+00 0.0000000000000000e+00 + 14 1.7374462491637865e+00 2.8923272868599521e+00 0.0000000000000000e+00 + 15 2.8010114873848120e+00 2.9327543705370616e+00 0.0000000000000000e+00 + 16 4.1288356453575030e+00 2.8991038019088959e+00 0.0000000000000000e+00 + 17 5.1773477391366587e+00 2.8575427558738986e+00 0.0000000000000000e+00 + 18 6.2126117896844937e+00 2.7886443119745796e+00 0.0000000000000000e+00 + 19 4.8545403530135423e-01 4.0920499372966805e+00 0.0000000000000000e+00 + 20 1.7467305646616464e+00 4.1268678350335328e+00 0.0000000000000000e+00 + 21 2.8093364816583661e+00 4.0592805556689688e+00 0.0000000000000000e+00 + 22 3.9294095530935680e+00 3.9982565376184573e+00 0.0000000000000000e+00 + 23 5.0982000303101662e+00 4.1090608126001058e+00 0.0000000000000000e+00 + 24 6.3254383689613141e+00 3.9215490388246637e+00 0.0000000000000000e+00 + 25 6.5293127263208106e-01 5.1563129730498298e+00 0.0000000000000000e+00 + 26 1.6870854028425952e+00 5.2794437469913156e+00 0.0000000000000000e+00 + 27 2.8034918210148305e+00 5.2369679440453840e+00 0.0000000000000000e+00 + 28 4.0884375330068830e+00 5.0724758638444474e+00 0.0000000000000000e+00 + 29 5.1317499942018570e+00 5.1896263058369199e+00 0.0000000000000000e+00 + 30 6.3124588443931815e+00 5.1581047414271968e+00 0.0000000000000000e+00 + 31 5.0302038335923349e-01 6.3624622585839257e+00 0.0000000000000000e+00 + 32 1.8210483252435197e+00 6.3186392727984151e+00 0.0000000000000000e+00 + 33 2.8688292219585723e+00 6.3732362963269571e+00 0.0000000000000000e+00 + 34 3.9709911802996452e+00 6.3067951552099988e+00 0.0000000000000000e+00 + 35 5.2308000096166589e+00 6.4004659622957218e+00 0.0000000000000000e+00 + 36 6.3521807632868930e+00 6.3692481640359979e+00 0.0000000000000000e+00 +run_vel: |2 + 1 2.2624137159906206e+00 1.1569948171188051e-01 0.0000000000000000e+00 + 2 1.0188537851751800e-01 8.2879425685409547e-01 0.0000000000000000e+00 + 3 -6.1241612169635162e-01 5.4243929880688124e-01 0.0000000000000000e+00 + 4 2.0826645726016893e-01 -6.3436773818973768e-01 0.0000000000000000e+00 + 5 -2.3458331128730947e-01 6.3719725616443235e-01 0.0000000000000000e+00 + 6 -9.8239068773713401e-01 -4.6434964189187733e-01 0.0000000000000000e+00 + 7 -2.2966836994089870e-01 -1.2541572630666187e+00 0.0000000000000000e+00 + 8 -5.7968106114994844e-01 -2.5020437996413125e-01 0.0000000000000000e+00 + 9 9.6124323557857050e-02 3.5501728961479156e-01 0.0000000000000000e+00 + 10 2.9725727423494142e-01 1.3666366543205919e+00 0.0000000000000000e+00 + 11 -3.3910717439706678e-01 -6.8058485327010115e-02 0.0000000000000000e+00 + 12 1.3471876280205003e-01 -3.6166991496423745e-02 0.0000000000000000e+00 + 13 3.1210668521942575e-01 2.2630686638267985e+00 0.0000000000000000e+00 + 14 -3.1134431088996456e-01 5.9560515614790210e-01 0.0000000000000000e+00 + 15 7.0910882452565960e-01 -5.7512139623194591e-01 0.0000000000000000e+00 + 16 -5.0355141964243832e-01 1.7949979205939537e-01 0.0000000000000000e+00 + 17 4.6780165396259887e-01 -1.3985973378979238e-01 0.0000000000000000e+00 + 18 1.8461588105259175e-01 -3.1754315699385799e-01 0.0000000000000000e+00 + 19 2.3333173975750895e-01 -5.0782197059857070e-01 0.0000000000000000e+00 + 20 -1.3252370209497157e+00 -2.5485066913303323e-01 0.0000000000000000e+00 + 21 5.7101495119841117e-01 -9.0709531061878415e-02 0.0000000000000000e+00 + 22 4.2819963898869717e-01 2.3026386661240836e-02 0.0000000000000000e+00 + 23 -1.2173332499193328e-01 -3.4389986804081862e-01 0.0000000000000000e+00 + 24 -3.2828544351280414e-01 3.7705440656237166e-01 0.0000000000000000e+00 + 25 -1.2809083424266570e+00 7.4786752211389074e-01 0.0000000000000000e+00 + 26 9.4437518015979882e-01 1.7482470590823435e-01 0.0000000000000000e+00 + 27 -2.2537852533901176e-01 -1.4699591350012417e-01 0.0000000000000000e+00 + 28 -1.3592548419621731e+00 3.3302084711383476e-02 0.0000000000000000e+00 + 29 2.0498196469303016e+00 7.9249940726051427e-01 0.0000000000000000e+00 + 30 2.8173286114270885e-01 6.0360203451876621e-02 0.0000000000000000e+00 + 31 1.4108610260242755e+00 8.1100624860493548e-03 0.0000000000000000e+00 + 32 -9.8869395413324856e-01 -7.7144578086196525e-01 0.0000000000000000e+00 + 33 1.0318377921998125e+00 -4.0393611005627972e-01 0.0000000000000000e+00 + 34 -1.3681696974492513e-01 1.0220839087109471e-01 0.0000000000000000e+00 + 35 -1.5998393187360921e-01 -1.0883769008766477e+00 0.0000000000000000e+00 + 36 -2.1321608742247311e+00 -2.5347532232628506e-01 0.0000000000000000e+00 +... diff --git a/unittest/force-styles/tests/in.2d b/unittest/force-styles/tests/in.2d new file mode 100644 index 00000000000..6a801fa1c68 --- /dev/null +++ b/unittest/force-styles/tests/in.2d @@ -0,0 +1,17 @@ +variable newton_pair index on +variable newton_bond index on +variable units index lj +variable input_dir index . +variable data_file index ${input_dir}/data.2d +variable pair_style index 'zero 2.5' + +dimension 2 +atom_style atomic +atom_modify map array +neigh_modify delay 2 every 2 check no +units ${units} +timestep 0.005 +newton ${newton_pair} ${newton_bond} + +pair_style ${pair_style} +read_data ${data_file} From feffa9884d87971f7dca879793966a71b20f9b54 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:06:26 +0000 Subject: [PATCH 047/120] test: add DPD-REACT force-style references None of the reaction DPD styles had a test, which left the largest untested group of KOKKOS styles: pair exp6/rx, table/rx and dpd/fdt/energy, fix rx and fix eos/table/rx, and with them fix shardlow and the SSA neighbor list and binning classes that only the DPD-REACT styles request. The 32 atom systems reproduce the number density and nearest neighbor distance of the examples in examples/PACKAGES/dpd-react. The kinetics, exp-6 parameter and thermodynamics files are copied verbatim from there; the equation of state table is subsampled from the example table over its full temperature range, and the tabulated pair potential is written with pair_write from lj/cut, sampled around its minimum at the nearest neighbor distance of the system. The pair fixtures set "fix_modify rx_chemistry off": with the reaction integrator active, the plain newton on and newton off trajectories drift apart by 5e-7 within four steps, which is far above what the pair test compares. The reaction integrator is covered by the two fix references instead, where the plain and the KOKKOS results agree to the last bit. Two limitations of fix rx found while writing the tests are recorded as tags: it has no r-RESPA hook, so pair exp6/rx aborts under run_style respa (no_respa), and FixEOStableRX::setup() adds one chemical energy increment that the continuous run does not perform, so a restart in the middle of a run does not reproduce the trajectory (no_restart). --- unittest/force-styles/tests/coeffs.dpd-react | 23 ++ unittest/force-styles/tests/data.dpd-react | 83 +++++++ .../force-styles/tests/dpd_rx_eos_table.txt | 30 +++ .../force-styles/tests/dpd_rx_exp6_params.txt | 17 ++ .../force-styles/tests/dpd_rx_kinetics.txt | 13 ++ .../force-styles/tests/dpd_rx_pair_table.txt | 214 ++++++++++++++++++ unittest/force-styles/tests/dpd_rx_thermo.txt | 18 ++ .../tests/fix-timestep-eos_table_rx.yaml | 92 ++++++++ .../force-styles/tests/fix-timestep-rx.yaml | 94 ++++++++ unittest/force-styles/tests/in.dpd-fdt | 20 ++ unittest/force-styles/tests/in.dpd-rx | 28 +++ .../tests/mol-pair-dpd_fdt_energy.yaml | 97 ++++++++ .../force-styles/tests/mol-pair-exp6_rx.yaml | 118 ++++++++++ .../force-styles/tests/mol-pair-table_rx.yaml | 119 ++++++++++ 14 files changed, 966 insertions(+) create mode 100644 unittest/force-styles/tests/coeffs.dpd-react create mode 100644 unittest/force-styles/tests/data.dpd-react create mode 100644 unittest/force-styles/tests/dpd_rx_eos_table.txt create mode 100644 unittest/force-styles/tests/dpd_rx_exp6_params.txt create mode 100644 unittest/force-styles/tests/dpd_rx_kinetics.txt create mode 100644 unittest/force-styles/tests/dpd_rx_pair_table.txt create mode 100644 unittest/force-styles/tests/dpd_rx_thermo.txt create mode 100644 unittest/force-styles/tests/fix-timestep-eos_table_rx.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-rx.yaml create mode 100644 unittest/force-styles/tests/in.dpd-fdt create mode 100644 unittest/force-styles/tests/in.dpd-rx create mode 100644 unittest/force-styles/tests/mol-pair-dpd_fdt_energy.yaml create mode 100644 unittest/force-styles/tests/mol-pair-exp6_rx.yaml create mode 100644 unittest/force-styles/tests/mol-pair-table_rx.yaml diff --git a/unittest/force-styles/tests/coeffs.dpd-react b/unittest/force-styles/tests/coeffs.dpd-react new file mode 100644 index 00000000000..9a2daba1be0 --- /dev/null +++ b/unittest/force-styles/tests/coeffs.dpd-react @@ -0,0 +1,23 @@ +# initial per-atom species concentrations for the DPD-REACT (fix rx) fixture. +# the "d_" per-atom properties are created by the "fix rx" command in +# in.dpd-rx, so this file must be processed after that input template. +# the concentrations of each atom type add up to 1.0 + +set type 1 d_rdx 0.30 +set type 1 d_hcn 0.20 +set type 1 d_no2 0.10 +set type 1 d_no 0.15 +set type 1 d_h2o 0.15 +set type 1 d_n2 0.05 +set type 1 d_h2 0.03 +set type 1 d_co 0.01 +set type 1 d_co2 0.01 +set type 2 d_rdx 0.10 +set type 2 d_hcn 0.30 +set type 2 d_no2 0.20 +set type 2 d_no 0.05 +set type 2 d_h2o 0.10 +set type 2 d_n2 0.10 +set type 2 d_h2 0.05 +set type 2 d_co 0.05 +set type 2 d_co2 0.05 diff --git a/unittest/force-styles/tests/data.dpd-react b/unittest/force-styles/tests/data.dpd-react new file mode 100644 index 00000000000..6d9cefd694a --- /dev/null +++ b/unittest/force-styles/tests/data.dpd-react @@ -0,0 +1,83 @@ +LAMMPS data file via write_data, version 2 Sep 2026, timestep = 0, units = metal + +32 atoms +2 atom types + +0 18.81564 xlo xhi +0 18.81564 ylo yhi +0 18.81564 zlo zhi + +Masses + +1 222.12 +2 222.12 + +Atoms # dpd + +1 2 2065 18.519669966101063 18.447280260588208 18.593499706048785 -1 -1 -1 +2 1 2065 4.173348318940549 4.753736433812187 18.648513081431197 0 0 -1 +3 1 2065 5.141374184797119 0.060553885186348966 4.833058326967446 0 0 0 +4 1 2065 18.297900440887073 4.255139989040284 4.22633580006012 -1 0 0 +5 1 2065 9.448057079486361 18.280234927273966 0.2469426935757243 0 -1 0 +6 2 2065 14.64901748501152 4.894670588641632 18.528853299919483 0 0 -1 +7 1 2065 14.286400142482345 0.48108470080470883 4.694476424741673 0 0 0 +8 1 2065 9.245816202352454 4.70608293771085 5.224474106256032 0 0 0 +9 1 2065 18.538019046828662 9.032460049331187 18.540949109280493 -1 0 -1 +10 1 2065 4.47105252474119 13.676143325192598 0.294756512015479 0 0 0 +11 2 2065 4.966858518275725 9.183566660109491 4.878026460221873 0 0 0 +12 1 2065 0.43625404864375195 14.233525555540263 4.521811965239039 0 0 0 +13 2 2065 9.81420478799089 9.116951762901847 0.1775390913605406 0 0 0 +14 2 2065 14.181067602830181 14.268820766894205 0.22451919094869824 0 0 0 +15 2 2065 14.471123951184763 8.941957562352297 4.95392045505051 0 0 0 +16 1 2065 8.980747706582903 14.70769453886291 4.679914668965937 0 0 0 +17 2 2065 0.0914989714936814 18.23885389430352 8.963741559294649 0 -1 0 +18 1 2065 4.989910292043201 4.310818370092003 9.916796136291854 0 0 0 +19 1 2065 4.633912000429668 18.359261221437873 14.153598706346425 0 -1 0 +20 1 2065 18.58006015914452 4.113524741992957 14.30669867563341 -1 0 0 +21 1 2065 9.907097897132223 18.57925710129474 9.720441460721185 0 -1 0 +22 2 2065 13.925329299645794 5.067339146894919 9.561491862908486 0 0 0 +23 2 2065 14.279449096675382 0.054857823185090825 14.507164271821487 0 0 0 +24 2 2065 9.338097685695457 5.280973483547914 14.41769798979955 0 0 0 +25 1 2065 0.3035212770586467 9.489923524674708 9.321759207845338 0 0 0 +26 1 2065 4.629244288424502 14.405115550609501 9.538769093928071 0 0 0 +27 2 2065 5.292438746361158 9.210460092001593 13.88375627080121 0 0 0 +28 1 2065 18.540542095796958 14.141254059514292 13.52259825673043 -1 0 0 +29 1 2065 9.463000535956835 9.227087826536328 9.042180596087928 0 0 0 +30 2 2065 14.46215335845084 14.07711548328233 9.641637526155066 0 0 0 +31 2 2065 14.708133946725837 9.568952621188243 13.867694310819264 0 0 0 +32 1 2065 9.518933143484626 14.390332546117547 14.184722597647472 0 0 0 + +Velocities + +1 1.6054999744373464 -0.01505366216416683 0.2912170523488621 +2 3.490058482711546 -2.168470372507177 -1.4014448677045541 +3 0.964889171946071 9.4774140300024 -2.0884498744500877 +4 0.6369778423975928 0.2231308974836377 1.146275994159686 +5 4.377664813983293 -0.23194559567685002 0.07327146276375528 +6 -3.70236995957204 2.0012046853727723 -1.3298008150503124 +7 -1.3258742923323228 0.8319058671660954 -3.5822902595526527 +8 2.87795672845232 1.1090057110083569 2.1686564374472352 +9 0.0657502688848309 -0.18757415204503314 1.0617029799632725 +10 -2.117444752040618 -1.303127636986309 2.664620982490913 +11 -0.6915974466792971 -0.6700737631820771 -3.4775120292745374 +12 -3.977617428217358 -2.7197876556877554 3.0453929370192028 +13 2.5576702196768375 -1.072170068891168 -6.235935023471404 +14 2.5389561334366237 1.514891610675868 1.2984678456446572 +15 3.9944899994543954 -6.572634731814777 2.11766245901057 +16 -4.546028156991956 2.198452590489954 -2.2792040349709466 +17 -1.6309665339790147 -2.8803653400693605 -2.2037380375862514 +18 1.5467297074093802 -0.9517419307785298 2.992131575709927 +19 1.4428048068854589 -0.9453574976628395 -1.9848937028591187 +20 -2.1440623974804414 -1.0001879881877191 1.6921781727138003 +21 -1.1061528796056095 1.3816463620401855 1.017381509919363 +22 -3.3739332836431597 4.781678142907396 -1.2224016305862064 +23 -2.365725776025356 0.5392143818192504 4.432954558214005 +24 2.3082798611005266 -0.27528665925148577 0.3564998872367881 +25 -4.099190000997962 -0.02071750538487372 -1.9620923984737637 +26 2.417933717372052 2.5815531191465904 -3.9695016381799744 +27 4.597394271946599 1.7319536320549864 1.5387605959624933 +28 4.096316121402671 -2.498750476477075 6.271676996703631 +29 -1.6525855411486643 -0.9839299556002502 1.2156725741698613 +30 1.8990143337405745 -0.5520212436659381 1.9147014534315054 +31 -5.769955101728314 -1.4579946840100524 -2.848818290182841 +32 -2.9148829047960065 -1.8648601101240532 -0.7131428725668801 diff --git a/unittest/force-styles/tests/dpd_rx_eos_table.txt b/unittest/force-styles/tests/dpd_rx_eos_table.txt new file mode 100644 index 00000000000..756c02ef4df --- /dev/null +++ b/unittest/force-styles/tests/dpd_rx_eos_table.txt @@ -0,0 +1,30 @@ +# EOS TABLE FROM MARTIN +# Reduced copy of examples/PACKAGES/dpd-react/dpdrx-shardlow/table.eos: +# every 200th tabulated point (1000 K spacing) of the original 4001 entries. +# All values are copied verbatim, only the entry index was renumbered and +# trailing blanks were removed. + +KEYWORD +N 21 rdx h2 no2 n2 hcn no h2o co co2 + +1 0.00 -4.69225982859849288786e-01 -8.95260588880977536963e-02 -1.18526952517906569717e-01 -9.15809242071203427615e-02 -1.12576258266148046538e-01 -9.41081115411522145520e-02 -1.01883310117228328973e-01 -9.24290185576487621777e-02 -1.23100093449991648820e-01 +2 1000.00 2.37857627717337782869e+00 2.15630508488717120841e-01 3.38728649074641230410e-01 2.26720484755961682044e-01 3.20722946317064772082e-01 2.34108513275895463446e-01 2.72361888997366463627e-01 2.27353798535345180687e-01 3.46173777472382260267e-01 +3 2000.00 7.02761824697445902643e+00 5.49505554500144488550e-01 9.24360060722232645958e-01 5.82068154122476699719e-01 8.90619966327035106346e-01 5.99998789733114046285e-01 7.58417289635173186291e-01 5.83607304466202125859e-01 9.46571427683965294086e-01 +4 3000.00 1.20411397326476432568e+01 9.17272353695683051455e-01 1.54996190355374663383e+00 9.61026328401057394757e-01 1.51197785992709898828e+00 9.85924121454829549549e-01 1.32457106672512003875e+00 9.66812930748111809542e-01 1.58538484844056548617e+00 +5 4000.00 1.71699099773129830737e+01 1.31266953881822301398e+00 2.20505596263326930639e+00 1.35015035517774939500e+00 2.15327018339277120873e+00 1.37965223846967788290e+00 1.93814259488075579796e+00 1.36148636964188907150e+00 2.23177350916031080885e+00 +6 5000.00 2.23481974976913946307e+01 1.72825843989184013694e+00 2.89889423929051526230e+00 1.74219593773869796394e+00 2.80525894112050444562e+00 1.77672313223867672782e+00 2.57998581704873908294e+00 1.75679655599879347427e+00 2.88603753018285358323e+00 +7 6000.00 2.75481220183258024292e+01 2.15708501431800536707e+00 3.63520040294589197316e+00 2.13577151786408281353e+00 3.46140765302854580554e+00 2.17700911175506739426e+00 3.24036501595553350086e+00 2.15036141912529066289e+00 3.55842906780091361441e+00 +8 7000.00 3.27606229997025479861e+01 2.59190810533865212406e+00 4.40960026675123728523e+00 2.53349689376485276426e+00 4.11746950513489373691e+00 2.58127897633772063202e+00 3.91273596549376145859e+00 2.54834986181543809991e+00 4.26004649480913943904e+00 +9 8000.00 3.79857004419252746175e+01 3.02478636996317629126e+00 5.21432544274922182836e+00 2.94011725581400140683e+00 4.77353135728269784011e+00 2.98914578980151679488e+00 4.59005715223517363199e+00 2.96320533696284149627e+00 4.99909268417785224159e+00 +10 9000.00 4.32233543447866992437e+01 3.44777179553908297294e+00 6.04261389906816326345e+00 3.36105066553076081703e+00 5.42959320940977452352e+00 3.39858461453316440526e+00 5.26445929076382324041e+00 3.41011525299289308677e+00 5.77921269902960865750e+00 +11 10000.00 4.84735847083904687338e+01 3.85432116151518933123e+00 6.89034270707215057428e+00 3.80132887816895337352e+00 6.08565506153685031876e+00 3.80655151499322697006e+00 5.92906630879425033953e+00 3.90315930093100682541e+00 6.59875057683478161152e+00 +12 11000.00 5.37301033024172127739e+01 4.24061293194205646273e+00 7.75530839175058961388e+00 4.26471832899595693078e+00 6.74171691364319869422e+00 4.21000371753056601420e+00 6.58009805861728303000e+00 4.45187865639791446881e+00 7.45084410086757831237e+00 +13 12000.00 5.89866218964439710248e+01 4.60605071372383179096e+00 8.63571554522945561416e+00 4.75287208060368815410e+00 7.39777876577027448946e+00 4.60669856186694648414e+00 7.21770492738392466237e+00 5.05881687128511714491e+00 8.32457490839689207007e+00 +14 13000.00 6.42431404904707221704e+01 4.95265041842985898057e+00 9.52934129324291667729e+00 5.26455657508946739398e+00 8.05384061789735206105e+00 4.99542134907433066360e+00 7.84489797935263677431e+00 5.71839213083848729724e+00 9.20717342469288446694e+00 +15 14000.00 6.94996590844974804213e+01 5.28355145090162459098e+00 1.04340083781321606438e+01 5.79521116244795830852e+00 8.70990247004515616425e+00 5.37564492710409336240e+00 8.46505597539147913722e+00 6.41726941285293595030e+00 1.00868083658507003975e+01 +16 15000.00 7.47561776785242244614e+01 5.60136744787116214184e+00 1.13489196022465232971e+01 6.33722559886367964310e+00 9.36596432214114038572e+00 5.74694240555971713746e+00 9.07942328770019635442e+00 7.13620994675961117792e+00 1.09550333522996385938e+01 +17 16000.00 8.00126962725509827123e+01 5.90730413439544577159e+00 1.22755777220534607608e+01 6.88125303620491468592e+00 1.00220261742474878730e+01 6.10864430462580898507e+00 9.68637106915032042309e+00 7.85318423163144441190e+00 1.18077829511570993049e+01 +18 17000.00 8.52692148665777409633e+01 6.20172558659258488234e+00 1.32169341613213795483e+01 7.41850547000680826670e+00 1.06780880264574769001e+01 6.46013826462452378507e+00 1.02835887541832100567e+01 8.54734373298343896863e+00 1.26441716496229012989e+01 +19 18000.00 9.05257334605008310291e+01 6.48595041642958758388e+00 1.41745736741464369857e+01 7.94319719016778336140e+00 1.13341498784809111555e+01 6.80173872186794348238e+00 1.08724147709170875231e+01 9.20325523934337041965e+00 1.34635162850086373965e+01 +20 19000.00 9.57822520545275892800e+01 6.76331095917684077534e+00 1.51466469121714943924e+01 8.45300149789245836018e+00 1.19902117306079887271e+01 7.13509123899721053874e+00 1.14598149391264509944e+01 9.81461072072996287829e+00 1.42632397507848196483e+01 +21 20000.00 1.01038770648554361742e+02 7.03471627701791568654e+00 1.61344052755348137396e+01 8.94414898897155907775e+00 1.26462735827350645224e+01 7.46050701199851928891e+00 1.20476851259601023258e+01 1.03864343922335553572e+01 1.50438857951701212556e+01 diff --git a/unittest/force-styles/tests/dpd_rx_exp6_params.txt b/unittest/force-styles/tests/dpd_rx_exp6_params.txt new file mode 100644 index 00000000000..7dab2aadf9f --- /dev/null +++ b/unittest/force-styles/tests/dpd_rx_exp6_params.txt @@ -0,0 +1,17 @@ +# taken verbatim from examples/PACKAGES/dpd-react/dpdrx-shardlow/params.exp6 +# rx parameters for various molecules +# multiple entries can be added to this file, LAMMPS reads the ones it needs +# these entries are in LAMMPS "metal" units: +# alpha = unitless; epsilon = eV; rho = Angstroms; + +# format of a single entry (one or more lines): +# species, exp6, alpha, epsilon, rm + +hcn exp6 13.57 0.030862657941745 5.3725 +no2 exp6 13.57 0.029126283357001 4.2744 +no exp6 13.10 0.013090454747817 3.7142 +h2o exp6 11.01 0.022473771300313 3.5348 +co exp6 13.24 0.0086353397713660428 4.1759 +co2 exp6 14.09 0.019672305322873507 4.1757 +h2 exp6 11.23 0.002618780329051 3.4925 +n2 exp6 12.97 0.008635339808299 4.1778 diff --git a/unittest/force-styles/tests/dpd_rx_kinetics.txt b/unittest/force-styles/tests/dpd_rx_kinetics.txt new file mode 100644 index 00000000000..147f2a0712f --- /dev/null +++ b/unittest/force-styles/tests/dpd_rx_kinetics.txt @@ -0,0 +1,13 @@ +# taken verbatim from examples/PACKAGES/dpd-react/dpdrx-shardlow/kinetics.dpdrx +# reaction equations and parameters +# multiple entries can be added to this file +# these entries are in LAMMPS "metal" units: +# Arr = 1/picosec or Angstroms^3/mol/picosec; Ern = eV + +# format of a single entry (one or more lines): +# rxn equation, Arn, n, Ern + +1.0 rdx = 3.0 hcn + 1.5 no2 + 1.5 no + 1.5 h2o 2.51000000000000E+04 0.0 1.912325921964536 +1.0 hcn + 1.0 no2 = 1.0 no + 0.5 n2 + 0.5 h2 + 1.0 co 2.49081028001241E+01 0.0 1.344265387322009 +1.0 hcn + 1.0 no = 1.0 co + 1.0 n2 + 0.5 h2 4.98162056E+00 0.0 1.517718985686140 +1.0 no + 1.0 co = 0.5 n2 + 1.0 co2 1.66054018667494E+06 0.0 6.938245245 diff --git a/unittest/force-styles/tests/dpd_rx_pair_table.txt b/unittest/force-styles/tests/dpd_rx_pair_table.txt new file mode 100644 index 00000000000..9cf49ce6262 --- /dev/null +++ b/unittest/force-styles/tests/dpd_rx_pair_table.txt @@ -0,0 +1,214 @@ +# DATE: 2026-09-04 UNITS: metal Created by pair_write +# Tabulated 12-6 Lennard-Jones potentials for the pair style table/rx tests, +# created with the LAMMPS pair_write command from pair style lj/cut: +# LJ_A: epsilon = 0.025 eV, sigma = 5.2 Angstrom; LJ_B: epsilon = 0.018 eV, sigma = 5.6 Angstrom +# Pair potential lj/cut for atom types 1 1: i,r,energy,force + +LJ_A +N 100 R 2 8 + + 1 2 9512.00408856822 57164.6992642093 + 2 2.06060606060606 6643.78456570642 38765.4728605866 + 3 2.12121212121212 4688.40582943918 26584.3694259701 + 4 2.18181818181818 3340.72982122146 18424.4152793463 + 5 2.24242424242424 2402.28619555108 12897.0826060085 + 6 2.3030303030303 1742.4254949861 9113.47413007185 + 7 2.36363636363636 1274.16227270492 6497.60489859422 + 8 2.42424242424242 938.956959581187 4671.94371759805 + 9 2.48484848484848 697.010423104893 3386.33052154196 + 10 2.54545454545455 521.001807161626 2473.28360633278 + 11 2.60606060606061 392.003166180884 1819.56830733105 + 12 2.66666666666667 296.786085324034 1347.90796749292 + 13 2.72727272727273 226.028172432226 1005.09386957413 + 14 2.78787878787879 173.107347779682 754.176862975568 + 15 2.84848484848485 133.283896614442 569.289899773471 + 16 2.90909090909091 103.140747008627 432.183337841737 + 17 2.96969696969697 80.1972650201395 329.885948431887 + 18 3.03030303030303 62.6406551645969 253.112550055318 + 19 3.09090909090909 49.1377303209318 195.171177223394 + 20 3.15151515151515 38.7020401595944 151.20726736643 + 21 3.21212121212121 30.5994203899488 117.677049013843 + 22 3.27272727272727 24.2804019252494 91.9780085299454 + 23 3.33333333333333 19.3315292759004 72.1878047933514 + 24 3.39393939393939 15.4400805324117 56.8785899213688 + 25 3.45454545454545 12.3683469794732 44.9841203181963 + 26 3.51515151515152 9.93477427674075 35.7040687727554 + 27 3.57575757575758 8.00005818124342 28.4347183401148 + 28 3.63636363636364 6.45683848928067 22.7184798001363 + 29 3.6969696969697 5.22202074390026 18.2069191158279 + 30 3.75757575757576 4.23102731331981 14.6335364636049 + 31 3.81818181818182 3.43347241874724 11.7936226911666 + 32 3.87878787878788 2.78989336321354 9.52927966976898 + 33 3.93939393939394 2.26926898554775 7.71822772105526 + 34 4 1.8471276122481 6.2654041867443 + 35 4.06060606060606 1.50409844464977 5.09662900796166 + 36 4.12121212121212 1.22479797301726 4.15380817190874 + 37 4.18181818181818 0.996970587490161 3.39128649679825 + 38 4.24242424242424 0.810822850760544 2.77306313500724 + 39 4.3030303030303 0.658505901514771 2.27065739201216 + 40 4.36363636363636 0.533711600033688 1.86146676437582 + 41 4.42424242424242 0.431356337838844 1.52749901790282 + 42 4.48484848484848 0.347332657773766 1.25438959934759 + 43 4.54545454545454 0.27831351210716 1.03063752895871 + 44 4.60606060606061 0.221597520784555 0.847009193845495 + 45 4.66666666666667 0.174986271018684 0.696071628338761 + 46 4.72727272727273 0.136686737672101 0.571825999475333 + 47 4.78787878787879 0.105233460278512 0.46941889656465 + 48 4.84848484848485 0.0794263052082678 0.384914227821527 + 49 4.90909090909091 0.0582805585682404 0.315112477223793 + 50 4.96969696969697 0.0409868029783317 0.257407083802048 + 51 5.03030303030303 0.02687857904318 0.209670005620401 + 52 5.09090909090909 0.0154062576117103 0.170160294722944 + 53 5.15151515151515 0.00611588016779004 0.137450866653153 + 54 5.21212121212121 -0.0013680165117037 0.110369695890959 + 55 5.27272727272727 -0.00735637251625411 0.0879524798238503 + 56 5.33333333333333 -0.012106995519874 0.06940444394564 + 57 5.39393939393939 -0.0158338662381248 0.0540694517738756 + 58 5.45454545454546 -0.0187147555937305 0.0414049663839122 + 59 5.51515151515152 -0.0208974719632722 0.0309617108139429 + 60 5.57575757575758 -0.0225049944495151 0.0223671105358129 + 61 5.63636363636364 -0.0236396984139255 0.0153117870220344 + 62 5.6969696969697 -0.0243868398236897 0.0095385181927825 + 63 5.75757575757576 -0.0248174332174592 0.00483319771241895 + 64 5.81818181818182 -0.0249906326298781 0.00101741731924238 + 65 5.87878787878788 -0.0249557043456164 -0.00205763026156624 + 66 5.93939393939394 -0.0247536638627988 -0.00451617176252523 + 67 6 -0.0244186361312578 -0.00646199434756363 + 68 6.06060606060606 -0.0239789873583856 -0.00798186681714845 + 69 6.12121212121212 -0.0234582679412608 -0.00914837066197266 + 70 6.18181818181818 -0.0228759989881447 -0.0100222463739559 + 71 6.24242424242424 -0.0222483291166709 -0.0106543409025868 + 72 6.3030303030303 -0.0215885835055769 -0.0110872263713917 + 73 6.36363636363636 -0.0209077233279877 -0.0113565473984397 + 74 6.42424242424242 -0.0202147305437067 -0.0114921440044279 + 75 6.48484848484848 -0.0195169304444339 -0.0115189886708791 + 76 6.54545454545455 -0.018820262223587 -0.0114579692534181 + 77 6.60606060606061 -0.0181295060961435 -0.0113265438604496 + 78 6.66666666666667 -0.0174484740546759 -0.0111392892350566 + 79 6.72727272727273 -0.0167801701596336 -0.0109083604342716 + 80 6.78787878787879 -0.0161269252795947 -0.0106438765295604 + 81 6.84848484848485 -0.0154905103837777 -0.0103542445300629 + 82 6.90909090909091 -0.0148722318145469 -0.0100464316546667 + 83 6.96969696969697 -0.0142730114074384 -0.00972619436845561 + 84 7.03030303030303 -0.0136934538603484 -0.00939827118712171 + 85 7.09090909090909 -0.0131339033655572 -0.00906654508566068 + 86 7.15151515151515 -0.0125944911947435 -0.00873418038125162 + 87 7.21212121212121 -0.0120751756570407 -0.00840373815893955 + 88 7.27272727272727 -0.0115757756243818 -0.00807727364343251 + 89 7.33333333333333 -0.011095998629396 -0.00775641836716299 + 90 7.39393939393939 -0.0106354643827651 -0.00744244952422475 + 91 7.45454545454545 -0.0101937244241063 -0.00713634851587116 + 92 7.51515151515152 -0.00977027850889475 -0.00683885037279883 + 93 7.57575757575758 -0.00936458824016155 -0.00655048547161814 + 94 7.63636363636364 -0.0089760883747914 -0.00627161473881582 + 95 7.6969696969697 -0.00860419616777939 -0.00600245934778551 + 96 7.75757575757576 -0.00824831906177164 -0.00574312575706019 + 97 7.81818181818182 -0.00790786098193518 -0.00549362680569474 + 98 7.87878787878788 -0.00758222745627526 -0.00525389947064693 + 99 7.93939393939394 -0.00727082974777449 -0.0050238197975326 + 100 8 0 0 +# Pair potential lj/cut for atom types 2 2: i,r,energy,force + +LJ_B +N 100 R 2 8 + + 1 2 16685.0189845353 100214.202212876 + 2 2.06060606060606 11656.5434931848 67966.683098446 + 3 2.12121212121212 8228.01197820704 46615.9874346857 + 4 2.18181818181818 5864.68168563447 32312.3578186681 + 5 2.24242424242424 4218.72589562382 22622.6136261066 + 6 2.3030303030303 3061.16512584663 15989.0531004162 + 7 2.36363636363636 2239.53780330175 11402.2868054317 + 8 2.42424242424242 1651.23344742595 8200.68125762656 + 9 2.48484848484848 1226.48535980909 5945.80469869158 + 10 2.54545454545455 917.396836347543 4344.11298934585 + 11 2.60606060606061 690.781761077342 3197.12904595086 + 12 2.66666666666667 523.444420107838 2369.39400208727 + 13 2.72727272727273 399.036227079137 1767.63107204631 + 14 2.78787878787879 305.942518310073 1327.06176942624 + 15 2.84848484848485 235.848892922027 1002.33236381744 + 16 2.90909090909091 182.760102309261 761.44175099133 + 17 2.96969696969697 142.323046868666 581.642032516636 + 18 3.03030303030303 111.355897270008 446.647537534209 + 19 3.09090909090909 87.5180844544316 344.71929376536 + 20 3.15151515151515 69.0773253029531 267.340153622407 + 21 3.21212121212121 54.7439985663393 208.291632289863 + 22 3.27272727272727 43.5526083150528 163.006063183016 + 23 3.33333333333333 34.7763991333924 128.108843273649 + 24 3.39393939393939 27.8654689149079 101.092858753556 + 25 3.45454545454545 22.4016444529962 80.0854530146551 + 26 3.51515151515152 18.0653899344854 63.6806128668378 + 27 3.57575757575758 14.6114049663824 50.8174086724771 + 28 3.63636363636364 11.8505340763392 40.691439492212 + 29 3.6969696969697 9.63628603936391 32.6899684737594 + 30 3.75757575757576 7.85473831985924 26.3441595186672 + 31 3.81818181818182 6.41694023279019 21.2937268327339 + 32 3.87878787878788 5.25316980867958 17.2606422552601 + 33 3.93939393939394 4.30857253672349 14.0294861258188 + 34 4 3.53983509902131 11.4326951850639 + 35 4.06060606060606 2.9126378138276 9.33943752701468 + 36 4.12121212121212 2.39969554663117 7.64718650355797 + 37 4.18181818181818 1.97924522175694 6.27531204080337 + 38 4.24242424242424 1.63387366959438 5.16018653350551 + 39 4.3030303030303 1.34960586872185 4.25143264180559 + 40 4.36363636363636 1.11519319351471 3.50903556090368 + 41 4.42424242424242 0.921555862129075 2.90111235263538 + 42 4.48484848484848 0.761344704919544 2.40218262947003 + 43 4.54545454545454 0.628595591043308 1.99182322279472 + 44 4.60606060606061 0.518456056841387 1.65361802024571 + 45 4.66666666666667 0.426968384274433 1.3743355069914 + 46 4.72727272727273 0.350896957779233 1.143282573531 + 47 4.78787878787879 0.287590462202877 0.951795231018364 + 48 4.84848484848485 0.234871580224836 0.792836011588701 + 49 4.90909090909091 0.190948459578996 0.660674767476249 + 50 4.96969696969697 0.154343464329049 0.55063486740348 + 51 5.03030303030303 0.123835687582151 0.458890829004848 + 52 5.09090909090909 0.098414451123912 0.382306525363507 + 53 5.15151515151515 0.0772416003428843 0.318305489047748 + 54 5.21212121212121 0.0596208583504681 0.26476667870463 + 55 5.27272727272727 0.0449728602688141 0.219940499642473 + 56 5.33333333333333 0.0328147693485931 0.182380977924959 + 57 5.39393939393939 0.0227435978485519 0.150890850886864 + 58 5.45454545454546 0.0144225305168562 0.124477011653528 + 59 5.51515151515152 0.00756968714456978 0.102314273942908 + 60 5.57575757575758 0.0019488708256878 0.0837158388783586 + 61 5.63636363636364 -0.00263806367562204 0.0681091728800448 + 62 5.6969696969697 -0.00635751695370732 0.0550162642987006 + 63 5.75757575757576 -0.00934936676947 0.0440374312694171 + 64 5.81818181818182 -0.0117312989845855 0.0348380158882692 + 65 5.87878787878788 -0.0136024057427184 0.0271374292581725 + 66 5.93939393939394 -0.015046179813556 0.0207001152298933 + 67 6 -0.0161330104187082 0.015328083261349 + 68 6.06060606060606 -0.0169222667518658 0.0108547270264431 + 69 6.12121212121212 -0.0174640399020233 0.00713969859461917 + 70 6.18181818181818 -0.0178006012826806 0.00406465082747512 + 71 6.24242424242424 -0.0179676253994944 0.00152969519279762 + 72 6.3030303030303 -0.0179952164047134 -0.000549549864793231 + 73 6.36363636363636 -0.017908771029287 -0.00224442222097589 + 74 6.42424242424242 -0.0177297048642421 -0.00361527488385924 + 75 6.48484848484848 -0.0174760643497671 -0.00471319921971746 + 76 6.54545454545455 -0.0171630430364706 -0.00558146930783503 + 77 6.60606060606061 -0.0168034175575628 -0.00625675419209807 + 78 6.66666666666667 -0.0164079161711081 -0.00677013665927782 + 79 6.72727272727273 -0.0159855305990517 -0.00714797050505748 + 80 6.78787878787879 -0.0155437801240154 -0.0074126027740162 + 81 6.84848484848485 -0.0150889354404961 -0.00758298295745149 + 82 6.90909090909091 -0.0146262085407431 -0.00767517742409536 + 83 6.96969696969697 -0.014159913903704 -0.0077028042985595 + 84 7.03030303030303 -0.0136936054123779 -0.0076774014732168 + 85 7.09090909090909 -0.0132301927215163 -0.00760873834571177 + 86 7.15151515151515 -0.0127720402098891 -0.00750508013867719 + 87 7.21212121212121 -0.0123210511595858 -0.00737341221715073 + 88 7.27272727272727 -0.0118787393928266 -0.00721963062087733 + 89 7.33333333333333 -0.01144629025111 -0.00704870403080427 + 90 7.39393939393939 -0.0110246125111833 -0.00686481155692192 + 91 7.45454545454545 -0.01061438258812 -0.00667146003968746 + 92 7.51515151515152 -0.0102160821701481 -0.00647158397616956 + 93 7.57575757575758 -0.00983003025649829 -0.00626763069548204 + 94 7.63636363636364 -0.00945641042320117 -0.00606163300012742 + 95 7.6969696969697 -0.009095294018099 -0.00585527114740899 + 96 7.75757575757576 -0.00874665988172817 -0.005649925757223 + 97 7.81818181818182 -0.00841041110213796 -0.00544672299030895 + 98 7.87878787878788 -0.00808638923661268 -0.0052465731369456 + 99 7.93939393939394 -0.0077743863695385 -0.00505020358392876 + 100 8 0 0 diff --git a/unittest/force-styles/tests/dpd_rx_thermo.txt b/unittest/force-styles/tests/dpd_rx_thermo.txt new file mode 100644 index 00000000000..2b0bc78b663 --- /dev/null +++ b/unittest/force-styles/tests/dpd_rx_thermo.txt @@ -0,0 +1,18 @@ +# taken verbatim from examples/PACKAGES/dpd-react/dpdrx-shardlow/thermo.dpdrx +# rx heats of formation for various molecules +# multiple entries can be added to this file, LAMMPS reads the ones it needs +# the entries are in LAMMPS "metal" units (eV) +# Be sure the units are consistent with your input file + +# format of a single entry (one or more lines): +# species DeltaHformation + +rdx 1.989907438211819 +h2 0.000000000000000 +no2 0.343004076201018 +n2 0.000000000000000 +hcn 1.400635733970104 +no 0.935781955892458 +h2o -2.506184777415379 +co -1.145533746031845 +co2 -4.078501848437456 diff --git a/unittest/force-styles/tests/fix-timestep-eos_table_rx.yaml b/unittest/force-styles/tests/fix-timestep-eos_table_rx.yaml new file mode 100644 index 00000000000..2dc6d9a7fd7 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-eos_table_rx.yaml @@ -0,0 +1,92 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 14:41:37 2026 +epsilon: 5e-13 +timestep: 0.001 +skip_tests: +prerequisites: | + atom dpd + pair hybrid/overlay + pair dpd/fdt/energy + pair exp6/rx + fix rx + fix eos/table/rx +pre_commands: "" +post_commands: | + if "$(is_defined(fix,rxfix))==0" then "fix rxfix all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1" + pair_style hybrid/overlay dpd/fdt/energy 8.0 234324 exp6/rx 8.0 + pair_coeff * * dpd/fdt/energy 0.075 0.0 10.0 8.0 + pair_coeff * * exp6/rx ${input_dir}/dpd_rx_exp6_params.txt 1fluid 1fluid exponent 1.0 1.0 8.0 + fix move all nve + fix test all eos/table/rx linear ${input_dir}/dpd_rx_eos_table.txt 21 KEYWORD ${input_dir}/dpd_rx_thermo.txt +input_file: in.dpd-rx +input_coeffs: coeffs.dpd-react +natoms: 32 +run_pos: |2 + 1 1.8532527407740009e+01 1.8447150500163346e+01 1.8595835193723286e+01 + 2 4.2012872415637430e+00 4.7363829442384295e+00 1.8637308120879226e+01 + 3 5.1490793591919575e+00 1.3639042522555550e-01 4.8163419064164223e+00 + 4 1.8303024649941616e+01 4.2569298600554211e+00 4.2355316912339118e+00 + 5 9.4830756542701877e+00 1.8278408472945834e+01 2.4751673580149341e-01 + 6 1.4619369464744441e+01 4.9106761463933557e+00 1.8518217235357522e+01 + 7 1.4275782662158615e+01 4.8773086840014379e-01 4.6658235504752854e+00 + 8 9.2688420556542397e+00 4.7149462980467405e+00 5.2417973969621521e+00 + 9 1.8538556637696825e+01 9.0309823349340750e+00 1.8549444467336407e+01 + 10 4.4541116851028661e+00 1.3665710961594066e+01 3.1605566246696243e-01 + 11 4.9613138434485844e+00 9.1781989693283492e+00 4.8502024197886522e+00 + 12 4.0442207394494678e-01 1.4211758230764895e+01 4.5461723464207688e+00 + 13 9.8346670802056728e+00 9.1083824843410373e+00 1.2765691544433783e-01 + 14 1.4201380069959873e+01 1.4280922805079760e+01 2.3491424516760814e-01 + 15 1.4503072596404206e+01 8.8894003122334908e+00 4.9708582230737433e+00 + 16 8.9444024999132967e+00 1.4725256673687259e+01 4.6616895839632937e+00 + 17 7.8441159217318285e-02 1.8215836047938183e+01 8.9461159711216158e+00 + 18 5.0022613576059021e+00 4.3032010135214813e+00 9.9407262333694710e+00 + 19 4.6454606278251402e+00 1.8351707339745762e+01 1.4137730834208279e+01 + 20 1.8562919760256896e+01 4.1055292634543079e+00 1.4320208664014242e+01 + 21 9.8982544208454293e+00 1.8590315829278651e+01 9.7285846776597875e+00 + 22 1.3898350336125954e+01 5.1055798856370220e+00 9.5517234903321508e+00 + 23 1.4260513993725146e+01 5.9177745100308599e-02 1.4542618843097477e+01 + 24 9.3565701015946185e+00 5.2787527776484620e+00 1.4420558077070362e+01 + 25 2.7073865585179346e-01 9.4897376269406877e+00 9.3060584771266495e+00 + 26 4.6485988709496153e+00 1.4425756304648568e+01 9.5070140369915883e+00 + 27 5.3292022473037717e+00 9.2243266451027512e+00 1.3896072391415283e+01 + 28 1.8573324523652527e+01 1.4121258247367061e+01 1.3572793124342786e+01 + 29 9.4497819108195920e+00 9.2192418589000038e+00 9.0519096002073240e+00 + 30 1.4477327898248657e+01 1.4072698041263148e+01 9.6569341577742946e+00 + 31 1.4661958513999766e+01 9.5572899319527114e+00 1.3844905859084756e+01 + 32 9.4956154416926903e+00 1.4375394584985688e+01 1.4179019282587722e+01 +run_vel: |2 + 1 1.6088685531926696e+00 -1.7364692007568357e-02 2.9266054343986658e-01 + 2 3.4946486609973380e+00 -2.1698806361657330e+00 -1.3998251536785977e+00 + 3 9.6138870230234896e-01 9.4816618765633489e+00 -2.0906517540392944e+00 + 4 6.4406836099737785e-01 2.2430959122540572e-01 1.1526757171163415e+00 + 5 4.3769212832765270e+00 -2.2470990228698395e-01 7.0235229191619536e-02 + 6 -3.7095769026129504e+00 2.0001941685353324e+00 -1.3292067345899428e+00 + 7 -1.3284813858212186e+00 8.2964066122123781e-01 -3.5808798015510899e+00 + 8 2.8784781416183653e+00 1.1068608737699044e+00 2.1621465717597679e+00 + 9 6.8634723365859282e-02 -1.8189638415291226e-01 1.0621004436479822e+00 + 10 -2.1177323045597696e+00 -1.3049202873385310e+00 2.6601956293688782e+00 + 11 -6.9453487968415528e-01 -6.7187161837717169e-01 -3.4784646787116347e+00 + 12 -3.9803335310828811e+00 -2.7219996488937590e+00 3.0446832442730436e+00 + 13 2.5578948017223300e+00 -1.0701167555318203e+00 -6.2345090717047302e+00 + 14 2.5391356966391183e+00 1.5105672818193667e+00 1.3002972753628956e+00 + 15 3.9926208385762267e+00 -6.5666431242393148e+00 2.1167483143906001e+00 + 16 -4.5402391243054971e+00 2.1920488050828943e+00 -2.2770543358065605e+00 + 17 -1.6335096771545694e+00 -2.8740764068947611e+00 -2.2026187925757048e+00 + 18 1.5409852834173225e+00 -9.5256119981851917e-01 2.9903971886360012e+00 + 19 1.4443299976940551e+00 -9.4311442910356680e-01 -1.9820513499686565e+00 + 20 -2.1410201011772556e+00 -9.9866513214634478e-01 1.6852928648463679e+00 + 21 -1.1046510397254004e+00 1.3830059141542006e+00 1.0184054079611851e+00 + 22 -3.3707681149173960e+00 4.7784278227667079e+00 -1.2196702504194412e+00 + 23 -2.3680139518282117e+00 5.4074119126143760e-01 4.4306244754566277e+00 + 24 2.3097803611754797e+00 -2.7990691668683315e-01 3.5851743826506188e-01 + 25 -4.0963725839306218e+00 -2.5752011373838320e-02 -1.9630171551211968e+00 + 26 2.4206679032506044e+00 2.5786137910783848e+00 -3.9692744731481757e+00 + 27 4.5934049547244085e+00 1.7346551119569991e+00 1.5402392317112632e+00 + 28 4.0992802218108739e+00 -2.5002025499996545e+00 6.2769825129410446e+00 + 29 -1.6520993939083966e+00 -9.7752026242368772e-01 1.2165141601319429e+00 + 30 1.8945750445871654e+00 -5.5229879561796280e-01 1.9094617440317168e+00 + 31 -5.7738308605010369e+00 -1.4576411506448392e+00 -2.8482839465698482e+00 + 32 -2.9145196781387135e+00 -1.8695851857314176e+00 -7.1267049464733823e-01 +... diff --git a/unittest/force-styles/tests/fix-timestep-rx.yaml b/unittest/force-styles/tests/fix-timestep-rx.yaml new file mode 100644 index 00000000000..69a6167f69c --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-rx.yaml @@ -0,0 +1,94 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 14:40:50 2026 +epsilon: 5e-13 +timestep: 0.001 +skip_tests: +prerequisites: | + atom dpd + pair hybrid/overlay + pair dpd/fdt/energy + pair exp6/rx + fix rx + fix eos/table/rx +pre_commands: | + variable rx_fix_id delete + variable rx_fix_id index test +post_commands: | + if "$(is_defined(fix,test))==0" then "fix test all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1" + pair_style hybrid/overlay dpd/fdt/energy 8.0 234324 exp6/rx 8.0 + pair_coeff * * dpd/fdt/energy 0.075 0.0 10.0 8.0 + pair_coeff * * exp6/rx ${input_dir}/dpd_rx_exp6_params.txt 1fluid 1fluid exponent 1.0 1.0 8.0 + fix move all nve + fix eosfix all eos/table/rx linear ${input_dir}/dpd_rx_eos_table.txt 21 KEYWORD ${input_dir}/dpd_rx_thermo.txt +input_file: in.dpd-rx +input_coeffs: coeffs.dpd-react +natoms: 32 +run_pos: |2 + 1 1.8532527407740009e+01 1.8447150500163346e+01 1.8595835193723286e+01 + 2 4.2012872415637430e+00 4.7363829442384295e+00 1.8637308120879226e+01 + 3 5.1490793591919575e+00 1.3639042522555550e-01 4.8163419064164223e+00 + 4 1.8303024649941616e+01 4.2569298600554211e+00 4.2355316912339118e+00 + 5 9.4830756542701877e+00 1.8278408472945834e+01 2.4751673580149341e-01 + 6 1.4619369464744441e+01 4.9106761463933557e+00 1.8518217235357522e+01 + 7 1.4275782662158615e+01 4.8773086840014379e-01 4.6658235504752854e+00 + 8 9.2688420556542397e+00 4.7149462980467405e+00 5.2417973969621521e+00 + 9 1.8538556637696825e+01 9.0309823349340750e+00 1.8549444467336407e+01 + 10 4.4541116851028661e+00 1.3665710961594066e+01 3.1605566246696243e-01 + 11 4.9613138434485844e+00 9.1781989693283492e+00 4.8502024197886522e+00 + 12 4.0442207394494678e-01 1.4211758230764895e+01 4.5461723464207688e+00 + 13 9.8346670802056728e+00 9.1083824843410373e+00 1.2765691544433783e-01 + 14 1.4201380069959873e+01 1.4280922805079760e+01 2.3491424516760814e-01 + 15 1.4503072596404206e+01 8.8894003122334908e+00 4.9708582230737433e+00 + 16 8.9444024999132967e+00 1.4725256673687259e+01 4.6616895839632937e+00 + 17 7.8441159217318285e-02 1.8215836047938183e+01 8.9461159711216158e+00 + 18 5.0022613576059021e+00 4.3032010135214813e+00 9.9407262333694710e+00 + 19 4.6454606278251402e+00 1.8351707339745762e+01 1.4137730834208279e+01 + 20 1.8562919760256896e+01 4.1055292634543079e+00 1.4320208664014242e+01 + 21 9.8982544208454293e+00 1.8590315829278651e+01 9.7285846776597875e+00 + 22 1.3898350336125954e+01 5.1055798856370220e+00 9.5517234903321508e+00 + 23 1.4260513993725146e+01 5.9177745100308599e-02 1.4542618843097477e+01 + 24 9.3565701015946185e+00 5.2787527776484620e+00 1.4420558077070362e+01 + 25 2.7073865585179346e-01 9.4897376269406877e+00 9.3060584771266495e+00 + 26 4.6485988709496153e+00 1.4425756304648568e+01 9.5070140369915883e+00 + 27 5.3292022473037717e+00 9.2243266451027512e+00 1.3896072391415283e+01 + 28 1.8573324523652527e+01 1.4121258247367061e+01 1.3572793124342786e+01 + 29 9.4497819108195920e+00 9.2192418589000038e+00 9.0519096002073240e+00 + 30 1.4477327898248657e+01 1.4072698041263148e+01 9.6569341577742946e+00 + 31 1.4661958513999766e+01 9.5572899319527114e+00 1.3844905859084756e+01 + 32 9.4956154416926903e+00 1.4375394584985688e+01 1.4179019282587722e+01 +run_vel: |2 + 1 1.6088685531926696e+00 -1.7364692007568357e-02 2.9266054343986658e-01 + 2 3.4946486609973380e+00 -2.1698806361657330e+00 -1.3998251536785977e+00 + 3 9.6138870230234896e-01 9.4816618765633489e+00 -2.0906517540392944e+00 + 4 6.4406836099737785e-01 2.2430959122540572e-01 1.1526757171163415e+00 + 5 4.3769212832765270e+00 -2.2470990228698395e-01 7.0235229191619536e-02 + 6 -3.7095769026129504e+00 2.0001941685353324e+00 -1.3292067345899428e+00 + 7 -1.3284813858212186e+00 8.2964066122123781e-01 -3.5808798015510899e+00 + 8 2.8784781416183653e+00 1.1068608737699044e+00 2.1621465717597679e+00 + 9 6.8634723365859282e-02 -1.8189638415291226e-01 1.0621004436479822e+00 + 10 -2.1177323045597696e+00 -1.3049202873385310e+00 2.6601956293688782e+00 + 11 -6.9453487968415528e-01 -6.7187161837717169e-01 -3.4784646787116347e+00 + 12 -3.9803335310828811e+00 -2.7219996488937590e+00 3.0446832442730436e+00 + 13 2.5578948017223300e+00 -1.0701167555318203e+00 -6.2345090717047302e+00 + 14 2.5391356966391183e+00 1.5105672818193667e+00 1.3002972753628956e+00 + 15 3.9926208385762267e+00 -6.5666431242393148e+00 2.1167483143906001e+00 + 16 -4.5402391243054971e+00 2.1920488050828943e+00 -2.2770543358065605e+00 + 17 -1.6335096771545694e+00 -2.8740764068947611e+00 -2.2026187925757048e+00 + 18 1.5409852834173225e+00 -9.5256119981851917e-01 2.9903971886360012e+00 + 19 1.4443299976940551e+00 -9.4311442910356680e-01 -1.9820513499686565e+00 + 20 -2.1410201011772556e+00 -9.9866513214634478e-01 1.6852928648463679e+00 + 21 -1.1046510397254004e+00 1.3830059141542006e+00 1.0184054079611851e+00 + 22 -3.3707681149173960e+00 4.7784278227667079e+00 -1.2196702504194412e+00 + 23 -2.3680139518282117e+00 5.4074119126143760e-01 4.4306244754566277e+00 + 24 2.3097803611754797e+00 -2.7990691668683315e-01 3.5851743826506188e-01 + 25 -4.0963725839306218e+00 -2.5752011373838320e-02 -1.9630171551211968e+00 + 26 2.4206679032506044e+00 2.5786137910783848e+00 -3.9692744731481757e+00 + 27 4.5934049547244085e+00 1.7346551119569991e+00 1.5402392317112632e+00 + 28 4.0992802218108739e+00 -2.5002025499996545e+00 6.2769825129410446e+00 + 29 -1.6520993939083966e+00 -9.7752026242368772e-01 1.2165141601319429e+00 + 30 1.8945750445871654e+00 -5.5229879561796280e-01 1.9094617440317168e+00 + 31 -5.7738308605010369e+00 -1.4576411506448392e+00 -2.8482839465698482e+00 + 32 -2.9145196781387135e+00 -1.8695851857314176e+00 -7.1267049464733823e-01 +... diff --git a/unittest/force-styles/tests/in.dpd-fdt b/unittest/force-styles/tests/in.dpd-fdt new file mode 100644 index 00000000000..22f350326f4 --- /dev/null +++ b/unittest/force-styles/tests/in.dpd-fdt @@ -0,0 +1,20 @@ +variable newton_pair index on +variable newton_bond index on +variable units index metal +variable input_dir index . +variable data_file index ${input_dir}/data.dpd-react +variable pair_style index 'zero 8.0' + +units ${units} +atom_style dpd +atom_modify map array +boundary p p p +newton ${newton_pair} ${newton_bond} +comm_modify mode single vel yes +# the Shardlow splitting requires a box larger than 2*(cutoff+skin) +neighbor 1.0 bin +neigh_modify delay 2 every 2 check no +timestep 0.001 + +pair_style ${pair_style} +read_data ${data_file} diff --git a/unittest/force-styles/tests/in.dpd-rx b/unittest/force-styles/tests/in.dpd-rx new file mode 100644 index 00000000000..0acee03b1cf --- /dev/null +++ b/unittest/force-styles/tests/in.dpd-rx @@ -0,0 +1,28 @@ +variable newton_pair index on +variable newton_bond index on +variable units index metal +variable input_dir index . +variable data_file index ${input_dir}/data.dpd-react +variable pair_style index 'zero 8.0' +# id of the "fix rx" instance; the fix-timestep test for fix rx itself +# overrides this with "test" so the driver finds the fix under test +variable rx_fix_id index rxfix + +units ${units} +atom_style dpd +atom_modify map array +boundary p p p +newton ${newton_pair} ${newton_bond} +comm_modify mode single vel yes +neigh_modify delay 2 every 2 check no +timestep 0.001 + +# the DPD-REACT pair styles need the per-atom species concentrations that +# "fix rx" creates through two internal fix property/atom instances. the fix +# must therefore exist before the pair coefficients are read. the two extra +# data file sections are only present in the data file written by the test. + +fix ${rx_fix_id} all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1 + +pair_style ${pair_style} +read_data ${data_file} fix ${rx_fix_id}_SPECIES NULL NULL fix ${rx_fix_id}_SPECIES_OLD NULL NULL diff --git a/unittest/force-styles/tests/mol-pair-dpd_fdt_energy.yaml b/unittest/force-styles/tests/mol-pair-dpd_fdt_energy.yaml new file mode 100644 index 00000000000..527ac25ffe3 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-dpd_fdt_energy.yaml @@ -0,0 +1,97 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 14:36:13 2026 +epsilon: 5e-13 +skip_tests: extract extract_omp single +prerequisites: | + atom dpd + pair dpd/fdt/energy + fix shardlow + fix eos/cv +pre_commands: "" +post_commands: | + fix eosfix all eos/cv 0.0005 + fix ssafix all shardlow + fix 1 all nve +input_file: in.dpd-fdt +pair_style: dpd/fdt/energy 7.0 234324 +pair_coeff: | + * * 0.075 0.022 3.2e-5 7.0 +extract: "" +natoms: 32 +init_vdwl: 0.28905194279717583 +init_coul: 0 +init_stress: |2- + 1.6738367161943455e+00 1.6080173263129940e+00 1.6605823270677822e+00 -1.4788704516794197e-02 3.1744826196034609e-02 -8.7962816591994168e-03 +init_forces: |2 + 1 1.5208591640901705e-02 -2.0981477787812199e-03 5.7087693393971014e-03 + 2 1.4347954040365297e-02 -6.4802558350064935e-03 5.1740196975988044e-03 + 3 -1.4189656254660808e-02 9.2969440236142162e-03 -4.7531630319347165e-03 + 4 2.0786385662409604e-02 4.0962812785026300e-03 1.6657910653766539e-02 + 5 -3.1569111411828749e-03 1.9226991340493112e-02 -8.7293883033366469e-03 + 6 -2.1408713776792775e-02 -4.7471864125992538e-03 2.7184510884411444e-03 + 7 -1.1323498382836120e-02 -1.3299668538404228e-02 2.6095613673368778e-03 + 8 4.8931859277024830e-03 -7.3178077170063058e-03 -1.5439789865642154e-02 + 9 1.0859098808993356e-02 1.9228776210095666e-02 4.3641506578144251e-03 + 10 5.5007588381497108e-03 -2.2812923633464910e-04 -1.5557860378507244e-02 + 11 -9.1982098039036942e-03 2.0941413465438096e-04 -2.6688201621011031e-03 + 12 -1.1550724788394109e-02 -9.9077559718286634e-03 2.0337438198881896e-03 + 13 -4.4270613921281905e-03 1.0845286828066479e-02 3.5537270403991888e-03 + 14 -2.5240054811204746e-04 -1.5641103844267673e-02 1.6681338884183754e-03 + 15 -3.3426479944340141e-03 1.6974530187302203e-02 -6.1814438370013476e-03 + 16 1.5678943956863409e-02 -1.9962533802125721e-02 7.2372750575627432e-03 + 17 -1.1797517707443153e-03 2.3562986756691415e-02 7.2260937149516667e-03 + 18 -1.2622873051673441e-02 2.1152673237656485e-04 -6.4984690476936023e-03 + 19 2.2286465187187111e-03 7.8371435905535657e-03 8.1425801981501456e-03 + 20 1.1195818255352999e-02 6.7288379702818571e-03 -2.1215480961957543e-02 + 21 -3.9871851334693544e-03 8.3305151504605782e-03 -8.1887248738318069e-04 + 22 1.0222529473026503e-02 -1.3775288891834214e-02 5.8916614760761736e-03 + 23 -1.1407447775654948e-02 8.2223197171492693e-04 -1.2529758731159694e-02 + 24 1.1178468858361056e-02 -1.8027916149679281e-02 -2.6979630207141052e-04 + 25 5.8567594231483397e-03 -1.2447840523183118e-02 -1.9662884071594208e-03 + 26 1.2132702146784826e-02 -1.3505333927169861e-02 -2.8333218286346689e-03 + 27 -1.4621285215972881e-02 1.3618130866838097e-02 6.1484571346691963e-03 + 28 1.0755881519629537e-02 -2.5537356976962759e-03 2.1658975507654089e-02 + 29 2.4159470199261153e-03 1.9898162719089070e-02 8.3537167792394444e-03 + 30 -1.4390187775159401e-02 -2.1708563631651443e-03 -1.7845123533412142e-02 + 31 -1.7914033039965263e-02 -1.9414366450829299e-03 5.9995031326514105e-03 + 32 1.7109157547505853e-03 -1.6782762426569731e-02 2.1608463239793708e-03 +run_vdwl: 0.2900034898810438 +run_coul: 0 +run_stress: |2- + 1.6751169055383213e+00 1.6107254555926287e+00 1.6612891268214598e+00 -1.4376686373013169e-02 3.2103986042246499e-02 -9.4683448274293907e-03 +run_forces: |2 + 1 1.5260147324322444e-02 -1.8788360124499406e-03 5.8614380949820188e-03 + 2 1.3996839701891575e-02 -6.1500910085538034e-03 4.9204948439606723e-03 + 3 -1.4616820823400876e-02 8.3440725771416757e-03 -4.6437769455263695e-03 + 4 2.0949056703900803e-02 3.8562523221679101e-03 1.6412079864100818e-02 + 5 -3.8569509258583618e-03 1.9041446329043067e-02 -8.8701107732586711e-03 + 6 -2.0808024342793559e-02 -5.0046612239343577e-03 2.9817109371794346e-03 + 7 -1.1139609648728420e-02 -1.3078422350993222e-02 3.1468253540225047e-03 + 8 4.6093868498851328e-03 -7.0684263964620585e-03 -1.5745021812115338e-02 + 9 1.0780712306318744e-02 1.9031184538113810e-02 4.0936516882430357e-03 + 10 5.5987904249170141e-03 3.5921719871596209e-04 -1.5699176314475254e-02 + 11 -9.0280876345889723e-03 4.7454979936147794e-05 -2.5065836771074115e-03 + 12 -1.1070077301859015e-02 -9.5015649463497717e-03 1.6965513472672654e-03 + 13 -4.2909295391084252e-03 1.1137844728069472e-02 4.4266779611568541e-03 + 14 -6.2623477258021045e-04 -1.6004250027708812e-02 1.4941001858680128e-03 + 15 -3.9177151614242078e-03 1.7612986996731726e-02 -6.5100940412244172e-03 + 16 1.5864092311375110e-02 -1.9901153578208958e-02 7.2422701838700879e-03 + 17 -9.3756247478028222e-04 2.3668689173642093e-02 7.4368795530087321e-03 + 18 -1.2959689395839731e-02 3.2504048721856277e-04 -6.4507572570850118e-03 + 19 1.9757953548012385e-03 7.8067505043660007e-03 8.5073387885640506e-03 + 20 1.1250321688329089e-02 6.7971205911058520e-03 -2.1370146160845524e-02 + 21 -3.3784136552371868e-03 8.1425894790264335e-03 -1.0048015886223814e-03 + 22 1.0557579205515834e-02 -1.4552099349654891e-02 6.0681006051287534e-03 + 23 -1.1210235671227420e-02 4.8051363232649857e-04 -1.3008033352309670e-02 + 24 1.0761234473864213e-02 -1.8420493350821392e-02 -4.5639010717894724e-04 + 25 6.8301395165219179e-03 -1.2293792524505992e-02 -1.3510830047439555e-03 + 26 1.1586882203490165e-02 -1.3821388499740019e-02 -2.6343220233010921e-03 + 27 -1.5386707847226835e-02 1.3523614178564708e-02 5.6627529161135332e-03 + 28 1.0603788230669160e-02 -2.6637321532583117e-03 2.1270970595891156e-02 + 29 2.4396878558898163e-03 2.0273300739405722e-02 8.0537162661264532e-03 + 30 -1.4704241287656211e-02 -2.0162569777386948e-03 -1.7661781471072335e-02 + 31 -1.7396471708842787e-02 -1.5778136754579541e-03 6.3016951233264874e-03 + 32 2.2633180394602400e-03 -1.6515096379737474e-02 2.3348242200565130e-03 +... diff --git a/unittest/force-styles/tests/mol-pair-exp6_rx.yaml b/unittest/force-styles/tests/mol-pair-exp6_rx.yaml new file mode 100644 index 00000000000..7a417f36aa1 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-exp6_rx.yaml @@ -0,0 +1,118 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 14:33:24 2026 +epsilon: 5e-13 +skip_tests: extract extract_omp single +prerequisites: | + atom dpd + pair hybrid/overlay + pair dpd/fdt/energy + pair exp6/rx + fix rx + fix eos/table/rx +pre_commands: "" +post_commands: | + if "$(is_defined(fix,rxfix))==0" then "fix rxfix all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1" + pair_coeff * * exp6/rx ${input_dir}/dpd_rx_exp6_params.txt 1fluid 1fluid exponent 1.0 1.0 8.0 + set type 1 d_rdx 0.30 + set type 1 d_hcn 0.20 + set type 1 d_no2 0.10 + set type 1 d_no 0.15 + set type 1 d_h2o 0.15 + set type 1 d_n2 0.05 + set type 1 d_h2 0.03 + set type 1 d_co 0.01 + set type 1 d_co2 0.01 + set type 2 d_rdx 0.10 + set type 2 d_hcn 0.30 + set type 2 d_no2 0.20 + set type 2 d_no 0.05 + set type 2 d_h2o 0.10 + set type 2 d_n2 0.10 + set type 2 d_h2 0.05 + set type 2 d_co 0.05 + set type 2 d_co2 0.05 + fix eosfix all eos/table/rx linear ${input_dir}/dpd_rx_eos_table.txt 21 KEYWORD ${input_dir}/dpd_rx_thermo.txt + fix_modify rxfix rx_chemistry off +input_file: in.dpd-rx +pair_style: hybrid/overlay dpd/fdt/energy 8.0 234324 exp6/rx 8.0 +pair_coeff: | + * * dpd/fdt/energy 0.0 0.0 10.0 8.0 +extract: "" +natoms: 32 +init_vdwl: -0.05241782740400008 +init_coul: 0 +init_stress: |- + -1.9245124775244579e-01 -2.0222727527120180e-01 -1.9777575830715594e-01 3.5186995487554804e-03 -1.1914386771068861e-02 2.3213574244556057e-03 +init_forces: |2 + 1 -4.3074179410066207e-03 -1.3559921798610863e-04 -1.7938933064753340e-03 + 2 -4.9457731604708982e-05 3.8838203443123650e-04 -2.9115530178125827e-04 + 3 5.4166792824045113e-05 -3.1848989470793370e-04 2.2629338950822317e-04 + 4 -1.5331455313699999e-03 -1.2799295397370458e-05 -8.9374442323596269e-04 + 5 6.6164805182653583e-04 -6.8425094365179729e-04 2.3691902750942468e-05 + 6 1.1839325106709196e-03 6.3071278452796718e-04 -1.2342829638927596e-03 + 7 8.4840537407784324e-04 3.1213157328007906e-04 -1.3515837595593142e-04 + 8 7.3095999231387389e-05 8.8980183618936782e-04 3.7258429452452605e-04 + 9 -1.5633106521876765e-03 -9.7513774268639095e-04 -3.3586231993157920e-04 + 10 -9.1266178033236431e-05 -2.7151590885695265e-04 4.2723406814921335e-04 + 11 1.1350839715930702e-03 6.2048599186159293e-05 -1.6452921951967065e-04 + 12 -1.1812390894047072e-04 6.4048805738893566e-04 1.3305851720543584e-04 + 13 1.0706266746933111e-03 -1.9514219104399132e-03 -1.5814792127303871e-03 + 14 9.4226616514742241e-04 1.7867440873020801e-03 -1.1395576922400587e-03 + 15 -3.5092569467986342e-04 -2.0730292015428628e-03 6.5296908319418655e-04 + 16 -2.7384380063307168e-04 2.6570246411361547e-04 -3.7054524124307658e-04 + 17 -1.0918098291531177e-03 -2.5446141535298865e-03 5.5815082484022454e-05 + 18 4.3762582975716920e-04 4.3523876480372497e-04 5.5745029693879075e-04 + 19 -3.3032140113400173e-04 -1.0306941155423180e-04 -1.2763460774195372e-04 + 20 -1.6966039499602700e-03 -7.4143114454432537e-04 1.1677963267419727e-03 + 21 6.8543387061786702e-04 -1.1225822835906538e-04 3.2314605111122995e-04 + 22 -6.9185718105871504e-04 2.5280357096888789e-03 -1.2303579633422370e-04 + 23 2.4292455289692326e-03 2.4633749772522140e-04 2.7254075891748938e-03 + 24 -1.0107935365617298e-03 4.5565150069048800e-03 9.5154733863864801e-04 + 25 -6.5212349810792611e-04 2.6231617509962172e-04 2.1887196548383962e-05 + 26 -7.4368614164213760e-04 4.2127048351747975e-04 1.8834470565195685e-05 + 27 3.5193242127091518e-03 -2.9545205471625422e-03 4.0394765990641097e-04 + 28 -1.8447004911382394e-03 2.5419790485647664e-04 -1.2332486117224953e-03 + 29 1.8787262780388283e-04 -8.4352683696450425e-04 -1.2250833235972664e-04 + 30 2.4616950070693046e-03 1.6034728513000145e-04 2.2899613694690266e-03 + 31 1.6195424155252469e-04 -2.4060525028837538e-04 -8.6328062543214131e-04 + 32 4.9701060866811936e-04 1.2199942352653498e-04 5.8291393685455981e-05 +run_vdwl: -0.05269757004068524 +run_coul: 0 +run_stress: |- + -1.9290887513587021e-01 -2.0298122205420027e-01 -1.9828694144970266e-01 3.2769953763738362e-03 -1.1712839006168239e-02 2.2514447368977880e-03 +run_forces: |2 + 1 -4.3188590803762738e-03 -1.7645196496834226e-04 -1.7957067901980520e-03 + 2 -4.0978196055688068e-05 3.8538714299248596e-04 -2.8729321641156834e-04 + 3 6.1355773212246154e-05 -3.0523514449500326e-04 2.2121083620689307e-04 + 4 -1.5346441805233219e-03 1.3134827490296977e-05 -8.6466487922625930e-04 + 5 6.8708202342807360e-04 -6.8504582167836761e-04 1.9728941062419558e-05 + 6 1.0790995569851423e-03 6.7549224881939714e-04 -1.2788226180699179e-03 + 7 8.4445740144695766e-04 3.0427045099729380e-04 -1.5741030653604061e-04 + 8 9.5557538793583093e-05 8.8134400065434729e-04 3.9164220705333828e-04 + 9 -1.5462097986822286e-03 -9.6494939902907638e-04 -3.0660386520282498e-04 + 10 -9.4200598159841116e-05 -2.8174686687685744e-04 4.3251587369656162e-04 + 11 1.1070110181221485e-03 7.7649908059685782e-05 -1.7651298083324425e-04 + 12 -1.3295353890257442e-04 6.4232029486153757e-04 1.5599161052884500e-04 + 13 1.0814877767623475e-03 -2.0526265747686330e-03 -1.7452217586747352e-03 + 14 9.6819838658958226e-04 1.8680969227547757e-03 -1.1557688218313651e-03 + 15 -3.0259243298743520e-04 -2.1993402841777141e-03 7.7025234164153919e-04 + 16 -2.8373780920337764e-04 2.7514581989754457e-04 -3.7396071414247736e-04 + 17 -1.0980780509100025e-03 -2.5891617922299678e-03 2.2049138601359778e-05 + 18 4.4986833561116025e-04 4.2734657212443805e-04 5.6096088503846449e-04 + 19 -3.2321178037148976e-04 -1.0430193819514184e-04 -1.3217734312480654e-04 + 20 -1.7030157032364146e-03 -7.4968137390886598e-04 1.1841942971205068e-03 + 21 6.6605801810649653e-04 -1.0241815479079468e-04 3.2452127576383980e-04 + 22 -7.1513254883276726e-04 2.6927382150832790e-03 -1.9455683179608497e-04 + 23 2.4113077570773094e-03 2.7024008387063194e-04 2.8019842891983120e-03 + 24 -9.3794860995895148e-04 4.6373639549989569e-03 1.0110500812993727e-03 + 25 -7.0407457695967910e-04 2.6086346672357197e-04 -5.3005142560320385e-06 + 26 -7.3896894580518558e-04 4.3124692116483943e-04 1.5867607460410209e-05 + 27 3.5774602065998069e-03 -2.9551070976690037e-03 4.3514701635890001e-04 + 28 -1.8024006720028462e-03 2.5555223696588071e-04 -1.1904206672161050e-03 + 29 2.0491808638433586e-04 -8.6807260803332725e-04 -9.1152555329971187e-05 + 30 2.4835972669229839e-03 1.4477661184248434e-04 2.2744444853355240e-03 + 31 8.3777420945357396e-05 -3.0891101793378693e-04 -9.2114035912040917e-04 + 32 4.7576995598054778e-04 1.0008035945343519e-04 5.5153335603608711e-05 +... diff --git a/unittest/force-styles/tests/mol-pair-table_rx.yaml b/unittest/force-styles/tests/mol-pair-table_rx.yaml new file mode 100644 index 00000000000..b8003087348 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-table_rx.yaml @@ -0,0 +1,119 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 14:32:35 2026 +epsilon: 5e-13 +skip_tests: extract extract_omp single +prerequisites: | + atom dpd + pair hybrid/overlay + pair dpd/fdt/energy + pair table/rx + fix rx + fix eos/table/rx +pre_commands: "" +post_commands: | + if "$(is_defined(fix,rxfix))==0" then "fix rxfix all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1" + pair_coeff * * table/rx ${input_dir}/dpd_rx_pair_table.txt LJ_A 1fluid 1fluid 8.0 + pair_coeff 2 2 table/rx ${input_dir}/dpd_rx_pair_table.txt LJ_B h2o h2o 8.0 + set type 1 d_rdx 0.30 + set type 1 d_hcn 0.20 + set type 1 d_no2 0.10 + set type 1 d_no 0.15 + set type 1 d_h2o 0.15 + set type 1 d_n2 0.05 + set type 1 d_h2 0.03 + set type 1 d_co 0.01 + set type 1 d_co2 0.01 + set type 2 d_rdx 0.10 + set type 2 d_hcn 0.30 + set type 2 d_no2 0.20 + set type 2 d_no 0.05 + set type 2 d_h2o 0.10 + set type 2 d_n2 0.10 + set type 2 d_h2 0.05 + set type 2 d_co 0.05 + set type 2 d_co2 0.05 + fix eosfix all eos/table/rx linear ${input_dir}/dpd_rx_eos_table.txt 21 KEYWORD ${input_dir}/dpd_rx_thermo.txt + fix_modify rxfix rx_chemistry off +input_file: in.dpd-rx +pair_style: hybrid/overlay dpd/fdt/energy 8.0 234324 table/rx linear 1000 +pair_coeff: | + * * dpd/fdt/energy 0.0 0.0 10.0 8.0 +extract: "" +natoms: 32 +init_vdwl: -0.41785599042643795 +init_coul: 0 +init_stress: |- + -4.3356507891899765e-01 -4.2449787645611720e-01 -4.6597044500033002e-01 -1.4137820876106997e-03 2.0251602533324767e-02 -6.7452656665755355e-03 +init_forces: |2 + 1 4.9789710886279110e-03 1.4876134267074919e-03 2.5344135929303195e-03 + 2 -2.0310874882240385e-04 -5.8848083666942141e-04 1.8988898414349633e-04 + 3 -2.5224337516745765e-03 1.5000326664127233e-03 6.2391830072859632e-04 + 4 5.6910979630298442e-03 3.9865709081096838e-03 -1.5373000485816544e-04 + 5 -3.2052436361802803e-04 1.3570707237161644e-03 -1.6940686270920295e-03 + 6 -2.6926989790624083e-03 -1.8549883761576438e-03 1.3046887417418826e-03 + 7 -4.9617228309583152e-03 -4.5568533469604036e-03 2.5382107193016944e-04 + 8 4.0581853570012251e-04 -1.3034765102266106e-03 1.3383726251637153e-04 + 9 2.4280421269243283e-03 1.5783738217345908e-03 6.4904777391759281e-04 + 10 1.6325789876438001e-03 1.0372059230207766e-03 -8.3148253202802269e-04 + 11 -5.6899356299422172e-04 7.1675148056243930e-04 9.1373960506117412e-05 + 12 -5.3602379404162244e-04 -2.9341570232354307e-04 1.1190277287993419e-03 + 13 -1.1382699660555707e-03 2.1844476131194154e-03 1.9764148345518011e-03 + 14 -1.5001243734333481e-03 -1.2702019829075165e-03 3.5770803148505728e-04 + 15 4.8146707046271175e-04 1.1387097890048616e-03 -1.2799645151639859e-03 + 16 1.4300297323352152e-03 -3.8466921092942582e-03 2.4477750805535015e-03 + 17 1.6427532633865650e-03 2.1491931204854582e-03 8.1704832060724292e-05 + 18 8.4090290640345504e-04 8.7357077852309747e-05 -5.4731116511924399e-04 + 19 -3.1252494260421973e-04 2.2383360279628565e-04 6.3420747089509301e-05 + 20 2.2781544353041409e-03 1.1158653097422641e-03 -6.9797091886587359e-04 + 21 -1.4719410115521725e-03 4.3775577079468520e-04 -1.1746470613233895e-03 + 22 -5.8410624846915533e-05 -2.6124280866698080e-03 -1.3684516392131470e-04 + 23 -3.5143122181805152e-03 -1.4695648177546856e-03 -3.3948308071643143e-03 + 24 3.9788413802148695e-03 -7.0770384594318128e-03 -2.1176123611970892e-03 + 25 -2.0726016030531863e-04 8.6789093053603978e-04 1.7179843825256762e-04 + 26 7.9489193436904268e-04 -7.2648079608092866e-04 -8.4272501137135037e-04 + 27 -5.7029988049676454e-03 5.1522851863859053e-03 -1.0281177968210179e-03 + 28 3.5454288751271025e-03 5.8180137983813909e-04 2.5272278508858053e-03 + 29 -3.5560227220317146e-04 5.1702151142506104e-04 1.3283793917679659e-03 + 30 -3.6659403671184085e-03 -1.3072592574688274e-04 -2.9354278507924083e-03 + 31 4.2908558068965744e-05 -6.7934052958722960e-04 1.0443890380326705e-03 + 32 -4.3899608515921289e-04 2.8990723756644856e-04 -6.4101846175285658e-05 +run_vdwl: -0.41721933059368893 +run_coul: 0 +run_stress: |- + -4.3277014451227741e-01 -4.2026996624798513e-01 -4.6453825242449648e-01 -2.7672271383877046e-03 1.9276693304041283e-02 -6.6769445998862247e-03 +run_forces: |2 + 1 4.9962280518811254e-03 1.5227540768193136e-03 2.5318747237208748e-03 + 2 -2.4045589652641635e-04 -5.7021450606399115e-04 2.1056929708686799e-04 + 3 -2.4667999124278438e-03 1.4074303738045402e-03 6.2411160673465395e-04 + 4 5.6326660279896858e-03 3.9042490423497681e-03 -2.5102042730081888e-04 + 5 -2.9308942452750892e-04 1.4726297892265583e-03 -1.7965933185904669e-03 + 6 -2.5328844349526425e-03 -1.8884334177684014e-03 1.4374153340020570e-03 + 7 -4.9234155083492217e-03 -4.5132273127430058e-03 2.2039444845524042e-04 + 8 4.1270252746716503e-04 -1.3271691571346282e-03 8.9869808472949845e-05 + 9 2.3848704148948102e-03 1.5433965322872213e-03 6.1227880692452325e-04 + 10 1.5735165597403132e-03 1.0238812143123594e-03 -8.5636569493717767e-04 + 11 -5.5635972742315576e-04 7.1530429654803379e-04 1.0007920939419208e-04 + 12 -5.1246068834969035e-04 -3.5206374514074263e-04 1.0269603427205199e-03 + 13 -1.1498925355550992e-03 2.3478901275926587e-03 2.1397738181565215e-03 + 14 -1.5185773521951022e-03 -1.3308875409365917e-03 3.7490866049556723e-04 + 15 6.9401591388569312e-04 1.1229046402229507e-03 -1.4877990654021019e-03 + 16 1.0758743607484690e-03 -3.5771427424882520e-03 2.5467428276390617e-03 + 17 1.6964808641690529e-03 2.2252743854737586e-03 1.3630048518853931e-04 + 18 8.8150300423000952e-04 8.4840393850625271e-05 -5.6625604407152942e-04 + 19 -3.1447102637813988e-04 2.3687409796678918e-04 7.5442377372334879e-05 + 20 2.3080181816471125e-03 1.1234127547405201e-03 -6.9797351777358156e-04 + 21 -1.4995704137837974e-03 4.3695561643402182e-04 -1.1619805461444391e-03 + 22 -5.4505392882666227e-05 -2.8662547605401694e-03 2.9939930391626669e-05 + 23 -3.5363081818132244e-03 -1.4920912580057481e-03 -3.4157538326985491e-03 + 24 3.9504013767527298e-03 -7.2366015276083794e-03 -2.2658417963882602e-03 + 25 -2.1794955522881350e-04 8.8397320744204350e-04 1.6065230930633495e-04 + 26 7.8670158739655664e-04 -7.3392740105118477e-04 -8.0535530445680461e-04 + 27 -5.7062553297141383e-03 5.1859722942296967e-03 -1.0222677133657236e-03 + 28 3.3211918162340758e-03 5.4396453847008013e-04 2.3247207943530961e-03 + 29 -3.7843125032648473e-04 5.7507353124487811e-04 1.3703363705167915e-03 + 30 -3.5347081560237886e-03 -1.5194985686190930e-04 -2.7965429930267884e-03 + 31 1.4000442925529689e-04 -5.9530479707322649e-04 1.1839028309331620e-03 + 32 -4.1804032983436181e-04 2.7848711040041147e-04 -7.2523727708673387e-05 +... From 695063033dc4e7b4ecd65dd85bc89f137409664a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:06:35 +0000 Subject: [PATCH 048/120] KOKKOS: fix the density energy tally of pair multi/lucy/rx The local density contribution to the energy was halved when newton off was set, and it was never added to the per-atom energy at all, so "compute pe/atom pair" returned zero for this style under KOKKOS. The CPU style tallies the term with ev_tally(0,0,nlocal,newton_pair,...). Both indices are local, so the whole term goes into the global energy for newton on and newton off alike, and into the per-atom energy of the first atom. Do the same, and drop the FIXME comment that marked the guess. The new reference exercises this: on the sparse lattice of the other DPD-REACT fixtures every neighbor sits where the Lucy weight vanishes, which pins the local density to the first table bin and freezes the energy, so this one uses a denser system whose density lands in the middle of the table. --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 14 ++- .../force-styles/tests/data.dpd-react-dense | 83 ++++++++++++ .../tests/dpd_rx_multibody_table.txt | 109 ++++++++++++++++ unittest/force-styles/tests/in.dpd-rx-dense | 27 ++++ .../tests/mol-pair-multi_lucy_rx.yaml | 118 ++++++++++++++++++ 5 files changed, 347 insertions(+), 4 deletions(-) create mode 100644 unittest/force-styles/tests/data.dpd-react-dense create mode 100644 unittest/force-styles/tests/dpd_rx_multibody_table.txt create mode 100644 unittest/force-styles/tests/in.dpd-rx-dense create mode 100644 unittest/force-styles/tests/mol-pair-multi_lucy_rx.yaml diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 8d38bcee7b1..1d01999c026 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -283,8 +283,9 @@ template KOKKOS_INLINE_FUNCTION void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii, EV_FLOAT& ev) const { - // The f array is atomic for Half/Thread neighbor style + // The f and eatom arrays are atomic for Half/Thread neighbor style Kokkos::View::value,Kokkos::MemoryTraits::value> > a_f = f; + Kokkos::View::value,Kokkos::MemoryTraits::value> > v_eatom = d_eatom; int i,jj,jnum,itype,jtype,itable; KK_FLOAT xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; @@ -437,9 +438,14 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute(1.0):static_cast(0.5))*static_cast(evdwl); + // the CPU style tallies this term with ev_tally(0,0,nlocal,newton_pair,...), + // i.e. with i == j == 0. both indices are always local, so the whole term + // ends up in the global energy for newton on and off alike, and in the + // per-atom energy of the first atom + if (EVFLAG) { + if (eflag_global) ev.evdwl += static_cast(evdwl); + if (eflag_atom) v_eatom[0] += static_cast(evdwl); + } } template diff --git a/unittest/force-styles/tests/data.dpd-react-dense b/unittest/force-styles/tests/data.dpd-react-dense new file mode 100644 index 00000000000..c90e867afdd --- /dev/null +++ b/unittest/force-styles/tests/data.dpd-react-dense @@ -0,0 +1,83 @@ +LAMMPS data file via write_data, version 2 Sep 2026, timestep = 0, units = metal + +32 atoms +2 atom types + +0 9 xlo xhi +0 9 ylo yhi +0 9 zlo zhi + +Masses + +1 222.12 +2 222.12 + +Atoms # dpd + +1 2 2065 8.852014983050532 8.815820130294105 8.888929853024393 -1 -1 -1 +2 2 2065 2.4356043654892616 2.3025707780162668 8.757066119395693 0 0 -1 +3 1 2065 2.3568167024323796 0.06831778100147741 2.0669452918306668 0 0 0 +4 2 2065 0.2705154108677597 2.002510454437002 2.4932077226895872 0 0 0 +5 1 2065 4.25003924614286 0.10960992305055724 0.21397671071532032 0 0 0 +6 1 2065 6.908444506981617 2.4268288400381937 0.16231452192287638 0 0 0 +7 2 2065 6.695100536497822 0.10471691889908019 2.427255936841134 0 0 0 +8 2 2065 4.454638280651829 2.4555829152956528 2.082057374032241 0 0 0 +9 1 2065 8.974226507579083 4.524912881629967 8.910801554848813 -1 0 -1 +10 1 2065 2.150660251640091 6.9468493150066815 0.04643731729427225 0 0 0 +11 1 2065 2.212047381262317 4.430336875762016 2.021870932202726 0 0 0 +12 1 2065 8.732391773458753 6.65853652125622 2.223312753286824 -1 0 0 +13 1 2065 4.799621772207144 4.4431254854626605 8.91003417093774 0 0 -1 +14 2 2065 6.580244693593236 6.67256522151761 8.953678046471289 0 0 -1 +15 1 2065 6.9484595110167096 4.609001657836606 2.440863259830914 0 0 0 +16 1 2065 4.789029183419901 6.863485738268814 2.2048030839556843 0 0 0 +17 2 2065 8.989480587881747 0.2002405285370725 4.542563122577296 -1 0 0 +18 1 2065 2.3784920486754237 2.415862087842944 4.544110376361809 0 0 0 +19 1 2065 2.0903470050265764 8.912113481672533 6.8412864702713145 0 -1 0 +20 1 2065 0.24080270488783842 2.4210610499005116 6.573065677901295 0 0 0 +21 1 2065 4.245608065857369 0.0347628648089072 4.3594688433033735 0 0 0 +22 1 2065 6.8299663845356395 2.2450248904968726 4.283334580940816 0 0 0 +23 2 2065 6.541778015667469 0.21310932315565148 6.478394277034511 0 0 0 +24 2 2065 4.759566459040887 2.183477100186738 6.499622838501643 0 0 0 +25 1 2065 0.04862565200246203 4.551333205379235 4.457182808805808 0 0 0 +26 1 2065 1.9577506846784385 6.5157573905148345 4.7844623828234445 0 0 0 +27 1 2065 2.42538504715794 4.396487583497766 7.016815846956715 0 0 0 +28 1 2065 8.711172118601935 7.01979734272221 7.033939132180037 -1 0 0 +29 1 2065 4.221305549527195 4.682370903567584 4.207776260379598 0 0 0 +30 2 2065 6.717628100732168 6.875489005551436 4.593716302976811 0 0 0 +31 2 2065 6.603353273194913 4.608462586909748 6.880698192133893 0 0 0 +32 1 2065 4.42756239093261 6.691104404368021 6.89172421332529 0 0 0 + +Velocities + +1 3.5323967893385717 5.216096508014665 1.3708434444210114 +2 4.650440480021299 1.0788025437307016 -2.8814737870436216 +3 4.186791671729711 0.9766379074756149 -1.1533481984488607 +4 0.05900974034336235 -4.267028889450987 0.9274518591542125 +5 -0.8425212509000386 -2.8746995105721793 4.905198508930825 +6 -1.3389016516120917 -0.7603801504355002 5.772874411343121 +7 -3.129828591559906 2.7181611251854623 -2.519445787049951 +8 -1.9442912853155758 1.3599406383113317 -5.467756388755713 +9 -2.207677467738002 -2.178492502664742 -5.010646286038301 +10 1.3947050764794524 0.9714307575254394 -6.435436635455211 +11 -0.251450543576089 1.2820891208012333 1.6796304126623556 +12 -6.527013637994316 -1.5167903655971036 -0.06033427066775072 +13 4.526518862337593 -3.8165187877346085 -5.057180374607168 +14 0.6556634436271237 -1.127312852973388 2.041337429016479 +15 4.429966587269975 -1.202358534105398 -1.080495437940248 +16 -3.4626616313987886 -1.727021889839128 3.098829758244288 +17 1.134000744551347 0.7349321573593911 2.5954038171862837 +18 3.4893804341386514 1.0676572851749113 0.01720606119331616 +19 -6.02417459901818 -0.06753627996071408 -1.4225027117653557 +20 0.3248160537693562 -3.6811544322929524 1.5308000438054907 +21 0.7304380966673707 -3.778126157203968 -2.2799828461404 +22 -0.27626717184024635 1.2961469241142007 -0.0811103192294918 +23 0.3555251615230845 3.375744803062647 1.545901400620238 +24 1.1677730102523523 1.426783147358595 4.958651760827444 +25 -2.5063096618586185 1.8686529395116254 -4.638065815084418 +26 0.7141628766450027 1.7952465772277841 -0.03696499697194383 +27 -1.3282611422653927 3.1392613954372544 1.1721191210308033 +28 1.2676084473194829 0.632838292962056 1.730862613690603 +29 2.4018247765468272 0.09920050840806499 1.0615737359533615 +30 -1.8152825954607246 1.571481584407799 3.3986874125568916 +31 -2.388409932144802 -1.2091656881436783 1.989620208528431 +32 -0.9779710898777898 -2.404518175094428 -1.6722481439667212 diff --git a/unittest/force-styles/tests/dpd_rx_multibody_table.txt b/unittest/force-styles/tests/dpd_rx_multibody_table.txt new file mode 100644 index 00000000000..b428b1a8032 --- /dev/null +++ b/unittest/force-styles/tests/dpd_rx_multibody_table.txt @@ -0,0 +1,109 @@ +# TABLE FILE +# Reduced copy of examples/PACKAGES/dpd-react/multi-lucy/table.multibody: +# every 757th tabulated point of the original 74923 entries plus the last +# entry, so that the tabulated density range is unchanged. All values are +# copied verbatim, only the entry index was renumbered. + +KEYWORD +N 100 R 0.0000000000000000E-00 1.8730500000000001E-02 + +1 0.0000000000000000E-00 3.7865000000000000E-04 -1.8444000000000000E-01 +2 1.8924999999999999E-04 3.4453045836265627E-04 -1.7606443571268354E-01 +3 3.7849999999999998E-04 3.1200273850911391E-04 -1.6768953896147637E-01 +4 5.6775000000000000E-04 2.8105996786573749E-04 -1.5931464221026923E-01 +5 7.5699999999999997E-04 2.5170214643252710E-04 -1.5093974545906208E-01 +6 9.4625000000000004E-04 2.2392927420948256E-04 -1.4256484870785491E-01 +7 1.1355000000000000E-03 1.9774135119660400E-04 -1.3418995195664776E-01 +8 1.3247500000000000E-03 1.7313837739389137E-04 -1.2581505520544059E-01 +9 1.5139999999999999E-03 1.5012035280134468E-04 -1.1744015845423345E-01 +10 1.7032499999999999E-03 1.2868727741896399E-04 -1.0906526170302629E-01 +11 1.8924999999999999E-03 1.0883915124674928E-04 -1.0069036495181914E-01 +12 2.0817499999999998E-03 9.0575974284700462E-05 -9.2315468200611983E-02 +13 2.2709999999999996E-03 7.3897746532817661E-05 -8.3940571449404838E-02 +14 2.4602499999999998E-03 5.8804467991100762E-05 -7.5565674698197680E-02 +15 2.6494999999999995E-03 4.5296138659549833E-05 -6.7190777946990535E-02 +16 2.8387499999999997E-03 3.3372758538164841E-05 -5.8815881195783376E-02 +17 3.0279999999999999E-03 2.3034327626945816E-05 -5.0440984444576203E-02 +18 3.2172499999999996E-03 1.4280845925892753E-05 -4.2066087693369059E-02 +19 3.4064999999999998E-03 7.1123134350056296E-06 -3.3691190942161886E-02 +20 3.5957499999999996E-03 1.5287301542844764E-06 -2.5316294190954741E-02 +21 3.7849999999999997E-03 -2.2055973290851735E-06 -1.1260820344870108E-02 +22 3.9742500000000004E-03 -2.1724037281385057E-06 1.1566850185050267E-02 +23 4.1634999999999997E-03 2.0542525792484551E-06 3.2923703252051947E-02 +24 4.3527499999999998E-03 1.0350862091820537E-05 5.5245665068235299E-02 +25 4.5420000000000000E-03 2.3235686835367518E-05 8.1775742083578670E-02 +26 4.7312500000000002E-03 4.1633372013138779E-05 1.1347916857843859E-01 +27 4.9205000000000004E-03 6.6458159141767560E-05 1.4944577917007329E-01 +28 5.1097499999999997E-03 9.8357640614790009E-05 1.8793527370793292E-01 +29 5.2989999999999999E-03 1.3764038865759468E-04 2.2721469552875248E-01 +30 5.4882500000000001E-03 1.8432831789507698E-04 2.6604066442698626E-01 +31 5.6775000000000003E-03 2.3827127910782637E-04 3.0385157930795809E-01 +32 5.8667499999999996E-03 2.9927874250309209E-04 3.4077243617119801E-01 +33 6.0559999999999998E-03 3.6724165319439297E-04 3.7751823072208707E-01 +34 6.2452499999999999E-03 4.4223126923948218E-04 4.1525494019157738E-01 +35 6.4345000000000001E-03 5.2447861577117655E-04 4.5393761851496517E-01 +36 6.6237500000000003E-03 6.1404665872541008E-04 4.9262029683835318E-01 +37 6.8129999999999996E-03 7.1093539599474762E-04 5.3130297516174096E-01 +38 7.0022499999999998E-03 8.1514483439953315E-04 5.6998565348512897E-01 +39 7.1915000000000000E-03 9.2667496878276955E-04 6.0866833180851676E-01 +40 7.3807500000000002E-03 1.0455257946839741E-03 6.4735101013190477E-01 +41 7.5700000000000003E-03 1.1716973260578823E-03 6.8603368845529278E-01 +42 7.7592499999999997E-03 1.3051895489537154E-03 7.2471636677868034E-01 +43 7.9485000000000007E-03 1.4460024705702480E-03 7.6339904510206857E-01 +44 8.1377499999999992E-03 1.5941360868703854E-03 8.0208172342545614E-01 +45 8.3269999999999993E-03 1.7495904014623188E-03 8.4076440174884415E-01 +46 8.5162499999999995E-03 1.9123654160282488E-03 8.7944708007223193E-01 +47 8.7054999999999997E-03 2.0824611229793553E-03 9.1812975839561994E-01 +48 8.8947499999999999E-03 2.2598775283932345E-03 9.5681243671900795E-01 +49 9.0840000000000001E-03 2.4446146293110524E-03 9.9549511504239574E-01 +50 9.2732500000000002E-03 2.6366724275235982E-03 1.0341777933657839E+00 +51 9.4625000000000004E-03 2.8360509241910459E-03 1.0728604716891716E+00 +52 9.6517500000000006E-03 3.0427501180540707E-03 1.1115431500125594E+00 +53 9.8409999999999991E-03 3.2567700065108227E-03 1.1502258283359472E+00 +54 1.0030249999999999E-02 3.4781105892800579E-03 1.1889085066593350E+00 +55 1.0219499999999999E-02 3.7067718727631796E-03 1.2275911849827228E+00 +56 1.0408750000000000E-02 3.9427538564089926E-03 1.2662738633061110E+00 +57 1.0598000000000000E-02 4.1860565409264066E-03 1.3049565416294988E+00 +58 1.0787250000000000E-02 4.4366799019733968E-03 1.3436392199528866E+00 +59 1.0976500000000000E-02 4.6946239775432063E-03 1.3823218982762748E+00 +60 1.1165750000000000E-02 4.9598887495241111E-03 1.4210045765996626E+00 +61 1.1355000000000001E-02 5.2324742103205353E-03 1.4596872549230504E+00 +62 1.1544249999999999E-02 5.5123803685378564E-03 1.4983699332464382E+00 +63 1.1733499999999999E-02 5.7996072295975294E-03 1.5370526115698260E+00 +64 1.1922749999999999E-02 6.0941547862965236E-03 1.5757352898932142E+00 +65 1.2112000000000000E-02 6.3960230421990687E-03 1.6144179682166020E+00 +66 1.2301250000000000E-02 6.7052119768013568E-03 1.6531006465399898E+00 +67 1.2490500000000000E-02 7.0217216316880065E-03 1.6917833248633780E+00 +68 1.2679750000000000E-02 7.3455519726654973E-03 1.7304660031867658E+00 +69 1.2869000000000000E-02 7.6767030026217179E-03 1.7691486815101536E+00 +70 1.3058250000000000E-02 8.0151747488831325E-03 1.8078313598335418E+00 +71 1.3247499999999999E-02 8.3609671850360702E-03 1.8465140381569292E+00 +72 1.3436749999999999E-02 8.7140803056151989E-03 1.8851967164803174E+00 +73 1.3625999999999999E-02 9.0745141388465719E-03 1.9238793948037052E+00 +74 1.3815249999999999E-02 9.4422686662381985E-03 1.9625620731270930E+00 +75 1.4004500000000000E-02 9.8173438838397766E-03 2.0012447514504812E+00 +76 1.4193750000000000E-02 1.0199739803046460E-02 2.0399274297738690E+00 +77 1.4383000000000000E-02 1.0589456421447116E-02 2.0786101080972568E+00 +78 1.4572250000000000E-02 1.0986493702268511E-02 2.1172927864206450E+00 +79 1.4761500000000000E-02 1.1390851731015146E-02 2.1559754647440328E+00 +80 1.4950749999999999E-02 1.1802530445700142E-02 2.1946581430674201E+00 +81 1.5139999999999999E-02 1.2221529848473918E-02 2.2333408213908084E+00 +82 1.5329249999999999E-02 1.2647849948464547E-02 2.2720234997141961E+00 +83 1.5518499999999999E-02 1.3081490701295028E-02 2.3107061780375839E+00 +84 1.5707749999999999E-02 1.3522452230880949E-02 2.3493888563609722E+00 +85 1.5896999999999998E-02 1.3970734422407155E-02 2.3880715346843595E+00 +86 1.6086250000000000E-02 1.4426337307550012E-02 2.4267542130077477E+00 +87 1.6275499999999998E-02 1.4889260896962126E-02 2.4654368913311355E+00 +88 1.6464750000000000E-02 1.5359505076978830E-02 2.5041195696545238E+00 +89 1.6653999999999999E-02 1.5837070146822112E-02 2.5428022479779115E+00 +90 1.6843250000000001E-02 1.6321955833311180E-02 2.5814849263012998E+00 +91 1.7032499999999999E-02 1.6814162191206336E-02 2.6201676046246871E+00 +92 1.7221750000000001E-02 1.7313689217337582E-02 2.6588502829480758E+00 +93 1.7410999999999999E-02 1.7820537031620096E-02 2.6975329612714631E+00 +94 1.7600249999999998E-02 1.8334705276060490E-02 2.7362156395948509E+00 +95 1.7789500000000000E-02 1.8856194642304851E-02 2.7748983179182392E+00 +96 1.7978749999999998E-02 1.9385004516549648E-02 2.8135809962416265E+00 +97 1.8168000000000000E-02 1.9921135057529561E-02 2.8522636745650147E+00 +98 1.8357249999999999E-02 2.0464586300601849E-02 2.8909463528884025E+00 +99 1.8546500000000000E-02 2.1015358254842277E-02 2.9296290312117907E+00 +100 1.8730500000000001E-02 2.1557870059756155E-02 2.9672386101365116E+00 diff --git a/unittest/force-styles/tests/in.dpd-rx-dense b/unittest/force-styles/tests/in.dpd-rx-dense new file mode 100644 index 00000000000..2372104e78e --- /dev/null +++ b/unittest/force-styles/tests/in.dpd-rx-dense @@ -0,0 +1,27 @@ +variable newton_pair index on +variable newton_bond index on +variable units index metal +variable input_dir index . +variable data_file index ${input_dir}/data.dpd-react-dense +variable pair_style index 'zero 4.4' +variable rx_fix_id index rxfix + +units ${units} +atom_style dpd +atom_modify map array +boundary p p p +newton ${newton_pair} ${newton_bond} +comm_modify mode single vel yes +neighbor 1.0 bin +neigh_modify delay 2 every 2 check no +timestep 0.001 + +# same setup as in.dpd-rx, but on a much denser configuration with a short +# cutoff. pair style multi/lucy/rx needs the Lucy weighted local density to +# fall inside the tabulated density range, which requires neighbors well +# inside the cutoff sphere, not just a single shell close to the cutoff. + +fix ${rx_fix_id} all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1 + +pair_style ${pair_style} +read_data ${data_file} fix ${rx_fix_id}_SPECIES NULL NULL fix ${rx_fix_id}_SPECIES_OLD NULL NULL diff --git a/unittest/force-styles/tests/mol-pair-multi_lucy_rx.yaml b/unittest/force-styles/tests/mol-pair-multi_lucy_rx.yaml new file mode 100644 index 00000000000..bd3dbcf6778 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-multi_lucy_rx.yaml @@ -0,0 +1,118 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 14:46:21 2026 +epsilon: 5e-13 +skip_tests: extract extract_omp single +prerequisites: | + atom dpd + pair hybrid/overlay + pair dpd/fdt/energy + pair multi/lucy/rx + fix rx + fix eos/table/rx +pre_commands: "" +post_commands: | + if "$(is_defined(fix,rxfix))==0" then "fix rxfix all rx ${input_dir}/dpd_rx_kinetics.txt none dense lammps_rk4 1" + pair_coeff * * multi/lucy/rx ${input_dir}/dpd_rx_multibody_table.txt KEYWORD 1fluid 1fluid 4.4 + set type 1 d_rdx 0.30 + set type 1 d_hcn 0.20 + set type 1 d_no2 0.10 + set type 1 d_no 0.15 + set type 1 d_h2o 0.15 + set type 1 d_n2 0.05 + set type 1 d_h2 0.03 + set type 1 d_co 0.01 + set type 1 d_co2 0.01 + set type 2 d_rdx 0.10 + set type 2 d_hcn 0.30 + set type 2 d_no2 0.20 + set type 2 d_no 0.05 + set type 2 d_h2o 0.10 + set type 2 d_n2 0.10 + set type 2 d_h2 0.05 + set type 2 d_co 0.05 + set type 2 d_co2 0.05 + fix eosfix all eos/table/rx linear ${input_dir}/dpd_rx_eos_table.txt 21 KEYWORD ${input_dir}/dpd_rx_thermo.txt + fix_modify rxfix rx_chemistry off +input_file: in.dpd-rx-dense +pair_style: hybrid/overlay dpd/fdt/energy 4.4 234324 multi/lucy/rx linear 1000 +pair_coeff: | + * * dpd/fdt/energy 0.0 0.0 10.0 4.4 +extract: "" +natoms: 32 +init_vdwl: 1.7449043438650542 +init_coul: 0 +init_stress: |2- + 1.7194380054365638e+01 1.7430142000833857e+01 1.7069544685429083e+01 1.4033963205302824e-01 3.7267570492895474e-02 -7.9573304840816310e-03 +init_forces: |2 + 1 -5.5324621150674651e-02 2.6190607355072254e-01 1.3982877624724382e-01 + 2 -1.3173772615733212e-01 -5.0030194981469718e-02 5.1090796843893657e-02 + 3 -1.3777951445048975e-01 -9.7320486347931501e-02 1.7384328249282163e-01 + 4 -3.7342309732315879e-02 1.0970687572698504e-01 -2.0764073682161743e-01 + 5 2.5542960920813057e-01 -1.3280027713024611e-02 -1.8572050652215283e-01 + 6 6.7677367899963009e-02 -1.4290005908754055e-01 -3.3883978816577322e-02 + 7 1.6695836545931104e-02 -9.8519690327674159e-03 -1.1168749849655510e-01 + 8 5.5571679222109982e-02 -1.9781074417363403e-02 1.0615934187124786e-01 + 9 2.7455724940820353e-02 -5.3488216997047422e-02 3.7080359222478293e-02 + 10 5.1012035103310260e-02 -1.7460389462037884e-01 4.6121857168902686e-02 + 11 -3.7996873222165703e-02 1.0912386009902504e-01 -3.7127792622965589e-03 + 12 1.5838738375063233e-01 1.2775516531618042e-01 2.8379105710091949e-02 + 13 -1.5718438900039677e-01 -1.8084986331905278e-02 1.3137176807903003e-01 + 14 1.3902903451696078e-02 1.8455016713056147e-01 5.6068255807325273e-02 + 15 -6.5583342326405891e-02 -1.0027251289882519e-01 -2.2852184083186927e-02 + 16 -1.5941699553808739e-01 -6.5916098849503058e-02 6.4567905844901186e-02 + 17 8.8096528299743126e-02 -1.7993720816156189e-01 2.6739107684686986e-02 + 18 4.0956556067439386e-02 -3.3667613580425991e-02 8.3929431647569198e-03 + 19 1.1096016578962808e-01 4.0582944645314270e-02 -1.0729205977950683e-01 + 20 -1.6613743183703061e-01 -3.6662570277571915e-02 8.6631405751162571e-02 + 21 -3.2009279848163638e-02 -8.1827682422245029e-02 4.6122224243920325e-02 + 22 -8.4568690814419450e-02 1.2601159565655784e-01 5.9933088926286945e-02 + 23 2.4223414963871051e-02 -4.5165184193828589e-02 1.3909868570968889e-01 + 24 -6.7875827796415225e-02 3.8037861750087922e-02 4.7027973446830483e-02 + 25 -1.5906661020971269e-03 2.2251280495374122e-02 9.0555072531146905e-02 + 26 5.3397552737362623e-02 1.0526652650774031e-01 -8.3962787610231779e-02 + 27 -3.4885542794307209e-02 1.4517190331377464e-01 -9.3212684791974490e-02 + 28 6.6630757456233231e-02 -1.6118945829964981e-01 -2.1775544927924623e-01 + 29 8.5865842871011233e-02 3.8467049617418834e-02 8.2572295109096611e-02 + 30 -2.1659474055567420e-02 -3.5554832180159923e-02 4.3941279176205168e-02 + 31 1.1902099304494254e-01 -1.1099430527871648e-01 -2.6839721941522748e-01 + 32 -4.4191666526956108e-02 1.2169707186217414e-01 -1.2940764015314546e-01 +run_vdwl: 1.7687576867561572 +run_coul: 0 +run_stress: |2- + 1.7300315745919686e+01 1.7559514613340401e+01 1.7176071755287168e+01 1.4652380301770729e-01 3.4666065852630566e-02 -3.2952193226796385e-02 +run_forces: |2 + 1 -6.3890868033805975e-02 2.4805039031193704e-01 1.4130846973874450e-01 + 2 -1.4392551581239221e-01 -4.7766499212826746e-02 5.2607324205640627e-02 + 3 -1.5920929913187698e-01 -1.0163270569433398e-01 1.8554224338032257e-01 + 4 -2.9564787412412655e-02 1.1587163216350320e-01 -2.0320435645679252e-01 + 5 2.6660976173929313e-01 -1.9461954033568873e-02 -2.0825501690790330e-01 + 6 8.0333764713032996e-02 -1.5362611759427883e-01 -4.0077900995724863e-02 + 7 2.3044865135691470e-02 -1.7717251611474222e-02 -1.0014243715453167e-01 + 8 5.4218340661874406e-02 -1.1977648718367970e-02 1.2883036604384712e-01 + 9 3.9100722636946139e-02 -5.1539191299613707e-02 4.5170579991508107e-02 + 10 4.3660540391939839e-02 -1.8385706626498927e-01 6.1546583015780948e-02 + 11 -4.2786207220385807e-02 1.0857722826566577e-01 -8.7131050635002386e-03 + 12 1.7473898002448038e-01 1.4381445228442666e-01 2.2698522596742446e-02 + 13 -1.7475092228270050e-01 -1.0458260994100632e-04 1.5204830645082199e-01 + 14 1.3279176346385729e-02 1.9753070022567154e-01 5.2830870725057960e-02 + 15 -8.0187637054005584e-02 -1.0197793404791303e-01 -2.0513213574060173e-02 + 16 -1.4981710886743144e-01 -7.5790597618520972e-02 5.9154366254387192e-02 + 17 7.9083584941233506e-02 -1.8098040732177678e-01 1.5368994627290133e-02 + 18 3.6256761069560335e-02 -3.0358063061183889e-02 1.0061956170913086e-02 + 19 1.3038257754020086e-01 4.5647660015729237e-02 -1.1006222104684202e-01 + 20 -1.6399980333895381e-01 -2.2000356387505526e-02 7.6468899964002898e-02 + 21 -3.0223037908129306e-02 -6.9051706303833782e-02 5.8072664161459980e-02 + 22 -8.7348849681616908e-02 1.1865601254975329e-01 6.1232303113317274e-02 + 23 2.3509185904328045e-02 -5.1801374429980312e-02 1.3812254068532004e-01 + 24 -7.2944302430900693e-02 2.1932126586454395e-02 2.8546234081490925e-02 + 25 1.2476204564453086e-02 1.4039512165577327e-02 1.0691325526053583e-01 + 26 4.9011211276857009e-02 9.7739394856052736e-02 -8.8166624415998485e-02 + 27 -4.3946558366302457e-02 1.3925594731951227e-01 -1.0359435195305886e-01 + 28 5.1591061618174033e-02 -1.6190645082321176e-01 -2.1455166508565376e-01 + 29 8.1583409907614896e-02 3.3126192881728862e-02 8.0064536017845633e-02 + 30 -1.7734002148592425e-02 -3.1943145309638689e-02 3.9799564779283300e-02 + 31 1.4094224154922533e-01 -1.0551409817711049e-01 -2.9083082545528638e-01 + 32 -3.9493490331784412e-02 1.3476590089405741e-01 -1.2827686315496017e-01 +... From d5350f42599a16cd02ea91cfb68b45781da11351 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:18:34 +0000 Subject: [PATCH 049/120] KOKKOS: let fix wall/flow use the host random number generator fix wall/flow/kk drew its random numbers from the Kokkos XorShift pool unconditionally, so its results could not be compared with the CPU style and the fixture skipped every KOKKOS case. All other KOKKOS styles with a random number generator switch to the RanMars wrapper when LMP_KOKKOS_DEBUG_RNG is defined, which makes a Serial run bit-for-bit identical to the CPU style. Do the same here, following fix langevin/kk. The fixture's skip entries become "_devicerng" qualified accordingly: the KOKKOS cases still skip in a normal build and now run, and pass, in a build configured with -D KOKKOS_DEBUG_RNG=on. --- src/KOKKOS/fix_wall_flow_kokkos.cpp | 14 +++++++++++++- src/KOKKOS/fix_wall_flow_kokkos.h | 9 +++++++++ .../force-styles/tests/fix-timestep-wall_flow.yaml | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_wall_flow_kokkos.cpp b/src/KOKKOS/fix_wall_flow_kokkos.cpp index 2dcbff3a87c..08c8a95c41d 100644 --- a/src/KOKKOS/fix_wall_flow_kokkos.cpp +++ b/src/KOKKOS/fix_wall_flow_kokkos.cpp @@ -29,7 +29,12 @@ using namespace LAMMPS_NS; template FixWallFlowKokkos::FixWallFlowKokkos(LAMMPS *lmp, int narg, char **arg) : - FixWallFlow(lmp, narg, arg), rand_pool(rndseed + comm->me) + FixWallFlow(lmp, narg, arg), +#ifdef LMP_KOKKOS_DEBUG_RNG + rand_pool(rndseed + comm->me, lmp) +#else + rand_pool(rndseed + comm->me) +#endif { kokkosable = 1; exchange_comm_device = sort_device = 1; @@ -52,10 +57,17 @@ template FixWallFlowKokkos::~FixWallFlowKokkos() { if (copymode) return; memoryKK->destroy_kokkos(k_current_segment, current_segment); +#ifdef LMP_KOKKOS_DEBUG_RNG + rand_pool.destroy(); +#endif } template void FixWallFlowKokkos::init() { +#ifdef LMP_KOKKOS_DEBUG_RNG + rand_pool.init(random, rndseed + comm->me); +#endif + atomKK->sync(execution_space, datamask_read); k_current_segment.template sync(); d_x = atomKK->k_x.template view(); diff --git a/src/KOKKOS/fix_wall_flow_kokkos.h b/src/KOKKOS/fix_wall_flow_kokkos.h index 0302f4c5a4a..8b000f529bd 100644 --- a/src/KOKKOS/fix_wall_flow_kokkos.h +++ b/src/KOKKOS/fix_wall_flow_kokkos.h @@ -26,7 +26,11 @@ FixStyle(wall/flow/kk/host,FixWallFlowKokkos); #include "fix_wall_flow.h" #include "kokkos_type.h" #include "kokkos_base.h" +#ifdef LMP_KOKKOS_DEBUG_RNG +#include "rand_pool_wrap_kokkos.h" +#else #include "Kokkos_Random.hpp" +#endif namespace LAMMPS_NS { @@ -90,8 +94,13 @@ class FixWallFlowKokkos : public FixWallFlow, public KokkosBase { typename AT::t_kkfloat_1d d_rmass; typedef typename AT::t_kkfloat_1d d_walls_t; +#ifndef LMP_KOKKOS_DEBUG_RNG typedef Kokkos::Random_XorShift64_Pool rand_pool_t; typedef typename rand_pool_t::generator_type rand_type_t; +#else + typedef RandPoolWrap rand_pool_t; + typedef RandWrap rand_type_t; +#endif DAT::tdual_int_1d k_current_segment; typename AT::t_int_1d d_current_segment; diff --git a/unittest/force-styles/tests/fix-timestep-wall_flow.yaml b/unittest/force-styles/tests/fix-timestep-wall_flow.yaml index c69f900b287..cf25ebee4ca 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_flow.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_flow.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: no_restart date_generated: Fri Jul 10 18:25:42 2026 epsilon: 5e-12 -skip_tests: kokkos_omp kokkos_serial kokkos_gpu +skip_tests: kokkos_omp_devicerng kokkos_serial_devicerng kokkos_gpu_devicerng prerequisites: | atom full fix wall/flow From 9fd7adf80ff49275ec7e8e15847100094e0339b0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:19:52 +0000 Subject: [PATCH 050/120] test: add a fix cmap force-style reference in.cmap and data.cmap were in the tree but no fixture referenced them, so the CMAP crossterm fix was never tested at all, on the host or under KOKKOS. The fix has to exist before read_data, because the CMAP section of the data file is parsed by the fix itself, while the fix-timestep driver expects the fix under test to be named "test" and re-creates it from post_commands after reading a restart. Parameterise the fix id in in.cmap - the idiom of in.dpd-rx - so the fixture can name it "test", and re-create it after the restart behind the usual is_defined() guard. The KOKKOS results agree with the CPU reference to 5e-15, well inside the 5e-13 tolerance, and the reference is sensitive to the crossterm forces: the same run without the CMAP section of the data file deviates by 2e-3 Angstrom after eight steps. --- .../force-styles/tests/fix-timestep-cmap.yaml | 83 +++++++++++++++++++ unittest/force-styles/tests/in.cmap | 11 ++- 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 unittest/force-styles/tests/fix-timestep-cmap.yaml diff --git a/unittest/force-styles/tests/fix-timestep-cmap.yaml b/unittest/force-styles/tests/fix-timestep-cmap.yaml new file mode 100644 index 00000000000..c219051c285 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-cmap.yaml @@ -0,0 +1,83 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 15:11:17 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix cmap +pre_commands: | + variable cmap_fix_id delete + variable cmap_fix_id index test +post_commands: | + if "$(is_defined(fix,test))==0" then "fix test all cmap charmm36.cmap" + fix_modify test energy yes + fix move all nve +input_file: in.cmap +input_coeffs: coeffs.fourmol +natoms: 29 +run_stress: |- + -1.6714314953412412e-01 2.7379717446984508e+00 -2.5708285951643184e+00 2.2344464694880202e+00 1.2303970339689951e+00 -7.5506096252240185e-01 +global_scalar: 4.786193036840075 +run_pos: |2 + 1 -2.7045576931365384e-01 2.4912153915127910e+00 -1.6695660174193144e-01 + 2 3.1006650885653392e-01 2.9612066384818774e+00 -8.5468359240877056e-01 + 3 -7.0398718670996585e-01 1.2305509689997693e+00 -6.2777234357568623e-01 + 4 -1.5814449350624078e+00 1.4843404724798535e+00 -1.2538273456433655e+00 + 5 -9.0783243756685006e-01 9.2526534460922938e-01 3.9949965943785426e-01 + 6 2.4859337464110062e-01 2.8395437677292801e-01 -1.2315849919995718e+00 + 7 3.4129121643837462e-01 -2.3102788529791828e-02 -2.5291407998329900e+00 + 8 1.1743406680717965e+00 -4.8860189094234913e-01 -6.3780684414657063e-01 + 9 1.3800528609303513e+00 -2.5274652114108015e-01 2.8354186861628400e-01 + 10 2.0510776838326117e+00 -1.4602212365720617e+00 -9.8289749648832170e-01 + 11 1.7878063062190042e+00 -1.9921840498876129e+00 -1.8890528117809133e+00 + 12 3.0062653102416346e+00 -4.9030348819064951e-01 -1.6234817573863822e+00 + 13 4.0515398561601499e+00 -8.9202280298994308e-01 -1.6400070473765287e+00 + 14 2.6066954671851068e+00 -4.1789389390575277e-01 -2.6634066414774398e+00 + 15 2.9697386898129197e+00 5.5405474601205984e-01 -1.2343532907729176e+00 + 16 2.6747029564056741e+00 -2.4124117273842192e+00 -2.3434860532736367e-02 + 17 2.2153579387356999e+00 -2.0897987524705992e+00 1.1963152377872239e+00 + 18 2.1369285315978819e+00 3.0156108277459790e+00 -3.5183940657539963e+00 + 19 1.5355811460020863e+00 2.6255306350384799e+00 -4.2354168844939002e+00 + 20 2.7727385869610495e+00 3.6933911950960656e+00 -3.9313456335665453e+00 + 21 4.9040149976454908e+00 -4.0752342739930612e+00 -3.6210280393155685e+00 + 22 4.3584283483000474e+00 -4.2126170417598745e+00 -4.4609852540369923e+00 + 23 5.7439382608753773e+00 -3.5821957713386881e+00 -3.8766362488100117e+00 + 24 2.0689237180918769e+00 3.1513348704499196e+00 3.1550384095102570e+00 + 25 1.3045090135211659e+00 3.2665689836321810e+00 2.5111204914634193e+00 + 26 2.5809239161761726e+00 4.0117601377202847e+00 3.2212062405016724e+00 + 27 -1.9611007896081207e+00 -4.3563573211261462e+00 2.1098614022771494e+00 + 28 -2.7473545914982185e+00 -4.0200829741975630e+00 1.5830064034427631e+00 + 29 -1.3125994707851243e+00 -3.5962514442513154e+00 2.2746344518754498e+00 +run_vel: |2 + 1 8.1702074645354245e-03 1.6515202117650989e-02 4.7941469336088569e-03 + 2 5.4793033469769832e-03 5.1464824735920301e-03 -1.4591356769853583e-03 + 3 -8.2335058988087587e-03 -1.2926663429897286e-02 -4.0922324315820239e-03 + 4 -3.3968512986425896e-03 -5.9586658523124135e-03 -1.0756650770777732e-03 + 5 -1.1658826051209275e-02 -1.1193993209032556e-02 -2.8787337175040116e-03 + 6 -3.9380810946715861e-02 4.7658078376635958e-02 3.6984166084389578e-02 + 7 7.6859250359065520e-04 -1.0596844346008383e-02 -5.1474108818315739e-02 + 8 7.8658367472618541e-03 -3.3020166182538549e-03 3.4576616847351263e-02 + 9 1.5651759825792172e-03 3.7379367797178613e-03 1.5051270508251535e-02 + 10 2.9209115027410210e-02 -2.9079636336334622e-02 -1.4693353834959967e-02 + 11 -4.7791036632847325e-03 -3.7420517412193972e-03 -2.3314072395415062e-03 + 12 2.2371540751205381e-03 -5.1178724927781680e-04 -3.3452354485908392e-03 + 13 2.7521535591674470e-03 5.8111658360700752e-03 -8.0472550021756155e-04 + 14 3.5228591162840507e-03 -5.7968032496769481e-03 -3.9605392790085618e-03 + 15 -1.6484125488189579e-03 -6.0254944267966555e-03 6.1452231213603593e-03 + 16 1.8681533496201778e-02 -1.3262182433081764e-02 -4.5636846184444781e-02 + 17 -1.2895956946875307e-02 9.7523042076136327e-03 3.7296862271497824e-02 + 18 -8.3844604949622544e-04 -1.0959331979630920e-03 -1.8883231141051705e-03 + 19 1.2400642737389221e-03 -2.5031680516680276e-03 7.2633208828032413e-03 + 20 3.5619032388416552e-03 4.6664333858458919e-03 4.9145981095079193e-03 + 21 -1.4645071159471662e-03 -2.7242209180838791e-04 7.1272665704736661e-04 + 22 -6.8856986268787017e-03 -4.2649670960839062e-03 5.6565289286038007e-04 + 23 6.0446701004681610e-03 -1.3999558207043038e-03 2.5817272842782093e-03 + 24 3.1797174259548148e-04 -9.9409313510120337e-04 1.4885702447403577e-04 + 25 1.1518919433985874e-04 -4.3777019831790272e-03 -8.8058800262529545e-04 + 26 2.0489472664324436e-03 2.7810807643201753e-03 4.3249553258435623e-03 + 27 4.8891848045180331e-04 -1.0464891567315263e-03 2.4353637884337858e-04 + 28 -6.2510920436768891e-03 1.4107986848621830e-03 -1.8406053609070112e-03 + 29 6.4221263686005717e-04 3.1280619277518898e-03 3.7257842641040140e-03 +... diff --git a/unittest/force-styles/tests/in.cmap b/unittest/force-styles/tests/in.cmap index 6a731ea759b..c74b923fe2d 100644 --- a/unittest/force-styles/tests/in.cmap +++ b/unittest/force-styles/tests/in.cmap @@ -12,6 +12,11 @@ variable angle_style index zero variable dihedral_style index zero variable improper_style index zero variable t_target index 100.0 +# id of the "fix cmap" instance. the fix must exist before the data file is +# read, because the CMAP crossterm section is parsed by the fix itself. the +# fix-timestep test for fix cmap overrides this with "test" so the driver +# finds the fix under test. +variable cmap_fix_id index cmap atom_style full atom_modify map array @@ -27,7 +32,7 @@ angle_style ${angle_style} dihedral_style ${dihedral_style} improper_style ${improper_style} -fix cmap all cmap charmm36.cmap -fix_modify cmap energy yes +fix ${cmap_fix_id} all cmap charmm36.cmap +fix_modify ${cmap_fix_id} energy yes -read_data ${data_file} fix cmap crossterm CMAP +read_data ${data_file} fix ${cmap_fix_id} crossterm CMAP From aa8d92ebda846ab9d4993aca0f3fa86d9b906c66 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:31:27 +0000 Subject: [PATCH 051/120] test: check the ReaxFF bonds and species output files fix reaxff/bonds and fix reaxff/species write files rather than producing values the force-style drivers can compare, so neither had a test and their KOKKOS variants were never executed. The new test builds a small gas phase system of four water molecules and two hydrogen molecules, runs it with pair reaxff and fix qeq/reaxff, and parses the two output files back. It asserts on structure and on invariants of the content rather than on a table of numbers: one bonds record per atom with a consistent field count, a bond graph in which every bond is reciprocated, bond orders inside the physical range, total bond order consistent with the listed bonds, lone pairs of about two for oxygen and zero for hydrogen, a neutral total charge, and species counts whose atoms add up to the atom count. A handful of representative values are compared with a tolerance. The ctest entry is registered twice, plain and with the accelerator arguments, so the same assertions run against the KOKKOS variants of both fixes. Their output is byte identical to the host version. --- unittest/commands/CMakeLists.txt | 10 + unittest/commands/test_reaxff_output.cpp | 395 +++++++++++++++++++++++ 2 files changed, 405 insertions(+) create mode 100644 unittest/commands/test_reaxff_output.cpp diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index 7966f5411aa..7af4815d991 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -176,6 +176,16 @@ if(PKG_PHONON) add_kokkos_test(NAME PhononCommands COMMAND test_phonon_commands) endif() +if(PKG_REAXFF) + add_executable(test_reaxff_output test_reaxff_output.cpp) + target_link_libraries(test_reaxff_output PRIVATE lammps GTest::GMock) + add_test(NAME ReaxFFOutput COMMAND test_reaxff_output) + set_tests_properties(ReaxFFOutput PROPERTIES + ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") + add_kokkos_test(NAME ReaxFFOutput COMMAND test_reaxff_output + ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +endif() + add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) target_link_libraries(test_mpi_load_balancing PRIVATE lammps GTest::GMock) add_mpi_test(NAME MPILoadBalancing NUM_PROCS 4 COMMAND $) diff --git a/unittest/commands/test_reaxff_output.cpp b/unittest/commands/test_reaxff_output.cpp new file mode 100644 index 00000000000..404adac8bff --- /dev/null +++ b/unittest/commands/test_reaxff_output.cpp @@ -0,0 +1,395 @@ +/* ---------------------------------------------------------------------- + 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 "../testing/core.h" +#include "../testing/utils.h" + +#include "atom.h" +#include "info.h" +#include "lammps.h" +#include "library.h" +#include "utils.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +// whether to print verbose output (i.e. not capturing LAMMPS screen output). +bool verbose = false; + +namespace LAMMPS_NS { + +// the fixes reaxff/bonds and reaxff/species of the REAXFF package do not +// contribute to forces or energies but write the bond topology and the +// molecular species detected by the reactive force field to a file. the +// force-style YAML test drivers therefore cannot cover them. the tests +// below build a small gas phase system of four water molecules and two +// hydrogen molecules, whose bond topology and species composition are known +// in advance, run a few steps, and parse the two output files back. the +// ReaxFFOutputKokkos ctest entry runs the very same test bodies with +// LAMMPS_ACCELERATOR_ARGS="-k on t 1 -sf kk" so that the KOKKOS versions of +// the two fixes are exercised as well. + +class ReaxFFOutputTest : public LAMMPSTest { +protected: + // geometry of the molecules placed into the box. the oxygen of each water + // molecule is created first, so the atom-IDs are 1-3, 4-6, 7-9, and 10-12 + // for the four water molecules and 13-14 and 15-16 for the two hydrogen + // molecules. the molecules are 8 angstrom or more apart, which is well + // beyond any bond order cutoff, so they stay individual molecules. + static constexpr int num_water = 4; + static constexpr int num_hydrogen = 2; + + void SetUp() override + { + testbinary = "ReaxFFOutputTest"; + LAMMPSTest::SetUp(); + if (!info->has_style("pair", "reaxff")) return; + + const double water[3][3] = {{0.0, 0.0, 0.0}, {0.9572, 0.0, 0.0}, {-0.2400, 0.9266, 0.0}}; + const double hydro[2][3] = {{0.0, 0.0, 0.0}, {0.7414, 0.0, 0.0}}; + const double wpos[num_water][3] = { + {3.0, 3.0, 3.0}, {9.0, 3.0, 9.0}, {3.0, 9.0, 9.0}, {9.0, 9.0, 3.0}}; + const double hpos[num_hydrogen][3] = {{3.0, 3.0, 9.0}, {9.0, 9.0, 9.0}}; + + BEGIN_HIDE_OUTPUT(); + command("units real"); + command("atom_style charge"); + command("atom_modify map array"); + command("boundary p p p"); + command("region box block 0 12 0 12 0 12"); + command("create_box 2 box"); + command("mass 1 1.008"); + command("mass 2 15.999"); + + // atom type 1 is hydrogen, atom type 2 is oxygen + for (int m = 0; m < num_water; ++m) + for (int a = 0; a < 3; ++a) + command(fmt::format("create_atoms {} single {:.6f} {:.6f} {:.6f} units box", + (a == 0) ? 2 : 1, wpos[m][0] + water[a][0], + wpos[m][1] + water[a][1], wpos[m][2] + water[a][2])); + for (int m = 0; m < num_hydrogen; ++m) + for (int a = 0; a < 2; ++a) + command(fmt::format("create_atoms 1 single {:.6f} {:.6f} {:.6f} units box", + hpos[m][0] + hydro[a][0], hpos[m][1] + hydro[a][1], + hpos[m][2] + hydro[a][2])); + + command("set type * charge 0.0"); + command("pair_style reaxff NULL"); + command("pair_coeff * * ffield.reax.mattsson H O"); + command("fix qeq all qeq/reaxff 1 0.0 10.0 1.0e-6 reaxff"); + command("neighbor 1.0 bin"); + command("neigh_modify every 1 delay 0 check no"); + command("timestep 0.1"); + command("fix nve all nve"); + END_HIDE_OUTPUT(); + } + + // number of atoms in a chemical formula like "H2O" or "C2H4". + // returns -1 if the string is not a valid formula. + static int formula_atoms(const std::string &formula) + { + int total = 0; + std::size_t idx = 0; + while (idx < formula.size()) { + if ((formula[idx] < 'A') || (formula[idx] > 'Z')) return -1; + ++idx; + while ((idx < formula.size()) && (formula[idx] >= 'a') && (formula[idx] <= 'z')) + ++idx; + int count = 0; + while ((idx < formula.size()) && (formula[idx] >= '0') && (formula[idx] <= '9')) { + count = count * 10 + (formula[idx] - '0'); + ++idx; + } + if (count == 0) count = 1; + total += count; + } + return total; + } + + // one atom record of the fix reaxff/bonds output file: + // id type nb id_1...id_nb mol bo_1...bo_nb abo nlp q + struct BondRecord { + int type; + std::vector neighid; + std::vector bondorder; + double abo; + double nlp; + double q; + }; + + struct BondBlock { + bigint timestep; + bigint natoms; + std::map records; + }; +}; + +TEST_F(ReaxFFOutputTest, Bonds) +{ + if (!info->has_style("pair", "reaxff")) GTEST_SKIP(); + if (!info->has_style("fix", "reaxff/bonds")) GTEST_SKIP(); + + const std::string outfile = "test_reaxff_bonds.tmp"; + delete_file(outfile); + + BEGIN_HIDE_OUTPUT(); + command("fix bonds all reaxff/bonds 5 " + outfile); + command("run 10 post no"); + END_HIDE_OUTPUT(); + + const int natoms = (int)lmp->atom->natoms; + ASSERT_EQ(natoms, 3 * num_water + 2 * num_hydrogen); + + ASSERT_FILE_EXISTS(outfile); + auto lines = read_lines(outfile); + ASSERT_GT((int)lines.size(), 0); + + // split the file into the individual snapshots. everything that starts + // with a '#' is a comment, only "# Timestep" and "# Number of particles" + // carry information that is checked here. + std::vector blocks; + for (const auto &line : lines) { + auto words = utils::split_words(line); + if (words.empty()) continue; + if (words[0] == "#") { + if ((words.size() > 2) && (words[1] == "Timestep")) { + BondBlock block; + block.timestep = std::stoll(words[2]); + block.natoms = 0; + blocks.push_back(block); + } else if ((words.size() > 4) && (words[1] == "Number") && (words[2] == "of")) { + ASSERT_FALSE(blocks.empty()); + blocks.back().natoms = std::stoll(words[4]); + } + continue; + } + + ASSERT_FALSE(blocks.empty()); + // id type nb, nb neighbor IDs, molecule ID, nb bond orders, abo, nlp, q + ASSERT_GE((int)words.size(), 3); + const int id = std::stoi(words[0]); + BondRecord rec; + rec.type = std::stoi(words[1]); + const int nb = std::stoi(words[2]); + ASSERT_EQ((int)words.size(), 7 + 2 * nb); + for (int k = 0; k < nb; ++k) + rec.neighid.push_back(std::stoi(words[3 + k])); + for (int k = 0; k < nb; ++k) + rec.bondorder.push_back(std::stod(words[4 + nb + k])); + rec.abo = std::stod(words[4 + 2 * nb]); + rec.nlp = std::stod(words[5 + 2 * nb]); + rec.q = std::stod(words[6 + 2 * nb]); + ASSERT_EQ((int)blocks.back().records.count(id), 0); + blocks.back().records[id] = rec; + } + + // fix reaxff/bonds with nevery 5 writes at the setup of the run and then + // every 5 steps, i.e. for timesteps 0, 5, and 10 + ASSERT_EQ((int)blocks.size(), 3); + EXPECT_EQ(blocks[0].timestep, 0); + EXPECT_EQ(blocks[1].timestep, 5); + EXPECT_EQ(blocks[2].timestep, 10); + + for (const auto &block : blocks) { + // the header must report the number of atoms and there must be exactly + // one record for each atom, with the IDs covering the full range + EXPECT_EQ(block.natoms, natoms); + ASSERT_EQ((int)block.records.size(), natoms); + for (int id = 1; id <= natoms; ++id) + EXPECT_EQ((int)block.records.count(id), 1); + + int nbonds = 0; + double sumq = 0.0; + double maxbo = 0.0; + for (const auto &item : block.records) { + const int id = item.first; + const BondRecord &r = item.second; + const int nb = (int)r.bondorder.size(); + + // hydrogen (type 1) has exactly one bond, oxygen (type 2) has two + EXPECT_EQ(nb, (r.type == 2) ? 2 : 1); + EXPECT_EQ((int)r.neighid.size(), nb); + + double sumbo = 0.0; + for (int k = 0; k < nb; ++k) { + // bond orders must be physically plausible: larger than the + // 0.3 bond graph cutoff that selects them and well below the + // maximum of 4 that a single covalent bond can reach + EXPECT_GT(r.bondorder[k], 0.3); + EXPECT_LT(r.bondorder[k], 4.0); + sumbo += r.bondorder[k]; + maxbo = std::max(maxbo, r.bondorder[k]); + + // the bond must be listed by the bonded partner as well + const int jd = r.neighid[k]; + EXPECT_GE(jd, 1); + EXPECT_LE(jd, natoms); + ASSERT_EQ((int)block.records.count(jd), 1); + const auto &partner = block.records.at(jd); + EXPECT_NE(std::find(partner.neighid.begin(), partner.neighid.end(), id), + partner.neighid.end()); + } + nbonds += nb; + + // the sum of the bond orders of the listed bonds must not exceed + // the total bond order of the atom (up to the rounding of the + // printed values) and the difference, i.e. the bonds below the + // cutoff, must be small for these isolated molecules + EXPECT_GT(r.abo - sumbo, -0.005); + EXPECT_LT(r.abo - sumbo, 0.1); + + // oxygen has two lone pairs, hydrogen has none + if (r.type == 2) { + EXPECT_NEAR(r.nlp, 2.0, 0.1); + } else { + EXPECT_NEAR(r.nlp, 0.0, 0.1); + } + sumq += r.q; + } + + // every hydrogen contributes one and every oxygen two bonds, and each + // bond is listed by both of its atoms + EXPECT_EQ(nbonds % 2, 0); + EXPECT_EQ(nbonds / 2, 2 * num_water + num_hydrogen); + + // the bond orders must not be all zero + EXPECT_GT(maxbo, 0.5); + + // charge equilibration conserves the total charge of the neutral system + EXPECT_NEAR(sumq, 0.0, 0.02); + } + + // representative values of the undistorted initial geometry: the O-H bond + // of a water molecule, the total bond order and charge of its oxygen, and + // the stronger H-H bond of a hydrogen molecule + const auto &first = blocks[0].records; + EXPECT_NEAR(first.at(1).bondorder[0], 0.936, 0.01); + EXPECT_NEAR(first.at(1).abo, 1.873, 0.01); + EXPECT_NEAR(first.at(1).q, -0.653, 0.01); + EXPECT_NEAR(first.at(2).bondorder[0], 0.936, 0.01); + EXPECT_NEAR(first.at(13).bondorder[0], 0.966, 0.01); + EXPECT_GT(first.at(13).bondorder[0], first.at(1).bondorder[0]); + + delete_file(outfile); +} + +TEST_F(ReaxFFOutputTest, Species) +{ + if (!info->has_style("pair", "reaxff")) GTEST_SKIP(); + if (!info->has_style("fix", "reaxff/species")) GTEST_SKIP(); + + const std::string outfile = "test_reaxff_species.tmp"; + delete_file(outfile); + + BEGIN_HIDE_OUTPUT(); + command("fix species all reaxff/species 1 1 5 " + outfile); + command("run 10 post no"); + END_HIDE_OUTPUT(); + + const int natoms = (int)lmp->atom->natoms; + ASSERT_EQ(natoms, 3 * num_water + 2 * num_hydrogen); + + ASSERT_FILE_EXISTS(outfile); + auto lines = read_lines(outfile); + + // each snapshot consists of a header line naming the species found and a + // data line with the timestep, the number of molecules, the number of + // species, and the number of molecules of each species + ASSERT_EQ((int)lines.size(), 6); + + const bigint expected_steps[3] = {0, 5, 10}; + for (int n = 0; n < 3; ++n) { + auto head = utils::split_words(lines[2 * n]); + auto data = utils::split_words(lines[2 * n + 1]); + + ASSERT_GE((int)head.size(), 4); + EXPECT_EQ(head[0], "#"); + EXPECT_EQ(head[1], "Timestep"); + EXPECT_EQ(head[2], "No_Moles"); + EXPECT_EQ(head[3], "No_Specs"); + + ASSERT_GE((int)data.size(), 3); + EXPECT_EQ(std::stoll(data[0]), expected_steps[n]); + const int nmole = std::stoi(data[1]); + const int nspec = std::stoi(data[2]); + + // one column with the number of molecules for each species + ASSERT_EQ((int)head.size(), 4 + nspec); + ASSERT_EQ((int)data.size(), 3 + nspec); + + std::map species; + int summole = 0; + int sumatom = 0; + for (int k = 0; k < nspec; ++k) { + const std::string name = head[4 + k]; + const int count = std::stoi(data[3 + k]); + EXPECT_GT(count, 0); + const int size = formula_atoms(name); + EXPECT_GT(size, 0) << "not a valid chemical formula: " << name; + summole += count; + sumatom += count * size; + species[name] = count; + } + + // the molecule counts of the individual species add up to the total + // number of molecules and the atoms of all molecules to all atoms + EXPECT_EQ(summole, nmole); + EXPECT_EQ(sumatom, natoms); + + // the four water molecules and the two hydrogen molecules must be + // recognized as such and stay intact for the duration of the run + EXPECT_EQ(nspec, 2); + EXPECT_EQ(nmole, num_water + num_hydrogen); + EXPECT_EQ(species["H2O"], num_water); + EXPECT_EQ(species["H2"], num_hydrogen); + } + + delete_file(outfile); +} + +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = LAMMPS_NS::utils::split_words(var); + for (auto arg : env) { + if (arg == "-v") verbose = true; + } + } + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + + // finalize the KOKKOS package explicitly: otherwise Kokkos is torn down by + // static destructors at program exit, leading to segfaults in some cases + + lammps_kokkos_finalize(); + + MPI_Finalize(); + return rv; +} From 37e574b2f08f404bbaf1c29a94e2426a6a5d04bc Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 15:41:04 +0000 Subject: [PATCH 052/120] KOKKOS: initialize neighflag for the host backend of pair pod PairPODKokkos::init_style() assigned neighflag after the host_flag early return, so on a host backend the member stayed uninitialized. Unlike other KOKKOS pair styles the host branch of pod/kk does not call the non-accelerated compute() but runs the same kernels on a neighbor list copied from a non-KOKKOS list, and compute() reads neighflag to decide whether the virial comes from an explicit tally or from fdotr. The virial path was therefore selected by an uninitialized value. Move the assignment in front of the early return, and correct the neighbor list error message, which named pair pace/kk. With that, the fixture's KOKKOS cases run and agree with the CPU reference without touching the tolerance - the KOKKOS deviations are in fact smaller than the plain ones (init_forces MaxErr 2.3e-11 against 2.6e-11 of the reference data itself). The fixture needs the single_thread tag, as snap and pace do, because pod/kk rejects more than one thread on a host backend. kokkos_serial_full skips at runtime through the driver's newton-off handling: pair pod requires newton pair on and says so in init_style(). --- src/KOKKOS/pair_pod_kokkos.cpp | 11 ++++++++--- unittest/force-styles/tests/manybody-pair-pod.yaml | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_pod_kokkos.cpp b/src/KOKKOS/pair_pod_kokkos.cpp index 4fbb9edf4ee..01d76185f58 100644 --- a/src/KOKKOS/pair_pod_kokkos.cpp +++ b/src/KOKKOS/pair_pod_kokkos.cpp @@ -86,6 +86,13 @@ PairPODKokkos::~PairPODKokkos() template void PairPODKokkos::init_style() { + // record the neighbor list style for both backends. unlike other KOKKOS pair + // styles the host backend does not fall back to the non-accelerated compute() + // but runs the same kernels on a neighbor list copied over from a non-KOKKOS + // list, and compute() reads neighflag to decide how the virial is tallied. + + neighflag = lmp->kokkos->neighflag; + if (host_flag) { if (lmp->kokkos->nthreads > 1) error->all(FLERR,"Pair style pod/kk can currently only run on a single " @@ -98,14 +105,12 @@ void PairPODKokkos::init_style() if (atom->tag_enable == 0) error->all(FLERR, "Pair style POD requires atom IDs"); if (force->newton_pair == 0) error->all(FLERR, "Pair style POD requires newton pair on"); - neighflag = lmp->kokkos->neighflag; - auto request = neighbor->add_request(this, NeighConst::REQ_FULL); request->set_kokkos_host(std::is_same_v && !std::is_same_v); request->set_kokkos_device(std::is_same_v); if (neighflag == FULL) - error->all(FLERR,"Must use half neighbor list style with pair pace/kk"); + error->all(FLERR,"Must use half neighbor list style with pair pod/kk"); } /* ---------------------------------------------------------------------- diff --git a/unittest/force-styles/tests/manybody-pair-pod.yaml b/unittest/force-styles/tests/manybody-pair-pod.yaml index 211c00153d9..433f9448653 100644 --- a/unittest/force-styles/tests/manybody-pair-pod.yaml +++ b/unittest/force-styles/tests/manybody-pair-pod.yaml @@ -1,8 +1,9 @@ --- lammps_version: 17 Apr 2024 +tags: single_thread date_generated: Wed May 22 23:39:15 2024 epsilon: 5e-11 -skip_tests: kokkos_omp kokkos_serial kokkos_gpu +skip_tests: prerequisites: ! | pair pod From 1a1d5b12ae4a91edf4b33a779bde46c21a8e09ef Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 16:19:49 +0000 Subject: [PATCH 053/120] unittest: declare the dipole atom style prerequisite of the in.brownian tests in.brownian sets "atom_style hybrid dipole sphere", but the fixtures using it listed only "atom sphere" as a prerequisite. In a build without the DIPOLE package they therefore did not skip but failed while setting up the system, with an unrecognized atom style error. --- unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml | 1 + unittest/force-styles/tests/fix-timestep-brownian_point.yaml | 1 + unittest/force-styles/tests/fix-timestep-damping_cundall.yaml | 1 + unittest/force-styles/tests/fix-timestep-electron_stopping.yaml | 1 + unittest/force-styles/tests/fix-timestep-freeze.yaml | 1 + unittest/force-styles/tests/fix-timestep-settorque_atom.yaml | 1 + unittest/force-styles/tests/fix-timestep-viscous_nonlinear.yaml | 1 + unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml | 1 + unittest/force-styles/tests/fix-timestep-wall_gran.yaml | 1 + 9 files changed, 9 insertions(+) diff --git a/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml b/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml index b60732dcc7f..29c80e6a118 100644 --- a/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml +++ b/unittest/force-styles/tests/fix-timestep-addtorque_atom.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix addtorque/atom fix nve/sphere diff --git a/unittest/force-styles/tests/fix-timestep-brownian_point.yaml b/unittest/force-styles/tests/fix-timestep-brownian_point.yaml index b9c2eccef27..865be346e2c 100644 --- a/unittest/force-styles/tests/fix-timestep-brownian_point.yaml +++ b/unittest/force-styles/tests/fix-timestep-brownian_point.yaml @@ -5,6 +5,7 @@ date_generated: Fri Jul 10 18:20:04 2026 epsilon: 5e-14 skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | + atom dipole atom sphere fix brownian pre_commands: "" diff --git a/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml b/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml index edee9774ea9..181e566ca32 100644 --- a/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml +++ b/unittest/force-styles/tests/fix-timestep-damping_cundall.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix damping/cundall fix addforce diff --git a/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml b/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml index 925fc8a6461..6c11d56ea27 100644 --- a/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml +++ b/unittest/force-styles/tests/fix-timestep-electron_stopping.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix electron/stopping fix nve/sphere diff --git a/unittest/force-styles/tests/fix-timestep-freeze.yaml b/unittest/force-styles/tests/fix-timestep-freeze.yaml index f14bfc71e2f..c64fe01688b 100644 --- a/unittest/force-styles/tests/fix-timestep-freeze.yaml +++ b/unittest/force-styles/tests/fix-timestep-freeze.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix freeze fix addforce diff --git a/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml b/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml index b301e9136de..199ea82bc1c 100644 --- a/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml +++ b/unittest/force-styles/tests/fix-timestep-settorque_atom.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix settorque/atom fix nve/sphere diff --git a/unittest/force-styles/tests/fix-timestep-viscous_nonlinear.yaml b/unittest/force-styles/tests/fix-timestep-viscous_nonlinear.yaml index 0d8b08dc2de..04c67953132 100644 --- a/unittest/force-styles/tests/fix-timestep-viscous_nonlinear.yaml +++ b/unittest/force-styles/tests/fix-timestep-viscous_nonlinear.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix viscous/nonlinear pre_commands: "" diff --git a/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml b/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml index 4c738e35534..13e485c401d 100644 --- a/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml +++ b/unittest/force-styles/tests/fix-timestep-viscous_sphere.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 5e-04 skip_tests: prerequisites: | + atom dipole atom sphere fix viscous/sphere fix nve/sphere diff --git a/unittest/force-styles/tests/fix-timestep-wall_gran.yaml b/unittest/force-styles/tests/fix-timestep-wall_gran.yaml index 3347335903c..c6ed88f1eb3 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_gran.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_gran.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 timestep: 1e-05 skip_tests: prerequisites: | + atom dipole atom sphere fix wall/gran fix nve/sphere From 8c33e4aa81792ef8698105120b1db983db9890a4 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 17:05:49 +0000 Subject: [PATCH 054/120] unittest: honor the nofdotr skip token in the accelerator test cases The plain pair style test case skips the comparison against the fdotr virial when the fixture lists "nofdotr" in skip_tests, which a style whose pair forces are not central has to do. The omp, kokkos and intel/opt cases ran that leg unconditionally and failed on such a style for a reason the fixture had already declared. --- unittest/force-styles/test_pair_style.cpp | 88 ++++++++++++++--------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index a23116c0252..b8d3b27e1dd 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -712,20 +712,27 @@ TEST(PairStyle, omp) if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl; } - if (!verbose) ::testing::internal::CaptureStdout(); - restart_lammps(lmp, test_config, true); - if (!verbose) ::testing::internal::GetCapturedStdout(); + // the "nofdotr" token in skip_tests opts a style out of comparing the + // virial tallied by ev_tally() with the fdotr one of the reference, for the + // same reason as in the plain test case above - pair = lmp->force->pair; + if (!test_config.skip_tests.count("nofdotr")) { + if (!verbose) ::testing::internal::CaptureStdout(); + restart_lammps(lmp, test_config, true); + if (!verbose) ::testing::internal::GetCapturedStdout(); - EXPECT_FORCES("nofdotr_forces", lmp->atom, test_config.init_forces, 5 * epsilon); - EXPECT_MAG_FORCES("nofdotr_mag_forces", lmp->atom, test_config.init_mag_forces, 5 * epsilon); - EXPECT_STRESS("nofdotr_stress", pair->virial, test_config.init_stress, 10 * epsilon); + pair = lmp->force->pair; - stats.reset(); - EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, 5 * epsilon); - EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, 5 * epsilon); - if (print_stats) std::cerr << "nofdotr_energy stats:" << stats << std::endl; + EXPECT_FORCES("nofdotr_forces", lmp->atom, test_config.init_forces, 5 * epsilon); + EXPECT_MAG_FORCES("nofdotr_mag_forces", lmp->atom, test_config.init_mag_forces, + 5 * epsilon); + EXPECT_STRESS("nofdotr_stress", pair->virial, test_config.init_stress, 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, 5 * epsilon); + EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, 5 * epsilon); + if (print_stats) std::cerr << "nofdotr_energy stats:" << stats << std::endl; + } if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); @@ -863,20 +870,28 @@ static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl; } - if (!verbose) ::testing::internal::CaptureStdout(); - restart_lammps(lmp, test_config, true, newton); - if (!verbose) ::testing::internal::GetCapturedStdout(); + // the "nofdotr" token in skip_tests opts a style out of comparing the + // virial tallied by ev_tally() with the fdotr one of the reference. it + // applies here for the same reason it applies to the plain test case: the + // random or dissipative pair forces of the style are not central - pair = lmp->force->pair; + if (!test_config.skip_tests.count("nofdotr")) { + if (!verbose) ::testing::internal::CaptureStdout(); + restart_lammps(lmp, test_config, true, newton); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + pair = lmp->force->pair; - EXPECT_FORCES("nofdotr_forces", lmp->atom, test_config.init_forces, 5 * epsilon); - EXPECT_MAG_FORCES("nofdotr_mag_forces", lmp->atom, test_config.init_mag_forces, 5 * epsilon); - EXPECT_STRESS("nofdotr_stress", pair->virial, test_config.init_stress, 10 * epsilon); + EXPECT_FORCES("nofdotr_forces", lmp->atom, test_config.init_forces, 5 * epsilon); + EXPECT_MAG_FORCES("nofdotr_mag_forces", lmp->atom, test_config.init_mag_forces, + 5 * epsilon); + EXPECT_STRESS("nofdotr_stress", pair->virial, test_config.init_stress, 10 * epsilon); - stats.reset(); - EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, 5 * epsilon); - EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, 5 * epsilon); - if (print_stats) std::cerr << "nofdotr_energy stats:" << stats << std::endl; + stats.reset(); + EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, 5 * epsilon); + EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, 5 * epsilon); + if (print_stats) std::cerr << "nofdotr_energy stats:" << stats << std::endl; + } if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); @@ -1468,20 +1483,27 @@ TEST(PairStyle, opt) EXPECT_FP_LE_WITH_EPS((pair->eng_vdwl + pair->eng_coul), energy, epsilon); if (print_stats) std::cerr << "run_energy stats:" << stats << std::endl; - if (!verbose) ::testing::internal::CaptureStdout(); - restart_lammps(lmp, test_config, true); - if (!verbose) ::testing::internal::GetCapturedStdout(); + // the "nofdotr" token in skip_tests opts a style out of comparing the + // virial tallied by ev_tally() with the fdotr one of the reference, for the + // same reason as in the plain test case above - pair = lmp->force->pair; + if (!test_config.skip_tests.count("nofdotr")) { + if (!verbose) ::testing::internal::CaptureStdout(); + restart_lammps(lmp, test_config, true); + if (!verbose) ::testing::internal::GetCapturedStdout(); - EXPECT_FORCES("nofdotr_forces", lmp->atom, test_config.init_forces, 5 * epsilon); - EXPECT_MAG_FORCES("nofdotr_mag_forces", lmp->atom, test_config.init_mag_forces, 5 * epsilon); - EXPECT_STRESS("nofdotr_stress", pair->virial, test_config.init_stress, 10 * epsilon); + pair = lmp->force->pair; - stats.reset(); - EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, 5 * epsilon); - EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, 5 * epsilon); - if (print_stats) std::cerr << "nofdotr_energy stats:" << stats << std::endl; + EXPECT_FORCES("nofdotr_forces", lmp->atom, test_config.init_forces, 5 * epsilon); + EXPECT_MAG_FORCES("nofdotr_mag_forces", lmp->atom, test_config.init_mag_forces, + 5 * epsilon); + EXPECT_STRESS("nofdotr_stress", pair->virial, test_config.init_stress, 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, 5 * epsilon); + EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, 5 * epsilon); + if (print_stats) std::cerr << "nofdotr_energy stats:" << stats << std::endl; + } if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); From 6f0687fdbfbd1d5e269dd6ff0d7ab923ce4bb8b2 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 17:05:49 +0000 Subject: [PATCH 055/120] KOKKOS: fix the random seed and the per-atom energy of pair brownian Two defects, both found by the first test this style has ever had: The constructor seeded the random number pool with "seed + comm->me", but seed is read by PairBrownian::settings(), which runs after the constructor. The pool was therefore seeded from an uninitialized value and the seed given in the pair_style command was ignored. Seed the pool in init_style() instead, the way pair dpd/kk does. compute() called ev_init() without letting it allocate the per-atom arrays but never allocated eatom itself, so any per-atom energy compute - compute pe/atom pair, which the force style test driver always adds - dereferenced a null pointer and the run crashed. Allocate and zero it on the host, as pair dpd/tstat/kk does: the style has no potential energy. Also add the LMP_KOKKOS_DEBUG_RNG switch, so the style can be compared with the CPU version bit for bit in a build configured with -D KOKKOS_DEBUG_RNG=on. The two new references cover the log and the no-log form of the lubrication terms. Both force newton pair on: with newton off the style draws the random force of a pair twice on purpose, and no single reference can cover both. The flaglog reference carries the nofdotr token because the shear and pumping random forces are not central, so the tallied virial cannot reproduce the fdotr one; the no-log reference, which has only the central squeeze term, passes that comparison unmodified. --- src/KOKKOS/pair_brownian_kokkos.cpp | 32 ++++++- src/KOKKOS/pair_brownian_kokkos.h | 9 ++ .../tests/atomic-pair-brownian.yaml | 92 +++++++++++++++++++ .../tests/atomic-pair-brownian_nolog.yaml | 92 +++++++++++++++++++ 4 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 unittest/force-styles/tests/atomic-pair-brownian.yaml create mode 100644 unittest/force-styles/tests/atomic-pair-brownian_nolog.yaml diff --git a/src/KOKKOS/pair_brownian_kokkos.cpp b/src/KOKKOS/pair_brownian_kokkos.cpp index 07c435c2f9a..99217f60c03 100644 --- a/src/KOKKOS/pair_brownian_kokkos.cpp +++ b/src/KOKKOS/pair_brownian_kokkos.cpp @@ -47,7 +47,11 @@ enum { EDGE, CONSTANT, VARIABLE }; template PairBrownianKokkos::PairBrownianKokkos(LAMMPS *lmp) : PairBrownian(lmp), - rand_pool(seed + comm->me) +#ifdef LMP_KOKKOS_DEBUG_RNG + rand_pool(0 /* unused */, lmp) +#else + rand_pool() +#endif { respa_enable = 0; @@ -65,6 +69,10 @@ PairBrownianKokkos::~PairBrownianKokkos() { if (copymode) return; +#ifdef LMP_KOKKOS_DEBUG_RNG + rand_pool.destroy(); +#endif + if (allocated) { memoryKK->destroy_kokkos(k_vatom,vatom); memoryKK->destroy_kokkos(k_cut_inner,cut_inner); @@ -81,6 +89,18 @@ void PairBrownianKokkos::init_style() { PairBrownian::init_style(); + // the random number pool can only be seeded here: the seed is read by + // settings(), which runs after the constructor + +#ifdef LMP_KOKKOS_DEBUG_RNG + rand_pool.init(random,seed + comm->me); +#else + typedef Kokkos::Experimental::UniqueToken< + DeviceType, Kokkos::Experimental::UniqueTokenScope::Global> unique_token_type; + unique_token_type unique_token; + rand_pool = decltype(rand_pool)(seed + comm->me,unique_token.size()); +#endif + // error if rRESPA with inner levels if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) { @@ -160,7 +180,15 @@ void PairBrownianKokkos::compute(int eflag_in, int vflag_in) prethermostat *= static_cast(sqrt(force->vxmu2f / force->ftm2v / force->mvv2e)); // reallocate per-atom arrays if necessary - + // the style has no potential energy, so the per-atom energy is all zero + // and only needs to exist on the host (compare pair dpd/tstat/kk) + + if (eflag_atom) { + maxeatom = atom->nmax; + memory->destroy(eatom); + memory->create(eatom,maxeatom,"pair:eatom"); + memset(&eatom[0], 0, maxeatom * sizeof(double)); + } if (vflag_atom) { memoryKK->destroy_kokkos(k_vatom,vatom); memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom"); diff --git a/src/KOKKOS/pair_brownian_kokkos.h b/src/KOKKOS/pair_brownian_kokkos.h index 3b648e710fc..94bcc7023e9 100644 --- a/src/KOKKOS/pair_brownian_kokkos.h +++ b/src/KOKKOS/pair_brownian_kokkos.h @@ -27,7 +27,11 @@ PairStyle(brownian/kk/host,PairBrownianKokkos); #include "pair_kokkos.h" #include "kokkos_type.h" #include "kokkos_base.h" +#ifdef LMP_KOKKOS_DEBUG_RNG +#include "rand_pool_wrap_kokkos.h" +#else #include "Kokkos_Random.hpp" +#endif #include "comm_kokkos.h" namespace LAMMPS_NS { @@ -152,8 +156,13 @@ class PairBrownianKokkos : public PairBrownian, public KokkosBase { friend void pair_virial_fdotr_compute(PairBrownianKokkos*); +#ifdef LMP_KOKKOS_DEBUG_RNG + RandPoolWrap rand_pool; + typedef RandWrap rand_type; +#else Kokkos::Random_XorShift64_Pool rand_pool; typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; +#endif }; } diff --git a/unittest/force-styles/tests/atomic-pair-brownian.yaml b/unittest/force-styles/tests/atomic-pair-brownian.yaml new file mode 100644 index 00000000000..c74a7aa1cda --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-brownian.yaml @@ -0,0 +1,92 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 15:58:46 2026 +epsilon: 5e-13 +skip_tests: nofdotr kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng kokkos_omp_full kokkos_serial_full +prerequisites: | + atom sphere + pair brownian +pre_commands: | + variable atom_style index sphere + variable units index lj + variable newton_pair delete + variable newton_pair index on +post_commands: | + neighbor 1.0 bin + set type * diameter 2.0 + set type 1 mass 9 + set type 2 mass 1 + comm_style brick + comm_modify mode single +input_file: in.colloid +pair_style: brownian 1.5 1 1 2.01 2.5 2.0 5878567 +pair_coeff: | + * * +extract: "" +natoms: 27 +init_vdwl: 0 +init_coul: 0 +init_stress: |- + -1.0024661609096561e+03 -1.6156219490820963e+03 -4.9486836911923365e+03 2.0366987908192541e+03 -2.1477873971010831e+02 -3.0862115879675284e+03 +init_forces: |2 + 1 1.1066325644063483e+02 1.7498538444677746e+02 -1.2496434979988696e+02 + 2 -8.7569775575177673e+01 -2.6997908182931578e+01 -7.0728111727233369e+01 + 3 -9.0522364866005560e+01 3.1785084171318090e+01 -1.9039648588140867e+02 + 4 -1.3073401178384503e+02 -2.9018425433091352e+02 -1.5699853093368722e+02 + 5 1.3792209580213327e+02 -1.6019441428862271e+02 -9.4269943472333466e+01 + 6 3.1616731138677395e+01 1.3361621951695889e+02 -1.5440890102137658e+02 + 7 -8.9358653193196574e+01 1.6233255661628453e+02 -7.4840619906937832e+01 + 8 4.1385815825182226e+02 -3.7967352604931722e+02 -2.2137364385190017e+02 + 9 1.6451317902468162e+02 -7.5357422128077857e+01 -8.3781076984963065e+01 + 10 5.2644795240203905e+01 8.1630439947876468e+01 1.0761050222193938e+02 + 11 3.2898715776432596e+01 -1.0747011726371943e+02 1.3323237028758783e+02 + 12 2.6644464708794047e+01 1.7833286548905056e+02 2.1509592684355027e+02 + 13 5.8402241810503575e+01 1.0419479948585206e+02 -1.7057833680467866e+02 + 14 -1.3132332304634409e+02 1.1761080543837487e+02 -9.7437205067722260e+01 + 15 1.4540109360673625e+02 -4.8703681317035020e+01 1.0908262140848082e+02 + 16 1.7330510564388044e+02 -3.8051453430312804e+01 1.3800692205562657e+02 + 17 6.4236255548993398e+01 -1.3509406541611037e+02 5.2679836075951684e+01 + 18 -1.7285905919926856e+02 -1.9110251087660635e+02 -6.6365424459482458e-01 + 19 -1.9187461183376283e+02 -8.3938654252386911e+01 -6.1750701132384577e+01 + 20 1.6121228278009804e+02 5.5923413502813176e+01 -9.3593433548102482e+01 + 21 -9.0971420795831875e+01 1.4208631875848965e+02 -1.5350507416827571e+02 + 22 -1.7098341039443829e+02 1.3974243816621811e+02 -1.7165911683424557e+02 + 23 8.4516681883817640e+01 -2.1274125187086563e+02 3.4861213864709487e+02 + 24 -1.6893038922526739e+02 1.1438406637483443e+02 1.7079677420127280e+02 + 25 -4.0471633014439004e+02 2.2820814756404414e+02 -1.7295551176849318e+02 + 26 -1.2954160513329896e+02 1.1334962975761432e+02 1.6408938624965634e+02 + 27 1.5526755523656780e+02 9.3656018935708914e+01 1.0598626727899772e+01 +run_vdwl: 0 +run_coul: 0 +run_stress: |- + -4.2837262928080245e+03 4.7711379885511024e+03 -2.7896510088254454e+03 6.7133351991396762e+02 -1.4157225876903344e+03 -2.6454688584950636e+03 +run_forces: |2 + 1 -1.2857387856643669e+02 -8.6321486163203048e+01 6.0536955201525544e+01 + 2 -6.1178855579427164e+01 7.7888244856588642e+01 -7.7152784416426002e+01 + 3 -1.3563412680454965e+02 -1.1174381717956174e+02 -8.4622694367902341e+01 + 4 3.2917560664665325e+02 3.4402078953338798e+02 4.6867474331140706e+01 + 5 1.4239700905589677e+02 6.4851410644076367e+01 4.3592767039049406e+01 + 6 -1.8516190449141848e+02 -2.4069111156278652e+02 -7.4901055581681749e+02 + 7 7.7050992425380400e+01 -1.1689916400810671e+02 1.6097930874777055e+02 + 8 -5.4297805451824138e+02 4.1416832584686586e+02 4.2364287398150520e+02 + 9 1.4480823160629558e+02 -2.0478016238255563e+01 1.4146221498554749e+02 + 10 -1.3012001620617576e+02 1.4733515983960388e+02 -7.6014301333681374e+01 + 11 -4.3575316543625138e+02 -3.0813094377753475e+02 -2.4578297877739095e+02 + 12 5.1226658793194559e+00 -2.3256120137055714e+02 4.2030338773332282e+01 + 13 -8.3569967691767701e+01 1.1830054588752128e+02 -9.7943212911842309e+01 + 14 -6.2566217645526223e+01 7.9307915101823156e+01 7.3182196769209867e+01 + 15 -1.2553160952713257e+02 1.0796379515655111e+02 -1.0556699836944675e+02 + 16 -9.9830660424031592e+01 -1.0835891358697658e+01 1.9298299899500182e+02 + 17 -6.2388955407213423e+01 1.3777199910023370e+02 -1.1962774304252838e+02 + 18 5.1119028806139411e+01 1.2905511373397286e+02 1.3256463002017460e+02 + 19 -1.8785447883337892e+02 -1.6322493070926842e+02 1.5270986279559486e+02 + 20 -4.9823913034931714e+01 -1.0211179524566154e+02 1.1162898539034941e+01 + 21 1.4598966911861720e+02 1.5584674956600878e+02 -5.1682217532809986e+01 + 22 3.8998115341072051e+01 -6.9607948902985655e+01 -3.4486308082461278e+01 + 23 1.6179952876302139e+02 -8.7168862338190209e+01 4.6690394408330201e+02 + 24 -1.5120391450279749e+02 -2.4841394836515789e+01 -4.9098500170906448e+01 + 25 1.5545169086352266e+02 -1.6022796792503803e+02 -3.1328356981087404e+02 + 26 3.6616779999657012e+02 1.3849562787626624e+02 7.6325035240463109e+01 + 27 -5.7679547940413009e+01 1.6266900880237563e+02 -5.7380708805585208e+01 +... diff --git a/unittest/force-styles/tests/atomic-pair-brownian_nolog.yaml b/unittest/force-styles/tests/atomic-pair-brownian_nolog.yaml new file mode 100644 index 00000000000..c21976b4149 --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-brownian_nolog.yaml @@ -0,0 +1,92 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread +date_generated: Fri Sep 4 16:12:44 2026 +epsilon: 5e-13 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng kokkos_omp_full kokkos_serial_full +prerequisites: | + atom sphere + pair brownian +pre_commands: | + variable atom_style index sphere + variable units index lj + variable newton_pair delete + variable newton_pair index on +post_commands: | + neighbor 1.0 bin + set type * diameter 2.0 + set type 1 mass 9 + set type 2 mass 1 + comm_style brick + comm_modify mode single +input_file: in.colloid +pair_style: brownian 1.5 0 0 2.01 2.5 2.0 5878567 +pair_coeff: | + * * +extract: "" +natoms: 27 +init_vdwl: 0 +init_coul: 0 +init_stress: |- + -3.7030148527730580e+02 7.9694573034673977e+02 6.1564078084366065e+02 -3.2770418225282810e+01 -4.0091958139264989e+01 6.1914831754391616e+02 +init_forces: |2 + 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 3 1.4078609639205249e+02 -2.7464913222459302e+01 -3.2826768867867074e+01 + 4 -3.3105804209620374e+01 4.3542813994305436e+02 3.7481570300370583e+02 + 5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 6 1.4717399544515888e+02 -1.9719282053880755e+02 2.3645356652712493e+01 + 7 -1.0248145673791453e+02 -2.7289865113308824e+01 -6.9321130578003192e+01 + 8 3.0207533070367447e+02 2.1610230722730378e+02 2.2612873103159029e+02 + 9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 11 -9.1222229457086272e+01 -5.3161884844010665e+01 -3.7261376808162254e+01 + 12 -1.0768029218243211e+02 -4.0796322672059506e+02 -3.4198893413583875e+02 + 13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 17 1.0248145673791453e+02 2.7289865113308824e+01 6.9321130578003192e+01 + 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 20 -4.2282917082653320e+01 -6.4510076396287168e+00 -2.8459287161479856e+00 + 21 4.2282917082653320e+01 6.4510076396287168e+00 2.8459287161479856e+00 + 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 23 -1.5516342943874434e+02 -3.6642207413047601e-01 -2.0343734278726410e+02 + 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 25 -2.9408589671008900e+02 -1.8543064614365754e+01 -4.6336744897038685e+01 + 26 9.1222229457086272e+01 5.3161884844010665e+01 3.7261376808162254e+01 + 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +run_vdwl: 0 +run_coul: 0 +run_stress: |2- + 3.4417284696410815e+02 3.1684475020854677e+02 2.2551311480334107e+02 2.3699984322363366e+02 5.2515361303351665e+02 -1.1280739519246572e+02 +run_forces: |2 + 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 3 -1.5909538334602951e+02 1.0669191027686569e+01 2.0108228416845542e+01 + 4 1.4739105438320746e+02 -6.0994527087002353e+01 -6.7656992599731211e+01 + 5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 6 3.9472951337245865e+02 -2.8392962692759897e+02 3.7623918738768236e+02 + 7 -6.9748941104774602e+01 -2.1103483516650805e+01 -4.6604168117790508e+01 + 8 4.1724001178592675e+02 -1.1618553854774053e+02 -7.3056113384954841e+01 + 9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 11 7.2238068223236360e+02 3.7367881884455227e+02 2.7323671499791016e+02 + 12 1.1704328962822046e+01 5.0325336059315788e+01 4.7548764182885662e+01 + 13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 17 6.9748941104774602e+01 2.1103483516650805e+01 4.6604168117790508e+01 + 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 20 -1.0948042859887754e+02 -1.4413696589010499e+01 -1.1541622860420138e+00 + 21 1.0948042859887754e+02 1.4413696589010499e+01 1.1541622860420138e+00 + 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 23 -3.6351192133330841e+02 3.1150212690965037e+02 -3.5396838240570861e+02 + 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 25 -4.4845760382507700e+02 8.8613038565689095e+01 5.0785308402981101e+01 + 26 -7.2238068223236360e+02 -3.7367881884455227e+02 -2.7323671499791016e+02 + 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +... From e07db66302bd22cd8af7dffc3ab8ae4062a7bc75 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 17:06:04 +0000 Subject: [PATCH 056/120] test: add fix wall/piston references Two fixtures for a style that had none. The plain one moves the piston without a thermostat and is deterministic, so its KOKKOS cases run in an ordinary build; the second adds the temp and rough keywords and is compared in a build configured with -D KOKKOS_DEBUG_RNG=on. Both carry the no_respa tag. Respa calls post_integrate_respa(), which FixWallPiston does not implement, so the fix is silently inert under run_style respa - a limitation of the CPU style, not of the KOKKOS variant. --- .../tests/fix-timestep-wall_piston.yaml | 78 +++++++++++++++++++ .../tests/fix-timestep-wall_piston_temp.yaml | 78 +++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 unittest/force-styles/tests/fix-timestep-wall_piston.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-wall_piston_temp.yaml diff --git a/unittest/force-styles/tests/fix-timestep-wall_piston.yaml b/unittest/force-styles/tests/fix-timestep-wall_piston.yaml new file mode 100644 index 00000000000..274bdda4423 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-wall_piston.yaml @@ -0,0 +1,78 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 16:06:08 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix wall/piston +pre_commands: "" +post_commands: | + change_box all boundary p p s + fix move all nve + fix test all wall/piston zlo pos -4.35 vel 0.01 units box +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +run_pos: |2 + 1 -2.7045559775384231e-01 2.4912159905679703e+00 -1.6695851791541580e-01 + 2 3.1004029573899528e-01 2.9612354631094391e+00 -8.5466363037021453e-01 + 3 -7.0398551400766696e-01 1.2305509955828715e+00 -6.2777526944456252e-01 + 4 -1.5818159336499196e+00 1.4837407818929775e+00 -1.2538710836062164e+00 + 5 -9.0719763672790676e-01 9.2652103885677084e-01 3.9954210488375047e-01 + 6 2.4831720528334547e-01 2.8313021495041552e-01 -1.2314233331619984e+00 + 7 3.4143527639485316e-01 -2.2646551006289074e-02 -2.5292291414623356e+00 + 8 1.1743552230936252e+00 -4.8863228582589818e-01 -6.3783432918283700e-01 + 9 1.3800524229549833e+00 -2.5274721031094366e-01 2.8353985886366467e-01 + 10 2.0510765226249932e+00 -1.4604063745271656e+00 -9.8323745116291017e-01 + 11 1.7878031946048565e+00 -1.9921863274088210e+00 -1.8890602448072109e+00 + 12 3.0063007044562853e+00 -4.9013350583925130e-01 -1.6231898109795748e+00 + 13 4.0515402960655775e+00 -8.9202011646346391e-01 -1.6400005531616897e+00 + 14 2.6066963346042500e+00 -4.1789253972155060e-01 -2.6634003608604711e+00 + 15 2.9695287185833776e+00 5.5422613161837520e-01 -1.2342022021858117e+00 + 16 2.6747029702347316e+00 -2.4124119059538045e+00 -2.3435747032086954e-02 + 17 2.2153577786351653e+00 -2.0897985187427341e+00 1.1963150793230914e+00 + 18 2.1369701704148887e+00 3.0158507413674163e+00 -3.5179348337110579e+00 + 19 1.5355837135401960e+00 2.6255292354745432e+00 -4.2353987771402659e+00 + 20 2.7727573006256381e+00 3.6923910450056878e+00 -3.9330842452711767e+00 + 21 4.9184941604873043e+00 -4.0722066674575821e+00 -3.6028702410333531e+00 + 22 4.3014243310449567e+00 -4.2250710435224352e+00 -4.2732353678529291e+00 + 23 5.7429410118324622e+00 -3.5818248363625136e+00 -3.8806111875531752e+00 + 24 2.0689243582454213e+00 3.1513346907303501e+00 3.1550389751128463e+00 + 25 1.3045351331414130e+00 3.2665125705869009e+00 2.5111855257365274e+00 + 26 2.5809237402714267e+00 4.0117602605512728e+00 3.2212060528800821e+00 + 27 -1.9611343130357228e+00 -4.3563411931359752e+00 2.1098293115523705e+00 + 28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00 + 29 -1.3126000191359855e+00 -3.5962518039482929e+00 2.2746342468737835e+00 +run_vel: |2 + 1 8.1705744183187337e-03 1.6516406176267789e-02 4.7902264318998907e-03 + 2 5.4501493445687672e-03 5.1791699408499248e-03 -1.4372931530371789e-03 + 3 -8.2298292716997522e-03 -1.2926551615059543e-02 -4.0984181178009829e-03 + 4 -3.7699042589820135e-03 -6.5722892099259788e-03 -1.1184640360602496e-03 + 5 -1.1021961004384361e-02 -9.8906780938855035e-03 -2.8410737829213327e-03 + 6 -3.9676663120835884e-02 4.6817061435073769e-02 3.7148492006778382e-02 + 7 9.1033948874697814e-04 -1.0128524336334113e-02 -5.1568251745059725e-02 + 8 7.9064714683479698e-03 -3.3507256623968376e-03 3.4557098428600198e-02 + 9 1.5644176192712550e-03 3.7365545994843654e-03 1.5047408809863917e-02 + 10 2.9201447646038072e-02 -2.9249579336432650e-02 -1.5018077741569951e-02 + 11 -4.7835959737451599e-03 -3.7481386148466682e-03 -2.3464104098369315e-03 + 12 2.2696460389046323e-03 -3.4774269487626065e-04 -3.0640772314828530e-03 + 13 2.7531743405937990e-03 5.8171055034154364e-03 -7.9467479479249342e-04 + 14 3.5246183074717804e-03 -5.7939996216184670e-03 -3.9478430722834886e-03 + 15 -1.8547943404484456e-03 -5.8554730560520865e-03 6.2938485045677030e-03 + 16 1.8681501188443438e-02 -1.3262466931634255e-02 -4.5638652664860495e-02 + 17 -1.2896269759091472e-02 9.7527664187143197e-03 3.7296535106456336e-02 + 18 -8.0065794160733852e-04 -8.6270472276901646e-04 -1.4483040481180292e-03 + 19 1.2452390081164023e-03 -2.5061097767567070e-03 7.2998639304763299e-03 + 20 3.5930060819597187e-03 3.6938860775996927e-03 3.2322739019243034e-03 + 21 1.1246046978630417e-02 2.2765034491926107e-03 1.7023410398084277e-02 + 22 -5.7093527512362185e-02 -1.5027590355773730e-02 -4.7395971889019631e-02 + 23 5.3115771117545636e-03 -8.0963865528694895e-04 -1.7428733474804401e-03 + 24 3.1926368451268419e-04 -9.9445664487426673e-04 1.4999960207064431e-04 + 25 1.3789752933078488e-04 -4.4335894831520730e-03 -8.1808138106079882e-04 + 26 2.0485904023409989e-03 2.7813358660936137e-03 4.3245726853349264e-03 + 27 4.5604120293367824e-04 -1.0305523026921278e-03 2.1188058381359023e-04 + 28 -6.2544520861855159e-03 1.4127711176146873e-03 -1.8429821884794260e-03 + 29 6.4110631534401654e-04 3.1273432719593789e-03 3.7253671105656767e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-wall_piston_temp.yaml b/unittest/force-styles/tests/fix-timestep-wall_piston_temp.yaml new file mode 100644 index 00000000000..23080885789 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-wall_piston_temp.yaml @@ -0,0 +1,78 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread no_respa +date_generated: Fri Sep 4 16:07:58 2026 +epsilon: 5e-13 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom full + fix wall/piston +pre_commands: "" +post_commands: | + change_box all boundary p p s + fix move all nve + fix test all wall/piston zlo pos -4.35 vel 0.01 temp 100.0 10.0 12345 3.0 rough 0.1 units box +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +run_pos: |2 + 1 -2.7045559775384109e-01 2.4912159905679712e+00 -1.6695851791541733e-01 + 2 3.1004029573899528e-01 2.9612354631094391e+00 -8.5466363037021453e-01 + 3 -7.0398551400775433e-01 1.2305509955829421e+00 -6.2777526944456830e-01 + 4 -1.5818159336499236e+00 1.4837407818929846e+00 -1.2538710836062088e+00 + 5 -9.0719763672790055e-01 9.2652103885676296e-01 3.9954210488374930e-01 + 6 2.4831720526994272e-01 2.8313021495953267e-01 -1.2314233331684721e+00 + 7 3.4143527640797444e-01 -2.2646551029423093e-02 -2.5292291414789867e+00 + 8 1.1743552230150109e+00 -4.8863228576205864e-01 -6.3783432916156380e-01 + 9 1.3800524229526692e+00 -2.5274721030817726e-01 2.8353985886630073e-01 + 10 2.0510765223688274e+00 -1.4604063743300046e+00 -9.8323745104717086e-01 + 11 1.7878031945445785e+00 -1.9921863273719296e+00 -1.8890602448034948e+00 + 12 3.0063007041992091e+00 -4.9013350547119477e-01 -1.6231898109033676e+00 + 13 4.0515402959832647e+00 -8.9202011627005562e-01 -1.6400005530843300e+00 + 14 2.6066963345831575e+00 -4.1789253970097956e-01 -2.6634003608739989e+00 + 15 2.9695287185771910e+00 5.5422613163296719e-01 -1.2342022021834054e+00 + 16 2.6747029698817761e+00 -2.4124119057322471e+00 -2.3435746649630860e-02 + 17 2.2153577785783254e+00 -2.0897985187175045e+00 1.1963150793824349e+00 + 18 2.1369701704136799e+00 3.0158507413646936e+00 -3.5179348337134178e+00 + 19 1.5355837135402270e+00 2.6255292354740845e+00 -4.2353987771406514e+00 + 20 2.7727573006256474e+00 3.6923910450062158e+00 -3.9330842452715595e+00 + 21 4.9098898770226480e+00 -4.0740483946544392e+00 -3.6123990684503897e+00 + 22 4.3353904197423470e+00 -4.2174702258839636e+00 -4.3289926306792115e+00 + 23 5.7433225895023181e+00 -3.5820736181437116e+00 -3.8788919343890149e+00 + 24 2.0689243582454213e+00 3.1513346907303501e+00 3.1550389751128463e+00 + 25 1.3045351331414130e+00 3.2665125705869009e+00 2.5111855257365274e+00 + 26 2.5809237402714267e+00 4.0117602605512728e+00 3.2212060528800821e+00 + 27 -1.9611343130357228e+00 -4.3563411931359752e+00 2.1098293115523705e+00 + 28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00 + 29 -1.3126000191359855e+00 -3.5962518039482929e+00 2.2746342468737835e+00 +run_vel: |2 + 1 8.1705744183231763e-03 1.6516406176270010e-02 4.7902264318954715e-03 + 2 5.4501493445687785e-03 5.1791699408498294e-03 -1.4372931530373654e-03 + 3 -8.2298292719009715e-03 -1.2926551614903532e-02 -4.0984181178260904e-03 + 4 -3.7699042589946189e-03 -6.5722892099052029e-03 -1.1184640360379443e-03 + 5 -1.1021961004367182e-02 -9.8906780939070852e-03 -2.8410737829245390e-03 + 6 -3.9676663137965189e-02 4.6817061442480240e-02 3.7148491990336409e-02 + 7 9.1033951686300414e-04 -1.0128524385289078e-02 -5.1568251779862899e-02 + 8 7.9064713551245096e-03 -3.3507255880623268e-03 3.4557098436913895e-02 + 9 1.5644176156106799e-03 3.7365546036575280e-03 1.5047408813839955e-02 + 10 2.9201447269855515e-02 -2.9249579115700121e-02 -1.5018077666639422e-02 + 11 -4.7835960328784866e-03 -3.7481385950063240e-03 -2.3464104403721833e-03 + 12 2.2696456056253956e-03 -3.4774220741825977e-04 -3.0640771924662622e-03 + 13 2.7531741750137914e-03 5.8171058303505838e-03 -7.9467467504070995e-04 + 14 3.5246182770838309e-03 -5.7939996086265677e-03 -3.9478431015834356e-03 + 15 -1.8547943528614834e-03 -5.8554730294223013e-03 6.2938485076389408e-03 + 16 1.8681500576516546e-02 -1.3262466608514769e-02 -4.5638652143660474e-02 + 17 -1.2896269875343759e-02 9.7527664701962773e-03 3.7296535225808704e-02 + 18 -8.0065794409036651e-04 -8.6270472851317963e-04 -1.4483040530331574e-03 + 19 1.2452390081625598e-03 -2.5061097777395731e-03 7.2998639298600494e-03 + 20 3.5930060819771006e-03 3.6938860787710994e-03 3.2322739013838113e-03 + 21 4.3334869840424553e-03 8.7090104568856392e-04 9.3194726721110392e-03 + 22 -2.9686471912250007e-02 -9.0301001218040834e-03 -1.8496317294170152e-02 + 23 5.4989550060794597e-03 -1.1960718222439012e-03 1.1101930833888756e-04 + 24 3.1926368451268283e-04 -9.9445664487427541e-04 1.4999960207063629e-04 + 25 1.3789752933078488e-04 -4.4335894831520756e-03 -8.1808138106079990e-04 + 26 2.0485904023409989e-03 2.7813358660936129e-03 4.3245726853349264e-03 + 27 4.5604120293368783e-04 -1.0305523026921202e-03 2.1188058381358730e-04 + 28 -6.2544520861855151e-03 1.4127711176146877e-03 -1.8429821884794260e-03 + 29 6.4110631534401838e-04 3.1273432719593807e-03 3.7253671105656758e-03 +... From 99a1a479159fa159e6c850354c9036e0055a1606 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 17:06:04 +0000 Subject: [PATCH 057/120] KOKKOS: use the host random numbers in the dpd pair styles when asked for The five dpd KOKKOS pair styles already had a DPD_USE_RAN_MARS compile option that draws the random numbers from the host RanMars generator, but it was independent of the LMP_KOKKOS_DEBUG_RNG switch that all other KOKKOS styles with a random number generator follow. Select it from that switch, unless a generator was chosen explicitly, so a build configured with -D KOKKOS_DEBUG_RNG=on compares these styles with the CPU version bit for bit like the rest. The new fix dpd/energy reference needs this: the fix has no random numbers of its own, but the conservative and dissipative forces it accumulates come from pair dpd/fdt/energy, which has. It cannot be combined with fix shardlow - PairDPDfdtEnergy only grows duCond and duMech in the non-split branch of compute() - so the deck uses fix eos/cv and fix nve instead, which also feeds the energy the fix computes back into the temperature and thus into the trajectory that is compared. --- src/KOKKOS/pair_dpd_ext_kokkos.h | 8 ++ src/KOKKOS/pair_dpd_ext_tstat_kokkos.h | 8 ++ src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 8 ++ src/KOKKOS/pair_dpd_kokkos.h | 8 ++ src/KOKKOS/pair_dpd_tstat_kokkos.h | 8 ++ unittest/force-styles/tests/coeffs.dpd-fdt | 6 ++ .../tests/fix-timestep-dpd_energy.yaml | 86 +++++++++++++++++++ 7 files changed, 132 insertions(+) create mode 100644 unittest/force-styles/tests/coeffs.dpd-fdt create mode 100644 unittest/force-styles/tests/fix-timestep-dpd_energy.yaml diff --git a/src/KOKKOS/pair_dpd_ext_kokkos.h b/src/KOKKOS/pair_dpd_ext_kokkos.h index 9d9d1cc9791..b1656e43af5 100644 --- a/src/KOKKOS/pair_dpd_ext_kokkos.h +++ b/src/KOKKOS/pair_dpd_ext_kokkos.h @@ -26,6 +26,14 @@ PairStyle(dpd/ext/kk/host,PairDPDExtKokkos); #include "pair_kokkos.h" #include "kokkos_type.h" +// a build configured with -D KOKKOS_DEBUG_RNG=on draws the random numbers from +// the host RanMars generator, so that the results can be compared bit for bit +// with the plain style. an explicit choice of generator still wins. + +#if defined(LMP_KOKKOS_DEBUG_RNG) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) +#define DPD_USE_RAN_MARS +#endif + #if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) #define DPD_USE_Random_XorShift64 #endif diff --git a/src/KOKKOS/pair_dpd_ext_tstat_kokkos.h b/src/KOKKOS/pair_dpd_ext_tstat_kokkos.h index 5b1cd1c9fd0..890ccbfc18d 100644 --- a/src/KOKKOS/pair_dpd_ext_tstat_kokkos.h +++ b/src/KOKKOS/pair_dpd_ext_tstat_kokkos.h @@ -26,6 +26,14 @@ PairStyle(dpd/ext/tstat/kk/host,PairDPDExtTstatKokkos); #include "pair_kokkos.h" #include "kokkos_type.h" +// a build configured with -D KOKKOS_DEBUG_RNG=on draws the random numbers from +// the host RanMars generator, so that the results can be compared bit for bit +// with the plain style. an explicit choice of generator still wins. + +#if defined(LMP_KOKKOS_DEBUG_RNG) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) +#define DPD_USE_RAN_MARS +#endif + #if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) #define DPD_USE_Random_XorShift64 #endif diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index ef39159945a..d3d2568024d 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -23,6 +23,14 @@ PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos); #ifndef LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H #define LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H +// a build configured with -D KOKKOS_DEBUG_RNG=on draws the random numbers from +// the host RanMars generator, so that the results can be compared bit for bit +// with the plain style. an explicit choice of generator still wins. + +#if defined(LMP_KOKKOS_DEBUG_RNG) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) +#define DPD_USE_RAN_MARS +#endif + #if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) #define DPD_USE_Random_XorShift64 #endif diff --git a/src/KOKKOS/pair_dpd_kokkos.h b/src/KOKKOS/pair_dpd_kokkos.h index 73f1b4af086..99123272931 100644 --- a/src/KOKKOS/pair_dpd_kokkos.h +++ b/src/KOKKOS/pair_dpd_kokkos.h @@ -26,6 +26,14 @@ PairStyle(dpd/kk/host,PairDPDKokkos); #include "pair_kokkos.h" #include "kokkos_type.h" +// a build configured with -D KOKKOS_DEBUG_RNG=on draws the random numbers from +// the host RanMars generator, so that the results can be compared bit for bit +// with the plain style. an explicit choice of generator still wins. + +#if defined(LMP_KOKKOS_DEBUG_RNG) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) +#define DPD_USE_RAN_MARS +#endif + #if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) #define DPD_USE_Random_XorShift64 #endif diff --git a/src/KOKKOS/pair_dpd_tstat_kokkos.h b/src/KOKKOS/pair_dpd_tstat_kokkos.h index 8fe2c2121d0..84e65f4fa53 100644 --- a/src/KOKKOS/pair_dpd_tstat_kokkos.h +++ b/src/KOKKOS/pair_dpd_tstat_kokkos.h @@ -26,6 +26,14 @@ PairStyle(dpd/tstat/kk/host,PairDPDTstatKokkos); #include "pair_kokkos.h" #include "kokkos_type.h" +// a build configured with -D KOKKOS_DEBUG_RNG=on draws the random numbers from +// the host RanMars generator, so that the results can be compared bit for bit +// with the plain style. an explicit choice of generator still wins. + +#if defined(LMP_KOKKOS_DEBUG_RNG) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) +#define DPD_USE_RAN_MARS +#endif + #if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) #define DPD_USE_Random_XorShift64 #endif diff --git a/unittest/force-styles/tests/coeffs.dpd-fdt b/unittest/force-styles/tests/coeffs.dpd-fdt new file mode 100644 index 00000000000..08fd71dfde4 --- /dev/null +++ b/unittest/force-styles/tests/coeffs.dpd-fdt @@ -0,0 +1,6 @@ +# force field for the DPD-REACT fixtures built on in.dpd-fdt. the fix-timestep +# driver needs the pair style set up from a coeffs file, the pair style tests +# take it from their own "pair_style"/"pair_coeff" keywords instead. + +pair_style dpd/fdt/energy 7.0 234324 +pair_coeff * * 0.075 0.022 3.2e-5 7.0 diff --git a/unittest/force-styles/tests/fix-timestep-dpd_energy.yaml b/unittest/force-styles/tests/fix-timestep-dpd_energy.yaml new file mode 100644 index 00000000000..7ba941e6e58 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-dpd_energy.yaml @@ -0,0 +1,86 @@ +--- +lammps_version: 2 Sep 2026 +tags: single_thread no_respa no_restart +date_generated: Fri Sep 4 16:08:44 2026 +epsilon: 5e-13 +timestep: 0.001 +skip_tests: kokkos_omp_devicerng kokkos_serial_devicerng kokkos_gpu_devicerng kokkos_omp_full kokkos_serial_full +prerequisites: | + atom dpd + fix dpd/energy + pair dpd/fdt/energy +pre_commands: "" +post_commands: | + fix eosfix all eos/cv 0.0005 + fix move all nve + fix test all dpd/energy +input_file: in.dpd-fdt +input_coeffs: coeffs.dpd-fdt +natoms: 32 +run_pos: |2 + 1 1.8532556121712322e+01 1.8447239081189206e+01 1.8595812345142374e+01 + 2 4.2012801947877181e+00 4.7364136991145260e+00 1.8637315317935400e+01 + 3 5.1489804095009122e+00 1.3651469779465933e-01 4.8163749467629247e+00 + 4 1.8302912066746039e+01 4.2569267572204135e+00 4.2355145765087743e+00 + 5 9.4830788304005598e+00 1.8278441157949008e+01 2.4751985098678136e-01 + 6 1.4619397205856359e+01 4.9107067894930463e+00 1.8518273599696514e+01 + 7 1.4275812729613474e+01 4.8774185480285315e-01 4.6657437353831979e+00 + 8 9.2687449868825169e+00 4.7148431906620232e+00 5.2417439044465404e+00 + 9 1.8538578433650116e+01 9.0309102686749778e+00 1.8549398768357687e+01 + 10 4.4541506986705528e+00 1.3665693245499106e+01 3.1610759148211093e-01 + 11 4.9613774972853664e+00 9.1782542040697574e+00 4.8501831392540433e+00 + 12 4.0447242255293692e-01 1.4211759349719546e+01 4.5462821611705984e+00 + 13 9.8346299112110511e+00 9.1083562265346973e+00 1.2760240737439668e-01 + 14 1.4201322154819508e+01 1.4280876944305106e+01 2.3488668933383008e-01 + 15 1.4503087465000956e+01 8.8893427126453162e+00 4.9708773995370139e+00 + 16 8.9444542113059970e+00 1.4725100529420937e+01 4.6616909499686523e+00 + 17 7.8410914343567603e-02 1.8215770954122871e+01 8.9461018193498827e+00 + 18 5.0023166307904408e+00 4.3032033811350114e+00 9.9406706871693604e+00 + 19 4.6454214113464376e+00 1.8351756456323422e+01 1.4137752569649859e+01 + 20 1.8562918803286792e+01 4.1054702474986007e+00 1.4320231776441148e+01 + 21 9.8981856387036746e+00 1.8590289584417185e+01 9.7285737298545278e+00 + 22 1.3898437662035649e+01 5.1055628770396080e+00 9.5517659314071413e+00 + 23 1.4260583029552556e+01 5.9246933402349593e-02 1.4542608361217617e+01 + 24 9.3565431685388400e+00 5.2787952567532512e+00 1.4420586143678857e+01 + 25 2.7067723835430324e-01 9.4896950997609579e+00 9.3061281725854741e+00 + 26 4.6486648187835202e+00 1.4425760914507817e+01 9.5069298773185462e+00 + 27 5.3291896584429406e+00 9.2243095855314863e+00 1.3896107836248836e+01 + 28 1.8573324111453772e+01 1.4121363718049427e+01 1.3572795150581522e+01 + 29 9.4497809664586701e+00 9.2193498681898038e+00 9.0518848778446852e+00 + 30 1.4477409177617499e+01 1.4072828662984703e+01 9.6569096441294828e+00 + 31 1.4661903229624452e+01 9.5571631693401962e+00 1.3844951419940205e+01 + 32 9.4956330023263931e+00 1.4375344012764682e+01 1.4179014034156875e+01 +run_vel: |2 + 1 1.6284503603659253e+00 -9.8851051233061257e-03 2.9490067195211511e-01 + 2 3.4861602538011627e+00 -2.1615489734481219e+00 -1.4018889355895896e+00 + 3 9.4230034723594669e-01 9.5039809920743750e+00 -2.0841506656264581e+00 + 4 6.2508544748219808e-01 2.2263284020113416e-01 1.1623245396652602e+00 + 5 4.3709065171818393e+00 -2.1673227887098923e-01 6.9705905026571036e-02 + 6 -3.7162954048651708e+00 2.0166769500271906e+00 -1.3113672987348493e+00 + 7 -1.3186754891989645e+00 8.3339129964811620e-01 -3.5953753192577969e+00 + 8 2.8599212386092612e+00 1.0845435532482326e+00 2.1497669081752813e+00 + 9 8.3289541321936722e-02 -1.9711634843452222e-01 1.0582433296595000e+00 + 10 -2.1105694490473894e+00 -1.3093053660673317e+00 2.6649140158218270e+00 + 11 -6.7640412200944400e-01 -6.6130621564831960e-01 -3.4843696906638675e+00 + 12 -3.9761992408969311e+00 -2.7237331305882346e+00 3.0593172118356344e+00 + 13 2.5570376127614072e+00 -1.0815367744850595e+00 -6.2493279188465625e+00 + 14 2.5296152922225867e+00 1.4928417046802362e+00 1.2976896771614199e+00 + 15 3.9925363372115905e+00 -6.5832404574163599e+00 2.1207614769244052e+00 + 16 -4.5317849577992169e+00 2.1595070496501325e+00 -2.2698695911664672e+00 + 17 -1.6410647909962073e+00 -2.8820201053975043e+00 -2.2004035149617112e+00 + 18 1.5499604646737388e+00 -9.5828594728262639e-01 2.9735707449080775e+00 + 19 1.4409047137004436e+00 -9.3472327135602196e-01 -1.9826096119682810e+00 + 20 -2.1342194263982655e+00 -1.0042201397393937e+00 1.6864163070523024e+00 + 21 -1.1175074002283549e+00 1.3686765357917783e+00 1.0216492632744250e+00 + 22 -3.3503852083666090e+00 4.7803920133184423e+00 -1.2114855243764666e+00 + 23 -2.3587624477814173e+00 5.5168626752708227e-01 4.4188483413601922e+00 + 24 2.3087757005544596e+00 -2.6780632977121183e-01 3.7575130909288434e-01 + 25 -4.1137500295820821e+00 -3.6320634706489420e-02 -1.9474384974214305e+00 + 26 2.4326337361076904e+00 2.5812342077121695e+00 -3.9893779975324279e+00 + 27 4.5965992562384530e+00 1.7282183290554245e+00 1.5407822248869203e+00 + 28 4.1009148763143415e+00 -2.4731183084807817e+00 6.2810102366484530e+00 + 29 -1.6564509059007406e+00 -9.4565165198733081e-01 1.2170331448910514e+00 + 30 1.9087487181546094e+00 -5.2994363963596625e-01 1.9107780060544863e+00 + 31 -5.7962409140873810e+00 -1.4800172713353112e+00 -2.8561767821943373e+00 + 32 -2.9155306267794172e+00 -1.8672697931594253e+00 -7.1962196605056628e-01 +... From a25b5255e44b719fa35232bce574419ee27fd128 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 18:28:34 +0000 Subject: [PATCH 058/120] KOKKOS: subtract the zeroed force from the tally of fix langevin With "zero yes" the fix removes the average of the thermostat force from every atom of the group, so that the group's total momentum is conserved. The CPU style removes it from the tallied thermostat force as well when "tally yes" is set, because the energy reported by compute_scalar() integrates that tally against the velocities. The KOKKOS zero-force kernel changed only the force array, so with both keywords the reported thermostat energy was that of the force before it was zeroed. Measured on an eight step run of the new reference: 2.1268867742947801 against the 2.1135499990769127 of the CPU style, 0.6 percent. Positions and velocities were never affected, which is why nothing noticed - the two new references cover "zero yes" on its own and combined with "tally yes". --- src/KOKKOS/fix_langevin_kokkos.cpp | 8 ++ .../tests/fix-timestep-langevin_zero.yaml | 78 +++++++++++++++++++ .../fix-timestep-langevin_zero_tally.yaml | 78 +++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 unittest/force-styles/tests/fix-timestep-langevin_zero.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-langevin_zero_tally.yaml diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index 212d746df11..ba9adc8a0ee 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -478,6 +478,14 @@ void FixLangevinKokkos::zero_force_item(int i) const f(i,0) -= static_cast(d_fsumall[0]); f(i,1) -= static_cast(d_fsumall[1]); f(i,2) -= static_cast(d_fsumall[2]); + + // the tallied thermostat force has to lose the same amount, or the energy + // reported by compute_scalar() is that of the force before it was zeroed + if (tallyflag) { + d_flangevin(i,0) -= static_cast(d_fsumall[0]); + d_flangevin(i,1) -= static_cast(d_fsumall[1]); + d_flangevin(i,2) -= static_cast(d_fsumall[2]); + } } } diff --git a/unittest/force-styles/tests/fix-timestep-langevin_zero.yaml b/unittest/force-styles/tests/fix-timestep-langevin_zero.yaml new file mode 100644 index 00000000000..47c896d15a0 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-langevin_zero.yaml @@ -0,0 +1,78 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 18:03:37 2026 +epsilon: 5e-14 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom full + fix langevin +pre_commands: "" +post_commands: | + fix move all nve + fix test solute langevin 50.0 ${t_target} 100.0 82573 zero yes +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 0 +run_pos: |2 + 1 -2.7022852690518584e-01 2.4906408164588361e+00 -1.6754756912343161e-01 + 2 3.1119819311128338e-01 2.9611705585367223e+00 -8.5515881046569464e-01 + 3 -7.0402129511453893e-01 1.2310682254364691e+00 -6.2831176736812755e-01 + 4 -1.5813104628084962e+00 1.4837006910617672e+00 -1.2542474257892033e+00 + 5 -9.0716408500328372e-01 9.2600486201051158e-01 4.0062039243558328e-01 + 6 2.4783139618131378e-01 2.8273566223991486e-01 -1.2319780783223071e+00 + 7 3.4182625530860383e-01 -2.2730352989328427e-02 -2.5288841248212819e+00 + 8 1.1749015020151279e+00 -4.8838734173851850e-01 -6.3772198999009910e-01 + 9 1.3794305600119019e+00 -2.5271414407920695e-01 2.8382126264755242e-01 + 10 2.0503483849954645e+00 -1.4607565482942821e+00 -9.8218181376825930e-01 + 11 1.7865091411389322e+00 -1.9918640435658033e+00 -1.8886467039679735e+00 + 12 3.0071335642921295e+00 -4.9034849690442184e-01 -1.6231078306942259e+00 + 13 4.0512634833817325e+00 -8.9167031920927442e-01 -1.6396775358728501e+00 + 14 2.6053330087406641e+00 -4.1844265037069295e-01 -2.6635529259041739e+00 + 15 2.9692911992632509e+00 5.5448138396392577e-01 -1.2335725257578598e+00 + 16 2.6742085188861591e+00 -2.4120677899320313e+00 -2.3470711721292708e-02 + 17 2.2154646052059697e+00 -2.0893014330588602e+00 1.1959650558037389e+00 + 18 2.1369701703816464e+00 3.0158507413696802e+00 -3.5179348337288836e+00 + 19 1.5355837136017145e+00 2.6255292355367637e+00 -4.2353987779832218e+00 + 20 2.7727573005668558e+00 3.6923910449611381e+00 -3.9330842459126920e+00 + 21 4.9040128073270361e+00 -4.0752348172837003e+00 -3.6210314709889082e+00 + 22 4.3582355554447672e+00 -4.2126119427286479e+00 -4.4612844196314621e+00 + 23 5.7439382849305165e+00 -3.5821957939262292e+00 -3.8766361295929084e+00 + 24 2.0689243582628891e+00 3.1513346907117756e+00 3.1550389754882127e+00 + 25 1.3045351331708133e+00 3.2665125705812263e+00 2.5111855257665048e+00 + 26 2.5809237402724428e+00 4.0117602605480300e+00 3.2212060529099618e+00 + 27 -1.9611343130603474e+00 -4.3563411931511089e+00 2.1098293115589812e+00 + 28 -2.7473562684519526e+00 -4.0200819932387830e+00 1.5830052163435806e+00 + 29 -1.3126000191362590e+00 -3.5962518039499130e+00 2.2746342468744096e+00 +run_vel: |2 + 1 8.3933757436158076e-03 1.5950570695520330e-02 3.9288623894663133e-03 + 2 6.0229414295157454e-03 5.3444797940207225e-03 -2.0470070067897762e-03 + 3 -8.4436053353404254e-03 -1.2683403398814123e-02 -4.7112220851590406e-03 + 4 -3.2942922188929440e-03 -6.8315487134691872e-03 -2.4278109999487348e-03 + 5 -1.0310537032816024e-02 -1.0151185792108299e-02 -2.6126916125432074e-03 + 6 -3.9736017459732868e-02 4.6319087437977823e-02 3.7168794365431940e-02 + 7 1.3198322691934025e-03 -1.0135137211376963e-02 -5.0985406395577054e-02 + 8 8.1067983082689626e-03 -2.9279609766371117e-03 3.4911092542454183e-02 + 9 1.7186773973229825e-03 3.9976710386618163e-03 1.5004698848897935e-02 + 10 2.8640392319453575e-02 -2.9712234688333811e-02 -1.4075580772353833e-02 + 11 -5.8129460910915001e-03 -3.1445155006096445e-03 -1.9652283210250254e-03 + 12 2.8650507366381759e-03 -3.4805279178777885e-04 -2.9925793548298608e-03 + 13 2.8977025423885753e-03 6.1128973629279073e-03 -1.3427744801776151e-04 + 14 2.5149920590690380e-03 -5.5933494149497708e-03 -4.8101023292918439e-03 + 15 -1.7675953285285039e-03 -6.2955904216700845e-03 6.5187630877007194e-03 + 16 1.7809879210446782e-02 -1.3192000747049230e-02 -4.5295043991310305e-02 + 17 -1.2903781731687327e-02 1.0226150354142070e-02 3.6928970176284777e-02 + 18 -8.0065801736709311e-04 -8.6270470788278489e-04 -1.4483040575726600e-03 + 19 1.2452390684119302e-03 -2.5061097129326407e-03 7.2998631128789460e-03 + 20 3.5930060198867938e-03 3.6938860308351061e-03 3.2322732708411168e-03 + 21 -1.4689220096627672e-03 -2.7352129011263702e-04 7.0581622590584129e-04 + 22 -7.0694199235822579e-03 -4.2577148931245172e-03 2.8079117510160353e-04 + 23 6.0446963123999510e-03 -1.4000131594340095e-03 2.5819754850821427e-03 + 24 3.1926373729257202e-04 -9.9445667595531181e-04 1.4999999379149902e-04 + 25 1.3789761637298477e-04 -4.4335894814311310e-03 -8.1808128173936764e-04 + 26 2.0485904078165773e-03 2.7813358636391517e-03 4.3245727184064962e-03 + 27 4.5604116388680730e-04 -1.0305523254251145e-03 2.1188059073837191e-04 + 28 -6.2544520875242732e-03 1.4127711155182137e-03 -1.8429821881329703e-03 + 29 6.4110631580151353e-04 3.1273432690968076e-03 3.7253671107636476e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-langevin_zero_tally.yaml b/unittest/force-styles/tests/fix-timestep-langevin_zero_tally.yaml new file mode 100644 index 00000000000..bae37a636b4 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-langevin_zero_tally.yaml @@ -0,0 +1,78 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 18:14:26 2026 +epsilon: 5e-14 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom full + fix langevin +pre_commands: "" +post_commands: | + fix move all nve + fix test solute langevin 50.0 ${t_target} 100.0 82573 tally yes zero yes +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 2.1135499990769127 +run_pos: |2 + 1 -2.7022852690518584e-01 2.4906408164588361e+00 -1.6754756912343161e-01 + 2 3.1119819311128338e-01 2.9611705585367223e+00 -8.5515881046569464e-01 + 3 -7.0402129511453893e-01 1.2310682254364691e+00 -6.2831176736812755e-01 + 4 -1.5813104628084962e+00 1.4837006910617672e+00 -1.2542474257892033e+00 + 5 -9.0716408500328372e-01 9.2600486201051158e-01 4.0062039243558328e-01 + 6 2.4783139618131378e-01 2.8273566223991486e-01 -1.2319780783223071e+00 + 7 3.4182625530860383e-01 -2.2730352989328427e-02 -2.5288841248212819e+00 + 8 1.1749015020151279e+00 -4.8838734173851850e-01 -6.3772198999009910e-01 + 9 1.3794305600119019e+00 -2.5271414407920695e-01 2.8382126264755242e-01 + 10 2.0503483849954645e+00 -1.4607565482942821e+00 -9.8218181376825930e-01 + 11 1.7865091411389322e+00 -1.9918640435658033e+00 -1.8886467039679735e+00 + 12 3.0071335642921295e+00 -4.9034849690442184e-01 -1.6231078306942259e+00 + 13 4.0512634833817325e+00 -8.9167031920927442e-01 -1.6396775358728501e+00 + 14 2.6053330087406641e+00 -4.1844265037069295e-01 -2.6635529259041739e+00 + 15 2.9692911992632509e+00 5.5448138396392577e-01 -1.2335725257578598e+00 + 16 2.6742085188861591e+00 -2.4120677899320313e+00 -2.3470711721292708e-02 + 17 2.2154646052059697e+00 -2.0893014330588602e+00 1.1959650558037389e+00 + 18 2.1369701703816464e+00 3.0158507413696802e+00 -3.5179348337288836e+00 + 19 1.5355837136017145e+00 2.6255292355367637e+00 -4.2353987779832218e+00 + 20 2.7727573005668558e+00 3.6923910449611381e+00 -3.9330842459126920e+00 + 21 4.9040128073270361e+00 -4.0752348172837003e+00 -3.6210314709889082e+00 + 22 4.3582355554447672e+00 -4.2126119427286479e+00 -4.4612844196314621e+00 + 23 5.7439382849305165e+00 -3.5821957939262292e+00 -3.8766361295929084e+00 + 24 2.0689243582628891e+00 3.1513346907117756e+00 3.1550389754882127e+00 + 25 1.3045351331708133e+00 3.2665125705812263e+00 2.5111855257665048e+00 + 26 2.5809237402724428e+00 4.0117602605480300e+00 3.2212060529099618e+00 + 27 -1.9611343130603474e+00 -4.3563411931511089e+00 2.1098293115589812e+00 + 28 -2.7473562684519526e+00 -4.0200819932387830e+00 1.5830052163435806e+00 + 29 -1.3126000191362590e+00 -3.5962518039499130e+00 2.2746342468744096e+00 +run_vel: |2 + 1 8.3933757436158076e-03 1.5950570695520330e-02 3.9288623894663133e-03 + 2 6.0229414295157454e-03 5.3444797940207225e-03 -2.0470070067897762e-03 + 3 -8.4436053353404254e-03 -1.2683403398814123e-02 -4.7112220851590406e-03 + 4 -3.2942922188929440e-03 -6.8315487134691872e-03 -2.4278109999487348e-03 + 5 -1.0310537032816024e-02 -1.0151185792108299e-02 -2.6126916125432074e-03 + 6 -3.9736017459732868e-02 4.6319087437977823e-02 3.7168794365431940e-02 + 7 1.3198322691934025e-03 -1.0135137211376963e-02 -5.0985406395577054e-02 + 8 8.1067983082689626e-03 -2.9279609766371117e-03 3.4911092542454183e-02 + 9 1.7186773973229825e-03 3.9976710386618163e-03 1.5004698848897935e-02 + 10 2.8640392319453575e-02 -2.9712234688333811e-02 -1.4075580772353833e-02 + 11 -5.8129460910915001e-03 -3.1445155006096445e-03 -1.9652283210250254e-03 + 12 2.8650507366381759e-03 -3.4805279178777885e-04 -2.9925793548298608e-03 + 13 2.8977025423885753e-03 6.1128973629279073e-03 -1.3427744801776151e-04 + 14 2.5149920590690380e-03 -5.5933494149497708e-03 -4.8101023292918439e-03 + 15 -1.7675953285285039e-03 -6.2955904216700845e-03 6.5187630877007194e-03 + 16 1.7809879210446782e-02 -1.3192000747049230e-02 -4.5295043991310305e-02 + 17 -1.2903781731687327e-02 1.0226150354142070e-02 3.6928970176284777e-02 + 18 -8.0065801736709311e-04 -8.6270470788278489e-04 -1.4483040575726600e-03 + 19 1.2452390684119302e-03 -2.5061097129326407e-03 7.2998631128789460e-03 + 20 3.5930060198867938e-03 3.6938860308351061e-03 3.2322732708411168e-03 + 21 -1.4689220096627672e-03 -2.7352129011263702e-04 7.0581622590584129e-04 + 22 -7.0694199235822579e-03 -4.2577148931245172e-03 2.8079117510160353e-04 + 23 6.0446963123999510e-03 -1.4000131594340095e-03 2.5819754850821427e-03 + 24 3.1926373729257202e-04 -9.9445667595531181e-04 1.4999999379149902e-04 + 25 1.3789761637298477e-04 -4.4335894814311310e-03 -8.1808128173936764e-04 + 26 2.0485904078165773e-03 2.7813358636391517e-03 4.3245727184064962e-03 + 27 4.5604116388680730e-04 -1.0305523254251145e-03 2.1188059073837191e-04 + 28 -6.2544520875242732e-03 1.4127711155182137e-03 -1.8429821881329703e-03 + 29 6.4110631580151353e-04 3.1273432690968076e-03 3.7253671107636476e-03 +... From 949d37dc30e7903d3e14ed10942016e956b8151e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 18:28:46 +0000 Subject: [PATCH 059/120] test: cover the thermostat keywords and the temperature bias path Every existing thermostat reference used the plain form of the fix and an unbiased temperature, so eight files of the KOKKOS package never took the branch behind a keyword or behind "which == BIAS": the velocity update of the nose-hoover family and of fix langevin behaves differently when the temperature compute removes a bias, and this session already found a segfault in exactly that area. fix langevin gains references for "omega yes" on finite size spheres, "angmom" on aspherical particles and a partial temperature bias; fix baoab one for "zero yes"; and fix nvt four, biased by compute temp/com, temp/region, temp/deform, and temp/deform with a nested temp/partial bias - the last one reaches the bias branch of compute temp/deform/kk without needing fix deform. The deform reference uses a slow strain rate on purpose. ComputeTempDeform's KOKKOS variant round trips the coordinates themselves through lamda space on every bias removal, where the CPU style converts into a scratch variable, so a fast strain rate amplifies roundoff to the point where the relative comparison of a velocity component near zero fails without anything being wrong. --- .../tests/fix-timestep-baoab_zero.yaml | 77 ++++++++ .../tests/fix-timestep-langevin_angmom.yaml | 165 ++++++++++++++++++ .../fix-timestep-langevin_bias_partial.yaml | 81 +++++++++ .../tests/fix-timestep-langevin_omega.yaml | 109 ++++++++++++ .../tests/fix-timestep-nvt_bias_com.yaml | 82 +++++++++ .../tests/fix-timestep-nvt_bias_deform.yaml | 84 +++++++++ .../fix-timestep-nvt_bias_deform_nested.yaml | 85 +++++++++ .../tests/fix-timestep-nvt_bias_region.yaml | 83 +++++++++ 8 files changed, 766 insertions(+) create mode 100644 unittest/force-styles/tests/fix-timestep-baoab_zero.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-langevin_bias_partial.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-langevin_omega.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-nvt_bias_com.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-nvt_bias_deform.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-nvt_bias_deform_nested.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-nvt_bias_region.yaml diff --git a/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml b/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml new file mode 100644 index 00000000000..22815197eda --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml @@ -0,0 +1,77 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 18:13:44 2026 +epsilon: 1e-13 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom full + fix baoab +pre_commands: "" +post_commands: | + fix test all baoab 50.0 ${t_target} 100.0 82573 zero yes +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 3.6606108848920593 +run_pos: |2 + 1 -2.7065544220190391e-01 2.4911779835474488e+00 -1.6630178090272518e-01 + 2 3.1154762765336685e-01 2.9614874794212449e+00 -8.5345675664175580e-01 + 3 -7.0411913705053442e-01 1.2306168575599066e+00 -6.2749536931347982e-01 + 4 -1.5810979145214437e+00 1.4817787130513353e+00 -1.2531941067180228e+00 + 5 -9.0813989749230650e-01 9.2733681471656615e-01 3.9824402155294347e-01 + 6 2.4923259776560597e-01 2.8357033719316821e-01 -1.2315119579211076e+00 + 7 3.4193230732273677e-01 -2.2797061418065614e-02 -2.5291234989980591e+00 + 8 1.1735461001595002e+00 -4.8870934242842856e-01 -6.3769420561501922e-01 + 9 1.3796368175720506e+00 -2.5163155466034015e-01 2.8372100115155724e-01 + 10 2.0512119544372944e+00 -1.4597081796256712e+00 -9.8304188041582130e-01 + 11 1.7875223460235372e+00 -1.9921845604438904e+00 -1.8903443497496268e+00 + 12 3.0054437039770825e+00 -4.9069919886744923e-01 -1.6230628479382263e+00 + 13 4.0529102819981135e+00 -8.9092089612028269e-01 -1.6410002725417654e+00 + 14 2.6058383843415562e+00 -4.1772313378282200e-01 -2.6618514969951499e+00 + 15 2.9681750895611816e+00 5.5545681271484615e-01 -1.2351544003038268e+00 + 16 2.6742512015348341e+00 -2.4129907577800975e+00 -2.2996058488555324e-02 + 17 2.2151741055502736e+00 -2.0898342586976626e+00 1.1954825227154366e+00 + 18 2.1369461782623187e+00 3.0159409086854065e+00 -3.5182858172867579e+00 + 19 1.5351313107554068e+00 2.6251451580743863e+00 -4.2365877214351615e+00 + 20 2.7731144091031514e+00 3.6925883216404367e+00 -3.9333895545275057e+00 + 21 4.9049513843039074e+00 -4.0751797738144724e+00 -3.6217184348954796e+00 + 22 4.3569502595683973e+00 -4.2128758872087362e+00 -4.4621375880666267e+00 + 23 5.7431783006037413e+00 -3.5832912134826955e+00 -3.8761415672470978e+00 + 24 2.0689311834819648e+00 3.1517274704515930e+00 3.1553449978033581e+00 + 25 1.3056740564112883e+00 3.2666276975226438e+00 2.5098906951204767e+00 + 26 2.5802253335008194e+00 4.0104776888648175e+00 3.2217694509234391e+00 + 27 -1.9605522682301195e+00 -4.3565782675030782e+00 2.1107453005730057e+00 + 28 -2.7473741365201145e+00 -4.0196452499856239e+00 1.5838762251783427e+00 + 29 -1.3132071012459021e+00 -3.5966596007293687e+00 2.2734996802643330e+00 +run_vel: |2 + 1 7.8829824947026037e-03 1.6618157210244445e-02 5.1537759308672706e-03 + 2 7.1858663897778263e-03 5.1934715226229569e-03 -9.9692652780288422e-05 + 3 -8.7249105465370992e-03 -1.2934857580591333e-02 -4.0128290220286696e-03 + 4 -3.2953394902180549e-03 -8.5129978936032899e-03 1.7031184316892309e-04 + 5 -1.1380696967839497e-02 -9.2890057000471222e-03 -3.7108767494052073e-03 + 6 -3.8787388264837394e-02 4.7065160188456585e-02 3.6603755632862764e-02 + 7 1.2335090482665093e-03 -9.9755036884483662e-03 -5.0926080115392972e-02 + 8 7.5043779327633392e-03 -3.1774912134594283e-03 3.4502443244849884e-02 + 9 8.6911145900270118e-04 4.7508790782907354e-03 1.4664445487177878e-02 + 10 2.9755474674845607e-02 -2.8932794103208648e-02 -1.5021596969817447e-02 + 11 -5.5621311973566186e-03 -3.1751262333425856e-03 -3.2788416586086375e-03 + 12 1.7451592367141713e-03 -6.2154327457110273e-04 -3.0023980208555459e-03 + 13 3.3506785045005916e-03 6.1717559023839030e-03 -2.3670845759619858e-03 + 14 2.1988761769598459e-03 -6.0481665532413527e-03 -1.6308405000400471e-03 + 15 -2.8646737139397687e-03 -5.0775318550551453e-03 5.1134195807428342e-03 + 16 1.8459501446942982e-02 -1.3529365959023449e-02 -4.5115524357650635e-02 + 17 -1.2821228543121196e-02 9.6245632975165783e-03 3.6475593644334371e-02 + 18 -8.6278715473761211e-04 -6.3741966594076625e-04 -1.5498402577546753e-03 + 19 5.2385071469808410e-04 -2.7280777920406386e-03 6.4875479514169970e-03 + 20 4.1308526806433880e-03 3.7149201657838216e-03 2.7602693533039335e-03 + 21 -9.3469265412593342e-04 -1.3094534706537315e-06 -6.9656360551624186e-05 + 22 -8.2196932293271303e-03 -5.0042300711126957e-03 7.4438808836049103e-05 + 23 5.1043243418127616e-03 -1.9280847382906988e-03 3.0277795851672653e-03 + 24 7.3928083173641925e-05 -6.5955558176511019e-04 2.5435357885566503e-04 + 25 7.6935949370634344e-04 -4.7957302024276187e-03 -1.5187485855025185e-03 + 26 2.2459360436306868e-03 1.2833985726870920e-03 4.1613680007231875e-03 + 27 1.0674103385521442e-03 -1.3863613504104372e-03 1.1968564881002337e-03 + 28 -5.9521623569754514e-03 9.0342051190774877e-04 -9.6351122247416595e-04 + 29 -1.1856862903108020e-05 3.0923331539274936e-03 2.8778663178691630e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml b/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml new file mode 100644 index 00000000000..065d4f04da0 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml @@ -0,0 +1,165 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 18:05:47 2026 +epsilon: 5e-13 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom ellipsoid + fix langevin +pre_commands: "" +post_commands: | + fix move all nve/asphere + fix test solute langevin 1.0 1.0 1.0 82573 angmom 3.0 +input_file: in.ellipsoid +input_coeffs: coeffs.ellipsoid +natoms: 48 +global_scalar: 0 +run_pos: |2 + 1 5.0623024646239463e+00 2.5319958527283344e+00 4.1219025740739381e+00 + 2 7.8728106659295727e-01 7.2371730941576251e-01 5.8075049807466765e+00 + 3 5.7513786145522259e+00 7.6342058110869919e+00 5.9098533579218664e+00 + 4 6.6600437359631712e+00 7.7487104491806358e+00 2.1229540562602551e+00 + 5 -1.0487375649131425e-01 3.2204316130597825e+00 2.7814104499775461e+00 + 6 4.3375463124289206e+00 2.1899376120242788e+00 5.9432046195139261e+00 + 7 2.7277337962412269e+00 7.0750630764141880e+00 -2.9020008809632514e-02 + 8 4.8491087533803361e+00 7.3429027907205437e+00 -6.0021832223486360e-01 + 9 2.4640368702998492e+00 4.4404183628247962e+00 3.6050720506327467e+00 + 10 -3.0945629873840053e-01 2.5055609779148775e+00 1.4563733412294599e+00 + 11 6.7071168300101318e+00 1.6639676617800470e+00 1.4591376560951796e-01 + 12 3.1664327635787655e+00 4.1636061205375832e+00 2.7191322105236710e+00 + 13 7.9490465340596730e+00 2.0052949023425217e+00 3.6857649032134541e+00 + 14 -4.4497546525935389e-01 5.9965675919832595e+00 5.9097379153265781e-02 + 15 1.9251969931693258e+00 -7.4691576474687282e-01 -2.8407935911503562e-01 + 16 7.3228823129523124e-01 5.6073890018822201e+00 2.2567058346106585e+00 + 17 8.0999899555044905e+00 8.6478324163410858e-01 2.4070633205049456e+00 + 18 1.6503336923062020e+00 2.4937547109597915e+00 2.9452662986278355e+00 + 19 -1.2687951630136478e+00 4.6152593338170487e+00 4.2437870694817406e+00 + 20 6.9899709003617048e+00 6.6005748291128850e+00 4.7687743779725809e+00 + 21 5.8786712506983454e+00 1.9326327429580603e+00 -7.9278971819801392e-01 + 22 5.1740398259350586e+00 -1.1560156879144734e+00 4.3878784775183144e-01 + 23 1.4244114933464713e+00 5.1653705975627160e+00 4.8639592923938615e+00 + 24 5.0462979440020801e+00 -2.4575385424561044e-01 1.5786682039758624e+00 + 25 2.9862442148871620e+00 1.5949611196483617e+00 1.5185286042879176e+00 + 26 7.8372805600354019e+00 1.5772784989025490e+00 2.1894256039414315e+00 + 27 1.3968472047206979e+00 6.2083404398104438e+00 -5.5754162576790067e-01 + 28 -3.9639644470998342e-01 5.5782234651375182e+00 1.6935021194064297e+00 + 29 1.8716480058609388e+00 3.7876300367087348e+00 5.0763558548570424e+00 + 30 5.2000477782509380e+00 2.4559019773268531e+00 5.8760181635512678e+00 + 31 2.3318763231445816e+00 4.8362806389381197e+00 5.6499766744390145e+00 + 32 7.0261041916252456e+00 5.1839061544502849e+00 3.3702781518078213e+00 + 33 7.0674766903544866e+00 7.8418884367776682e+00 5.9787396517245481e+00 + 34 -7.3198784848100984e-01 -9.2903943766302566e-01 4.0911628247836553e+00 + 35 1.6646142238397483e+00 6.3896083411879285e+00 2.9124419402369321e+00 + 36 4.5437450840408706e+00 4.2066105934231750e+00 5.4021620636311711e+00 + 37 5.9959973759217213e+00 6.3758126277993812e+00 1.9697432800658212e+00 + 38 4.9272075547459062e+00 1.3396455216738370e+00 1.5999233819310530e+00 + 39 -1.0339879829394538e-01 9.4007613476039698e-01 4.6026055516042721e+00 + 40 2.4016755026169894e+00 1.3813236828715252e+00 3.9941179988978757e+00 + 41 1.8296274716011247e+00 2.7937217662330118e+00 4.7018466937787856e-01 + 42 1.1612634480986030e+00 4.1315173412868672e-01 3.7988230065787087e+00 + 43 5.8882283202523702e+00 4.4219452740738623e+00 7.5335726088000443e-01 + 44 -3.8071494998749456e-01 6.7626473684522512e+00 4.5595700249770248e+00 + 45 -4.3196964813012817e-01 5.1118622954910427e+00 4.2788377680283949e+00 + 46 7.0092832727574255e+00 3.5885439340135123e+00 2.3151145922839755e+00 + 47 2.3661043103507553e+00 6.8628730279457848e+00 1.6521288468239346e+00 + 48 4.6761815645621008e+00 7.1062932553828251e+00 7.9683257399900442e-01 +run_vel: |2 + 1 -7.8683713814457512e-01 1.2952147376295591e+00 2.1752553784017137e-03 + 2 3.0755849636135779e-01 -1.9012732051296921e+00 -5.9052520650934892e-01 + 3 3.6447441250647900e-01 5.3223893961089708e-01 -6.1631605599700601e-01 + 4 -1.0538672086221965e+00 1.1797029695511403e+00 1.3095887510295090e+00 + 5 1.0071606714464771e+00 -2.2429113491949981e-02 1.2838052806839217e+00 + 6 1.3644705331785940e+00 9.9363654184408501e-01 -1.5495603742433042e+00 + 7 -1.0240305481671819e-02 9.3693621331783661e-02 5.3122102642896241e-02 + 8 8.6136681193313569e-01 -5.6669639684977979e-01 -8.5364208591266100e-01 + 9 3.9508365850296412e-01 -5.6312918912846721e-01 3.9681074483245427e-03 + 10 -1.6851463456272825e-01 -4.0117716285614718e-01 4.7647235403174870e-01 + 11 1.8315981750080388e+00 2.4550619703411281e-01 7.5604276370519530e-01 + 12 4.8648930274167174e-01 3.2113555035066915e-01 6.8973601552694019e-01 + 13 -1.4980844292070448e+00 -1.4705844593664585e-02 6.7217967873594242e-01 + 14 -4.6610671216478750e-01 -1.2726361980743368e+00 6.5229856830025057e-01 + 15 1.7252228402212433e-01 9.6002665780992102e-01 3.4074008151544777e-01 + 16 5.8523489577914312e-01 -1.2111301717403686e+00 8.0277567498547114e-02 + 17 -5.4762417604651531e-02 5.3931949934150891e-01 -8.5575253299917475e-01 + 18 4.1183507742664466e-01 -8.6631777054939918e-01 2.4130942436437813e-01 + 19 3.2805459128311687e-01 3.6876572642922545e-01 1.1650097938033492e+00 + 20 1.4376954227095897e+00 -2.2712245563660066e-01 -5.9044828584748532e-01 + 21 4.6012642634107376e-01 1.6318752735042297e-01 -3.2611483022808768e-01 + 22 9.0905567684361399e-01 -2.7202193882525671e-01 1.3685345294414901e+00 + 23 -3.3929580770158657e-01 -1.0491259693299244e+00 -8.3185621480993033e-01 + 24 7.8261302325016069e-01 -7.8704425051754812e-01 -9.2623505407916407e-01 + 25 3.5411110344064222e-03 1.3879280034358621e-01 -4.1804150888384524e-02 + 26 -5.5373951289948105e-02 8.2997066670295022e-02 1.8338795826898105e-01 + 27 -1.4734813689115193e-02 2.9773875231241871e-02 -7.4497454917367589e-02 + 28 8.5716922423749259e-02 -9.9591212182767952e-02 9.4646651767421666e-02 + 29 -1.1502650021476947e-01 3.5470406574035704e-02 -3.2929456944440411e-01 + 30 1.1166194795162700e-01 6.1882669649480707e-02 2.1931821949422828e-01 + 31 -2.4431540428894843e-01 -1.9448245588962174e-01 3.6873722655259039e-02 + 32 2.6159360539446130e-02 -1.3583668086426662e-01 -4.1498754274420215e-02 + 33 8.8793592779090116e-02 8.1897392449156781e-02 1.3888280148646853e-01 + 34 -8.1615886133231175e-02 -1.0514218666347168e-01 -4.9997963985103549e-03 + 35 -1.7427167582137620e-01 2.3128706335430288e-01 -6.0541960751818391e-01 + 36 -1.3433577935222474e-01 -1.9824033461836099e-01 2.9815442350631738e-01 + 37 3.0467322499493309e-02 -3.2904716274067886e-01 -2.7156724931693865e-01 + 38 -6.5186137394588548e-02 8.8491600839166892e-02 -7.6891063998738912e-03 + 39 1.0516134115580525e-01 6.9495154330587658e-02 -3.5859005500581020e-02 + 40 -2.2700340965769583e-01 -1.8342046946771856e-01 -1.6974119215787628e-01 + 41 -1.6196839062380369e-01 -2.9836089524859055e-02 2.8665678481514120e-02 + 42 -2.3442022148854988e-01 3.8924053352836205e-02 4.9794021746520511e-01 + 43 1.0325972289745516e-01 9.3585536229071606e-02 4.4888519910899954e-01 + 44 -1.7022062550470554e-01 2.9032085021483973e-02 -1.7736768274110939e-01 + 45 -2.5492897475036497e-01 2.0723171671960763e-01 2.8273091563836639e-01 + 46 1.2032289438870365e-01 -2.8124352868211216e-01 2.1761296239736649e-01 + 47 -1.1483558439846396e-01 -5.8308823517116604e-01 1.7920140267602633e-01 + 48 -1.8450666194000282e-02 8.3774136131594429e-02 -3.3375812135800070e-02 +run_torque: |2 + 1 2.8191748088292221e+00 -5.5954033834526363e+01 1.9734914992868934e+02 + 2 6.7705799252250891e+00 -3.0287955719669504e+00 3.7368225758355740e+00 + 3 -1.1159665877103631e+00 -3.2244986741690812e-01 -5.9390202290214655e-01 + 4 -6.0275453668157990e+00 -8.9465857911646606e+02 4.7706318307312628e+01 + 5 8.7249675251495695e+00 1.6896496816452431e+00 7.2134978126866311e-01 + 6 -4.1368335570542125e-01 1.9607602539657731e+00 1.4267421730335803e+00 + 7 -2.1913894016228541e+00 2.7453304857418441e+00 7.6555305885880776e-02 + 8 -4.8468976881185832e-01 1.0093776577113776e+00 1.3921900691524236e-01 + 9 -3.7011792469678522e+00 -7.2543773937148244e+03 3.6114744302061208e+03 + 10 1.8218358649616873e-01 -1.9793035727497594e+00 -2.8376713149261175e+00 + 11 -2.8551820283505798e+00 3.8390312242448522e+03 -2.8098230729047650e+03 + 12 4.4405555169007291e+00 2.7178481787258752e+03 -1.7405052646535816e+02 + 13 -1.5312760590812260e+00 -4.5763169468485063e+02 -8.7678540138603140e+01 + 14 4.3003095749352047e+00 1.4593653374258011e+00 -7.0684481732124793e-01 + 15 1.1722095323717607e+00 1.9791433664350152e+03 -1.2238669223054262e+03 + 16 -2.9141412528227817e+00 -2.6408877800810893e-01 -2.0949319992120916e+00 + 17 6.4363690258920396e+00 -2.3444755089146125e+02 -2.1520757419999165e+02 + 18 -2.3521305722084440e+00 3.7580505584362305e+00 3.7297840084239859e+00 + 19 -4.1628165252592870e+00 -2.1447176701768590e+03 1.5800691134298279e+03 + 20 1.7529301038000453e+00 -5.9492289033159160e+00 -6.9962617704167762e+00 + 21 -7.1402450975078846e-01 1.4005297098221060e+03 -1.8107548583610212e+03 + 22 2.9811004637585743e+00 -1.6596587847572704e+00 -1.1603122926361495e+00 + 23 -7.4042870879661538e-01 8.4380349502903903e+02 -5.3556915040316676e+02 + 24 -9.3579158768505941e+00 1.0249190604435365e+00 2.9232696798607161e-01 + 25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 33 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 34 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 35 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 36 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 37 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 38 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 39 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 40 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 41 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 42 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 43 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 44 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 45 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 46 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 47 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 48 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-langevin_bias_partial.yaml b/unittest/force-styles/tests/fix-timestep-langevin_bias_partial.yaml new file mode 100644 index 00000000000..ac64f317207 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-langevin_bias_partial.yaml @@ -0,0 +1,81 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 18:11:47 2026 +epsilon: 5e-14 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom full + fix langevin + compute temp/partial +pre_commands: "" +post_commands: | + compute mytemp solute temp/partial 1 1 0 + fix move all nve + fix test solute langevin 50.0 ${t_target} 100.0 82573 + fix_modify test temp mytemp +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 0 +run_pos: |2 + 1 -2.7015825589777676e-01 2.4906575748122637e+00 -1.6695250717634183e-01 + 2 3.1144956749767627e-01 2.9612198015744720e+00 -8.5462488357246902e-01 + 3 -7.0393565231788779e-01 1.2310846516568144e+00 -6.2779017923213509e-01 + 4 -1.5810609315036075e+00 1.4837477381075299e+00 -1.2538767292869033e+00 + 5 -9.0693076451447441e-01 9.2604562236882249e-01 3.9952952295219674e-01 + 6 2.4788210331772240e-01 2.8276056191826049e-01 -1.2313904783573928e+00 + 7 3.4188409152112403e-01 -2.2701930310540179e-02 -2.5292267805813600e+00 + 8 1.1750114688080167e+00 -4.8841256936526534e-01 -6.3786490508351834e-01 + 9 1.3796892527840303e+00 -2.5265793590677449e-01 2.8357123260437561e-01 + 10 2.0504216087119391e+00 -1.4607330809071488e+00 -9.8325016381102526e-01 + 11 1.7867551338907877e+00 -1.9918162955538363e+00 -1.8890612634167401e+00 + 12 3.0072202256971816e+00 -4.9033353487400588e-01 -1.6231853100975635e+00 + 13 4.0515049893254806e+00 -8.9162024792076433e-01 -1.6400096186171946e+00 + 14 2.6055837629557703e+00 -4.1839647266056196e-01 -2.6633888795207015e+00 + 15 2.9695365729591319e+00 5.5453806860795363e-01 -1.2342118235840165e+00 + 16 2.6742913988399519e+00 -2.4120504683090975e+00 -2.3442481151830889e-02 + 17 2.2155252184497329e+00 -2.0892880503495737e+00 1.1963210346672488e+00 + 18 2.1369701704391790e+00 3.0158507414141082e+00 -3.5179348337527561e+00 + 19 1.5355837136086392e+00 2.6255292355439748e+00 -4.2353987779928017e+00 + 20 2.7727573005686916e+00 3.6923910449623283e+00 -3.9330842459136361e+00 + 21 4.9040128073079368e+00 -4.0752348172589681e+00 -3.6210314709727802e+00 + 22 4.3582355554439607e+00 -4.2126119427272979e+00 -4.4612844196300889e+00 + 23 5.7439382849291896e+00 -3.5821957939252100e+00 -3.8766361295918932e+00 + 24 2.0689243582463837e+00 3.1513346907010131e+00 3.1550389754643229e+00 + 25 1.3045351331541590e+00 3.2665125705691289e+00 2.5111855257373397e+00 + 26 2.5809237402711838e+00 4.0117602605470610e+00 3.2212060529085971e+00 + 27 -1.9611343130629761e+00 -4.3563411931523408e+00 2.1098293115617968e+00 + 28 -2.7473562684520472e+00 -4.0200819932387377e+00 1.5830052163436468e+00 + 29 -1.3126000191368292e+00 -3.5962518039499924e+00 2.2746342468748408e+00 +run_vel: |2 + 1 8.4147523883647338e-03 1.5992634998402488e-02 4.7989463283107667e-03 + 2 6.0976786430231751e-03 5.4790131892722494e-03 -1.3679829322942837e-03 + 3 -8.4120082801997439e-03 -1.2632434438150639e-02 -4.1244015250380831e-03 + 4 -3.2183696579155077e-03 -6.6966615066139292e-03 -1.1271362957064671e-03 + 5 -1.0261117594557799e-02 -1.0032108355992183e-02 -2.8597562587026563e-03 + 6 -3.9755070103488964e-02 4.6368781370393082e-02 3.7200532470547408e-02 + 7 1.3304389479591957e-03 -1.0070503934477464e-02 -5.1563447030751372e-02 + 8 8.1895893037418344e-03 -2.9505056571476392e-03 3.4510346240493588e-02 + 9 1.8099883439436425e-03 4.1427549717677498e-03 1.5097154637705754e-02 + 10 2.8647407137656102e-02 -2.9651563131565022e-02 -1.5042166597945002e-02 + 11 -5.7440834974404071e-03 -3.0134796555233044e-03 -2.3511170488770446e-03 + 12 2.8982319605055048e-03 -3.0207547636795594e-04 -3.0563231192836512e-03 + 13 2.9624657296146162e-03 6.2516317056134831e-03 -8.1081990244520998e-04 + 14 2.5910492739293534e-03 -5.4599510893842372e-03 -3.9274788076002487e-03 + 15 -1.6968045850584992e-03 -6.1477543462118093e-03 6.2796220123397511e-03 + 16 1.7825501489242210e-02 -1.3137059088300665e-02 -4.5654223486241076e-02 + 17 -1.2881036939021187e-02 1.0258122599037564e-02 3.7310132170211570e-02 + 18 -8.0065787929813244e-04 -8.6270461349082709e-04 -1.4483041300682182e-03 + 19 1.2452390836163567e-03 -2.5061097009482398e-03 7.2998630931117780e-03 + 20 3.5930060249898593e-03 3.6938860337720572e-03 3.2322732677387751e-03 + 21 -1.4689220492088424e-03 -2.7352124006304511e-04 7.0581625436863136e-04 + 22 -7.0694199253188185e-03 -4.2577148902833142e-03 2.8079117806726863e-04 + 23 6.0446963095354966e-03 -1.4000131574840337e-03 2.5819754871035140e-03 + 24 3.1926368593735425e-04 -9.9445670036141069e-04 1.4999993233263584e-04 + 25 1.3789755451925018e-04 -4.4335895175443346e-03 -8.1808137811593593e-04 + 26 2.0485904033952984e-03 2.7813358606031896e-03 4.3245727141929874e-03 + 27 4.5604115663177045e-04 -1.0305523296034664e-03 2.1188059996206707e-04 + 28 -6.2544520879153232e-03 1.4127711154968393e-03 -1.8429821879439486e-03 + 29 6.4110631393682923e-04 3.1273432684728536e-03 3.7253671121127937e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml b/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml new file mode 100644 index 00000000000..28864f74976 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml @@ -0,0 +1,109 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa no_restart +date_generated: Fri Sep 4 18:04:58 2026 +epsilon: 5e-14 +skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng +prerequisites: | + atom full + atom sphere + fix langevin +pre_commands: "" +post_commands: | + fix move all nve/sphere + fix test solute langevin 50.0 ${t_target} 100.0 82573 omega yes +input_file: in.dipole +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 0 +run_pos: |2 + 1 -2.7812001834623307e-01 2.4745222047454130e+00 -1.7223344740738472e-01 + 2 3.0850311828121918e-01 2.9612715934513307e+00 -8.5177045749258107e-01 + 3 -6.9720770003931354e-01 1.2463395794968093e+00 -6.2355051604393696e-01 + 4 -1.5796731404231517e+00 1.4861246203860887e+00 -1.2561116676068627e+00 + 5 -9.0102826842637140e-01 9.3213533967901885e-01 4.0124649371487753e-01 + 6 2.9062962650112345e-01 2.3323768554722704e-01 -1.2787832968924111e+00 + 7 3.4007364128074241e-01 -1.1066975061028014e-02 -2.4673011804422185e+00 + 8 1.1654982046961049e+00 -4.8550495737213700e-01 -6.7443868862033352e-01 + 9 1.3797684109928381e+00 -2.5524784989411675e-01 2.7641984257802921e-01 + 10 2.0213832446411892e+00 -1.4294995277791953e+00 -9.6851172932267005e-01 + 11 1.7890915949649364e+00 -1.9908870246869141e+00 -1.8881573713310442e+00 + 12 3.0053201713385271e+00 -4.9053786514845171e-01 -1.6215900151344804e+00 + 13 4.0516023793393332e+00 -8.9330122761710440e-01 -1.6393746642258122e+00 + 14 2.6051799051868874e+00 -4.1680925730648843e-01 -2.6633147604535505e+00 + 15 2.9683768659864027e+00 5.5555803385147451e-01 -1.2358668168263585e+00 + 16 2.6530451680075871e+00 -2.3975755458790204e+00 3.1779075777630970e-02 + 17 2.2316363381028741e+00 -2.1011176030723098e+00 1.1525573572846828e+00 + 18 2.1372510164773648e+00 3.0158506000673575e+00 -3.5167916423913081e+00 + 19 1.5345707099318386e+00 2.6249696297499949e+00 -4.2370263294604360e+00 + 20 2.7732095850735448e+00 3.6929598470823972e+00 -3.9337745509645496e+00 + 21 4.9045170966509204e+00 -4.0748031756041101e+00 -3.6218925414639060e+00 + 22 4.3601484254175737e+00 -4.2118940901720361e+00 -4.4596265759842479e+00 + 23 5.7410255603428002e+00 -3.5837707365543854e+00 -3.8765903698199513e+00 + 24 2.0689205181438228e+00 3.1527432700150415e+00 3.1544823899088130e+00 + 25 1.3065187961811098e+00 3.2665243034426203e+00 2.5127268092264456e+00 + 26 2.5789541569137886e+00 4.0089379439900492e+00 3.2207820820984172e+00 + 27 -1.9618638791883651e+00 -4.3549504053758241e+00 2.1090482240812722e+00 + 28 -2.7443201293863528e+00 -4.0212170735730135e+00 1.5850082667482568e+00 + 29 -1.3141860113745112e+00 -3.5978986954166197e+00 2.2741894687370658e+00 +run_vel: |2 + 1 1.0684886500200229e-03 1.2609380865805590e-03 -5.1737951181705444e-05 + 2 3.4898705157629792e-03 4.8222167409016446e-03 1.7855216027060034e-03 + 3 -1.5452896154855818e-03 6.9404126124945301e-04 -8.4397832166146678e-04 + 4 -1.7263821781887832e-03 -4.0386856330142809e-03 -2.5477015802601180e-03 + 5 -4.8813879031147306e-03 -4.0896769950122692e-03 -1.4769710211389407e-03 + 6 -3.1510251707241462e-03 4.7409553313336990e-03 4.6754053480082200e-03 + 7 3.2873112416584683e-05 -1.1551353537817132e-03 -3.1808798675686230e-03 + 8 8.5432245971987515e-04 -9.2982920384127011e-04 1.9580644118353573e-03 + 9 4.8043700617016497e-04 1.1423382210426036e-03 6.1290670799609747e-03 + 10 2.3825377000137068e-03 -1.6241908990503426e-03 -1.0870576244815654e-03 + 11 -3.2871962562046474e-03 -2.0142142890038780e-03 -1.5609268838385694e-03 + 12 1.2353414624795803e-03 -6.6457330446153618e-04 -1.5195298935816968e-03 + 13 3.0303372331314414e-03 4.5725256733386652e-03 -9.9542522775960193e-05 + 14 2.1942221755407256e-03 -4.8291830627846194e-03 -4.0632639569582862e-03 + 15 -3.0515588267658474e-03 -4.9115178132102047e-03 4.5424692283232660e-03 + 16 1.4787145683983250e-03 -1.3100413706902808e-03 -2.5444129863856505e-03 + 17 -3.7944602571610557e-06 7.6088104103312995e-04 2.4984084252746021e-03 + 18 -6.1590010011844853e-04 -9.3553764219054625e-04 -3.7200153130912002e-04 + 19 3.2061425398384154e-04 -3.0287047637631926e-03 5.8636911227150324e-03 + 20 4.1715098782446527e-03 4.3790563538786331e-03 2.5400818876406099e-03 + 21 -9.7312008980948088e-04 1.5100049638325347e-04 -1.5172282384181063e-04 + 22 -5.2572212425597304e-03 -3.5787417434384231e-03 1.8543943926083830e-03 + 23 3.2939362686230070e-03 -2.8836279186367510e-03 2.6255213556269008e-03 + 24 2.5638398674548502e-04 4.3450813126234421e-04 -4.5928187134789409e-04 + 25 2.1619084773343124e-03 -4.4534715366740434e-03 7.6930726300184047e-04 + 26 1.6282501463538721e-04 5.6085644914726212e-05 3.9231484245627109e-03 + 27 -2.4066098672624218e-04 3.1636377958593114e-04 -5.3626843393434485e-04 + 28 -3.4277217399584603e-03 3.7010237047596504e-04 1.5959546071464591e-05 + 29 -8.6242002733354843e-04 1.5767896869201973e-03 3.2980383775216750e-03 +run_torque: |2 + 1 4.4546579933806549e+02 -9.0972111361446616e+02 3.9760304981971200e+02 + 2 -4.7569936287784166e+01 3.6307550847138637e+00 -9.1659437345863441e+00 + 3 8.4980607025325651e+02 -1.0872270651040865e+03 3.4190085401383783e+01 + 4 4.9904690083002405e+00 -3.1774023951907765e+01 -5.4482133502784869e+01 + 5 -5.8233395818034765e+01 2.1056660197541873e+01 6.2835477965204340e+01 + 6 -9.2517548242928831e+02 -2.3357446496069301e+02 -2.4141846994342185e+02 + 7 -1.6457139090300741e+03 1.2787774076623998e+02 7.7171894208589947e+01 + 8 1.4430681151839788e+03 1.1680297464688608e+03 5.8216148675534032e+02 + 9 -5.7659290080932713e+01 -7.1197043071383987e+01 -5.5269892205228878e+01 + 10 -9.9691487867108344e+02 9.7386263008483263e+02 9.5693309174659510e+02 + 11 -6.6766354254906432e+01 2.4582852517402340e+00 6.6131645031455790e+01 + 12 -9.2686162483322494e+02 9.6062485294588828e+02 -6.3985517524862246e+01 + 13 1.8698887260152333e+01 -6.0055215988162871e+00 -1.4494464802537074e+01 + 14 1.1564870874877162e+00 -3.5941414832320369e+01 6.4125142518395876e+01 + 15 3.7557295105164620e+01 -6.4288078011052292e+01 4.6639506353437518e+01 + 16 -2.6158277191015873e+02 2.7688532016479314e+01 3.4379646003690607e+02 + 17 4.7347216662604740e+02 -1.3710899194797921e+03 -1.2109120529157460e+03 + 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-nvt_bias_com.yaml b/unittest/force-styles/tests/fix-timestep-nvt_bias_com.yaml new file mode 100644 index 00000000000..2e5603d6130 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-nvt_bias_com.yaml @@ -0,0 +1,82 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:07:06 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix nvt + compute temp/com +pre_commands: "" +post_commands: | + compute mytemp solute temp/com + fix test solute nvt temp 50.0 ${t_target} 1.0 mtk no tchain 1 + fix_modify test temp mytemp +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 161.08036902209835 +global_vector: |- + 4 6.3649981438210350e+00 4.5874238177578954e+00 6.0713121393065869e+01 1.0036724762903249e+02 +run_pos: |2 + 1 -2.7673919594847229e-01 2.4783838108823160e+00 -1.7058876666954215e-01 + 2 3.0498252427930250e-01 2.9551025084079541e+00 -8.5576219341512294e-01 + 3 -6.9716889481424427e-01 1.2401021553403735e+00 -6.2418223595545952e-01 + 4 -1.5784409687203558e+00 1.4890662136241606e+00 -1.2509421050691441e+00 + 5 -8.9854837811642074e-01 9.3311447857239083e-01 4.0140555006027862e-01 + 6 2.8017374984190840e-01 2.4475865791870421e-01 -1.2669509345507195e+00 + 7 3.4082822786774264e-01 -1.3514279920310811e-02 -2.4844949667339296e+00 + 8 1.1676469151029345e+00 -4.8538703856239857e-01 -6.6480172717876751e-01 + 9 1.3787900558797481e+00 -2.5380242888650489e-01 2.7305423516664817e-01 + 10 2.0287150248157388e+00 -1.4380702182258582e+00 -9.7219877503413310e-01 + 11 1.7916241129521884e+00 -1.9888016457848525e+00 -1.8860429006607806e+00 + 12 3.0043769960992877e+00 -4.8956893001324281e-01 -1.6204159809566261e+00 + 13 4.0475897232931972e+00 -8.9803093571783665e-01 -1.6391049385953425e+00 + 14 2.6045154502854664e+00 -4.1146504855377636e-01 -2.6584860523741849e+00 + 15 2.9734086436831180e+00 5.6017619022934328e-01 -1.2405310825273903e+00 + 16 2.6592195438247339e+00 -2.4010201083341078e+00 1.5091116008841044e-02 + 17 2.2263389293668765e+00 -2.0982736522081131e+00 1.1641253584892615e+00 + 18 2.1384791188033843e+00 3.0177261773770208e+00 -3.5160827596876225e+00 + 19 1.5349125211132961e+00 2.6315969880333707e+00 -4.2472859440220647e+00 + 20 2.7641167828863153e+00 3.6833419064000221e+00 -3.9380850623312638e+00 + 21 4.9064454390208301e+00 -4.0751205255383196e+00 -3.6215576073601046e+00 + 22 4.3687453488627543e+00 -4.2054270536772504e+00 -4.4651491269372565e+00 + 23 5.7374928154769504e+00 -3.5763355905184966e+00 -3.8820297194230728e+00 + 24 2.0684115301174013e+00 3.1518221747664397e+00 3.1554242678474576e+00 + 25 1.2998381073113014e+00 3.2755513587518097e+00 2.5092990173114837e+00 + 26 2.5807438597688113e+00 4.0120175892854135e+00 3.2133398379059099e+00 + 27 -1.9613581876744359e+00 -4.3556300596085160e+00 2.1101467673534788e+00 + 28 -2.7406520384725965e+00 -4.0207251278130975e+00 1.5828689861678511e+00 + 29 -1.3108232656499081e+00 -3.5992986322410760e+00 2.2680459788743503e+00 +run_vel: |2 + 1 9.6650014913339261e-04 1.7089578920139782e-03 4.6667865652530335e-04 + 2 4.6636312354173643e-04 7.6654324196128305e-05 -5.7326825260411247e-04 + 3 -5.3715317463321399e-04 -1.5679036328598288e-03 -4.9471724276664553e-04 + 4 -1.1170767844162816e-04 -5.3779909418296464e-04 2.3730710188411721e-04 + 5 -8.3303501171623918e-04 -1.0858756891090127e-03 -3.6370782272923755e-04 + 6 -4.0792589542324635e-03 4.9297034368249136e-03 3.8616204602280194e-03 + 7 3.0917093100773878e-04 -1.0068624040501576e-03 -5.5005091768496094e-03 + 8 1.0156115540696758e-03 -2.6713958149229714e-04 3.6105439530085500e-03 + 9 1.9483878782495034e-04 6.6048919693431391e-04 1.3105109194450845e-03 + 10 3.2462565428815439e-03 -3.1636107231823125e-03 -1.6144692104371407e-03 + 11 -2.7575508800691147e-04 -2.1322465820346152e-04 -5.9637217486570188e-06 + 12 3.0342216877392357e-04 4.8641158213027529e-05 -2.4885457244563767e-04 + 13 5.4503693976373861e-05 2.5712021691469758e-04 -6.8474340794940860e-05 + 14 5.5827671049968179e-04 -1.8061972485778764e-04 -8.2095460363268359e-05 + 15 4.3349999609833777e-04 -2.7382600629304661e-04 2.6390087300495307e-04 + 16 2.1929212797984735e-03 -1.3510128636203716e-03 -5.1486655634869630e-03 + 17 -1.2755374824574674e-03 1.0248150595637440e-03 3.8564277321763681e-03 + 18 -6.0936815808025862e-04 -9.3774557532468582e-04 -3.3558072507805731e-04 + 19 -6.9919768291957119e-04 -3.6060777270430031e-03 4.2833405289822791e-03 + 20 4.7777805013736515e-03 5.1003745845520452e-03 1.8002873923729241e-03 + 21 -9.5568188553430398e-04 1.6594630943762931e-04 -1.8199788009966615e-04 + 22 -3.3137518957653462e-03 -2.8683968287936054e-03 3.6384389958326871e-03 + 23 2.4209481134686401e-04 -4.5457709985051130e-03 2.7663581642115042e-03 + 24 2.5447450568861086e-04 4.8412447786110117e-04 -4.8021914527341357e-04 + 25 4.3722771097312743e-03 -4.5184411669545515e-03 2.5200952006556795e-03 + 26 -1.9250110555001179e-03 -3.0342169883610837e-03 3.5062814567984532e-03 + 27 -2.6510179146429716e-04 3.6306203629019116e-04 -5.6235585400647747e-04 + 28 -2.3068708109787484e-04 -8.5663070212203200e-04 2.1302563179109169e-03 + 29 -2.5054744388303732e-03 -1.6773997805290820e-04 2.8436699761004796e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-nvt_bias_deform.yaml b/unittest/force-styles/tests/fix-timestep-nvt_bias_deform.yaml new file mode 100644 index 00000000000..70aa5781257 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-nvt_bias_deform.yaml @@ -0,0 +1,84 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:11:29 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix nvt + fix deform + compute temp/deform +pre_commands: "" +post_commands: | + fix defo all deform 2 x erate 1.0e-4 remap v + compute mytemp solute temp/deform + fix test solute nvt temp 50.0 ${t_target} 1.0 mtk no tchain 1 + fix_modify test temp mytemp +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 160.9740333915956 +global_vector: |- + 4 6.3605606637551331e+00 4.5859607901288229e+00 6.0670794080499100e+01 1.0030323931109652e+02 +run_pos: |2 + 1 -2.7718716056208093e-01 2.4783708366635069e+00 -1.7050460119412458e-01 + 2 3.0460767506807362e-01 2.9550887856202022e+00 -8.5567679384892426e-01 + 3 -6.9767376680214954e-01 1.2400835437512168e+00 -6.2410000498059848e-01 + 4 -1.5790549728218917e+00 1.4890476472973193e+00 -1.2508607238145832e+00 + 5 -8.9907883739636407e-01 9.3309633823642968e-01 4.0148847243569369e-01 + 6 2.7978714280061345e-01 2.4475161148812463e-01 -1.2668557044704942e+00 + 7 3.4045614975321026e-01 -1.3533753119037553e-02 -2.4844243987277563e+00 + 8 1.1673801399059964e+00 -4.8540473827298469e-01 -6.6471235205960266e-01 + 9 1.3785490195230936e+00 -2.5381970607393878e-01 2.7314071555767128e-01 + 10 2.0285599214093599e+00 -1.4380913157996538e+00 -9.7211803659365026e-01 + 11 1.7914332610875159e+00 -1.9888197121789446e+00 -1.8859612594168376e+00 + 12 3.0043405057096000e+00 -4.8958607448621705e-01 -1.6203336815120823e+00 + 13 4.0476850955816186e+00 -8.9804454590571559e-01 -1.6390220984087931e+00 + 14 2.6044284960580160e+00 -4.1148486096486425e-01 -2.6584052792917894e+00 + 15 2.9733647771139688e+00 5.6015683728045640e-01 -1.2404448523500766e+00 + 16 2.6591425504671964e+00 -2.4010398569205957e+00 1.5164793561997594e-02 + 17 2.2262012257995787e+00 -2.0982879192262711e+00 1.1642176240741688e+00 + 18 2.1384791188033843e+00 3.0177261773770208e+00 -3.5160827596876225e+00 + 19 1.5349125211132961e+00 2.6315969880333707e+00 -4.2472859440220647e+00 + 20 2.7641167828863153e+00 3.6833419064000221e+00 -3.9380850623312638e+00 + 21 4.9064454390208301e+00 -4.0751205255383196e+00 -3.6215576073601046e+00 + 22 4.3687453488627543e+00 -4.2054270536772504e+00 -4.4651491269372565e+00 + 23 5.7374928154769504e+00 -3.5763355905184966e+00 -3.8820297194230728e+00 + 24 2.0684115301174013e+00 3.1518221747664397e+00 3.1554242678474576e+00 + 25 1.2998381073113014e+00 3.2755513587518097e+00 2.5092990173114837e+00 + 26 2.5807438597688113e+00 4.0120175892854135e+00 3.2133398379059099e+00 + 27 -1.9613581876744359e+00 -4.3556300596085160e+00 2.1101467673534788e+00 + 28 -2.7406520384725965e+00 -4.0207251278130975e+00 1.5828689861678511e+00 + 29 -1.3108232656499081e+00 -3.5992986322410760e+00 2.2680459788743503e+00 +run_vel: |2 + 1 6.0953264731464750e-04 1.6960397000760101e-03 5.3280494527814569e-04 + 2 1.6678024983538426e-04 6.2913611608635115e-05 -5.0654442267160274e-04 + 3 -9.3652855423488721e-04 -1.5812953392998692e-03 -4.2860254184801436e-04 + 4 -5.9793702857053406e-04 -5.5133999370671725e-04 3.0392430101858166e-04 + 5 -1.2524114019823137e-03 -1.0994873277166313e-03 -2.9758850218669880e-04 + 6 -4.3795074105069665e-03 4.9151248320726563e-03 3.9294923965723233e-03 + 7 1.3627724778627167e-05 -1.0201836108164686e-03 -5.4345799504285979e-03 + 8 8.0212857580958842e-04 -2.8026346754970641e-04 3.6754362004978954e-03 + 9 2.8642075890749446e-06 6.4747210145127030e-04 1.3772192272472016e-03 + 10 3.1185603992843055e-03 -3.1754114390180814e-03 -1.5480888956893838e-03 + 11 -4.2653680012843826e-04 -2.2656996100120595e-04 6.0343257284722683e-05 + 12 2.7380329582495490e-04 3.5184656998673327e-05 -1.8255061339193148e-04 + 13 1.2760810186139283e-04 2.4422826407753244e-04 -2.3225364930456597e-06 + 14 4.8909521771022630e-04 -1.9396962886129626e-04 -1.5766997326752045e-05 + 15 4.0071613077344672e-04 -2.8718152947867809e-04 3.3024450614723870e-04 + 16 2.1286412839921173e-03 -1.3640574738259302e-03 -5.0819729899040603e-03 + 17 -1.3828322902507792e-03 1.0114502559738802e-03 3.9223744072941474e-03 + 18 -6.0936815808025862e-04 -9.3774557532468582e-04 -3.3558072507805731e-04 + 19 -6.9919768291957119e-04 -3.6060777270430031e-03 4.2833405289822791e-03 + 20 4.7777805013736515e-03 5.1003745845520452e-03 1.8002873923729241e-03 + 21 -9.5568188553430398e-04 1.6594630943762931e-04 -1.8199788009966615e-04 + 22 -3.3137518957653462e-03 -2.8683968287936054e-03 3.6384389958326871e-03 + 23 2.4209481134686401e-04 -4.5457709985051130e-03 2.7663581642115042e-03 + 24 2.5447450568861086e-04 4.8412447786110117e-04 -4.8021914527341357e-04 + 25 4.3722771097312743e-03 -4.5184411669545515e-03 2.5200952006556795e-03 + 26 -1.9250110555001179e-03 -3.0342169883610837e-03 3.5062814567984532e-03 + 27 -2.6510179146429716e-04 3.6306203629019116e-04 -5.6235585400647747e-04 + 28 -2.3068708109787484e-04 -8.5663070212203200e-04 2.1302563179109169e-03 + 29 -2.5054744388303732e-03 -1.6773997805290820e-04 2.8436699761004796e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-nvt_bias_deform_nested.yaml b/unittest/force-styles/tests/fix-timestep-nvt_bias_deform_nested.yaml new file mode 100644 index 00000000000..0dbcbfdeaa9 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-nvt_bias_deform_nested.yaml @@ -0,0 +1,85 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:13:01 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix nvt + compute temp/partial + compute temp/deform +pre_commands: "" +post_commands: | + compute mypart solute temp/partial 1 1 0 + compute mytemp solute temp/deform + compute_modify mytemp temp mypart + fix test solute nvt temp 50.0 ${t_target} 1.0 mtk no tchain 1 + fix_modify test temp mytemp +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 64.24812232219082 +global_vector: |- + 4 4.4223461666047399e+00 3.3707716744699221e+00 2.8121970982388014e+01 3.6126151339802810e+01 +run_pos: |2 + 1 -2.7618443442535023e-01 2.4798738854533817e+00 -1.6682657590624753e-01 + 2 3.0545779468141648e-01 2.9559653403189525e+00 -8.5461288955875403e-01 + 3 -6.9821447019556193e-01 1.2390549728595712e+00 -6.2800283357091258e-01 + 4 -1.5790632616539342e+00 1.4883823699500700e+00 -1.2538673397740343e+00 + 5 -8.9981052768047542e-01 9.3236699708829340e-01 3.9953335278725999e-01 + 6 2.7623380248319462e-01 2.4886544023839371e-01 -1.2319224914372682e+00 + 7 3.4061937555340388e-01 -1.4257653407116417e-02 -2.5296943053711076e+00 + 8 1.1684124800764932e+00 -4.8600368022161200e-01 -6.3664878853310058e-01 + 9 1.3788411247347809e+00 -2.5374924838958873e-01 2.8354217403902049e-01 + 10 2.0310241443339283e+00 -1.4405419469837368e+00 -9.8342058810003141e-01 + 11 1.7909411717288841e+00 -1.9892571800960632e+00 -1.8890505913699742e+00 + 12 3.0044342757277418e+00 -4.8966373269041236e-01 -1.6231847273517921e+00 + 13 4.0479886085410737e+00 -8.9722555833125062e-01 -1.6399975748637536e+00 + 14 2.6045682382883752e+00 -4.1235941923396030e-01 -2.6634017450635001e+00 + 15 2.9725972626975410e+00 5.5934314210888691e-01 -1.2342172706093057e+00 + 16 2.6602753966844306e+00 -2.4020143376429992e+00 -2.4071295763929235e-02 + 17 2.2252987334092271e+00 -2.0975799054808713e+00 1.1967720920878882e+00 + 18 2.1384791188033843e+00 3.0177261773770208e+00 -3.5160827596876225e+00 + 19 1.5349125211132961e+00 2.6315969880333707e+00 -4.2472859440220647e+00 + 20 2.7641167828863153e+00 3.6833419064000221e+00 -3.9380850623312638e+00 + 21 4.9064454390208301e+00 -4.0751205255383196e+00 -3.6215576073601046e+00 + 22 4.3687453488627543e+00 -4.2054270536772504e+00 -4.4651491269372565e+00 + 23 5.7374928154769504e+00 -3.5763355905184966e+00 -3.8820297194230728e+00 + 24 2.0684115301174013e+00 3.1518221747664397e+00 3.1554242678474576e+00 + 25 1.2998381073113014e+00 3.2755513587518097e+00 2.5092990173114837e+00 + 26 2.5807438597688113e+00 4.0120175892854135e+00 3.2133398379059099e+00 + 27 -1.9613581876744359e+00 -4.3556300596085160e+00 2.1101467673534788e+00 + 28 -2.7406520384725965e+00 -4.0207251278130975e+00 1.5828689861678511e+00 + 29 -1.3108232656499081e+00 -3.5992986322410760e+00 2.2680459788743503e+00 +run_vel: |2 + 1 1.0758378430654203e-03 2.2765801094550078e-03 5.1434394864405411e-03 + 2 4.0779761497875970e-04 1.3452097874164614e-04 -1.2703630186861720e-03 + 3 -1.0243563835635855e-03 -2.0178690707582827e-03 -4.7346825642642148e-03 + 4 -4.1490695078825383e-04 -7.9771294004832641e-04 -1.1080894849684066e-03 + 5 -1.4607435901414568e-03 -1.5193421927648277e-03 -2.8668036148682954e-03 + 6 -5.6377488002067227e-03 5.7465833220836258e-03 3.5724042111280642e-02 + 7 1.9335131414495595e-05 -6.5460487391352535e-04 -5.2643962293162656e-02 + 8 1.3759421714232252e-03 -7.4154923389310051e-04 3.7636750896122423e-02 + 9 2.0458333253902053e-04 9.8615077876954937e-04 1.5086455628525822e-02 + 10 3.8947395513295492e-03 -3.9792260149120384e-03 -1.5522974684997418e-02 + 11 -6.9653637134205388e-04 -3.3315182252135507e-04 -2.3191622424307890e-03 + 12 1.8220765856378089e-04 5.5519475587330099e-05 -3.0514479117998250e-03 + 13 -1.4293950121702838e-04 3.7168212087633007e-04 -7.8442238037032444e-04 + 14 5.4099334707703327e-04 -2.7859904293936634e-04 -3.9509810568049506e-03 + 15 2.9650025388801646e-04 -4.5605291628957414e-04 6.2507274171023164e-03 + 16 1.5831639071249401e-03 -1.0906166187692331e-03 -4.7120254091280032e-02 + 17 -1.0755443512774753e-03 7.5164521690498215e-04 3.8350135388618423e-02 + 18 -6.0936815808025862e-04 -9.3774557532468582e-04 -3.3558072507805731e-04 + 19 -6.9919768291957119e-04 -3.6060777270430031e-03 4.2833405289822791e-03 + 20 4.7777805013736515e-03 5.1003745845520452e-03 1.8002873923729241e-03 + 21 -9.5568188553430398e-04 1.6594630943762931e-04 -1.8199788009966615e-04 + 22 -3.3137518957653462e-03 -2.8683968287936054e-03 3.6384389958326871e-03 + 23 2.4209481134686401e-04 -4.5457709985051130e-03 2.7663581642115042e-03 + 24 2.5447450568861086e-04 4.8412447786110117e-04 -4.8021914527341357e-04 + 25 4.3722771097312743e-03 -4.5184411669545515e-03 2.5200952006556795e-03 + 26 -1.9250110555001179e-03 -3.0342169883610837e-03 3.5062814567984532e-03 + 27 -2.6510179146429716e-04 3.6306203629019116e-04 -5.6235585400647747e-04 + 28 -2.3068708109787484e-04 -8.5663070212203200e-04 2.1302563179109169e-03 + 29 -2.5054744388303732e-03 -1.6773997805290820e-04 2.8436699761004796e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-nvt_bias_region.yaml b/unittest/force-styles/tests/fix-timestep-nvt_bias_region.yaml new file mode 100644 index 00000000000..9424c97e129 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-nvt_bias_region.yaml @@ -0,0 +1,83 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:13:26 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix nvt + compute temp/region +pre_commands: "" +post_commands: | + region half block -20 20 -20 20 0 20 units box + compute mytemp solute temp/region half + fix test solute nvt temp 50.0 ${t_target} 1.0 mtk no tchain 1 + fix_modify test temp mytemp +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 43.643375158790185 +global_vector: |- + 4 7.9941144176462942e+00 5.7285772774045327e+00 1.4297361958181982e+01 2.9346013200608205e+01 +run_pos: |2 + 1 -2.7045588340646542e-01 2.4912189210423077e+00 -1.6696587826235121e-01 + 2 3.1004033729512120e-01 2.9612355029853452e+00 -8.5466366704896690e-01 + 3 -7.0396158762654060e-01 1.2305604252633175e+00 -6.2778245117776699e-01 + 4 -1.5818354110099875e+00 1.4837382669270176e+00 -1.2538446180344285e+00 + 5 -8.9832768707576216e-01 9.3344992384224235e-01 4.0159658295955147e-01 + 6 2.4831647583005331e-01 2.8313039220859515e-01 -1.2314251791879725e+00 + 7 3.4143526230039539e-01 -2.2646544891768421e-02 -2.5292291995820357e+00 + 8 1.1743280597838024e+00 -4.8865524052284864e-01 -6.3795854120746531e-01 + 9 1.3785916822117612e+00 -2.5379885247740080e-01 2.7293948799900353e-01 + 10 2.0510673596954825e+00 -1.4604182607597245e+00 -9.8314463750095038e-01 + 11 1.7878213138754127e+00 -1.9922246134385864e+00 -1.8890417516598403e+00 + 12 3.0063071826053869e+00 -4.9013609276977443e-01 -1.6231835779984676e+00 + 13 4.0515403356971387e+00 -8.9202011477472432e-01 -1.6400005480401130e+00 + 14 2.6066963300924604e+00 -4.1789257458974732e-01 -2.6634003170271994e+00 + 15 2.9695287547996454e+00 5.5422613124332964e-01 -1.2342022020215329e+00 + 16 2.6581346580881018e+00 -2.4004282035594842e+00 1.7363586440911537e-02 + 17 2.2267108363252008e+00 -2.0987675602599185e+00 1.1623869406716321e+00 + 18 2.1384791188033843e+00 3.0177261773770208e+00 -3.5160827596876225e+00 + 19 1.5349125211132961e+00 2.6315969880333707e+00 -4.2472859440220647e+00 + 20 2.7641167828863153e+00 3.6833419064000221e+00 -3.9380850623312638e+00 + 21 4.9064454390208301e+00 -4.0751205255383196e+00 -3.6215576073601046e+00 + 22 4.3687453488627543e+00 -4.2054270536772504e+00 -4.4651491269372565e+00 + 23 5.7374928154769504e+00 -3.5763355905184966e+00 -3.8820297194230728e+00 + 24 2.0684115301174013e+00 3.1518221747664397e+00 3.1554242678474576e+00 + 25 1.2998381073113014e+00 3.2755513587518097e+00 2.5092990173114837e+00 + 26 2.5807438597688113e+00 4.0120175892854135e+00 3.2133398379059099e+00 + 27 -1.9613581876744359e+00 -4.3556300596085160e+00 2.1101467673534788e+00 + 28 -2.7406520384725965e+00 -4.0207251278130975e+00 1.5828689861678511e+00 + 29 -1.3108232656499081e+00 -3.5992986322410760e+00 2.2680459788743503e+00 +run_vel: |2 + 1 8.1701938280930135e-03 1.6524086680454311e-02 4.7710283347953443e-03 + 2 5.4503306969783463e-03 5.1793404904465863e-03 -1.4374580818939269e-03 + 3 -8.1705336560675586e-03 -1.2901859976970248e-02 -4.1159213586776204e-03 + 4 -3.8180494670732885e-03 -6.5774698583124904e-03 -1.0524295575644127e-03 + 5 -8.2252325235652253e-04 -8.7261259277833817e-04 -2.2804633728446252e-04 + 6 -3.9679658266571181e-02 4.6818710057776027e-02 3.7144353873155365e-02 + 7 9.1027971543975253e-04 -1.0128491641647254e-02 -5.1568441738420068e-02 + 8 7.8354034534387842e-03 -3.4154993518045367e-03 3.4226978109159055e-02 + 9 1.9150321022324480e-04 6.1507666858078415e-04 1.6696951276842184e-03 + 10 2.9183462392911121e-02 -2.9284778828491467e-02 -1.4787131148780714e-02 + 11 -4.7392344386650610e-03 -3.8437174684712258e-03 -2.3000580823032716e-03 + 12 2.2855129379972072e-03 -3.5394545318733975e-04 -3.0483055050208982e-03 + 13 2.7533391886112777e-03 5.8171103066471941e-03 -7.9465197534039488e-04 + 14 3.5245984751774663e-03 -5.7941485931582862e-03 -3.9476561959302225e-03 + 15 -1.8546422478782775e-03 -5.8554742308578956e-03 6.2938506621263409e-03 + 16 1.6828310697462351e-03 -1.1645072062377432e-03 -4.1273829297071626e-03 + 17 -1.1934235831267924e-03 8.3125078986753646e-04 3.1865210186942314e-03 + 18 -6.0936815808025862e-04 -9.3774557532468582e-04 -3.3558072507805731e-04 + 19 -6.9919768291957119e-04 -3.6060777270430031e-03 4.2833405289822791e-03 + 20 4.7777805013736515e-03 5.1003745845520452e-03 1.8002873923729241e-03 + 21 -9.5568188553430398e-04 1.6594630943762931e-04 -1.8199788009966615e-04 + 22 -3.3137518957653462e-03 -2.8683968287936054e-03 3.6384389958326871e-03 + 23 2.4209481134686401e-04 -4.5457709985051130e-03 2.7663581642115042e-03 + 24 2.5447450568861086e-04 4.8412447786110117e-04 -4.8021914527341357e-04 + 25 4.3722771097312743e-03 -4.5184411669545515e-03 2.5200952006556795e-03 + 26 -1.9250110555001179e-03 -3.0342169883610837e-03 3.5062814567984532e-03 + 27 -2.6510179146429716e-04 3.6306203629019116e-04 -5.6235585400647747e-04 + 28 -2.3068708109787484e-04 -8.5663070212203200e-04 2.1302563179109169e-03 + 29 -2.5054744388303732e-03 -1.6773997805290820e-04 2.8436699761004796e-03 +... From 26d0f940f10ce0af975ed1ca6c80e4519a01ccd4 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 18:29:32 +0000 Subject: [PATCH 060/120] test: cover the region keyword and the variable arguments of the forcing fixes Every existing reference passes plain numbers and no region, so two whole classes of code in the KOKKOS package were never entered: the branch that evaluates an equal-style or atom-style variable argument once per step, and the region test each per-atom kernel makes before it touches an atom. The latter is also the only route by which the KOKKOS region classes are reached from a fix. Fifteen references cover both, for fix addforce, aveforce, setforce, efield (the charge and the dipole kernel), addtorque/atom, settorque/atom, gravity (chute, vector and spherical form) and heat. Each variable is a function of the timestep, so the branch is re-evaluated rather than folded to a constant, and each region holds only part of the group, so the kernels take the test both ways: removing the region from the addforce reference changes exactly the three atoms of the one molecule that lies outside it. --- .../tests/fix-timestep-addforce_region.yaml | 80 +++++++++++ ...fix-timestep-addforce_region_variable.yaml | 84 +++++++++++ .../fix-timestep-addtorque_atom_region.yaml | 125 +++++++++++++++++ .../fix-timestep-addtorque_atom_variable.yaml | 130 ++++++++++++++++++ .../tests/fix-timestep-aveforce_region.yaml | 79 +++++++++++ ...fix-timestep-aveforce_region_variable.yaml | 81 +++++++++++ .../fix-timestep-efield_dipole_region.yaml | 111 +++++++++++++++ .../fix-timestep-efield_region_variable.yaml | 87 ++++++++++++ ...x-timestep-gravity_spherical_variable.yaml | 81 +++++++++++ .../tests/fix-timestep-gravity_variable.yaml | 81 +++++++++++ .../fix-timestep-gravity_vector_variable.yaml | 83 +++++++++++ .../tests/fix-timestep-heat_variable.yaml | 79 +++++++++++ ...fix-timestep-setforce_region_variable.yaml | 83 +++++++++++ .../fix-timestep-settorque_atom_region.yaml | 125 +++++++++++++++++ .../fix-timestep-settorque_atom_variable.yaml | 130 ++++++++++++++++++ 15 files changed, 1439 insertions(+) create mode 100644 unittest/force-styles/tests/fix-timestep-addforce_region.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-addforce_region_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-addtorque_atom_region.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-addtorque_atom_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-aveforce_region.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-aveforce_region_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-efield_dipole_region.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-efield_region_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-gravity_spherical_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-gravity_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-gravity_vector_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-heat_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-setforce_region_variable.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-settorque_atom_region.yaml create mode 100644 unittest/force-styles/tests/fix-timestep-settorque_atom_variable.yaml diff --git a/unittest/force-styles/tests/fix-timestep-addforce_region.yaml b/unittest/force-styles/tests/fix-timestep-addforce_region.yaml new file mode 100644 index 00000000000..39bb226e1ba --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-addforce_region.yaml @@ -0,0 +1,80 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:11:21 2026 +epsilon: 9e-12 +skip_tests: +prerequisites: | + atom full + fix addforce +pre_commands: "" +post_commands: | + region part block EDGE 3.5 EDGE EDGE EDGE EDGE units box + fix move all nve + fix test solvent addforce 0.0 -0.1 0.1 region part +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 2.2562179474688775 +global_vector: |- + 3 -2.9135372645050950e-02 -4.2476426800007516e-02 1.1644078004153791e-02 +run_pos: |2 + 1 -2.7045559775397010e-01 2.4912159905674023e+00 -1.6695851791636668e-01 + 2 3.1004029573898018e-01 2.9612354631094187e+00 -8.5466363037030557e-01 + 3 -7.0398551400757958e-01 1.2305509955831329e+00 -6.2777526944491413e-01 + 4 -1.5818159336499258e+00 1.4837407818929915e+00 -1.2538710836062053e+00 + 5 -9.0719763672789178e-01 9.2652103885674564e-01 3.9954210488374908e-01 + 6 2.4831720524908707e-01 2.8313021497935903e-01 -1.2314233331716831e+00 + 7 3.4143527641334509e-01 -2.2646551042395265e-02 -2.5292291414899140e+00 + 8 1.1743552229101639e+00 -4.8863228565805955e-01 -6.3783432910863835e-01 + 9 1.3800524229500304e+00 -2.5274721030406772e-01 2.8353985887095834e-01 + 10 2.0510765220543918e+00 -1.4604063740300859e+00 -9.8323745081722802e-01 + 11 1.7878031944442556e+00 -1.9921863272948841e+00 -1.8890602447625782e+00 + 12 3.0063007039337593e+00 -4.9013350496880237e-01 -1.6231898107390359e+00 + 13 4.0515402959192954e+00 -8.9202011606653531e-01 -1.6400005529924973e+00 + 14 2.6066963345543708e+00 -4.1789253965510847e-01 -2.6634003608794559e+00 + 15 2.9695287185712846e+00 5.5422613165235468e-01 -1.2342022021790335e+00 + 16 2.6747029695228468e+00 -2.4124119054563886e+00 -2.3435746150624305e-02 + 17 2.2153577785283773e+00 -2.0897985186907082e+00 1.1963150794479613e+00 + 18 2.1369701127897938e+00 3.0158454226265148e+00 -3.5179294604971303e+00 + 19 1.5355836921432058e+00 2.6255083952896539e+00 -4.2353781201178675e+00 + 20 2.7727575520534322e+00 3.6923704815401104e+00 -3.9330637176237930e+00 + 21 4.9040128073204272e+00 -4.0752348172957849e+00 -3.6210314709891702e+00 + 22 4.3582355554440841e+00 -4.2126119427287030e+00 -4.4612844196314052e+00 + 23 5.7439382849307599e+00 -3.5821957939275024e+00 -3.8766361295935821e+00 + 24 2.0689244010155314e+00 3.1513292691460331e+00 3.1550443097176264e+00 + 25 1.3045347725388925e+00 3.2664919029361505e+00 2.5112060475024207e+00 + 26 2.5809239301358042e+00 4.0117399350809153e+00 3.2212268729493467e+00 + 27 -1.9611343130357228e+00 -4.3563411931359752e+00 2.1098293115523705e+00 + 28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00 + 29 -1.3126000191359852e+00 -3.5962518039482925e+00 2.2746342468737839e+00 +run_vel: |2 + 1 8.1705744180627666e-03 1.6516406175112540e-02 4.7902264299502610e-03 + 2 5.4501493445410195e-03 5.1791699408066565e-03 -1.4372931532303543e-03 + 3 -8.2298292715962239e-03 -1.2926551614486456e-02 -4.0984181185411460e-03 + 4 -3.7699042590022898e-03 -6.5722892098852804e-03 -1.1184640360253069e-03 + 5 -1.1021961004340825e-02 -9.8906780939476517e-03 -2.8410737829294495e-03 + 6 -3.9676663165316386e-02 4.6817061466030353e-02 3.7148491978378266e-02 + 7 9.1033952905197522e-04 -1.0128524414039096e-02 -5.1568251804220797e-02 + 8 7.9064712062199959e-03 -3.3507254542834825e-03 3.4557098491783983e-02 + 9 1.5644176117285667e-03 3.7365546102688055e-03 1.5047408822046041e-02 + 10 2.9201446820579350e-02 -2.9249578745074580e-02 -1.5018077424523005e-02 + 11 -4.7835961513514880e-03 -3.7481385134141669e-03 -2.3464104142301022e-03 + 12 2.2696451836872683e-03 -3.4774154228006204e-04 -3.0640770336249554e-03 + 13 2.7531740451815839e-03 5.8171061612967041e-03 -7.9467454022495157e-04 + 14 3.5246182371751885e-03 -5.7939995584869357e-03 -3.9478431173124726e-03 + 15 -1.8547943640256359e-03 -5.8554729942417354e-03 6.2938485140110276e-03 + 16 1.8681499973433519e-02 -1.3262466204500568e-02 -4.5638651457020132e-02 + 17 -1.2896269981103815e-02 9.7527665267269324e-03 3.7296535360873698e-02 + 18 -8.0077498306846092e-04 -8.6811452934847718e-04 -1.4427834375373766e-03 + 19 1.2451970620330263e-03 -2.5269110534191937e-03 7.3202940392127058e-03 + 20 3.5935152342545496e-03 3.6736472076779247e-03 3.2524400548478664e-03 + 21 -1.4689220370839369e-03 -2.7352129759767788e-04 7.0581624215568066e-04 + 22 -7.0694199254630269e-03 -4.2577148924875866e-03 2.8079117614257260e-04 + 23 6.0446963117375858e-03 -1.4000131614792769e-03 2.5819754847013787e-03 + 24 3.1935178241289765e-04 -1.0000734766842370e-03 1.5544111851314806e-04 + 25 1.3716689706676097e-04 -4.4540402009395396e-03 -7.9792532837493445e-04 + 26 2.0489693536469775e-03 2.7615728786604546e-03 4.3453316838182130e-03 + 27 4.5604120293370735e-04 -1.0305523026920994e-03 2.1188058381358616e-04 + 28 -6.2544520861855151e-03 1.4127711176146862e-03 -1.8429821884794265e-03 + 29 6.4110631534461198e-04 3.1273432719603885e-03 3.7253671105660479e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-addforce_region_variable.yaml b/unittest/force-styles/tests/fix-timestep-addforce_region_variable.yaml new file mode 100644 index 00000000000..1af92f04260 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-addforce_region_variable.yaml @@ -0,0 +1,84 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:11:22 2026 +epsilon: 2e-11 +skip_tests: +prerequisites: | + atom full + fix addforce +pre_commands: "" +post_commands: | + region part block EDGE 3.5 EDGE EDGE EDGE EDGE units box + variable xforce delete + variable xforce atom 0.01*id + variable zforce delete + variable zforce equal 0.1*step/10.0 + fix move all nve + fix test solvent addforce v_xforce 0.0 v_zforce region part +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: -2.5008130590834448 +global_vector: |- + 3 -2.9135399728218658e-02 -4.2476348857469759e-02 1.1644021302734231e-02 +run_pos: |2 + 1 -2.7045559775446859e-01 2.4912159905673850e+00 -1.6695851791674385e-01 + 2 3.1004029573898612e-01 2.9612354631094302e+00 -8.5466363037028958e-01 + 3 -7.0398551400823817e-01 1.2305509955826710e+00 -6.2777526944445095e-01 + 4 -1.5818159336499387e+00 1.4837407818929857e+00 -1.2538710836062046e+00 + 5 -9.0719763672793563e-01 9.2652103885670523e-01 3.9954210488369790e-01 + 6 2.4831720524851023e-01 2.8313021497818430e-01 -1.2314233331708162e+00 + 7 3.4143527641447846e-01 -2.2646551040730635e-02 -2.5292291414905193e+00 + 8 1.1743552229101892e+00 -4.8863228565874389e-01 -6.3783432910822169e-01 + 9 1.3800524229500462e+00 -2.5274721030408637e-01 2.8353985887093758e-01 + 10 2.0510765220544527e+00 -1.4604063740302871e+00 -9.8323745081713465e-01 + 11 1.7878031944442563e+00 -1.9921863272948861e+00 -1.8890602447625777e+00 + 12 3.0063007039341678e+00 -4.9013350496929037e-01 -1.6231898107387794e+00 + 13 4.0515402959193008e+00 -8.9202011606653608e-01 -1.6400005529924957e+00 + 14 2.6066963345543850e+00 -4.1789253965512718e-01 -2.6634003608794465e+00 + 15 2.9695287185712971e+00 5.5422613165235224e-01 -1.2342022021790153e+00 + 16 2.6747029695228695e+00 -2.4124119054564193e+00 -2.3435746150616468e-02 + 17 2.2153577785284178e+00 -2.0897985186907704e+00 1.1963150794479449e+00 + 18 2.1369797697577000e+00 3.0158508907746704e+00 -3.5179334096661230e+00 + 19 1.5356230254378336e+00 2.6255290229206305e+00 -4.2353937229237717e+00 + 20 2.7727986766263593e+00 3.6923906611369217e+00 -3.9330785438418103e+00 + 21 4.9040128073204299e+00 -4.0752348172957875e+00 -3.6210314709891711e+00 + 22 4.3582355554440841e+00 -4.2126119427287048e+00 -4.4612844196314052e+00 + 23 5.7439382849307599e+00 -3.5821957939275024e+00 -3.8766361295935821e+00 + 24 2.0689373011964936e+00 3.1513348349623698e+00 3.1550406103748538e+00 + 25 1.3045862938406867e+00 3.2665128201491473e+00 2.5111900774746392e+00 + 26 2.5809775014360339e+00 4.0117594352096901e+00 3.2212114166809607e+00 + 27 -1.9611343130357228e+00 -4.3563411931359752e+00 2.1098293115523705e+00 + 28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00 + 29 -1.3126000191359857e+00 -3.5962518039482934e+00 2.2746342468737835e+00 +run_vel: |2 + 1 8.1705744170117670e-03 1.6516406175069380e-02 4.7902264290719219e-03 + 2 5.4501493445506498e-03 5.1791699408286918e-03 -1.4372931532077573e-03 + 3 -8.2298292729354929e-03 -1.2926551615428687e-02 -4.0984181176191847e-03 + 4 -3.7699042590327581e-03 -6.5722892098995433e-03 -1.1184640360229006e-03 + 5 -1.1021961004438439e-02 -9.8906780940322594e-03 -2.8410737830286033e-03 + 6 -3.9676663166496755e-02 4.6817061463651749e-02 3.7148491980126867e-02 + 7 9.1033953140890497e-04 -1.0128524410560962e-02 -5.1568251805445969e-02 + 8 7.9064712062747594e-03 -3.3507254556714660e-03 3.4557098492610586e-02 + 9 1.5644176117632046e-03 3.7365546102281779e-03 1.5047408822007337e-02 + 10 2.9201446820709520e-02 -2.9249578745485966e-02 -1.5018077424338423e-02 + 11 -4.7835961513498504e-03 -3.7481385134185913e-03 -2.3464104142292244e-03 + 12 2.2696451845194659e-03 -3.4774154325463891e-04 -3.0640770331061239e-03 + 13 2.7531740451977376e-03 5.8171061612930890e-03 -7.9467454022218913e-04 + 14 3.5246182372066356e-03 -5.7939995585271848e-03 -3.9478431172909707e-03 + 15 -1.8547943639979287e-03 -5.8554729942509095e-03 6.2938485140458435e-03 + 16 1.8681499973480301e-02 -1.3262466204564118e-02 -4.5638651457004992e-02 + 17 -1.2896269981021403e-02 9.7527665265949807e-03 3.7296535360838344e-02 + 18 -7.9086654857922706e-04 -8.6240189213778904e-04 -1.4460953401342579e-03 + 19 1.2841718245213915e-03 -2.5065494385413242e-03 7.3073199822885331e-03 + 20 3.6339945024629204e-03 3.6931168403656549e-03 3.2410535625179834e-03 + 21 -1.4689220370769074e-03 -2.7352129760255147e-04 7.0581624215305754e-04 + 22 -7.0694199254629775e-03 -4.2577148924878121e-03 2.8079117614256740e-04 + 23 6.0446963117375928e-03 -1.4000131614792560e-03 2.5819754847013592e-03 + 24 3.3261443001812008e-04 -9.9416939683531227e-04 1.5263150560963754e-04 + 25 1.8796722551715734e-04 -4.4330749406536318e-03 -8.1164106297308886e-04 + 26 2.1018146871230482e-03 2.7796746381578722e-03 4.3326817980070386e-03 + 27 4.5604120293369602e-04 -1.0305523026921137e-03 2.1188058381358348e-04 + 28 -6.2544520861855151e-03 1.4127711176146875e-03 -1.8429821884794260e-03 + 29 6.4110631534370927e-04 3.1273432719576243e-03 3.7253671105655067e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-addtorque_atom_region.yaml b/unittest/force-styles/tests/fix-timestep-addtorque_atom_region.yaml new file mode 100644 index 00000000000..a86a3bd0cbb --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-addtorque_atom_region.yaml @@ -0,0 +1,125 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 18:06:05 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom dipole + atom sphere + fix addtorque/atom + fix nve/sphere + fix viscous/sphere +pre_commands: "" +post_commands: | + group sub id 1:16 + region upper block INF INF INF INF 0.0 INF units box + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test sub addtorque/atom 12.0 -8.0 5.0 every 2 region upper +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 -2.0934248363186217e+01 6.1623092212940378e+01 5.4595751974088287e+01 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 3.4999149888402286e+01 1.9512238074702505e+01 1.4779739161063793e+01 + 2 -1.2388020507099295e+01 4.9745472883917756e+00 3.1387256954602471e+01 + 3 3.3782990318325822e+01 -3.1012124693084633e+01 -1.8694329215028800e+00 + 4 9.7425744499438203e+00 2.7918588484384280e+01 -2.7599872151694690e+01 + 5 -2.8855400716720965e+00 -4.0767593426391635e+01 3.5707278278958427e+01 + 6 -7.1757597232124954e+00 -1.2782097936501158e+01 2.8817329188827419e+00 + 7 3.6750612555404288e+01 -1.7871845723259177e+01 9.0494590104936989e+00 + 8 -1.5782983024606947e+01 -3.3357259725033060e+01 2.2312891927652473e+01 + 9 4.8464809628201799e+01 2.8622013410176187e+01 3.4134836690021253e+01 + 10 1.5821282141599262e+00 1.8828910067345717e+01 -1.4874132982907344e+00 + 11 1.8977864758001260e+01 -2.7323904664642402e+01 -1.1237568600415688e+01 + 12 -9.2184730830976918e+00 -2.0959198269513067e+01 3.5161044980754447e+01 + 13 -2.1821872860534270e+00 -4.6425389094957046e+00 -2.2875500137372075e+01 + 14 -5.7993021513758229e+00 -3.3992028783400514e+01 -3.6610775144482925e+00 + 15 1.0344315927890230e+01 -2.4986757471399887e+01 -2.2220217838284317e+01 + 16 -1.3291053486031315e+01 -2.2167497796588776e+01 1.8987093334742553e+01 + 17 -3.6245256163667364e+01 -6.3871111638224605e+00 -1.3495747501256501e+01 + 18 -3.3449264457958030e+01 -5.1211596898529228e+00 -1.6063046301513040e+01 + 19 9.3043983000234061e+00 -2.3735251406356383e+01 2.9944371209876916e+01 + 20 -2.4405251554499323e+01 1.2326350244656219e+01 1.8226255489083119e+01 + 21 5.3118160854329755e-01 -1.7920486666067696e+01 1.6953099712445379e+01 + 22 -3.3557628027146755e+01 1.2249117911837695e+01 -1.7589300363970636e+01 + 23 3.0739609373049564e+01 2.6993712418787631e+01 1.8418986687028031e+01 + 24 5.0644131551068856e+00 -1.1242047487707133e+01 -3.2378841254744543e+01 + 25 1.0202507096633921e+01 2.6024108048890692e+01 1.7811055792779975e+01 + 26 -1.3723409906199922e+01 -1.0575474673847591e+01 8.2690719199617373e+00 + 27 9.4128998826732033e+00 2.2890024767581750e+01 2.4136424334565429e+01 + 28 -1.7910692310779947e+01 -3.3294781390526161e+01 6.7281746292838989e+00 + 29 -7.9733826800536098e+00 3.1114003089361034e+01 2.2326437598377652e+01 + 30 2.3968291735833084e+01 2.8641275713082941e+01 -6.0887858668077675e+00 + 31 5.1720084493622815e+00 -2.1513073667316927e+01 2.3908844737698647e+01 + 32 1.8588536223960755e+01 3.2959381077417568e+01 -1.8718949743780824e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-addtorque_atom_variable.yaml b/unittest/force-styles/tests/fix-timestep-addtorque_atom_variable.yaml new file mode 100644 index 00000000000..35f5efe9be7 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-addtorque_atom_variable.yaml @@ -0,0 +1,130 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 18:06:05 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom dipole + atom sphere + fix addtorque/atom + fix nve/sphere + fix viscous/sphere +pre_commands: "" +post_commands: | + group sub id 1:16 + variable tqx delete + variable tqx equal 12.0-1.0*step + variable tqy delete + variable tqy equal -8.0+0.5*step + variable tqz delete + variable tqz equal 0.25*step + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test sub addtorque/atom v_tqx v_tqy v_tqz every 2 +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 5.8410915444408289e+00 -8.9937932244198620e+01 6.3489315750267792e+01 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 2.7004872859008987e+01 2.3509376589399153e+01 1.1786649533061130e+01 + 2 -2.0393734141380211e+01 8.9793102063468364e+00 2.8389402074563318e+01 + 3 3.7780131218662504e+01 -3.5009264798207973e+01 1.3390158788195716e-01 + 4 1.7454421925598647e+00 3.1917630484408043e+01 -3.0594151458026772e+01 + 5 -1.0888388242029132e+01 -3.6764740817719151e+01 3.2710617342220871e+01 + 6 -3.1757635948851366e+00 -1.6781141526951615e+01 4.8862571065970197e+00 + 7 2.8742043693132693e+01 -1.3865179319977004e+01 6.0504144521250858e+00 + 8 -1.1782986896279599e+01 -3.7356303315483522e+01 2.4317416115366754e+01 + 9 4.0453369151641525e+01 3.2630594222984151e+01 3.1134595625699024e+01 + 10 -6.4264406481116616e+00 2.2835576470627906e+01 -4.4864578566593494e+00 + 11 2.2977860886328621e+01 -3.1322948255092850e+01 -9.2330444127014104e+00 + 12 -1.7229913559657955e+01 -1.6950617456705096e+01 3.2160803916432208e+01 + 13 -1.0187900920334350e+01 -6.3777599154063402e-01 -2.5873355017411264e+01 + 14 -1.3805026714963020e+01 -2.9987258579241256e+01 -6.6589369483650795e+00 + 15 1.4330020223339289e+01 -2.8976273173264804e+01 -2.0221648580936005e+01 + 16 -9.3024939625915906e+00 -2.6158916983780799e+01 2.0986852270420332e+01 + 17 -3.6245256163667364e+01 -6.3871111638224605e+00 -1.3495747501256501e+01 + 18 -3.3449264457958030e+01 -5.1211596898529228e+00 -1.6063046301513040e+01 + 19 9.3043983000234061e+00 -2.3735251406356383e+01 2.9944371209876916e+01 + 20 -2.4405251554499323e+01 1.2326350244656219e+01 1.8226255489083119e+01 + 21 5.3118160854329755e-01 -1.7920486666067696e+01 1.6953099712445379e+01 + 22 -3.3557628027146755e+01 1.2249117911837695e+01 -1.7589300363970636e+01 + 23 3.0739609373049564e+01 2.6993712418787631e+01 1.8418986687028031e+01 + 24 5.0644131551068856e+00 -1.1242047487707133e+01 -3.2378841254744543e+01 + 25 1.0202507096633921e+01 2.6024108048890692e+01 1.7811055792779975e+01 + 26 -1.3723409906199922e+01 -1.0575474673847591e+01 8.2690719199617373e+00 + 27 9.4128998826732033e+00 2.2890024767581750e+01 2.4136424334565429e+01 + 28 -1.7910692310779947e+01 -3.3294781390526161e+01 6.7281746292838989e+00 + 29 -7.9733826800536098e+00 3.1114003089361034e+01 2.2326437598377652e+01 + 30 2.3968291735833084e+01 2.8641275713082941e+01 -6.0887858668077675e+00 + 31 5.1720084493622815e+00 -2.1513073667316927e+01 2.3908844737698647e+01 + 32 1.8588536223960755e+01 3.2959381077417568e+01 -1.8718949743780824e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-aveforce_region.yaml b/unittest/force-styles/tests/fix-timestep-aveforce_region.yaml new file mode 100644 index 00000000000..9439f0b32eb --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-aveforce_region.yaml @@ -0,0 +1,79 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:11:23 2026 +epsilon: 2e-11 +skip_tests: +prerequisites: | + atom full + fix aveforce +pre_commands: "" +post_commands: | + region part block EDGE 3.5 EDGE EDGE EDGE EDGE units box + fix move all nve + fix test solvent aveforce 0.0 -0.1 0.1 region part +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_vector: |- + 3 -2.9140197517609323e-02 -4.2488771317216845e-02 1.1672723006352470e-02 +run_pos: |2 + 1 -2.7045559775847483e-01 2.4912159905741951e+00 -1.6695851809823642e-01 + 2 3.1004029573982667e-01 2.9612354631120765e+00 -8.5466363036991200e-01 + 3 -7.0398551398007314e-01 1.2305509956006644e+00 -6.2777526947523099e-01 + 4 -1.5818159336501612e+00 1.4837407818928594e+00 -1.2538710836066187e+00 + 5 -9.0719763673071041e-01 9.2652103885541370e-01 3.9954210488008679e-01 + 6 2.4831720528694329e-01 2.8313021502654778e-01 -1.2314233331865632e+00 + 7 3.4143527641152732e-01 -2.2646551057682745e-02 -2.5292291414586070e+00 + 8 1.1743552229253869e+00 -4.8863228562402322e-01 -6.3783432914662042e-01 + 9 1.3800524229490618e+00 -2.5274721030824676e-01 2.8353985886545163e-01 + 10 2.0510765220564600e+00 -1.4604063740177440e+00 -9.8323745082476222e-01 + 11 1.7878031944442594e+00 -1.9921863272949925e+00 -1.8890602447627121e+00 + 12 3.0063007039255463e+00 -4.9013350489794888e-01 -1.6231898107527742e+00 + 13 4.0515402959192679e+00 -8.9202011606651221e-01 -1.6400005529925723e+00 + 14 2.6066963345544156e+00 -4.1789253965653517e-01 -2.6634003608795029e+00 + 15 2.9695287185720196e+00 5.5422613165167300e-01 -1.2342022021785306e+00 + 16 2.6747029695235507e+00 -2.4124119054573927e+00 -2.3435746155042653e-02 + 17 2.2153577785291905e+00 -2.0897985187059049e+00 1.1963150794372566e+00 + 18 2.1372601277462571e+00 3.0158450816482634e+00 -3.5167485856476155e+00 + 19 1.5335131088403624e+00 2.6243624595180637e+00 -4.2386979640820526e+00 + 20 2.7736713269819688e+00 3.6935202825079054e+00 -3.9344631886644699e+00 + 21 4.9040128073204583e+00 -4.0752348172957120e+00 -3.6210314709889002e+00 + 22 4.3582355554440833e+00 -4.2126119427287074e+00 -4.4612844196314025e+00 + 23 5.7439382849307599e+00 -3.5821957939275046e+00 -3.8766361295935825e+00 + 24 2.0689202243878118e+00 3.1527848191440535e+00 3.1544691650470740e+00 + 25 1.3085816446236698e+00 3.2664921033566796e+00 2.5143605065948429e+00 + 26 2.5768928207507167e+00 4.0059267822474709e+00 3.2203736997015544e+00 + 27 -1.9611343130357233e+00 -4.3563411931359752e+00 2.1098293115523705e+00 + 28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00 + 29 -1.3126000191360652e+00 -3.5962518039484332e+00 2.2746342468737542e+00 +run_vel: |2 + 1 8.1705744056008410e-03 1.6516406187753713e-02 4.7902260502908139e-03 + 2 5.4501493480446257e-03 5.1791699471386279e-03 -1.4372931543219589e-03 + 3 -8.2298292139629907e-03 -1.2926551578421501e-02 -4.0984181828798089e-03 + 4 -3.7699042593486161e-03 -6.5722892102958895e-03 -1.1184640370179276e-03 + 5 -1.1021961009590204e-02 -9.8906780961717233e-03 -2.8410737905369852e-03 + 6 -3.9676663085951309e-02 4.6817061566857068e-02 3.7148491942566329e-02 + 7 9.1033951852932617e-04 -1.0128524455555831e-02 -5.1568251738749744e-02 + 8 7.9064712369741504e-03 -3.3507253833881222e-03 3.4557098411465322e-02 + 9 1.5644176095265211e-03 3.7365546015790240e-03 1.5047408810214647e-02 + 10 2.9201446824498288e-02 -2.9249578719274926e-02 -1.5018077440437252e-02 + 11 -4.7835961513202950e-03 -3.7481385136026442e-03 -2.3464104145202841e-03 + 12 2.2696451649299883e-03 -3.4774139707867511e-04 -3.0640770634198585e-03 + 13 2.7531740448922012e-03 5.8171061616405628e-03 -7.9467454033507268e-04 + 14 3.5246182371318413e-03 -5.7939995610233304e-03 -3.9478431175598936e-03 + 15 -1.8547943625767773e-03 -5.8554729949451450e-03 6.2938485150403805e-03 + 16 1.8681499974849049e-02 -1.3262466206427322e-02 -4.5638651466335660e-02 + 17 -1.2896269979636143e-02 9.7527664949598972e-03 3.7296535338654541e-02 + 18 -6.0962272681994655e-04 -9.4334927125718914e-04 -3.3024598961823318e-04 + 19 -7.0021390249714905e-04 -3.6284472666824417e-03 4.3046363983106377e-03 + 20 4.7767642817960736e-03 5.0780050449126066e-03 1.8215832617012851e-03 + 21 -1.4689220370555326e-03 -2.7352129742343970e-04 7.0581624269895398e-04 + 22 -7.0694199254612818e-03 -4.2577148924944951e-03 2.8079117615170798e-04 + 23 6.0446963117393795e-03 -1.4000131614848197e-03 2.5819754846996860e-03 + 24 2.5421993694892353e-04 4.7852078192859774e-04 -4.7488440981358944e-04 + 25 4.3712608901536965e-03 -4.5408107065939901e-03 2.5413910699840386e-03 + 26 -1.9260272750776959e-03 -3.0565865280005222e-03 3.5275773261268122e-03 + 27 4.5604120293227403e-04 -1.0305523026938358e-03 2.1188058381324488e-04 + 28 -6.2544520861854552e-03 1.4127711176148330e-03 -1.8429821884794308e-03 + 29 6.4110631518142025e-04 3.1273432716735850e-03 3.7253671105046413e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-aveforce_region_variable.yaml b/unittest/force-styles/tests/fix-timestep-aveforce_region_variable.yaml new file mode 100644 index 00000000000..7fd58fa7a37 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-aveforce_region_variable.yaml @@ -0,0 +1,81 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:11:23 2026 +epsilon: 2.5e-11 +skip_tests: +prerequisites: | + atom full + fix aveforce +pre_commands: "" +post_commands: | + region part block EDGE 3.5 EDGE EDGE EDGE EDGE units box + variable zforce delete + variable zforce equal 0.1*step/10.0 + fix move all nve + fix test solvent aveforce 0.0 -0.1 v_zforce region part +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_vector: |- + 3 -2.9140219095886266e-02 -4.2488751605517905e-02 1.1672585090996890e-02 +run_pos: |2 + 1 -2.7045559775815309e-01 2.4912159905743798e+00 -1.6695851809723894e-01 + 2 3.1004029573983960e-01 2.9612354631120801e+00 -8.5466363036982740e-01 + 3 -7.0398551398017450e-01 1.2305509956006202e+00 -6.2777526947498896e-01 + 4 -1.5818159336501605e+00 1.4837407818928610e+00 -1.2538710836066138e+00 + 5 -9.0719763673069476e-01 9.2652103885542658e-01 3.9954210488009939e-01 + 6 2.4831720528675943e-01 2.8313021502627023e-01 -1.2314233331863744e+00 + 7 3.4143527641164195e-01 -2.2646551057486402e-02 -2.5292291414587500e+00 + 8 1.1743552229253478e+00 -4.8863228562414962e-01 -6.3783432914642213e-01 + 9 1.3800524229490667e+00 -2.5274721030822245e-01 2.8353985886546845e-01 + 10 2.0510765220564577e+00 -1.4604063740177942e+00 -9.8323745082472891e-01 + 11 1.7878031944442594e+00 -1.9921863272949925e+00 -1.8890602447627116e+00 + 12 3.0063007039256160e+00 -4.9013350489822050e-01 -1.6231898107526979e+00 + 13 4.0515402959192688e+00 -8.9202011606651299e-01 -1.6400005529925710e+00 + 14 2.6066963345544187e+00 -4.1789253965654471e-01 -2.6634003608795003e+00 + 15 2.9695287185720209e+00 5.5422613165167034e-01 -1.2342022021785142e+00 + 16 2.6747029695235507e+00 -2.4124119054573927e+00 -2.3435746155034631e-02 + 17 2.2153577785291900e+00 -2.0897985187058841e+00 1.1963150794372619e+00 + 18 2.1372601277462215e+00 3.0158450816482971e+00 -3.5167524429174888e+00 + 19 1.5335131088402238e+00 2.6243624595182014e+00 -4.2387133620180517e+00 + 20 2.7736713269818307e+00 3.6935202825080427e+00 -3.9344785866004703e+00 + 21 4.9040128073204583e+00 -4.0752348172957120e+00 -3.6210314709889011e+00 + 22 4.3582355554440833e+00 -4.2126119427287074e+00 -4.4612844196314025e+00 + 23 5.7439382849307599e+00 -3.5821957939275046e+00 -3.8766361295935825e+00 + 24 2.0689202243877762e+00 3.1527848191440873e+00 3.1544653077772007e+00 + 25 1.3085816446235312e+00 3.2664921033568173e+00 2.5143451086588424e+00 + 26 2.5768928207505786e+00 4.0059267822476077e+00 3.2203583017655548e+00 + 27 -1.9611343130357233e+00 -4.3563411931359752e+00 2.1098293115523705e+00 + 28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00 + 29 -1.3126000191360652e+00 -3.5962518039484328e+00 2.2746342468737542e+00 +run_vel: |2 + 1 8.1705744062257075e-03 1.6516406188105612e-02 4.7902260522214553e-03 + 2 5.4501493480646488e-03 5.1791699471446942e-03 -1.4372931541501118e-03 + 3 -8.2298292141556283e-03 -1.2926551578498103e-02 -4.0984181824102392e-03 + 4 -3.7699042593469846e-03 -6.5722892102918059e-03 -1.1184640370065935e-03 + 5 -1.1021961009562318e-02 -9.8906780961487591e-03 -2.8410737905105576e-03 + 6 -3.9676663086308891e-02 4.6817061566320824e-02 3.7148491942932953e-02 + 7 9.1033951875270477e-04 -1.0128524455171662e-02 -5.1568251739021444e-02 + 8 7.9064712368998070e-03 -3.3507253836293576e-03 3.4557098411849417e-02 + 9 1.5644176095375283e-03 3.7365546016272697e-03 1.5047408810251055e-02 + 10 2.9201446824495308e-02 -2.9249578719371772e-02 -1.5018077440373701e-02 + 11 -4.7835961513205336e-03 -3.7481385136027023e-03 -2.3464104145190664e-03 + 12 2.2696451650643613e-03 -3.4774139760314159e-04 -3.0640770632709897e-03 + 13 2.7531740448955219e-03 5.8171061616377898e-03 -7.9467454033302733e-04 + 14 3.5246182371384796e-03 -5.7939995610432719e-03 -3.9478431175530970e-03 + 15 -1.8547943625750653e-03 -5.8554729949528003e-03 6.2938485150723436e-03 + 16 1.8681499974848737e-02 -1.3262466206427440e-02 -4.5638651466319895e-02 + 17 -1.2896269979637453e-02 9.7527664950001706e-03 3.7296535338664505e-02 + 18 -6.0962272688784699e-04 -9.4334927119180513e-04 -3.3338410773634647e-04 + 19 -7.0021390276820479e-04 -3.6284472664214339e-03 4.2921092629196562e-03 + 20 4.7767642815250179e-03 5.0780050451736149e-03 1.8090561263103004e-03 + 21 -1.4689220370555443e-03 -2.7352129742327816e-04 7.0581624269655551e-04 + 22 -7.0694199254613009e-03 -4.2577148924945020e-03 2.8079117615163783e-04 + 23 6.0446963117393908e-03 -1.4000131614848184e-03 2.5819754846996526e-03 + 24 2.5421993688102244e-04 4.7852078199398163e-04 -4.7802252793170273e-04 + 25 4.3712608898826407e-03 -4.5408107063329818e-03 2.5288639345930545e-03 + 26 -1.9260272753487515e-03 -3.0565865277395144e-03 3.5150501907358282e-03 + 27 4.5604120293227636e-04 -1.0305523026938324e-03 2.1188058381324532e-04 + 28 -6.2544520861854561e-03 1.4127711176148317e-03 -1.8429821884794308e-03 + 29 6.4110631518148053e-04 3.1273432716737138e-03 3.7253671105044774e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-efield_dipole_region.yaml b/unittest/force-styles/tests/fix-timestep-efield_dipole_region.yaml new file mode 100644 index 00000000000..10212315470 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-efield_dipole_region.yaml @@ -0,0 +1,111 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:05:58 2026 +epsilon: 2e-13 +skip_tests: +prerequisites: | + atom full + atom dipole + fix efield +pre_commands: "" +post_commands: | + region half block 0 EDGE EDGE EDGE EDGE EDGE + fix move all nve + fix test solute efield 0.0 -0.1 0.1 region half +input_file: in.dipole +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 12.624940121664078 +global_vector: |- + 3 0.0000000000000000e+00 -7.1487701900000000e-01 7.1487701900000000e-01 +run_pos: |2 + 1 -2.7803395650963209e-01 2.4746087580118523e+00 -1.7220791621300566e-01 + 2 3.0862271574316386e-01 2.9608256420926056e+00 -8.5204254816620406e-01 + 3 -6.9730353893847941e-01 1.2462183503669202e+00 -6.2333153766326554e-01 + 4 -1.5803706703988540e+00 1.4864431593933680e+00 -1.2553547711002719e+00 + 5 -9.0224649401880530e-01 9.3189245553299771e-01 4.0097893708816806e-01 + 6 2.9068098260419090e-01 2.3317755393010861e-01 -1.2787854341315494e+00 + 7 3.4003718022218687e-01 -1.1136458543490921e-02 -2.4674043539781270e+00 + 8 1.1653603994073702e+00 -4.8553538245636746e-01 -6.7455699043277184e-01 + 9 1.3798605257891245e+00 -2.5606949147398594e-01 2.7646698442028089e-01 + 10 2.0213511597812350e+00 -1.4294263001051324e+00 -9.6869511230628846e-01 + 11 1.7900398780219073e+00 -1.9910605295844068e+00 -1.8892677004539031e+00 + 12 3.0052519569684688e+00 -4.9050496445328184e-01 -1.6215568178297481e+00 + 13 4.0521826738629381e+00 -8.9321351964942663e-01 -1.6399622114060937e+00 + 14 2.6048704355881824e+00 -4.1699645854738887e-01 -2.6633172811775410e+00 + 15 2.9682789927412943e+00 5.5558820658819119e-01 -1.2357788915285450e+00 + 16 2.6531499373970870e+00 -2.3977947524956038e+00 3.1767580086884059e-02 + 17 2.2316478624956799e+00 -2.1010963925555912e+00 1.1526347069081502e+00 + 18 2.1372510164775966e+00 3.0158506000670466e+00 -3.5167916423912597e+00 + 19 1.5345707099325760e+00 2.6249696297497223e+00 -4.2370263294605710e+00 + 20 2.7732095850735772e+00 3.6929598470822613e+00 -3.9337745509644741e+00 + 21 4.9045170966506779e+00 -4.0748031756039733e+00 -3.6218925414637724e+00 + 22 4.3601484254173615e+00 -4.2118940901718647e+00 -4.4596265759840623e+00 + 23 5.7410255603426821e+00 -3.5837707365543663e+00 -3.8765903698198994e+00 + 24 2.0689205181437256e+00 3.1527432700151756e+00 3.1544823899087220e+00 + 25 1.3065187961786229e+00 3.2665243034421088e+00 2.5127268092210882e+00 + 26 2.5789541569135648e+00 4.0089379439900030e+00 3.2207820820981481e+00 + 27 -1.9618638791883916e+00 -4.3549504053758268e+00 2.1090482240812847e+00 + 28 -2.7443201293863742e+00 -4.0212170735729584e+00 1.5850082667482344e+00 + 29 -1.3141860113747614e+00 -3.5978986954166357e+00 2.2741894687371453e+00 +run_vel: |2 + 1 1.1236198441430616e-03 1.3588711615268997e-03 2.1674807385875472e-05 + 2 3.8967477231198924e-03 4.6153260541769610e-03 1.3005297328774164e-03 + 3 -1.6759088394480200e-03 5.6393536590436779e-04 -6.5559399371328288e-04 + 4 -2.2597632600900447e-03 -3.8076114058230746e-03 -2.5010036756970304e-03 + 5 -6.0397063919675857e-03 -4.5135577258655505e-03 -1.3922605036140998e-03 + 6 -3.1023882580192208e-03 4.6637291343120989e-03 4.6189134000092884e-03 + 7 -5.2419940204427918e-05 -1.2319086468406092e-03 -3.2654613242790020e-03 + 8 8.3601735725068996e-04 -9.5637212626872132e-04 1.8785968904212356e-03 + 9 8.4122760006493746e-04 2.0922433382529080e-04 6.4346601849091592e-03 + 10 2.3678265535364957e-03 -1.5212081023157074e-03 -1.1281854658743531e-03 + 11 -2.5475261615115386e-03 -2.3919533481434065e-03 -2.2311276418186016e-03 + 12 1.1421771336923455e-03 -6.2449989986208354e-04 -1.3944269209125405e-03 + 13 3.3571788228536821e-03 4.5917035556154963e-03 -7.2280548749280489e-04 + 14 1.7062612115012121e-03 -4.9841491672053704e-03 -3.8873699403420589e-03 + 15 -3.0289993105673953e-03 -4.5330921360650835e-03 4.7358760687037605e-03 + 16 1.4739447117810779e-03 -1.5730324097179237e-03 -2.5910350086281119e-03 + 17 1.8178020174927756e-06 8.2471901124551766e-04 2.5861088770279496e-03 + 18 -6.1590009972234590e-04 -9.3553764271618991e-04 -3.7200153140978061e-04 + 19 3.2061425511788877e-04 -3.0287047640653857e-03 5.8636911223575493e-03 + 20 4.1715098782756426e-03 4.3790563537509878e-03 2.5400818877621720e-03 + 21 -9.7312009033477575e-04 1.5100049673511838e-04 -1.5172282348038980e-04 + 22 -5.2572212429860743e-03 -3.5787417430626811e-03 1.8543943930500845e-03 + 23 3.2939362683106128e-03 -2.8836279185067257e-03 2.6255213558360273e-03 + 24 2.5638398657849387e-04 4.3450813156262501e-04 -4.5928187145502893e-04 + 25 2.1619084722745044e-03 -4.4534715376669844e-03 7.6930725231997199e-04 + 26 1.6282501420137243e-04 5.6085644854739122e-05 3.9231484240537639e-03 + 27 -2.4066098679754541e-04 3.1636377958097438e-04 -5.3626843391506079e-04 + 28 -3.4277217399777040e-03 3.7010237059178597e-04 1.5959546005621427e-05 + 29 -8.6242002778626919e-04 1.5767896868742355e-03 3.2980383776092027e-03 +run_torque: |2 + 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 2 1.1164762300859654e+00 1.0884510402842875e+00 1.0884510402842875e+00 + 3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 6 9.8242175844085367e-01 -1.6908759916154248e-01 -1.6908759916154248e-01 + 7 -1.3684609891014952e+00 -8.0606058406150949e-01 -8.0606058406150949e-01 + 8 -1.1874337657028966e+00 -2.6646753617169627e-01 -2.6646753617169627e-01 + 9 -1.0177972619106430e+00 2.1477723017368913e+00 2.1477723017368913e+00 + 10 2.5538853609868983e+00 -1.3797674437477894e+00 -1.3797674437477894e+00 + 11 -1.3439139083704066e+00 1.5074058265158885e+00 1.5074058265158885e+00 + 12 2.9652524051282363e+00 -4.5726725480648156e-01 -4.5726725480648156e-01 + 13 -1.2321028588273288e+00 2.0829614135052950e+00 2.0829614135052950e+00 + 14 -2.3022900866870475e+00 3.4249143995027564e-01 3.4249143995027564e-01 + 15 -2.2389603707876993e-01 -1.0999871400210739e+00 -1.0999871400210739e+00 + 16 9.2419348248650579e-01 2.1428687117582701e+00 2.1428687117582701e+00 + 17 2.7094271617240540e+00 7.2665988123741851e-02 7.2665988123741851e-02 + 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + 29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-efield_region_variable.yaml b/unittest/force-styles/tests/fix-timestep-efield_region_variable.yaml new file mode 100644 index 00000000000..c44af343942 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-efield_region_variable.yaml @@ -0,0 +1,87 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:05:57 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + atom full + fix efield +pre_commands: "" +post_commands: | + region half block 0 EDGE EDGE EDGE EDGE EDGE + variable xefield delete + variable xefield atom 0.01*id + variable zefield delete + variable zefield equal 0.1*step/10.0 + fix move all nve + fix test solute efield v_xefield 0.0 v_zefield region half + fix_modify test virial yes +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +run_stress: |2- + 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +global_scalar: 0 +global_vector: |- + 3 1.9832072139999984e-01 0.0000000000000000e+00 5.7190161519999982e-01 +run_pos: |2 + 1 -2.7045563576442339e-01 2.4912160295145718e+00 -1.6695848815592224e-01 + 2 3.1007011740458190e-01 2.9612353350086877e+00 -8.5462444197055443e-01 + 3 -7.0398528184808640e-01 1.2305508746116089e+00 -6.2777530091331524e-01 + 4 -1.5818159082875174e+00 1.4837407431496006e+00 -1.2538711317473872e+00 + 5 -9.0719764799445601e-01 9.2652105038816057e-01 3.9954210569112109e-01 + 6 2.4836228088647871e-01 2.8313452963131625e-01 -1.2314067030663374e+00 + 7 3.4139170717343681e-01 -2.2646348829081397e-02 -2.5292441445597342e+00 + 8 1.1743090658786286e+00 -4.8863787152484223e-01 -6.3784786205174238e-01 + 9 1.3801857936037114e+00 -2.5274757234864315e-01 2.8357523470860890e-01 + 10 2.0510862456077414e+00 -1.4604047151224160e+00 -9.8323359808072319e-01 + 11 1.7878507578103056e+00 -1.9921865377806263e+00 -1.8890490429475122e+00 + 12 3.0062503969780572e+00 -4.9013346516568868e-01 -1.6232010151470690e+00 + 13 4.0515943377328663e+00 -8.9202007068023448e-01 -1.6399890625833882e+00 + 14 2.6067559693390856e+00 -4.1789212824105143e-01 -2.6633897115147200e+00 + 15 2.9695924960009195e+00 5.5422612436129459e-01 -1.2341911133881371e+00 + 16 2.6748327993030809e+00 -2.4124097782112681e+00 -2.3408501531252252e-02 + 17 2.2152539001982849e+00 -2.0897998154337736e+00 1.1962945275495380e+00 + 18 2.1369701704078405e+00 3.0158507413580424e+00 -3.5179348337192993e+00 + 19 1.5355837136087342e+00 2.6255292355373840e+00 -4.2353987779877471e+00 + 20 2.7727573005678048e+00 3.6923910449609374e+00 -3.9330842459132884e+00 + 21 4.9040128073202558e+00 -4.0752348172958630e+00 -3.6210314709877922e+00 + 22 4.3582355554440957e+00 -4.2126119427287021e+00 -4.4612844196313475e+00 + 23 5.7439382849307314e+00 -3.5821957939275348e+00 -3.8766361295935052e+00 + 24 2.0689243582418686e+00 3.1513346907273165e+00 3.1550389754829271e+00 + 25 1.3045351331491819e+00 3.2665125705842892e+00 2.5111855257433007e+00 + 26 2.5809237402711229e+00 4.0117602605482876e+00 3.2212060529089896e+00 + 27 -1.9611343130334324e+00 -4.3563411931340514e+00 2.1098293115517852e+00 + 28 -2.7473562684513717e+00 -4.0200819932379339e+00 1.5830052163434127e+00 + 29 -1.3126000191362157e+00 -3.5962518039482934e+00 2.2746342468739336e+00 +run_vel: |2 + 1 8.1704137672106367e-03 1.6516434306863788e-02 4.7903952840265039e-03 + 2 5.4802055989833301e-03 5.1790800527858703e-03 -1.3779142170422844e-03 + 3 -8.2293566587687446e-03 -1.2926794170223200e-02 -4.0984772509890582e-03 + 4 -3.7698474482206869e-03 -6.5723733526972233e-03 -1.1185681458976313e-03 + 5 -1.1021987461862615e-02 -9.8906495994846473e-03 -2.8410718476930439e-03 + 6 -3.9635091596927317e-02 4.6824693673040520e-02 3.7172121988106571e-02 + 7 8.6654610523355694e-04 -1.0128065250823394e-02 -5.1590384700978854e-02 + 8 7.8647614575864545e-03 -3.3604578878446653e-03 3.4537921820245780e-02 + 9 1.6966220328858794e-03 3.7354617920165069e-03 1.5098141798355520e-02 + 10 2.9210196434425503e-02 -2.9246939019239152e-02 -1.5011893902668310e-02 + 11 -4.7361476696258786e-03 -3.7486094586300042e-03 -2.3294699412919522e-03 + 12 2.2211368983131902e-03 -3.4765465339078562e-04 -3.0809379100941777e-03 + 13 2.8048475367317845e-03 5.8171753438951111e-03 -7.7718174486785267e-04 + 14 3.5831831101126891e-03 -5.7931443399301362e-03 -3.9321550350820671e-03 + 15 -1.7922896934537554e-03 -5.8555228516116763e-03 6.3105320254945385e-03 + 16 1.8810472846800812e-02 -1.3259019681301441e-02 -4.5597794540456364e-02 + 17 -1.2999797780970452e-02 9.7508305825352668e-03 3.7265621123803390e-02 + 18 -8.0065795588787447e-04 -8.6270474233279175e-04 -1.4483040654251591e-03 + 19 1.2452390836068159e-03 -2.5061097122651720e-03 7.2998631012492869e-03 + 20 3.5930060227632311e-03 3.6938860307024002e-03 3.2322732689580675e-03 + 21 -1.4689220373008322e-03 -2.7352129775991388e-04 7.0581624485379659e-04 + 22 -7.0694199254279135e-03 -4.2577148924855986e-03 2.8079117626977435e-04 + 23 6.0446963116799601e-03 -1.4000131615482861e-03 2.5819754848596965e-03 + 24 3.1926367820268170e-04 -9.9445664694793913e-04 1.4999996971163261e-04 + 25 1.3789754507190493e-04 -4.4335894884361795e-03 -8.1808136736905587e-04 + 26 2.0485904035118839e-03 2.7813358633933076e-03 4.3245727149195381e-03 + 27 4.5604120764724534e-04 -1.0305522987592681e-03 2.1188058256983142e-04 + 28 -6.2544520862288172e-03 1.4127711176123805e-03 -1.8429821884351351e-03 + 29 6.4110631493136821e-04 3.1273432720122125e-03 3.7253671108704476e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-gravity_spherical_variable.yaml b/unittest/force-styles/tests/fix-timestep-gravity_spherical_variable.yaml new file mode 100644 index 00000000000..3d918dedcd5 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-gravity_spherical_variable.yaml @@ -0,0 +1,81 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:06:04 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + fix gravity +pre_commands: "" +post_commands: | + variable gphi delete + variable gphi equal 45.0+5.0*step + variable gtheta delete + variable gtheta equal 30.0+2.0*step + fix move all nve + fix test solute gravity 1.0 spherical v_gphi v_gtheta +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 94.95316210139305 +run_pos: |2 + 1 -2.7021083931096473e-01 2.4916231493036722e+00 -1.6627664206654258e-01 + 2 3.1028505415626456e-01 2.9616426218486636e+00 -8.5398175461061510e-01 + 3 -7.0374075558959326e-01 1.2309581543233516e+00 -6.2709339367487416e-01 + 4 -1.5815711752350194e+00 1.4841479406325013e+00 -1.2531892078556606e+00 + 5 -9.0695287830962013e-01 9.2692819759897171e-01 4.0022398063671355e-01 + 6 2.4856196365717509e-01 2.8353737371333637e-01 -1.2307414574268936e+00 + 7 3.4168003480018150e-01 -2.2239392343931474e-02 -2.5285472657417132e+00 + 8 1.1745999813161851e+00 -4.8822512690878173e-01 -6.3715245334382564e-01 + 9 1.3802971813652070e+00 -2.5234005155908168e-01 2.8422173462485356e-01 + 10 2.0513212804479131e+00 -1.4599992152780452e+00 -9.8255557505819380e-01 + 11 1.7880479528536497e+00 -1.9917791685537400e+00 -1.8883783690119644e+00 + 12 3.0065454623230048e+00 -4.8972634621737532e-01 -1.6225079349853784e+00 + 13 4.0517850543274232e+00 -8.9161295731129964e-01 -1.6393186772345809e+00 + 14 2.6069410929663457e+00 -4.1748538091338838e-01 -2.6627184851296852e+00 + 15 2.9697734769846691e+00 5.5463329039321652e-01 -1.2335203264269661e+00 + 16 2.6749477279141773e+00 -2.4120047467038108e+00 -2.2753870377110765e-02 + 17 2.2156025369473662e+00 -2.0893913599360205e+00 1.1969969551984223e+00 + 18 2.1369701704917277e+00 3.0158507414637050e+00 -3.5179348337047447e+00 + 19 1.5355837136158141e+00 2.6255292355468880e+00 -4.2353987779967843e+00 + 20 2.7727573005704085e+00 3.6923910449633812e+00 -3.9330842459138569e+00 + 21 4.9040128073806901e+00 -4.0752348173451285e+00 -3.6210314710312650e+00 + 22 4.3582355554465302e+00 -4.2126119427316224e+00 -4.4612844196346222e+00 + 23 5.7439382849341198e+00 -3.5821957939288391e+00 -3.8766361295952971e+00 + 24 2.0689243581861176e+00 3.1513346906717099e+00 3.1550389753815047e+00 + 25 1.3045351330835886e+00 3.2665125705491764e+00 2.5111855256329125e+00 + 26 2.5809237402656025e+00 4.0117602605437543e+00 3.2212060529030655e+00 + 27 -1.9611343130455823e+00 -4.3563411931383742e+00 2.1098293115679145e+00 + 28 -2.7473562684517057e+00 -4.0200819932384553e+00 1.5830052163441743e+00 + 29 -1.3126000191350988e+00 -3.5962518039473044e+00 2.2746342468746787e+00 +run_vel: |2 + 1 8.3732085282244295e-03 1.6976704497510185e-02 5.4474267975282509e-03 + 2 5.6527834016552904e-03 5.6394682729685982e-03 -7.8009296733669428e-04 + 3 -8.0271952114887510e-03 -1.2466253280360986e-02 -3.4412179129304195e-03 + 4 -3.5672702062521577e-03 -6.1119908773234841e-03 -4.6126386920256198e-04 + 5 -1.0819326944935091e-02 -9.4303797561668644e-03 -2.1838736112352341e-03 + 6 -3.9474029124142579e-02 4.7277359788963455e-02 3.7805692132236224e-02 + 7 1.1129735208590032e-03 -9.6682261726313366e-03 -5.0911051640110748e-02 + 8 8.1091052421190697e-03 -2.8904270986380809e-03 3.5214298686752910e-02 + 9 1.7670516650654304e-03 4.1968529541783553e-03 1.5704608996025778e-02 + 10 2.9404080828447903e-02 -2.8789280385093454e-02 -1.4360877239685019e-02 + 11 -4.5809621103673299e-03 -3.2878401773809508e-03 -1.6892102470408594e-03 + 12 2.4722791820535306e-03 1.1255682132068278e-04 -2.4068768618838365e-03 + 13 2.9558080836705413e-03 6.2774045265373583e-03 -1.3747435784716873e-04 + 14 3.7272522835012658e-03 -5.3337012210555894e-03 -3.2906429521122856e-03 + 15 -1.6521603146423208e-03 -5.3951746588396304e-03 6.9510486838639772e-03 + 16 1.8884133976810654e-02 -1.2802167844932322e-02 -4.4981451241914265e-02 + 17 -1.2693635919565143e-02 1.0213064890943436e-02 3.7953735528047164e-02 + 18 -8.0065778513846257e-04 -8.6270452589601808e-04 -1.4483040323379022e-03 + 19 1.2452390987332559e-03 -2.5061096928686811e-03 7.2998630845555320e-03 + 20 3.5930060289489419e-03 3.6938860365463644e-03 3.2322732673320900e-03 + 21 -1.4689219105797943e-03 -2.7352140171336763e-04 7.0581615196198342e-04 + 22 -7.0694199203606501e-03 -4.2577148985409770e-03 2.8079116913753825e-04 + 23 6.0446963193352601e-03 -1.4000131639385557e-03 2.5819754807131596e-03 + 24 3.1926356487521455e-04 -9.9445675984022254e-04 1.4999976276373257e-04 + 25 1.3789741090977051e-04 -4.4335895587889742e-03 -8.1808159314985889e-04 + 26 2.0485903913163585e-03 2.7813358528480355e-03 4.3245727026393855e-03 + 27 4.5604118144966467e-04 -1.0305523081208215e-03 2.1188061610969062e-04 + 28 -6.2544520872521436e-03 1.4127711158469535e-03 -1.8429821866396995e-03 + 29 6.4110631693411850e-04 3.1273432737413832e-03 3.7253671125000018e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-gravity_variable.yaml b/unittest/force-styles/tests/fix-timestep-gravity_variable.yaml new file mode 100644 index 00000000000..fee1a4368f8 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-gravity_variable.yaml @@ -0,0 +1,81 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:06:04 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + fix gravity +pre_commands: "" +post_commands: | + variable gmag delete + variable gmag equal 1.0+0.1*step + variable gvert delete + variable gvert equal 24.0+2.0*step + fix move all nve + fix test solute gravity v_gmag chute v_gvert +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: -380.8273064561725 +run_pos: |2 + 1 -2.6993144577102451e-01 2.4912159905703626e+00 -1.6787297030916623e-01 + 2 3.1056444772006420e-01 2.9612354631097455e+00 -8.5557808266918056e-01 + 3 -7.0346136198930087e-01 1.2305509956115193e+00 -6.2868972178549143e-01 + 4 -1.5812917816663283e+00 1.4837407818930888e+00 -1.2547855358972231e+00 + 5 -9.0667348474554932e-01 9.2652103885657422e-01 3.9862765259259147e-01 + 6 2.4884135727152185e-01 2.8313021505371877e-01 -1.2323377855099094e+00 + 7 3.4195942834992982e-01 -2.2646551111778362e-02 -2.5301435937438503e+00 + 8 1.1748793749099584e+00 -4.8863228562210081e-01 -6.3874878144675928e-01 + 9 1.3805765749329895e+00 -2.5274721030734859e-01 2.8262540657752488e-01 + 10 2.0516006740667638e+00 -1.4604063740416966e+00 -9.8415190313678635e-01 + 11 1.7883273464378091e+00 -1.9921863273016649e+00 -1.8899746970575071e+00 + 12 3.0068248559139943e+00 -4.9013350497054381e-01 -1.6241042630472424e+00 + 13 4.0520644479054235e+00 -8.9202011608245013e-01 -1.6409150052893735e+00 + 14 2.6072204865398190e+00 -4.1789253965886702e-01 -2.6643148131701397e+00 + 15 2.9700528705553912e+00 5.5422613165050849e-01 -1.2351166544719623e+00 + 16 2.6752271215468952e+00 -2.4124119054755693e+00 -2.4350198490272732e-02 + 17 2.2158819305389650e+00 -2.0897985186859276e+00 1.1954006271467226e+00 + 18 2.1369701703629631e+00 3.0158507412560676e+00 -3.5179348336174217e+00 + 19 1.5355837136002297e+00 2.6255292355212596e+00 -4.2353987779604285e+00 + 20 2.7727573005626218e+00 3.6923910449540140e+00 -3.9330842459065267e+00 + 21 4.9040128072512790e+00 -4.0752348172083188e+00 -3.6210314709180302e+00 + 22 4.3582355554420094e+00 -4.2126119427245481e+00 -4.4612844196269146e+00 + 23 5.7439382849261067e+00 -3.5821957939240328e+00 -3.8766361295899521e+00 + 24 2.0689243582982968e+00 3.1513346907714248e+00 3.1550389755262502e+00 + 25 1.3045351332044868e+00 3.2665125706118707e+00 2.5111855258007996e+00 + 26 2.5809237402747280e+00 4.0117602605511911e+00 3.2212060529109858e+00 + 27 -1.9611343130813257e+00 -4.3563411931770313e+00 2.1098293115662790e+00 + 28 -2.7473562684534336e+00 -4.0200819932399874e+00 1.5830052163439909e+00 + 29 -1.3126000191421683e+00 -3.5962518039546958e+00 2.2746342468783665e+00 +run_vel: |2 + 1 8.8029032309293615e-03 1.6516406182766650e-02 3.8085420904103609e-03 + 2 6.0824781537851041e-03 5.1791699426282705e-03 -2.4189772972720972e-03 + 3 -7.5975003843375922e-03 -1.2926551554002018e-02 -5.0801023499526038e-03 + 4 -3.1375754454452728e-03 -6.5722892096731047e-03 -2.1001481625537643e-03 + 5 -1.0389632192996941e-02 -9.8906780939053661e-03 -3.8227579098980080e-03 + 6 -3.9044334268891881e-02 4.6817061624595577e-02 3.6166807750816168e-02 + 7 1.5426682398179267e-03 -1.0128524565762707e-02 -5.2549935852251067e-02 + 8 8.5388000538703067e-03 -3.3507253786217201e-03 3.3575414265177052e-02 + 9 2.1967464235368838e-03 3.7365546031529226e-03 1.4065724689876449e-02 + 10 2.9833775695352938e-02 -2.9249578770682655e-02 -1.5999761612323631e-02 + 11 -4.1512673165519150e-03 -3.7481385280872192e-03 -3.3280945492295609e-03 + 12 2.9019739895894659e-03 -3.4774154834369574e-04 -4.0457611961897243e-03 + 13 3.3855028637253086e-03 5.8171061276190272e-03 -1.7763586790578018e-03 + 14 4.1569470545416076e-03 -5.7939995666194608e-03 -4.9295272431380075e-03 + 15 -1.2224655495541520e-03 -5.8554729982228000e-03 5.3121643835938228e-03 + 16 1.9313828873613749e-02 -1.3262466246212593e-02 -4.6620335688335839e-02 + 17 -1.2263941109407511e-02 9.7527665375883674e-03 3.6314851212250969e-02 + 18 -8.0065804739538221e-04 -8.6270495307843610e-04 -1.4483038467178362e-03 + 19 1.2452390654062399e-03 -2.5061097464015320e-03 7.2998631596105056e-03 + 20 3.5930060108566460e-03 3.6938860149757871e-03 3.2322732844320273e-03 + 21 -1.4689221853822385e-03 -2.7352110912747646e-04 7.0581639612556221e-04 + 22 -7.0694199296800434e-03 -4.2577148835953298e-03 2.8079118641038438e-04 + 23 6.0446963013123921e-03 -1.4000131543250526e-03 2.5819754928824933e-03 + 24 3.1926379680234196e-04 -9.9445655519310883e-04 1.5000005787965662e-04 + 25 1.3789766146021440e-04 -4.4335894312062772e-03 -8.1808124847360596e-04 + 26 2.0485904117380129e-03 2.7813358705370294e-03 4.3245727190585059e-03 + 27 4.5604110511293362e-04 -1.0305523908040973e-03 2.1188061408349758e-04 + 28 -6.2544520911812047e-03 1.4127711125986899e-03 -1.8429821871225451e-03 + 29 6.4110630167701530e-04 3.1273432575007793e-03 3.7253671202994304e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-gravity_vector_variable.yaml b/unittest/force-styles/tests/fix-timestep-gravity_vector_variable.yaml new file mode 100644 index 00000000000..e598c6e1f8c --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-gravity_vector_variable.yaml @@ -0,0 +1,83 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:06:04 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + fix gravity +pre_commands: "" +post_commands: | + variable gxdir delete + variable gxdir equal 0.1*step + variable gydir delete + variable gydir equal -1.0 + variable gzdir delete + variable gzdir equal 0.5-0.05*step + fix move all nve + fix test solute gravity 1.0 vector v_gxdir v_gydir v_gzdir +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: -128.62428792076517 +run_pos: |2 + 1 -2.7026163957935190e-01 2.4904667272017686e+00 -1.6668086526882667e-01 + 2 3.1023425392726384e-01 2.9604861996989045e+00 -8.5438597775398917e-01 + 3 -7.0379155585078657e-01 1.2298017321647992e+00 -6.2749761680736982e-01 + 4 -1.5816219754630005e+00 1.4829915184806790e+00 -1.2535934309933754e+00 + 5 -9.0700367854202435e-01 9.2577177544377365e-01 3.9981975749595922e-01 + 6 2.4851116338203899e-01 2.8238095150826015e-01 -1.2311456805087995e+00 + 7 3.4162923465863521e-01 -2.3395814341310685e-02 -2.5289514889161775e+00 + 8 1.1745491810710420e+00 -4.8938154913109494e-01 -6.3755667646072733e-01 + 9 1.3802463811360557e+00 -2.5349647371861572e-01 2.8381751148137102e-01 + 10 2.0512704802467105e+00 -1.4611556374709349e+00 -9.8295979820541690e-01 + 11 1.7879971526357403e+00 -1.9929355907087467e+00 -1.8887825921534720e+00 + 12 3.0064946621609812e+00 -4.9088276849671419e-01 -1.6229121580989834e+00 + 13 4.0517342541102828e+00 -8.9276937948988722e-01 -1.6397229003903342e+00 + 14 2.6068902927454762e+00 -4.1864180307344984e-01 -2.6631227082682392e+00 + 15 2.9697226767590217e+00 5.5347686823837228e-01 -1.2339245495669871e+00 + 16 2.6748969277060120e+00 -2.4131611688685424e+00 -2.3158093543774919e-02 + 17 2.2155517366997848e+00 -2.0905477821150020e+00 1.1965927320569898e+00 + 18 2.1369701704335391e+00 3.0158507414019637e+00 -3.5179348338377663e+00 + 19 1.5355837136131212e+00 2.6255292355498536e+00 -4.2353987780096007e+00 + 20 2.7727573005715658e+00 3.6923910449668940e+00 -3.9330842459193933e+00 + 21 4.9040128072882787e+00 -4.0752348172705268e+00 -3.6210314709461722e+00 + 22 4.3582355554433363e+00 -4.2126119427278095e+00 -4.4612844196290453e+00 + 23 5.7439382849289009e+00 -3.5821957939269899e+00 -3.8766361295915814e+00 + 24 2.0689243582363481e+00 3.1513346907157178e+00 3.1550389754954820e+00 + 25 1.3045351331409833e+00 3.2665125705624680e+00 2.5111855257345970e+00 + 26 2.5809237402710448e+00 4.0117602605473133e+00 3.2212060529095954e+00 + 27 -1.9611343129992806e+00 -4.3563411931152816e+00 2.1098293115355489e+00 + 28 -2.7473562684496260e+00 -4.0200819932367722e+00 1.5830052163427737e+00 + 29 -1.3126000191315375e+00 -3.5962518039444067e+00 2.2746342468698990e+00 +run_vel: |2 + 1 8.4558934038064266e-03 1.5785125802732464e-02 5.0132072270743615e-03 + 2 5.7354683566289569e-03 4.4478894757090139e-03 -1.2143124160495617e-03 + 3 -7.9445103200965050e-03 -1.3657832091940153e-02 -3.8754373412832094e-03 + 4 -3.4845852496811426e-03 -7.3035696786694689e-03 -8.9548330601718390e-04 + 5 -1.0736641997212765e-02 -1.0621958563985913e-02 -2.6180930538422433e-03 + 6 -3.9391344263626164e-02 4.6085780883925162e-02 3.7371472805473815e-02 + 7 1.1956586549553764e-03 -1.0859804653899284e-02 -5.1345271150982863e-02 + 8 8.1917901627937047e-03 -4.0820060439658891e-03 3.4780079289537885e-02 + 9 1.8497366195518268e-03 3.0052741369967243e-03 1.5270389547329984e-02 + 10 2.9486765843313254e-02 -2.9980859273207240e-02 -1.4795096699809794e-02 + 11 -4.4982771317051582e-03 -4.4794189861024156e-03 -2.1234296925066462e-03 + 12 2.5549642744858926e-03 -1.0790222493264996e-03 -2.8410962491842288e-03 + 13 3.0384930634991566e-03 5.0858256685763197e-03 -5.7169383255727428e-04 + 14 3.8099372556674115e-03 -6.5252800405853151e-03 -3.7248623904289719e-03 + 15 -1.5694753527016447e-03 -6.5867534675771331e-03 6.5168292422019608e-03 + 16 1.8966818978192634e-02 -1.3993746673948648e-02 -4.5415670743505734e-02 + 17 -1.2610951000818960e-02 9.0214860343926038e-03 3.7519516081721521e-02 + 18 -8.0065790574307405e-04 -8.6270466171383254e-04 -1.4483042973519667e-03 + 19 1.2452390920191958e-03 -2.5061096877084807e-03 7.2998630576237202e-03 + 20 3.5930060307298893e-03 3.6938860431560937e-03 3.2322732561226074e-03 + 21 -1.4689221073995505e-03 -2.7352123910488789e-04 7.0581633657745531e-04 + 22 -7.0694199269587714e-03 -4.2577148904044603e-03 2.8079118169440682e-04 + 23 6.0446963072533118e-03 -1.4000131603847947e-03 2.5819754893660583e-03 + 24 3.1926366906680003e-04 -9.9445666980649706e-04 1.4999999382210141e-04 + 25 1.3789752951939377e-04 -4.4335895334556901e-03 -8.1808138693651312e-04 + 26 2.0485904032360820e-03 2.7813358611545559e-03 4.3245727159707875e-03 + 27 4.5604127295001374e-04 -1.0305522643637706e-03 2.1188055147110179e-04 + 28 -6.2544520826211475e-03 1.4127711197961640e-03 -1.8429821895204165e-03 + 29 6.4110632435510745e-04 3.1273432799975645e-03 3.7253671031301809e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-heat_variable.yaml b/unittest/force-styles/tests/fix-timestep-heat_variable.yaml new file mode 100644 index 00000000000..13c66ef37bc --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-heat_variable.yaml @@ -0,0 +1,79 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:06:05 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + fix heat +pre_commands: "" +post_commands: | + variable hflux delete + variable hflux equal 1.0+0.1*step + fix move all nve + fix test solute heat 1 v_hflux +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 1.0008594177028076 +run_pos: |2 + 1 -2.7037853578029880e-01 2.4913597711276720e+00 -1.6692460296520228e-01 + 2 3.1014680242110315e-01 2.9613975126099361e+00 -8.5457391011687289e-01 + 3 -7.0408703844672738e-01 1.2304887798176909e+00 -6.2781748828735440e-01 + 4 -1.5818744170433126e+00 1.4836590662685012e+00 -1.2539879758658918e+00 + 5 -9.0731654338723688e-01 9.2646941452655018e-01 3.9952543791442086e-01 + 6 2.4798495696611050e-01 2.8354687148491164e-01 -1.2310389142040272e+00 + 7 3.4143443371778676e-01 -2.2756483761501307e-02 -2.5297030866627499e+00 + 8 1.1744255405761859e+00 -4.8868148963099312e-01 -6.3755514179981132e-01 + 9 1.3800887953585630e+00 -2.5279401801418416e-01 2.8367431619995276e-01 + 10 2.0513113241403036e+00 -1.4606248981336414e+00 -9.8335489439573387e-01 + 11 1.7877523368346930e+00 -1.9922537930236244e+00 -1.8891517000220377e+00 + 12 3.0063399785934819e+00 -4.9015408111569736e-01 -1.6232451175292439e+00 + 13 4.0516643145306528e+00 -8.9188286525096583e-01 -1.6400250727999766e+00 + 14 2.6067123587344834e+00 -4.1804581675351776e-01 -2.6635330509711763e+00 + 15 2.9693913527583482e+00 5.5409666838089733e-01 -1.2340674195520014e+00 + 16 2.6748563678718460e+00 -2.4125404527069656e+00 -2.3798528281830378e-02 + 17 2.2152550398172410e+00 -2.0897035887859952e+00 1.1966658805906678e+00 + 18 2.1369701704232340e+00 3.0158507414057136e+00 -3.5179348337458127e+00 + 19 1.5355837136094979e+00 2.6255292355420798e+00 -4.2353987779909739e+00 + 20 2.7727573005682888e+00 3.6923910449621933e+00 -3.9330842459137347e+00 + 21 4.9040128073022746e+00 -4.0752348172791217e+00 -3.6210314709670905e+00 + 22 4.3582355554436072e+00 -4.2126119427279631e+00 -4.4612844196298784e+00 + 23 5.7439382849295546e+00 -3.5821957939270352e+00 -3.8766361295923648e+00 + 24 2.0689243582370040e+00 3.1513346907221851e+00 3.1550389754725203e+00 + 25 1.3045351331418364e+00 3.2665125705823663e+00 2.5111855257277260e+00 + 26 2.5809237402703693e+00 4.0117602605478631e+00 3.2212060529080668e+00 + 27 -1.9611343130330048e+00 -4.3563411931330949e+00 2.1098293115556577e+00 + 28 -2.7473562684515112e+00 -4.0200819932382270e+00 1.5830052163435819e+00 + 29 -1.3126000191365057e+00 -3.5962518039480842e+00 2.2746342468739678e+00 +run_vel: |2 + 1 8.2374109492943954e-03 1.6643002300374223e-02 4.8220103065341148e-03 + 2 5.5326778623457111e-03 5.2959471076919340e-03 -1.3850959071660556e-03 + 3 -8.3169389807203828e-03 -1.2985315426766042e-02 -4.1289412442911452e-03 + 4 -3.8178842179805946e-03 -6.6418769777091156e-03 -1.1950437414366814e-03 + 5 -1.1129167229961020e-02 -9.9501760407395903e-03 -2.8601369802312353e-03 + 6 -3.9953570135040119e-02 4.7156723322097603e-02 3.7413863881849599e-02 + 7 9.0791719041186157e-04 -1.0210128057799750e-02 -5.1934380332658903e-02 + 8 7.9572294320787006e-03 -3.3850168193729439e-03 3.4801258306383150e-02 + 9 1.5952703154177969e-03 3.7182688965610713e-03 1.5185425117152101e-02 + 10 2.9410746900196297e-02 -2.9447200180698355e-02 -1.5129934080265856e-02 + 11 -4.8288380894808188e-03 -3.8016599176911585e-03 -2.4108264841968307e-03 + 12 2.3008486743191559e-03 -3.6312893579489182e-04 -3.1079752781950046e-03 + 13 2.8381520596389067e-03 5.9204545414640371e-03 -8.1215336210456945e-04 + 14 3.5447567670191661e-03 -5.9050983955785397e-03 -4.0403060744151854e-03 + 15 -1.9482782571778939e-03 -5.9523092584462551e-03 6.3951379622846022e-03 + 16 1.8805490667680481e-02 -1.3364545990879412e-02 -4.5925218245011966e-02 + 17 -1.2978262960652534e-02 9.8264994760409313e-03 3.7571451417310310e-02 + 18 -8.0065792604950040e-04 -8.6270464885811204e-04 -1.4483041172899482e-03 + 19 1.2452390851787599e-03 -2.5061097030255682e-03 7.2998630949859351e-03 + 20 3.5930060241378715e-03 3.6938860336679022e-03 3.2322732676347025e-03 + 21 -1.4689220738640897e-03 -2.7352126397487379e-04 7.0581628688652176e-04 + 22 -7.0694199263641941e-03 -4.2577148910055594e-03 2.8079117943495438e-04 + 23 6.0446963091246525e-03 -1.4000131606871150e-03 2.5819754872712557e-03 + 24 3.1926366846136999e-04 -9.9445665726283455e-04 1.4999994889853852e-04 + 25 1.3789753033545188e-04 -4.4335894922875561e-03 -8.1808139862829499e-04 + 26 2.0485904019146581e-03 2.7813358624113765e-03 4.3245727130624950e-03 + 27 4.5604120824438264e-04 -1.0305522969980706e-03 2.1188059033032348e-04 + 28 -6.2544520867584925e-03 1.4127711163557971e-03 -1.8429821878426210e-03 + 29 6.4110631440882754e-04 3.1273432724712559e-03 3.7253671109469077e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-setforce_region_variable.yaml b/unittest/force-styles/tests/fix-timestep-setforce_region_variable.yaml new file mode 100644 index 00000000000..d1ed632d834 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-setforce_region_variable.yaml @@ -0,0 +1,83 @@ +--- +lammps_version: 2 Sep 2026 +date_generated: Fri Sep 4 18:05:57 2026 +epsilon: 2e-11 +skip_tests: +prerequisites: | + atom full + fix setforce +pre_commands: "" +post_commands: | + region half block 0 EDGE EDGE EDGE EDGE EDGE + variable xforce delete + variable xforce atom 0.01*id + variable zforce delete + variable zforce equal 0.1*step/10.0 + fix move all nve + fix test solute setforce v_xforce NULL v_zforce region half +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_vector: |- + 3 4.5840011600808026e+01 1.5788545415428587e+01 -3.7422169993400438e+01 +run_pos: |2 + 1 -2.7052383198391261e-01 2.4911956624050844e+00 -1.6691069008513398e-01 + 2 3.0740092125806029e-01 2.9613308789464625e+00 -8.4973076516933943e-01 + 3 -7.0368710368832232e-01 1.2303136432967203e+00 -6.2802845136405716e-01 + 4 -1.5818248901801422e+00 1.4837691695904844e+00 -1.2538451004435724e+00 + 5 -9.0713593989787022e-01 9.2644288293711363e-01 3.9952878829385696e-01 + 6 2.9351197955205199e-01 2.9015541252845767e-01 -1.2827160918495246e+00 + 7 3.3998161386675102e-01 -2.6303027800821017e-02 -2.4648543021131757e+00 + 8 1.1649047022377330e+00 -4.8865857282931630e-01 -6.7629397660123991e-01 + 9 1.3802598807051738e+00 -2.5301006173542928e-01 2.7100544850565261e-01 + 10 2.0194355023502029e+00 -1.4622479413303016e+00 -9.6780016852929396e-01 + 11 1.7922614639648604e+00 -1.9922211525783924e+00 -1.8898924616739676e+00 + 12 3.0052033151373383e+00 -4.9025763540059708e-01 -1.6214582548089909e+00 + 13 4.0529054327517242e+00 -8.9202905600699034e-01 -1.6400057359648736e+00 + 14 2.6030677672952232e+00 -4.1792032731962675e-01 -2.6633025654961284e+00 + 15 2.9670025013366832e+00 5.5426028537569183e-01 -1.2373520110302618e+00 + 16 2.6515731403895670e+00 -2.4164579138754521e+00 3.5899296643466388e-02 + 17 2.2323192142152517e+00 -2.0866200871745755e+00 1.1508661141107490e+00 + 18 2.1369701653139717e+00 3.0158507318635750e+00 -3.5179348274027391e+00 + 19 1.5355837133258063e+00 2.6255292347918089e+00 -4.2353987772529722e+00 + 20 2.7727573004081774e+00 3.6923910447389230e+00 -3.9330842457580517e+00 + 21 4.9040128090512463e+00 -4.0752348190243666e+00 -3.6210314733732427e+00 + 22 4.3582355554811061e+00 -4.2126119427992057e+00 -4.4612844197913013e+00 + 23 5.7439382850543401e+00 -3.5821957939727378e+00 -3.8766361297296452e+00 + 24 2.0689243585216381e+00 3.1513346917058622e+00 3.1550389760068378e+00 + 25 1.3045351331869746e+00 3.2665125707585836e+00 2.5111855258705749e+00 + 26 2.5809237402904830e+00 4.0117602605894165e+00 3.2212060529266338e+00 + 27 -1.9611343135792860e+00 -4.3563411936856635e+00 2.1098293111778892e+00 + 28 -2.7473562684451083e+00 -4.0200819932540650e+00 1.5830052163385833e+00 + 29 -1.3126000190080402e+00 -3.5962518039970046e+00 2.2746342468323135e+00 +run_vel: |2 + 1 8.0296962058338910e-03 1.6471414691809509e-02 4.8902040578709090e-03 + 2 2.7171287076256118e-03 5.3760989072348811e-03 3.5889063918105712e-03 + 3 -7.6315744730508974e-03 -1.3398625305305422e-02 -4.5892254976852625e-03 + 4 -3.7829010310341271e-03 -6.5208155204033594e-03 -1.0726426010666775e-03 + 5 -1.0898927066332213e-02 -1.0042394737215530e-02 -2.8686179755602701e-03 + 6 -3.0495977620905384e-04 5.9231943767243410e-02 7.9852988189535858e-04 + 7 -1.0671781237633283e-04 -1.6462064887238802e-02 -7.7008422614923192e-04 + 8 3.9538223972041892e-04 -3.3071780731841051e-03 1.5373612497734929e-04 + 9 1.2663437965243277e-03 3.1936154088629811e-03 1.1201117131372088e-03 + 10 4.5705695874376088e-04 -3.2705948170041070e-02 -2.3057549521760353e-04 + 11 -3.4681027911737491e-04 -3.8207770452697914e-03 -2.9092875657577752e-03 + 12 1.0934439981983132e-03 -5.9875095266764865e-04 -1.2943284138686624e-03 + 13 4.1025980425073577e-03 5.8000746902095446e-03 -7.7489345445261120e-04 + 14 -1.0914222599669207e-04 -5.8512683787859858e-03 -3.9249946949685144e-03 + 15 -4.2988529041749334e-03 -5.7873309614308675e-03 3.2121433267619931e-03 + 16 -8.5568357445082652e-05 -2.0336977965927878e-02 1.4973527359082950e-03 + 17 6.6581313880599222e-04 1.5347623532880805e-02 8.3704622311331378e-04 + 18 -8.0066803753122036e-04 -8.6272348062617907e-04 -1.4482915255361970e-03 + 19 1.2452384895772996e-03 -2.5061112057201758e-03 7.2998645617239665e-03 + 20 3.5930056102354102e-03 3.6938854812220978e-03 3.2322736775679444e-03 + 21 -1.4689186163705857e-03 -2.7352474861350542e-04 7.0581153708904054e-04 + 22 -7.0694198605800469e-03 -4.2577150333538870e-03 2.8079083590091451e-04 + 23 6.0446965740412776e-03 -1.4000132400443953e-03 2.5819752035738373e-03 + 24 3.1926422076422714e-04 -9.9445473576023993e-04 1.5000098167145546e-04 + 25 1.3789762389612942e-04 -4.4335891459402208e-03 -8.1808111755761654e-04 + 26 2.0485904514027150e-03 2.7813359635618842e-03 4.3245727490563660e-03 + 27 4.5604012795182113e-04 -1.0305533872249375e-03 2.1187984768208381e-04 + 28 -6.2544520818679696e-03 1.4127710887174457e-03 -1.8429822035100419e-03 + 29 6.4110655204479379e-04 3.1273431576419259e-03 3.7253670267130860e-03 +... diff --git a/unittest/force-styles/tests/fix-timestep-settorque_atom_region.yaml b/unittest/force-styles/tests/fix-timestep-settorque_atom_region.yaml new file mode 100644 index 00000000000..bbe204b9596 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-settorque_atom_region.yaml @@ -0,0 +1,125 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 18:06:05 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom dipole + atom sphere + fix settorque/atom + fix nve/sphere + fix viscous/sphere +pre_commands: "" +post_commands: | + group sub id 1:16 + region upper block INF INF INF INF 0.0 INF units box + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test sub settorque/atom 5.0 -15.0 NULL region upper +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 -2.0953031546862995e+01 6.2008153642723869e+01 5.4633889090155925e+01 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 5.0000000000000000e+00 -1.5000000000000000e+01 9.7880802757128045e+00 + 2 5.0000000000000000e+00 -1.5000000000000000e+01 2.6390832817214996e+01 + 3 3.3863293710174787e+01 -3.1058132038040185e+01 -1.8646676694663658e+00 + 4 5.0000000000000000e+00 -1.5000000000000000e+01 -3.2592720715375123e+01 + 5 5.0000000000000000e+00 -1.5000000000000000e+01 3.0712048084872546e+01 + 6 -7.1934206611735974e+00 -1.2785915207456656e+01 2.8876878492486968e+00 + 7 5.0000000000000000e+00 -1.5000000000000000e+01 4.0518451947767637e+00 + 8 -1.5813342429576814e+01 -3.3406387854601277e+01 2.2318846858018428e+01 + 9 5.0000000000000000e+00 -1.5000000000000000e+01 2.9136026368350699e+01 + 10 5.0000000000000000e+00 -1.5000000000000000e+01 -6.4850271140076714e+00 + 11 1.9028989178047308e+01 -2.7365967624358333e+01 -1.1231613670049732e+01 + 12 5.0000000000000000e+00 -1.5000000000000000e+01 3.0162234659083904e+01 + 13 5.0000000000000000e+00 -1.5000000000000000e+01 -2.7871924274759586e+01 + 14 5.0000000000000000e+00 -1.5000000000000000e+01 -8.6575062057134016e+00 + 15 1.0344315927890230e+01 -2.4986757471399887e+01 -2.2220217838284317e+01 + 16 -1.3292561017543751e+01 -2.2171126065432730e+01 1.8988283013072007e+01 + 17 -3.6245256163667364e+01 -6.3871111638224605e+00 -1.3495747501256501e+01 + 18 -3.3449264457958030e+01 -5.1211596898529228e+00 -1.6063046301513040e+01 + 19 9.3043983000234061e+00 -2.3735251406356383e+01 2.9944371209876916e+01 + 20 -2.4405251554499323e+01 1.2326350244656219e+01 1.8226255489083119e+01 + 21 5.3118160854329755e-01 -1.7920486666067696e+01 1.6953099712445379e+01 + 22 -3.3557628027146755e+01 1.2249117911837695e+01 -1.7589300363970636e+01 + 23 3.0739609373049564e+01 2.6993712418787631e+01 1.8418986687028031e+01 + 24 5.0644131551068856e+00 -1.1242047487707133e+01 -3.2378841254744543e+01 + 25 1.0202507096633921e+01 2.6024108048890692e+01 1.7811055792779975e+01 + 26 -1.3723409906199922e+01 -1.0575474673847591e+01 8.2690719199617373e+00 + 27 9.4128998826732033e+00 2.2890024767581750e+01 2.4136424334565429e+01 + 28 -1.7910692310779947e+01 -3.3294781390526161e+01 6.7281746292838989e+00 + 29 -7.9733826800536098e+00 3.1114003089361034e+01 2.2326437598377652e+01 + 30 2.3968291735833084e+01 2.8641275713082941e+01 -6.0887858668077675e+00 + 31 5.1720084493622815e+00 -2.1513073667316927e+01 2.3908844737698647e+01 + 32 1.8588536223960755e+01 3.2959381077417568e+01 -1.8718949743780824e+00 +... diff --git a/unittest/force-styles/tests/fix-timestep-settorque_atom_variable.yaml b/unittest/force-styles/tests/fix-timestep-settorque_atom_variable.yaml new file mode 100644 index 00000000000..94388ab1ea2 --- /dev/null +++ b/unittest/force-styles/tests/fix-timestep-settorque_atom_variable.yaml @@ -0,0 +1,130 @@ +--- +lammps_version: 2 Sep 2026 +tags: no_respa +date_generated: Fri Sep 4 18:06:06 2026 +epsilon: 5e-14 +timestep: 5e-04 +skip_tests: +prerequisites: | + atom dipole + atom sphere + fix settorque/atom + fix nve/sphere + fix viscous/sphere +pre_commands: "" +post_commands: | + group sub id 1:16 + variable tqx delete + variable tqx equal 5.0-0.5*step + variable tqy delete + variable tqy equal -15.0+1.0*step + variable tqz delete + variable tqz equal 0.25*step + fix move all nve/sphere + fix damp all viscous/sphere 0.05 + fix test sub settorque/atom v_tqx v_tqy v_tqz +input_file: in.brownian +input_coeffs: coeffs.brownian +natoms: 32 +global_vector: |- + 3 5.9120756462144346e+00 -8.9783463788501095e+01 6.3686624678701676e+01 +run_pos: |2 + 1 -1.2812693018139938e+00 -6.3933922535523768e-01 6.1471220712101982e-01 + 2 -2.3221091292313423e-02 2.4353559739230421e+00 6.9258231598129127e-01 + 3 -7.4243896395796694e-01 -2.2662367781395854e-02 -7.9942491015835127e-01 + 4 1.7659846938724244e+00 8.9448274803012096e-01 5.7131703606529527e-02 + 5 -1.6573368367309294e-01 -9.8561713523982086e-01 7.6722383333496458e-01 + 6 1.2034423633603999e+00 2.6305355674303605e+00 -1.0247433843040346e+00 + 7 1.0827429001846565e+00 -1.9272430270211915e+00 3.7762848946969974e-01 + 8 2.9726847378359844e-02 -1.5224751237986578e+00 -4.8233235241886074e-01 + 9 -7.5879504622619465e-01 1.7789389042061403e+00 7.9565457209825752e-01 + 10 2.5972911381190231e+00 -1.8647553097706866e+00 4.8927509270016450e-01 + 11 -1.4181746438901834e+00 1.7723796697279193e+00 -9.4165345143294044e-01 + 12 -5.5181376600118959e-01 2.4297720711099133e+00 9.6441439769697657e-01 + 13 -2.4888579088002591e-01 1.3572572578729498e+00 2.1660866608935664e-01 + 14 6.2908338213069914e-01 -8.7237051625291040e-01 2.4755252452391147e-01 + 15 -1.3555727666602950e+00 -1.7492646361957256e+00 -5.7081124597073596e-02 + 16 -2.0176539314064192e+00 -1.7289525286766123e+00 -1.1193810464551159e+00 + 17 2.1665627052873138e+00 -2.5002361318722661e+00 1.0068550369153102e+00 + 18 -7.3487656172229521e-01 -1.3974890978183860e+00 -2.4284610616729294e-01 + 19 1.3444539719263757e+00 1.3907405724019242e+00 1.0988683666520744e+00 + 20 1.7387089524909418e+00 2.5247886119980381e+00 4.4339323024689459e-01 + 21 1.1849277481028040e+00 8.1872613730077848e-01 2.1519624039636742e-01 + 22 -8.4121475177762584e-01 1.6806709537743880e+00 7.4408112099244850e-01 + 23 -1.5739390739742474e+00 5.5917153628499139e-03 -9.1569602243855175e-01 + 24 8.1654428638788268e-01 -1.1331006069622402e+00 -7.7245829048347536e-01 + 25 2.3909261298877809e+00 -5.6765613149510641e-01 -6.2710906350768969e-01 + 26 -1.3191138222200498e+00 -2.0140393592704600e+00 5.9375075028601221e-01 + 27 1.3330072908007100e+00 -5.4123329162876321e-01 9.7151828776292271e-01 + 28 8.9848082059038925e-01 1.6985441626621300e+00 9.7075984588388153e-01 + 29 2.6221013061094283e+00 2.2590094763917268e+00 -1.3337171287475211e+00 + 30 -1.0569766125817801e+00 2.4716891841039184e+00 1.2581497036818945e-01 + 31 -1.5868792273525720e+00 -5.8129493061036519e-01 1.4820619137391344e-01 + 32 -2.6825473764676246e+00 -1.2824034741783989e+00 5.5512080502794325e-01 +run_vel: |2 + 1 -5.2467696642998192e+02 2.1542199277006424e+02 -1.1227005568908588e+02 + 2 3.9134167994725419e+02 4.8795776187257601e+01 -6.2313115085072627e+02 + 3 1.0986388293585976e+02 6.6554998750548737e+02 -5.8343714924757887e+02 + 4 3.9848143293874227e+02 -1.1747798197974335e+02 -3.7625882363220865e+02 + 5 5.8453146014244737e+02 1.5982839534760055e+02 -1.9969054648577074e+02 + 6 6.0949755700255776e+02 7.3824395864591463e+02 2.8406966373218285e+02 + 7 -2.7968041606728725e+01 7.5236344093630726e+02 2.2361450405303790e+02 + 8 -4.5111897815654612e+02 -7.5964253365780598e+02 5.4706033814204818e+02 + 9 -5.4531235862640735e+01 -1.1514669625172510e+02 -6.1072797575828486e+02 + 10 7.4862924697896347e+02 7.0186936367923113e+02 -4.9819973989351331e+02 + 11 -1.7494532479742020e+02 1.5340962619436522e+02 3.9081580866666388e+02 + 12 -3.9358450479962613e+02 5.6274940077089116e+02 -5.1224950614934119e+02 + 13 2.9404856760414691e+02 -4.1648035862008169e+02 -6.7895504203504993e+02 + 14 -7.6412873739726172e+02 7.3381694428149990e+02 7.2060303172749877e+02 + 15 -9.1189404262633033e+01 2.2490365048821289e+02 2.8443264880751218e+02 + 16 1.7907740801693492e+02 -5.3544038345381523e+02 -3.1855850921823156e+02 + 17 -4.2820456417324630e+02 -4.9150884735767914e+02 -2.7061751625211969e+02 + 18 3.9507956746934320e+02 3.0616816926327959e+02 -1.3216405710204159e+01 + 19 -2.0364099865894289e+02 -5.4701509197392014e+01 5.8106357220322866e+02 + 20 -1.1592502268264624e+02 -7.6200004369551482e+02 -2.2311679620362929e+02 + 21 6.5874182428899485e+02 5.8671592667184598e+02 -6.2485733833437075e+02 + 22 5.6130364719052189e+01 2.6141167548131494e+02 3.7386530133823459e+02 + 23 -2.5299394908800596e+02 -4.6609490577221976e+02 -6.7084665168914705e+02 + 24 -6.2705981099190205e+02 2.7853716543954556e+02 4.5718418082455213e+02 + 25 -5.4238871745238600e+02 -1.0531239543953356e+02 6.9117030702108195e+01 + 26 -2.1346052521215381e+02 -5.3434496448952325e+02 2.4410991014562211e+02 + 27 5.9521537318514140e+02 6.2654012643225985e+02 -7.3672396441416799e+02 + 28 -4.0055444615195614e+02 6.0663818385510206e+02 1.2166288317511371e+02 + 29 -3.4766241432321169e+02 -3.6579172284005477e+02 -5.4163726170498592e+02 + 30 -1.0498117502101249e+02 5.0013886138471560e+02 7.3143173250820246e+02 + 31 7.5485585842633259e+02 -3.4937336585228245e+01 -7.2609480846882082e+02 + 32 1.4002839515740888e+02 6.4308471099519750e+02 -5.3558932645216328e+02 +run_torque: |2 + 1 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 2 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 3 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 4 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 5 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 6 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 7 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 8 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 9 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 10 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 11 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 12 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 13 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 14 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 15 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 16 1.0000000000000000e+00 -7.0000000000000000e+00 2.0000000000000000e+00 + 17 -3.6245256163667364e+01 -6.3871111638224605e+00 -1.3495747501256501e+01 + 18 -3.3449264457958030e+01 -5.1211596898529228e+00 -1.6063046301513040e+01 + 19 9.3043983000234061e+00 -2.3735251406356383e+01 2.9944371209876916e+01 + 20 -2.4405251554499323e+01 1.2326350244656219e+01 1.8226255489083119e+01 + 21 5.3118160854329755e-01 -1.7920486666067696e+01 1.6953099712445379e+01 + 22 -3.3557628027146755e+01 1.2249117911837695e+01 -1.7589300363970636e+01 + 23 3.0739609373049564e+01 2.6993712418787631e+01 1.8418986687028031e+01 + 24 5.0644131551068856e+00 -1.1242047487707133e+01 -3.2378841254744543e+01 + 25 1.0202507096633921e+01 2.6024108048890692e+01 1.7811055792779975e+01 + 26 -1.3723409906199922e+01 -1.0575474673847591e+01 8.2690719199617373e+00 + 27 9.4128998826732033e+00 2.2890024767581750e+01 2.4136424334565429e+01 + 28 -1.7910692310779947e+01 -3.3294781390526161e+01 6.7281746292838989e+00 + 29 -7.9733826800536098e+00 3.1114003089361034e+01 2.2326437598377652e+01 + 30 2.3968291735833084e+01 2.8641275713082941e+01 -6.0887858668077675e+00 + 31 5.1720084493622815e+00 -2.1513073667316927e+01 2.3908844737698647e+01 + 32 1.8588536223960755e+01 3.2959381077417568e+01 -1.8718949743780824e+00 +... From 6ef464e3603b056adfa904035dd64550b06d6e77 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 18:40:00 +0000 Subject: [PATCH 061/120] test: cover the coulomb table, the tilted box and hybrid sub-style dispatch Four references for option clusters the suite reached only partly. pair born/coul/long was the one style of the seventeen using ncoultablebits whose tabulated coulomb branch was never taken: its fixture pins "pair_modify table 0", so the whole CoulLongTable<1> instantiation was dead code as far as the tests were concerned. The new reference asks for a 16 bit table, which agrees with the analytic one to 1.6e-8 - the expected accuracy of the interpolation - while the Born part is byte identical. The two triclinic references target the two neighbor list builders a tilted box was still missing. A hybrid of sw and lj/cut in a tilted box is the only way to reach the triclinic half-from-full builder, which a hybrid style needs to derive a half list for its sub-styles from the full list of the manybody one; and gran/hooke in a tilted box reaches the triclinic size-aware builder and its stencil and binning helpers. compute temp/profile in a tilted box covers the lamda space conversion of the compute, binned along x rather than z so the tilt actually enters. Straightforward triclinic variants of lj/cut and lj/cut/coul/long were written and then dropped: measured against the whole suite they added no new branch at all, because the plain triclinic half list builders are already covered by the existing npt/deform/rigid tri references. --- .../tests/atomic-pair-gran_hooke_tri.yaml | 105 ++++++++++++ .../tests/compute-temp_profile_triclinic.yaml | 21 +++ .../tests/manybody-pair-hybrid_sw_lj_tri.yaml | 161 ++++++++++++++++++ .../tests/mol-pair-born_coul_table.yaml | 106 ++++++++++++ 4 files changed, 393 insertions(+) create mode 100644 unittest/force-styles/tests/atomic-pair-gran_hooke_tri.yaml create mode 100644 unittest/force-styles/tests/compute-temp_profile_triclinic.yaml create mode 100644 unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml create mode 100644 unittest/force-styles/tests/mol-pair-born_coul_table.yaml diff --git a/unittest/force-styles/tests/atomic-pair-gran_hooke_tri.yaml b/unittest/force-styles/tests/atomic-pair-gran_hooke_tri.yaml new file mode 100644 index 00000000000..1f188d7757c --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-gran_hooke_tri.yaml @@ -0,0 +1,105 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:30:41 2026 +epsilon: 5e-13 +skip_tests: +prerequisites: | + pair gran/hooke + atom sphere +pre_commands: | + atom_modify map array + units lj + atom_style sphere + comm_modify vel yes + lattice fcc 0.8442 + region box block 0 2 0 2 0 2 + create_box 1 box + create_atoms 1 box + displace_atoms all random 0.05 0.05 0.05 623426 + set group all diameter 1.25 + set group all mass 1.0 + velocity all create 3.0 4534624 loop geom +post_commands: | + change_box all triclinic xy final 0.5 xz final -0.4 yz final 0.3 units box +input_file: in.empty +pair_style: gran/hooke 1000.0 350.0 50.0 30.0 0.5 1 limit_damping +pair_coeff: | + * * +extract: "" +natoms: 32 +init_vdwl: 0 +init_coul: 0 +init_stress: |2- + 5.0405594084494696e+03 6.4729309206156377e+03 6.2583451629770661e+03 -3.6970289846277865e+01 6.0491150165041176e+02 -1.5450126465954952e+02 +init_forces: |2 + 1 -1.1980532336835897e+03 -8.2525258466274309e+01 2.7914289684711372e+02 + 2 6.3523801995350652e+01 1.1682045836935263e+03 -2.8656478668131103e+02 + 3 2.7545311592687881e+02 -1.3079351521949707e+02 3.6705760799287765e+02 + 4 2.4392410980110668e+02 2.5790742095428760e+02 1.3712818801550452e+02 + 5 7.7122364446487177e+02 -6.4857742653342575e+02 -4.7857300740432993e+02 + 6 -2.4934356083881710e+01 5.7421106822663006e+00 -1.3849165998677907e+02 + 7 -3.0746770177670851e+02 -2.1033874010687310e+02 5.9782908384081708e+00 + 8 -2.6467726120910226e+02 -3.8742345012836307e+02 2.5006780165886741e+02 + 9 1.4810521230819566e+02 2.7600403513622339e+01 4.1516052903203126e+02 + 10 -2.4005999882427187e+02 2.9315702691735584e+02 -4.1027587252551473e+02 + 11 -4.8631106567639375e+02 -4.2548276832130961e+02 2.0150738920419261e+02 + 12 1.8927571874747969e+02 1.6289742882399941e+02 -3.0135701798668742e+02 + 13 4.0094539063032187e+02 -5.0983824875378798e+02 8.4017659608591742e+01 + 14 1.1380031471177678e+02 1.8878501810714351e+02 -8.5510949703524815e+01 + 15 5.6602153734400315e+02 4.6916540559493268e+02 -2.4265269753190870e+02 + 16 1.0852844778700373e+02 -1.0678870245041198e+02 -1.2117835466514089e+02 + 17 -6.7446054418537460e+02 3.0961114287906463e+02 -1.3676531977708441e+02 + 18 2.4969882382335538e+02 5.3811856579491405e+02 9.2287531975212360e+00 + 19 6.2153104368981724e+02 -5.0433023449895052e+02 4.0109704786002453e+01 + 20 -6.6871641802955040e+01 3.1606642437687464e+02 -1.3537288281399100e+02 + 21 8.1433586094829167e+01 -2.9673900035181214e+02 5.4666699866294812e+02 + 22 4.2931504437630718e+02 -8.8023010417039671e+01 1.3187860368064187e+02 + 23 1.6216331421757280e+02 -2.2135434124629802e+02 7.3620960230371765e+01 + 24 -5.2105210626087023e+02 3.0143793901456843e+02 -1.5415016125950663e+02 + 25 -4.8512527365298240e+02 -2.1199412107392433e+02 8.6851526229184557e+01 + 26 3.6672086961882223e+02 -3.0518282470752542e+01 5.2333601347273361e+02 + 27 -2.9342692390905700e+02 2.4836517755002966e+01 -4.1872749595854702e+02 + 28 7.5949095703389375e+01 -2.4167519854523303e+02 4.8658199785113617e+01 + 29 -3.3218925993024067e+02 -1.8768325202613750e+02 4.6435579158642582e+02 + 30 -9.1369611825007894e+01 1.1052808161947056e+01 -2.2290363152491460e+02 + 31 6.7667766213291458e+01 -9.2344674762502152e+01 -3.4440654617124807e+02 + 32 5.0718141366062312e+01 3.0184742910308694e+02 -1.8783653083804154e+02 +run_vdwl: 0 +run_coul: 0 +run_stress: |2- + 4.9548042988866828e+03 6.4369108027381708e+03 6.2152621289151230e+03 -5.7996396109179841e+01 6.0487100063900857e+02 -1.3330500690586030e+02 +run_forces: |2 + 1 -1.1398088650896252e+03 -7.7243510552980268e+01 2.6300585942754759e+02 + 2 5.1477492091074829e+01 1.1178956672607264e+03 -2.7180041602338065e+02 + 3 2.5942081178159560e+02 -1.2229123199774841e+02 3.4549067983761148e+02 + 4 2.3719790668844439e+02 2.4423783114199378e+02 1.3322314083524822e+02 + 5 7.3913994874677212e+02 -6.1864735569554762e+02 -4.6020632508943692e+02 + 6 -2.7878717214767271e+01 1.4707903996848444e+01 -1.3531194083691520e+02 + 7 -2.9503327146784420e+02 -2.0155438411657340e+02 7.9937169497705440e-01 + 8 -2.5121099430736203e+02 -3.6672013485856263e+02 2.4651240255348802e+02 + 9 1.4418432932575240e+02 2.6668930699339356e+01 4.0412945598205886e+02 + 10 -2.3530977095489118e+02 2.7758888620528109e+02 -3.9474211630880865e+02 + 11 -4.6875904251989664e+02 -4.1085993005908585e+02 1.9330900010013423e+02 + 12 1.8807974499490348e+02 1.6041598302235238e+02 -2.8928254793608664e+02 + 13 3.7994169632995391e+02 -4.8355410070591330e+02 7.5614634778630517e+01 + 14 1.1948211232488023e+02 1.7574127479236782e+02 -9.1140667389841141e+01 + 15 5.5157937975568757e+02 4.5113242079226757e+02 -2.2800382739962356e+02 + 16 1.0337804584907080e+02 -1.1134404439984385e+02 -1.1187791931119506e+02 + 17 -6.3660982841305986e+02 2.9721859906973231e+02 -1.2034749282590634e+02 + 18 2.4405572100963650e+02 5.1747213395095253e+02 1.3146886761158889e+01 + 19 5.9651480876719063e+02 -4.8733957166542507e+02 4.5939940001821697e+01 + 20 -6.7340715754374116e+01 2.9904546820397906e+02 -1.2909509446591551e+02 + 21 7.5455131682558061e+01 -2.8157904930924093e+02 5.3119023006487407e+02 + 22 4.1503894309623729e+02 -8.3782745063720540e+01 1.2726425922869214e+02 + 23 1.5866163174123471e+02 -2.1970530804972981e+02 7.1858243309449165e+01 + 24 -5.0659785243851263e+02 2.9250108312596558e+02 -1.6114255891616187e+02 + 25 -4.7515305153437288e+02 -2.0398827655345480e+02 8.7015965779423169e+01 + 26 3.4679901606245841e+02 -3.1061204195766649e+01 5.0281935505647976e+02 + 27 -2.8690566093725346e+02 4.0370618717484405e+01 -4.0778670377327046e+02 + 28 7.3252229733985828e+01 -2.4322391075318114e+02 4.6311844876739649e+01 + 29 -3.1629678591679675e+02 -1.8736163922068351e+02 4.4320395495011604e+02 + 30 -9.0846670692602061e+01 7.6957908785907492e+00 -2.1382591614016016e+02 + 31 6.4967287136364916e+01 -8.4223244238409663e+01 -3.3279770563403900e+02 + 32 4.9124990123556529e+01 2.9178704957798584e+02 -1.8347399318770948e+02 +... diff --git a/unittest/force-styles/tests/compute-temp_profile_triclinic.yaml b/unittest/force-styles/tests/compute-temp_profile_triclinic.yaml new file mode 100644 index 00000000000..20a0f46d5c9 --- /dev/null +++ b/unittest/force-styles/tests/compute-temp_profile_triclinic.yaml @@ -0,0 +1,21 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:35:24 2026 +epsilon: 1e-08 +timestep: 0.25 +skip_tests: +prerequisites: | + atom full + compute temp/profile +pre_commands: "" +post_commands: | + change_box all triclinic xy final 4.0 xz final -3.0 yz final 2.5 units box + compute test all temp/profile 1 1 1 x 5 +input_file: in.fourmol +input_coeffs: coeffs.fourmol +natoms: 29 +global_scalar: 3848.8532240290137 +global_vector: |- + 6 1.0038697802395330e+02 1.2910315361438484e+02 3.2119948617736986e+02 -8.1783381453473339e+01 -1.0398128752787399e+02 1.3282205863381802e+02 +... diff --git a/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml b/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml new file mode 100644 index 00000000000..08bb0aa6bdf --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml @@ -0,0 +1,161 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:24:31 2026 +epsilon: 1e-10 +skip_tests: +prerequisites: | + pair sw + pair lj/cut +pre_commands: | + variable newton_pair delete + if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on" +post_commands: | + change_box all triclinic xy final 1.0 xz final -0.5 yz final 0.5 remap units box +input_file: in.manybody +pair_style: hybrid sw lj/cut 4.5 +pair_coeff: | + * * sw Si.sw Si Si Si Si Si Si NULL NULL + 1*6 7*8 lj/cut 0.02 2.5 + 7*8 7*8 lj/cut 0.03 2.8 +extract: "" +natoms: 64 +init_vdwl: -115.93525605514166 +init_coul: 0 +init_stress: |2- + 4.6183840925898245e+01 5.9769128272947192e+01 7.2397310447965708e+01 -6.4308300167829017e+01 6.2662742884690445e+01 -4.3927584443128481e+01 +init_forces: |2 + 1 5.8916456791038607e-01 2.3278238191317393e+00 2.8247546393464384e+00 + 2 -2.7542649222189414e-01 -9.3135556144643328e-01 -7.0178265920066374e-01 + 3 9.1158256047720909e-01 -1.5204653490266555e+00 1.7553159458477461e+00 + 4 -7.7021597904124961e-01 7.4744651266092033e-01 1.2072251626441353e+00 + 5 -2.5279269045180053e+00 4.9455750497123463e-01 -1.8996039682723842e+00 + 6 -4.1250105192089859e-01 4.6002299744503938e+00 -7.0112934062731003e-01 + 7 -5.7157182548742158e-01 -9.3796250619958443e-02 -7.6846302601903130e-02 + 8 -8.1452658211962992e-01 8.6476518282268922e-01 -1.5725120196289251e+00 + 9 1.1341570928999960e+00 -2.4687232101824454e+00 -9.0527557667642955e-01 + 10 1.2081165257298541e+00 -2.6491946187258875e+00 -2.5754619461630190e-01 + 11 2.8249813283727576e+00 -4.7868716037482724e+00 4.4153555665233917e+00 + 12 -4.1938316417574990e+00 -2.5160394696200576e+00 -3.8042349876409093e-01 + 13 -1.8815231855444858e+00 6.8788996952567212e+00 -3.5652427684887997e+00 + 14 -3.2124137506402235e+00 5.6486880193063840e+00 -2.3212743985445123e+00 + 15 -3.8076782606987853e+00 4.9193890170306389e+00 -5.9678277925902092e+00 + 16 6.4976910356627637e-01 7.4983557950208768e-01 1.9418909995203590e+00 + 17 2.1824305335445997e+00 6.6048547497349674e-01 -1.3413886814121947e+00 + 18 1.7514862957121826e+00 -1.6604371636141257e-01 4.2145705346709175e+00 + 19 -3.5725679934541155e-01 -2.7756790898406138e+00 1.8807278581019815e+00 + 20 -4.6485333810928617e+00 -1.3683781880091864e-01 2.1777066454047107e+00 + 21 1.2813549890623297e+00 1.7213643719936380e+00 -4.2698561541420075e+00 + 22 -6.5159065417511890e+00 5.5504562162446014e+00 -7.6156123786825249e+00 + 23 -2.9170639381149468e-02 1.1589284432975617e+00 1.3220222539718268e-01 + 24 3.0561890620493004e-01 1.0630590228326511e+00 3.2216192861852355e-01 + 25 2.1719982901739985e+00 -5.1500543424413847e-01 1.7405280378758150e+00 + 26 2.0205106815362051e+00 -6.0144898253725286e-02 1.3364733733920908e+00 + 27 2.1638077011317778e+00 -2.9493067114103044e+00 3.3376504457009672e+00 + 28 1.4775373201390891e+00 -2.0723371223841354e+00 4.8651101641737515e+00 + 29 -4.4459060611926926e+00 2.7620120914814517e+00 -3.7472052443459702e+00 + 30 -2.6476284400488592e+00 2.5020053929352022e+00 -2.6905039328073146e+00 + 31 -1.1537024439970716e+00 9.5586400598060828e-01 -1.3814817462094033e+00 + 32 -2.4172784624994135e+00 1.8712202209179134e+00 -1.8206840480325381e+00 + 33 6.1942637378684466e+00 -4.3636941711210762e+00 6.3655212796721878e+00 + 34 2.3700816447899471e+00 -9.2262229168307952e-02 7.6646169824508370e-01 + 35 1.0689061968093638e+00 -2.4357075192661299e+00 3.5846039649451313e+00 + 36 -8.0634092232286431e-02 -2.9488061068165585e+00 2.6093871204983849e+00 + 37 -2.9166775655620594e+00 3.1184123661673686e+00 -4.2918934991946411e+00 + 38 -1.2941939187839573e+00 1.5984639101151177e-01 -6.0761194619910097e-01 + 39 2.6443673557278807e-01 -6.9423792962615050e-01 -2.3218320205790302e+00 + 40 1.5643616838802410e+00 -1.5251820661257185e+00 -1.6020707663388989e+00 + 41 1.7967220727952344e+00 -7.6252046937237505e-01 3.1713933306568715e-02 + 42 -9.1091552258397357e-01 -9.0331853872353463e-01 -1.8855133355030690e-01 + 43 1.6770434568031516e+00 -5.0193233470246286e+00 3.7125814676998981e+00 + 44 3.1528494108421565e+00 -4.3057281000804828e+00 4.5353827135915985e+00 + 45 -2.9576766833350869e+00 2.9665916212566494e+00 -5.3108708193488363e+00 + 46 -3.0832568647878572e-01 -6.6527581120437973e-01 3.0092190501386731e+00 + 47 3.4120882709907246e-01 8.0264496786173767e-01 -1.6650034802588376e-01 + 48 -5.6108385819285331e-02 5.5252081148992771e-01 -6.4644794817283679e-01 + 49 -1.8981672371556657e-01 -3.8875842487304739e+00 -1.4200689374413178e+00 + 50 3.7430819494668066e-01 1.5350922206518072e+00 7.1488915180588031e-01 + 51 -1.3654700507183937e+00 2.7726854868672074e-01 3.5479088546441306e+00 + 52 3.8609967909414245e+00 -6.2273129475863858e+00 7.5160793466311784e+00 + 53 2.4335588319473880e+00 3.8275829366834393e+00 -3.8259034787401325e-01 + 54 1.9366359400945177e+00 -2.7267436644756726e+00 -3.0979811899554286e+00 + 55 6.6560431455591385e-01 -9.3694783361611222e-01 -2.6079359298966760e+00 + 56 -9.5196967048717418e-01 1.4492819848004779e+00 -2.0800378789336165e+00 + 57 2.2072028031135567e+00 -9.7566963996418765e-01 1.4511609212432458e-01 + 58 3.9524370363905286e+00 -1.6870720409238635e+00 2.2802169746650343e+00 + 59 2.4146569166753089e+00 -5.0472486835016414e-02 3.2247622658104974e-01 + 60 -1.2056048313163330e+00 -4.3576045184826562e+00 1.1315658885395701e+00 + 61 -1.4935895123588143e+00 2.7127765193928157e+00 -2.7423080351848528e+00 + 62 -4.8327689823173632e+00 5.1757569724944785e+00 -4.2026837782483319e+00 + 63 1.1082536104645153e+00 -1.3571891145138624e+00 -1.3555168487085654e+00 + 64 1.1907059669159927e+00 1.5096477520356646e+00 1.8163010429891120e+00 +run_vdwl: -115.95992922954757 +run_coul: 0 +run_stress: |2- + 4.6109282526093907e+01 5.9734302325027869e+01 7.2316695423845459e+01 -6.4139198551900435e+01 6.2465792518647760e+01 -4.3553060811792889e+01 +run_forces: |2 + 1 5.8547458423113086e-01 2.3290297970690856e+00 2.8232176235783308e+00 + 2 -2.8123721142741531e-01 -9.4985102895570006e-01 -7.1070122674804193e-01 + 3 8.9317716304517381e-01 -1.5181355248316848e+00 1.7638789333327967e+00 + 4 -7.5685675048460443e-01 7.5487733464810691e-01 1.1831878108067182e+00 + 5 -2.5430233541150589e+00 4.8732970593905500e-01 -1.8832167078332787e+00 + 6 -3.4887308108355863e-01 4.5956340403277736e+00 -6.6753265734351419e-01 + 7 -5.6630977921057513e-01 -8.2543687090145534e-02 -8.6371078088906442e-02 + 8 -8.2068466413494368e-01 8.6776932699139797e-01 -1.5740503121454412e+00 + 9 1.1069511705040793e+00 -2.4763532785564815e+00 -9.1911022553952215e-01 + 10 1.2033893140565719e+00 -2.6414580373137673e+00 -2.3050798344950260e-01 + 11 2.7880967592411885e+00 -4.7571554675857755e+00 4.3933258381839781e+00 + 12 -4.1964713398300502e+00 -2.5059535224249023e+00 -3.7638596182873613e-01 + 13 -1.8201913432040464e+00 6.8558657240224568e+00 -3.5304172871713040e+00 + 14 -3.2319493768517562e+00 5.6506398207617163e+00 -2.3287717761676920e+00 + 15 -3.7923171662055535e+00 4.8925691432410412e+00 -5.9307156543238619e+00 + 16 6.4541511276764307e-01 7.5149252033295311e-01 1.9350557335546976e+00 + 17 2.1878616811909679e+00 6.6757348839078579e-01 -1.3302278295436363e+00 + 18 1.7213605032636510e+00 -1.3436468496124121e-01 4.2174573796594341e+00 + 19 -3.8436122589347282e-01 -2.7882758511227275e+00 1.8674986231536519e+00 + 20 -4.6315463047613248e+00 -1.5621511760804727e-01 2.1617428601207891e+00 + 21 1.2928070991728244e+00 1.6783679948438952e+00 -4.2921317857227335e+00 + 22 -6.5015403443169806e+00 5.5590876098793682e+00 -7.6229781985310225e+00 + 23 -2.3637162408281315e-02 1.1668312883310967e+00 1.3918656810154695e-01 + 24 3.1425401549734727e-01 1.0557738176251081e+00 3.2470030263252037e-01 + 25 2.1642316335839520e+00 -5.1283226646069058e-01 1.7253087353801018e+00 + 26 2.0118098549138992e+00 -4.5722600948394171e-02 1.3405995608670278e+00 + 27 2.1810250773004434e+00 -2.9637130620921486e+00 3.3485062201425424e+00 + 28 1.4581387156727106e+00 -2.0489313037043808e+00 4.8627196082438680e+00 + 29 -4.4500716278552357e+00 2.7701077455582688e+00 -3.7530696044247094e+00 + 30 -2.6204082247631129e+00 2.4738234104479058e+00 -2.6984633613516777e+00 + 31 -1.1543043198769443e+00 9.5394392064080602e-01 -1.3798776095084542e+00 + 32 -2.3991257710767901e+00 1.8566080086683097e+00 -1.8095729758548644e+00 + 33 6.1683272685151120e+00 -4.3344067647224813e+00 6.3354596455180285e+00 + 34 2.3568885186563282e+00 -9.1036292103454486e-02 7.7947653070926803e-01 + 35 1.0721303116297127e+00 -2.4282465793144756e+00 3.5791711221481659e+00 + 36 -1.1157747314454866e-01 -2.9275557033882107e+00 2.5677835757533414e+00 + 37 -2.8987848114986670e+00 3.0962246443676427e+00 -4.2988144171319904e+00 + 38 -1.2747932908007267e+00 1.6038986923687748e-01 -5.8888125560252713e-01 + 39 2.6243188265897094e-01 -6.8755496604230359e-01 -2.3225482644120210e+00 + 40 1.5871132877164167e+00 -1.5496908755668197e+00 -1.6211814923558820e+00 + 41 1.8112906472427588e+00 -7.3987549916209339e-01 5.8524141825407369e-02 + 42 -9.1198071496398769e-01 -9.1860257230240783e-01 -2.0283714332549724e-01 + 43 1.6628924248083417e+00 -5.0077875493489152e+00 3.6911657870932917e+00 + 44 3.1630576882834847e+00 -4.2987778817451403e+00 4.5279169717742258e+00 + 45 -2.9784469907086732e+00 2.9357295319801668e+00 -5.2917048530739157e+00 + 46 -3.0845328828156460e-01 -6.5967843837816798e-01 3.0289934932011673e+00 + 47 3.4792889284475620e-01 8.0038604248324163e-01 -1.6411905570018334e-01 + 48 -6.0269634336956812e-02 5.6098364265478717e-01 -6.5303205495720029e-01 + 49 -2.3292843963932430e-01 -3.9156900516516604e+00 -1.4529492630333543e+00 + 50 3.7688606950023701e-01 1.5273774629105006e+00 7.0121452057286393e-01 + 51 -1.4101829208184411e+00 3.1775596921938121e-01 3.5534395992567958e+00 + 52 3.8615433978180129e+00 -6.2227362280492375e+00 7.5151819344043265e+00 + 53 2.4834227180841428e+00 3.8506367717788628e+00 -3.1284480485355531e-01 + 54 1.9279132539699970e+00 -2.7292580386797520e+00 -3.0926339129146152e+00 + 55 6.5434953816088270e-01 -9.3023448299666955e-01 -2.5851619882442809e+00 + 56 -9.3539387570961596e-01 1.4273108817703963e+00 -2.0649835546771405e+00 + 57 2.2072145068888513e+00 -9.9424478044176379e-01 1.3680469727058983e-01 + 58 3.9410617148609548e+00 -1.6662823283053798e+00 2.2579574888101708e+00 + 59 2.4226850348796969e+00 -4.1181182544644826e-02 3.1422364988694917e-01 + 60 -1.2502382805233918e+00 -4.3743699423209934e+00 1.0873458437355970e+00 + 61 -1.4833132824733897e+00 2.7222336065819417e+00 -2.7305815080288203e+00 + 62 -4.8207198870521211e+00 5.1606379077729159e+00 -4.1843011516167641e+00 + 63 1.1191025450296856e+00 -1.3720244595391857e+00 -1.3734037721409260e+00 + 64 1.2197595514611839e+00 1.5437490217839982e+00 1.8430359279273780e+00 +... diff --git a/unittest/force-styles/tests/mol-pair-born_coul_table.yaml b/unittest/force-styles/tests/mol-pair-born_coul_table.yaml new file mode 100644 index 00000000000..3f42716205b --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-born_coul_table.yaml @@ -0,0 +1,106 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Fri Sep 4 18:15:19 2026 +epsilon: 5e-12 +skip_tests: gpu +prerequisites: | + atom full + pair born/coul/long + kspace ewald +pre_commands: "" +post_commands: | + pair_modify table 16 + kspace_style ewald 1.0e-6 + kspace_modify gewald 0.3 + kspace_modify compute no +input_file: in.fourmol +pair_style: born/coul/long 8.0 +pair_coeff: | + 1 1 2.51937098847838 0.148356076521964 1.82166848001002 29.0375806150613 141.547923828784 + 1 2 2.87560097202631 0.103769845319212 1.18949647259382 1.7106306969663 4.09225030876458 + 1 3 2.73333746288062 0.169158133709025 2.06291417638668 63.7180294456725 403.51858739517 + 1 4 2.51591531388789 0.166186965980131 2.01659390849669 49.622913109061 303.336540547726 + 1 5 2.51591531388789 0.166186965980131 2.01659390849669 49.622913109061 303.336540547726 + 2 2 1.0594557710255 0.281261664467988 0.314884389172266 0.271080184997071 0.177172207445923 + 2 3 2.12127488295383 0.124576922646243 1.46526793359105 5.10367785279284 17.5662073921955 + 2 4 0.523836115049206 0.140093804714855 0.262040872137659 0.00432916334694855 0.000703093129207124 + 2 5 2.36887234111228 0.121604450909563 1.39946581861656 3.82529730669145 12.548008396489 + 3 3 2.81831917530019 0.189944649028137 2.31041576143228 127.684271782117 1019.38354056979 + 3 4 2.5316180773506 0.186976803503293 2.26748506873271 100.602835334624 778.254162800904 + 3 5 2.5316180773506 0.186976803503293 2.26748506873271 100.602835334624 778.254162800904 + 4 4 2.63841820292211 0.184008285863681 2.19742633928911 79.1465822481912 592.979935420722 + 4 5 2.63841820292211 0.184008285863681 2.19742633928911 79.1465822481912 592.979935420722 + 5 5 2.63841820292211 0.184008285863681 2.19742633928911 79.1465822481912 592.979935420722 +extract: | + cut_coul 0 +natoms: 29 +init_vdwl: 225.0132577500503 +init_coul: 225.82185054968838 +init_stress: |2- + 4.6612527067175290e+02 4.5192049759304649e+02 7.9054313968882650e+02 -1.0129684770153985e+02 3.7655421031361769e+01 1.0478181766237761e+02 +init_forces: |2 + 1 -4.2744121162086213e+00 6.5642053689877798e+01 8.4068008296441562e+01 + 2 4.0209522341969382e+01 3.0391856086066600e+01 -4.8931500434347903e+01 + 3 -3.3540726601327933e+01 -9.0449991492602251e+01 -3.5301559078419395e+01 + 4 -5.4885785197474526e+00 1.4626415038845488e+00 -4.0890599765992821e+00 + 5 -2.2350691953588164e+00 -2.1239945519962933e+00 7.8825541210495320e+00 + 6 -1.3482330186589286e+02 1.4551263305315936e+02 1.3402989798525695e+02 + 7 3.2821834697585421e+00 -4.2934247715165846e+01 -2.4388195652600081e+02 + 8 7.8570441002080189e+00 -8.2133362654334174e+00 6.5769506317059296e+01 + 9 1.9839976972374604e+01 1.3822692372255331e+01 8.2044386357916025e+01 + 10 9.3004047926266324e+01 -1.1568985516678586e+02 -3.3734440084397917e+01 + 11 -2.4562224797202696e+00 -2.9027344193248741e+00 -6.9791138115380535e+00 + 12 1.4141625107723215e+01 5.2480395422671542e+00 -3.4118160808669273e+00 + 13 5.5944697058090718e+00 -2.2564545852787758e+00 -2.8118816892813658e-01 + 14 -3.3931146096000435e+00 8.3034742188741095e-01 -6.1327526325415604e+00 + 15 2.1513223260264772e-01 5.7084751630156996e+00 1.0852109055804653e+00 + 16 7.5247046080281649e+01 -5.8376866634711590e+01 -1.7489363521315107e+02 + 17 -7.2022974251473485e+01 5.4112669590148023e+01 1.8109983822584377e+02 + 18 3.5544929223153998e-01 4.7679029399879633e+00 -7.8535477506115265e+00 + 19 1.9896253794576246e+00 -7.2222152060259381e-01 5.5228413859494907e+00 + 20 -2.9131789923307947e+00 -3.9874686570874189e+00 4.1258393793077239e+00 + 21 -1.6536109838694891e+01 -1.7262814988813130e+01 5.2560362576526551e+01 + 22 -2.7766839818702412e+01 -7.7369162644188281e+00 -4.0489968223404965e+01 + 23 4.3884327335032374e+01 2.5418122664705081e+01 -1.1563354300035030e+01 + 24 9.7879252498172296e+00 -4.7514640623159707e+01 2.6203561626475576e+01 + 25 -3.8118666731346380e+01 3.6915801896271265e+00 -3.1203283552565434e+01 + 26 2.7765722666215794e+01 4.3564021615917525e+01 4.3785217145881026e+00 + 27 9.7332843290364757e+00 -5.1358714752793027e+01 1.9618770976622841e+01 + 28 -4.2804241475953106e+01 1.6023906696639955e+01 -2.8346191402849396e+01 + 29 3.3466054307572577e+01 3.5333315108734013e+01 8.7040673676394231e+00 +run_vdwl: 224.23830525568812 +run_coul: 225.8013740209322 +run_stress: |2- + 4.6605250980474051e+02 4.5140738968127158e+02 7.8583112828153514e+02 -1.0069617378308664e+02 3.7937792451478636e+01 1.0482860880994677e+02 +run_forces: |2 + 1 -4.0613581885162020e+00 6.5516177670309716e+01 8.3581333305618713e+01 + 2 3.9976026224008891e+01 3.0258150289898687e+01 -4.8512323088098810e+01 + 3 -3.3591646827275817e+01 -9.0157756968306231e+01 -3.5206992383128586e+01 + 4 -5.4593244908855567e+00 1.4510013628556544e+00 -4.0785940824888209e+00 + 5 -2.2281671825989915e+00 -2.1153765728305762e+00 7.8585447126476300e+00 + 6 -1.3400719066101934e+02 1.4464619949018990e+02 1.3208521903938373e+02 + 7 3.2934764335947375e+00 -4.2631187931455536e+01 -2.4121630816269021e+02 + 8 7.2264035347357831e+00 -7.5980083635720144e+00 6.5580439511086340e+01 + 9 1.9742691048610745e+01 1.3614189734042945e+01 8.1519642195343479e+01 + 10 9.2962708064311471e+01 -1.1563036103223162e+02 -3.3820313359638760e+01 + 11 -2.4400423160233902e+00 -2.8543146402328849e+00 -6.9013844170900258e+00 + 12 1.4132703313025303e+01 5.2236958019527995e+00 -3.4842617278566506e+00 + 13 5.5693212731407051e+00 -2.2363818969798022e+00 -2.7971436437399544e-01 + 14 -3.3705759009533591e+00 8.1808994421932679e-01 -6.0675079348915517e+00 + 15 2.0412109105967963e-01 5.7164528161834038e+00 1.0979634028757137e+00 + 16 7.4892854059104209e+01 -5.8221977867174040e+01 -1.7407551751591652e+02 + 17 -7.1685129056879973e+01 5.3983975760660933e+01 1.8025811744427989e+02 + 18 3.0344691985774658e-01 4.7181974350798424e+00 -7.8131128337564268e+00 + 19 2.0273520899575388e+00 -6.9321553374525613e-01 5.5378275337615257e+00 + 20 -2.8992310903136613e+00 -3.9663419760767513e+00 4.0721713313655590e+00 + 21 -1.6633730854194020e+01 -1.7203199814885743e+01 5.2562361332852795e+01 + 22 -2.7844836054185766e+01 -7.7953379650779144e+00 -4.0489016725311373e+01 + 23 4.4059846459668371e+01 2.5416343734035159e+01 -1.1566164934410676e+01 + 24 1.0131367102541200e+01 -4.7953608461751706e+01 2.6596956443969667e+01 + 25 -3.8708288642504669e+01 3.7071271607944074e+00 -3.1709074370147196e+01 + 26 2.8012723148040525e+01 4.3989305966572722e+01 4.4933429859110223e+00 + 27 9.8571527353402146e+00 -5.1411301106916561e+01 1.9573051596604497e+01 + 28 -4.2912523216629509e+01 1.6049863381171459e+01 -2.8368160391929262e+01 + 29 3.3449850984983179e+01 3.5359599583269677e+01 8.7714754560281634e+00 +... From c5277f104b66dbe7567e2af72d11e4a8400a1b77 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 20:07:49 +0000 Subject: [PATCH 062/120] KOKKOS: size the per-atom virial of pair mliap by maxvatom The style allocates its own per-atom arrays, because it calls ev_init() with the allocation of the base class turned off, but it sized and compared the per-atom virial against maxeatom. Pair::ev_setup() raises maxeatom only when a per-atom energy is requested, so asking for a per-atom virial alone - what "compute stress/atom" on its own does - left the array unallocated and the first tally dereferenced a null pointer. lmp -sf kk with pair_style mliap and compute stress/atom segfaults in PairMLIAP::v_tally (src/ML-IAP/pair_mliap.cpp:317) Five references crashed on the new per-atom virial test case; they pass now, and the summed per-atom virial matches the global one to the last digit. --- src/KOKKOS/pair_mliap_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/pair_mliap_kokkos.cpp b/src/KOKKOS/pair_mliap_kokkos.cpp index cf8dc7d69a1..3937cf65a10 100644 --- a/src/KOKKOS/pair_mliap_kokkos.cpp +++ b/src/KOKKOS/pair_mliap_kokkos.cpp @@ -97,9 +97,9 @@ void PairMLIAPKokkos::compute(int eflag, int vflag) } if (vflag_atom) { - if ((int)k_vatom.view_host().extent(0) < maxeatom) { + if ((int)k_vatom.view_host().extent(0) < maxvatom) { memoryKK->destroy_kokkos(k_vatom,vatom); - memoryKK->create_kokkos(k_vatom,vatom,maxeatom,6,"pair:eatom"); + memoryKK->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); } else { Kokkos::deep_copy(k_vatom.template view(),0); k_vatom.modify(); From eca27e2ab2ae11aee90d329a6340a636299f50fb Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 20:07:49 +0000 Subject: [PATCH 063/120] unittest: compare the per-atom virial of a style with its global virial No force-style driver ever asked for a per-atom virial. They add "compute pe/atom" but never "compute stress/atom", so vflag_atom was zero in every case of every driver, plain and accelerated alike, and the per-atom virial tally of 208 files of the KOKKOS package was never entered. That is the same blind spot that hid the missing per-atom energy of pair lj/cut/coul/dsf/kk, and it hid a null pointer dereference in pair mliap/kk as well. Add a vatom_only case, and its omp and kokkos twins, to the pair and the four bonded drivers. It needs no new reference data: the sum of the per-atom virial over all atoms has to equal the style's global virial, which is a property of ev_tally() itself. Note that compute stress/atom scales its output by -nktv2p, so the comparison divides that out again. On the pair driver the case honors the nofdotr token as well: for a style whose pair forces are not central the two sides can only be compared when both come from ev_tally(), so it asks for pair_modify nofdotr first. 718 test cases across 511 references now run this comparison. The one skip entry added is for kspace pppm/dipole/spin, which aborts the run outright when a per-atom virial is requested, so the pair style behind it is never reached. --- unittest/force-styles/test_angle_style.cpp | 159 +++++++++++++++++ unittest/force-styles/test_bond_style.cpp | 163 ++++++++++++++++- unittest/force-styles/test_dihedral_style.cpp | 159 +++++++++++++++++ unittest/force-styles/test_improper_style.cpp | 159 +++++++++++++++++ unittest/force-styles/test_pair_style.cpp | 166 ++++++++++++++++++ .../tests/kspace-pppm_dipole_spin.yaml | 2 +- 6 files changed, 805 insertions(+), 3 deletions(-) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index e7c57a47337..653e3580611 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -714,6 +714,165 @@ static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) if (!verbose) ::testing::internal::GetCapturedStdout(); } +/* ---------------------------------------------------------------------- + the per-atom virial of a angle style has to add up to its global + virial. this is a self-consistency check that needs no stored + reference data and it is the only place in this driver where a + per-atom virial is requested at all: without it the "vflag_atom" + branches of the angle styles and of their accelerated variants are + never executed, so a style that computes the global virial correctly + but does not fill (or wrongly fills) its per-atom virial array is + not detected +------------------------------------------------------------------------- */ + +// "compute stress/atom" reports the per-atom virial of the selected +// contributions scaled by -nktv2p, so the sum has to be scaled back to +// the units of Angle::virial before it can be compared with it + +static void vatom_sum(LAMMPS *lmp, double *sum) +{ + auto *vas = lmp->modify->get_compute_by_id("vasum"); + ASSERT_NE(vas, nullptr); + vas->compute_vector(); + const double scale = -1.0 / lmp->force->nktv2p; + for (int k = 0; k < 6; ++k) + sum[k] = scale * vas->vector[k]; +} + +static void vatom_only_test(LAMMPS::argv args, const TestConfig &cfg, double epsilon) +{ + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = nullptr; + try { + lmp = init_lammps(args, cfg, true); + } catch (std::exception &e) { + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); + FAIL() << e.what(); + } + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (!lmp) GTEST_SKIP(); + + // exception safety matters here: leaving the capturer active on a + // throw aborts the whole test program at the next captured section + ::testing::internal::CaptureStdout(); + double sum[6], reference[6]; + for (int k = 0; k < 6; ++k) + sum[k] = reference[k] = 0.0; + try { + lmp->input->one("compute vaonly all stress/atom NULL angle"); + lmp->input->one("compute vasum all reduce sum c_vaonly[1] c_vaonly[2] c_vaonly[3] " + "c_vaonly[4] c_vaonly[5] c_vaonly[6]"); + lmp->input->one("run 0 post no"); + vatom_sum(lmp, sum); + for (int k = 0; k < 6; ++k) + reference[k] = lmp->force->angle->virial[k]; + } catch (std::exception &e) { + std::string errout = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << errout; + cleanup_lammps(lmp, cfg); + FAIL() << e.what(); + } + cleanup_lammps(lmp, cfg); + ::testing::internal::GetCapturedStdout(); + + double scale = 1.0; + for (int k = 0; k < 6; ++k) + if (fabs(reference[k]) > scale) scale = fabs(reference[k]); + + const char *label[6] = {"xx", "yy", "zz", "xy", "xz", "yz"}; + for (int k = 0; k < 6; ++k) + EXPECT_NEAR(sum[k], reference[k], scale * epsilon) + << "sum of the per-atom virial differs from the global virial " + << "for the " << label[k] << " component"; +} + +TEST(AngleStyle, vatom_only) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; + vatom_only_test(args, test_config, 10.0 * test_config.epsilon); +} + +TEST(AngleStyle, vatom_only_omp) +{ + if (!Info::has_package("OPENMP")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (test_config.skip_tests.count("omp")) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; + vatom_only_test(args, test_config, 50.0 * test_config.epsilon); +} + +TEST(AngleStyle, vatom_only_kokkos) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "vatom_only_kokkos_single" skips only single precision builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); + + // a style that cannot be tested with KOKKOS at all cannot have its + // per-atom virial tested with KOKKOS either, so the skip entries of the + // regular KOKKOS test case for the backend in use apply here as well + const bool kk_gpu = Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl"); + const bool kk_threads = Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads"); + std::string base = "kokkos_serial"; + if (kk_gpu) + base = "kokkos_gpu"; + else if (kk_threads) + base = "kokkos_omp"; + if (test_config.skip_tests.count(base)) GTEST_SKIP(); + if (test_config.skip_tests.count(base + "_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(base + "_devicerng")) + GTEST_SKIP(); + // transparently skip when no compatible GPU device is present + if (kk_gpu && !Info::has_kokkos_gpu_device()) + GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list with newton on, as in the regular KOKKOS + // test cases, so the setup matches what the input templates expect + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + if (kk_gpu) + args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "g", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "half", "newton", "on"}; + else if (kk_threads) + args[9] = "4"; + + // relax error a lot for reduced precision KOKKOS builds + double epsilon = 50.0 * test_config.epsilon; + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + vatom_only_test(args, test_config, epsilon); +} + TEST(AngleStyle, kokkos_omp) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index f3e921f6f84..7e4db4cf92e 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -463,7 +463,7 @@ TEST(BondStyle, omp) if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; + "-pk", "omp", "4", "-sf", "omp"}; ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; @@ -696,6 +696,165 @@ static void run_kokkos_test(LAMMPS::argv &args) if (!verbose) ::testing::internal::GetCapturedStdout(); } +/* ---------------------------------------------------------------------- + the per-atom virial of a bond style has to add up to its global + virial. this is a self-consistency check that needs no stored + reference data and it is the only place in this driver where a + per-atom virial is requested at all: without it the "vflag_atom" + branches of the bond styles and of their accelerated variants are + never executed, so a style that computes the global virial correctly + but does not fill (or wrongly fills) its per-atom virial array is + not detected +------------------------------------------------------------------------- */ + +// "compute stress/atom" reports the per-atom virial of the selected +// contributions scaled by -nktv2p, so the sum has to be scaled back to +// the units of Bond::virial before it can be compared with it + +static void vatom_sum(LAMMPS *lmp, double *sum) +{ + auto *vas = lmp->modify->get_compute_by_id("vasum"); + ASSERT_NE(vas, nullptr); + vas->compute_vector(); + const double scale = -1.0 / lmp->force->nktv2p; + for (int k = 0; k < 6; ++k) + sum[k] = scale * vas->vector[k]; +} + +static void vatom_only_test(LAMMPS::argv args, const TestConfig &cfg, double epsilon) +{ + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = nullptr; + try { + lmp = init_lammps(args, cfg, true); + } catch (std::exception &e) { + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); + FAIL() << e.what(); + } + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (!lmp) GTEST_SKIP(); + + // exception safety matters here: leaving the capturer active on a + // throw aborts the whole test program at the next captured section + ::testing::internal::CaptureStdout(); + double sum[6], reference[6]; + for (int k = 0; k < 6; ++k) + sum[k] = reference[k] = 0.0; + try { + lmp->input->one("compute vaonly all stress/atom NULL bond"); + lmp->input->one("compute vasum all reduce sum c_vaonly[1] c_vaonly[2] c_vaonly[3] " + "c_vaonly[4] c_vaonly[5] c_vaonly[6]"); + lmp->input->one("run 0 post no"); + vatom_sum(lmp, sum); + for (int k = 0; k < 6; ++k) + reference[k] = lmp->force->bond->virial[k]; + } catch (std::exception &e) { + std::string errout = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << errout; + cleanup_lammps(lmp, cfg); + FAIL() << e.what(); + } + cleanup_lammps(lmp, cfg); + ::testing::internal::GetCapturedStdout(); + + double scale = 1.0; + for (int k = 0; k < 6; ++k) + if (fabs(reference[k]) > scale) scale = fabs(reference[k]); + + const char *label[6] = {"xx", "yy", "zz", "xy", "xz", "yz"}; + for (int k = 0; k < 6; ++k) + EXPECT_NEAR(sum[k], reference[k], scale * epsilon) + << "sum of the per-atom virial differs from the global virial " + << "for the " << label[k] << " component"; +} + +TEST(BondStyle, vatom_only) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; + vatom_only_test(args, test_config, 10.0 * test_config.epsilon); +} + +TEST(BondStyle, vatom_only_omp) +{ + if (!Info::has_package("OPENMP")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (test_config.skip_tests.count("omp")) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; + vatom_only_test(args, test_config, 50.0 * test_config.epsilon); +} + +TEST(BondStyle, vatom_only_kokkos) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "vatom_only_kokkos_single" skips only single precision builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); + + // a style that cannot be tested with KOKKOS at all cannot have its + // per-atom virial tested with KOKKOS either, so the skip entries of the + // regular KOKKOS test case for the backend in use apply here as well + const bool kk_gpu = Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl"); + const bool kk_threads = Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads"); + std::string base = "kokkos_serial"; + if (kk_gpu) + base = "kokkos_gpu"; + else if (kk_threads) + base = "kokkos_omp"; + if (test_config.skip_tests.count(base)) GTEST_SKIP(); + if (test_config.skip_tests.count(base + "_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(base + "_devicerng")) + GTEST_SKIP(); + // transparently skip when no compatible GPU device is present + if (kk_gpu && !Info::has_kokkos_gpu_device()) + GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list with newton on, as in the regular KOKKOS + // test cases, so the setup matches what the input templates expect + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + if (kk_gpu) + args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "g", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "half", "newton", "on"}; + else if (kk_threads) + args[9] = "4"; + + // relax error a lot for reduced precision KOKKOS builds + double epsilon = 50.0 * test_config.epsilon; + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + vatom_only_test(args, test_config, epsilon); +} + TEST(BondStyle, kokkos_omp) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); @@ -798,7 +957,7 @@ TEST(BondStyle, kokkos_serial) GTEST_SKIP() << "Cannot test KOKKOS/Serial with GPU support enabled"; LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "1", "-sf", "kk"}; + "-k", "on", "t", "1", "-sf", "kk"}; run_kokkos_test(args); }; diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 07930febcf7..8dc7a106016 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -715,6 +715,165 @@ static void run_kokkos_test(LAMMPS::argv &args) if (!verbose) ::testing::internal::GetCapturedStdout(); } +/* ---------------------------------------------------------------------- + the per-atom virial of a dihedral style has to add up to its global + virial. this is a self-consistency check that needs no stored + reference data and it is the only place in this driver where a + per-atom virial is requested at all: without it the "vflag_atom" + branches of the dihedral styles and of their accelerated variants are + never executed, so a style that computes the global virial correctly + but does not fill (or wrongly fills) its per-atom virial array is + not detected +------------------------------------------------------------------------- */ + +// "compute stress/atom" reports the per-atom virial of the selected +// contributions scaled by -nktv2p, so the sum has to be scaled back to +// the units of Dihedral::virial before it can be compared with it + +static void vatom_sum(LAMMPS *lmp, double *sum) +{ + auto *vas = lmp->modify->get_compute_by_id("vasum"); + ASSERT_NE(vas, nullptr); + vas->compute_vector(); + const double scale = -1.0 / lmp->force->nktv2p; + for (int k = 0; k < 6; ++k) + sum[k] = scale * vas->vector[k]; +} + +static void vatom_only_test(LAMMPS::argv args, const TestConfig &cfg, double epsilon) +{ + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = nullptr; + try { + lmp = init_lammps(args, cfg, true); + } catch (std::exception &e) { + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); + FAIL() << e.what(); + } + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (!lmp) GTEST_SKIP(); + + // exception safety matters here: leaving the capturer active on a + // throw aborts the whole test program at the next captured section + ::testing::internal::CaptureStdout(); + double sum[6], reference[6]; + for (int k = 0; k < 6; ++k) + sum[k] = reference[k] = 0.0; + try { + lmp->input->one("compute vaonly all stress/atom NULL dihedral"); + lmp->input->one("compute vasum all reduce sum c_vaonly[1] c_vaonly[2] c_vaonly[3] " + "c_vaonly[4] c_vaonly[5] c_vaonly[6]"); + lmp->input->one("run 0 post no"); + vatom_sum(lmp, sum); + for (int k = 0; k < 6; ++k) + reference[k] = lmp->force->dihedral->virial[k]; + } catch (std::exception &e) { + std::string errout = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << errout; + cleanup_lammps(lmp, cfg); + FAIL() << e.what(); + } + cleanup_lammps(lmp, cfg); + ::testing::internal::GetCapturedStdout(); + + double scale = 1.0; + for (int k = 0; k < 6; ++k) + if (fabs(reference[k]) > scale) scale = fabs(reference[k]); + + const char *label[6] = {"xx", "yy", "zz", "xy", "xz", "yz"}; + for (int k = 0; k < 6; ++k) + EXPECT_NEAR(sum[k], reference[k], scale * epsilon) + << "sum of the per-atom virial differs from the global virial " + << "for the " << label[k] << " component"; +} + +TEST(DihedralStyle, vatom_only) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"}; + vatom_only_test(args, test_config, 10.0 * test_config.epsilon); +} + +TEST(DihedralStyle, vatom_only_omp) +{ + if (!Info::has_package("OPENMP")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (test_config.skip_tests.count("omp")) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; + vatom_only_test(args, test_config, 50.0 * test_config.epsilon); +} + +TEST(DihedralStyle, vatom_only_kokkos) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "vatom_only_kokkos_single" skips only single precision builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); + + // a style that cannot be tested with KOKKOS at all cannot have its + // per-atom virial tested with KOKKOS either, so the skip entries of the + // regular KOKKOS test case for the backend in use apply here as well + const bool kk_gpu = Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl"); + const bool kk_threads = Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads"); + std::string base = "kokkos_serial"; + if (kk_gpu) + base = "kokkos_gpu"; + else if (kk_threads) + base = "kokkos_omp"; + if (test_config.skip_tests.count(base)) GTEST_SKIP(); + if (test_config.skip_tests.count(base + "_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(base + "_devicerng")) + GTEST_SKIP(); + // transparently skip when no compatible GPU device is present + if (kk_gpu && !Info::has_kokkos_gpu_device()) + GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list with newton on, as in the regular KOKKOS + // test cases, so the setup matches what the input templates expect + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + if (kk_gpu) + args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "g", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "half", "newton", "on"}; + else if (kk_threads) + args[9] = "4"; + + // relax error a lot for reduced precision KOKKOS builds + double epsilon = 50.0 * test_config.epsilon; + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + vatom_only_test(args, test_config, epsilon); +} + TEST(DihedralStyle, kokkos_omp) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 2d02fda4a82..442978e3a7b 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -687,6 +687,165 @@ static void run_kokkos_test(LAMMPS::argv &args) if (!verbose) ::testing::internal::GetCapturedStdout(); } +/* ---------------------------------------------------------------------- + the per-atom virial of a improper style has to add up to its global + virial. this is a self-consistency check that needs no stored + reference data and it is the only place in this driver where a + per-atom virial is requested at all: without it the "vflag_atom" + branches of the improper styles and of their accelerated variants are + never executed, so a style that computes the global virial correctly + but does not fill (or wrongly fills) its per-atom virial array is + not detected +------------------------------------------------------------------------- */ + +// "compute stress/atom" reports the per-atom virial of the selected +// contributions scaled by -nktv2p, so the sum has to be scaled back to +// the units of Improper::virial before it can be compared with it + +static void vatom_sum(LAMMPS *lmp, double *sum) +{ + auto *vas = lmp->modify->get_compute_by_id("vasum"); + ASSERT_NE(vas, nullptr); + vas->compute_vector(); + const double scale = -1.0 / lmp->force->nktv2p; + for (int k = 0; k < 6; ++k) + sum[k] = scale * vas->vector[k]; +} + +static void vatom_only_test(LAMMPS::argv args, const TestConfig &cfg, double epsilon) +{ + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = nullptr; + try { + lmp = init_lammps(args, cfg, true); + } catch (std::exception &e) { + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); + FAIL() << e.what(); + } + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (!lmp) GTEST_SKIP(); + + // exception safety matters here: leaving the capturer active on a + // throw aborts the whole test program at the next captured section + ::testing::internal::CaptureStdout(); + double sum[6], reference[6]; + for (int k = 0; k < 6; ++k) + sum[k] = reference[k] = 0.0; + try { + lmp->input->one("compute vaonly all stress/atom NULL improper"); + lmp->input->one("compute vasum all reduce sum c_vaonly[1] c_vaonly[2] c_vaonly[3] " + "c_vaonly[4] c_vaonly[5] c_vaonly[6]"); + lmp->input->one("run 0 post no"); + vatom_sum(lmp, sum); + for (int k = 0; k < 6; ++k) + reference[k] = lmp->force->improper->virial[k]; + } catch (std::exception &e) { + std::string errout = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << errout; + cleanup_lammps(lmp, cfg); + FAIL() << e.what(); + } + cleanup_lammps(lmp, cfg); + ::testing::internal::GetCapturedStdout(); + + double scale = 1.0; + for (int k = 0; k < 6; ++k) + if (fabs(reference[k]) > scale) scale = fabs(reference[k]); + + const char *label[6] = {"xx", "yy", "zz", "xy", "xz", "yz"}; + for (int k = 0; k < 6; ++k) + EXPECT_NEAR(sum[k], reference[k], scale * epsilon) + << "sum of the per-atom virial differs from the global virial " + << "for the " << label[k] << " component"; +} + +TEST(ImproperStyle, vatom_only) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"}; + vatom_only_test(args, test_config, 10.0 * test_config.epsilon); +} + +TEST(ImproperStyle, vatom_only_omp) +{ + if (!Info::has_package("OPENMP")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (test_config.skip_tests.count("omp")) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; + vatom_only_test(args, test_config, 50.0 * test_config.epsilon); +} + +TEST(ImproperStyle, vatom_only_kokkos) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "vatom_only_kokkos_single" skips only single precision builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); + + // a style that cannot be tested with KOKKOS at all cannot have its + // per-atom virial tested with KOKKOS either, so the skip entries of the + // regular KOKKOS test case for the backend in use apply here as well + const bool kk_gpu = Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl"); + const bool kk_threads = Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads"); + std::string base = "kokkos_serial"; + if (kk_gpu) + base = "kokkos_gpu"; + else if (kk_threads) + base = "kokkos_omp"; + if (test_config.skip_tests.count(base)) GTEST_SKIP(); + if (test_config.skip_tests.count(base + "_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(base + "_devicerng")) + GTEST_SKIP(); + // transparently skip when no compatible GPU device is present + if (kk_gpu && !Info::has_kokkos_gpu_device()) + GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list with newton on, as in the regular KOKKOS + // test cases, so the setup matches what the input templates expect + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + if (kk_gpu) + args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "g", "1", "-sf", "kk", + "-pk", "kokkos", "neigh", "half", "newton", "on"}; + else if (kk_threads) + args[9] = "4"; + + // relax error a lot for reduced precision KOKKOS builds + double epsilon = 50.0 * test_config.epsilon; + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + vatom_only_test(args, test_config, epsilon); +} + TEST(ImproperStyle, kokkos_omp) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index b8d3b27e1dd..3f1df0bc647 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -1000,6 +1000,172 @@ TEST(PairStyle, eatom_only_omp) eatom_only_test(args, test_config); } +/* ---------------------------------------------------------------------- + the per-atom virial of a pair style has to add up to its global + virial. this is a self-consistency check that needs no stored + reference data and it is the only place in this driver where a + per-atom virial is requested at all: without it the "vflag_atom" + branches of the pair styles and of their accelerated variants are + never executed, so a style that computes the global virial correctly + but does not fill (or wrongly fills) its per-atom virial array is + not detected +------------------------------------------------------------------------- */ + +// "compute stress/atom" reports the per-atom virial of the selected +// contributions scaled by -nktv2p, so the sum has to be scaled back to +// the units of Pair::virial before it can be compared with it + +static void vatom_sum(LAMMPS *lmp, double *sum) +{ + auto *vas = lmp->modify->get_compute_by_id("vasum"); + ASSERT_NE(vas, nullptr); + vas->compute_vector(); + const double scale = -1.0 / lmp->force->nktv2p; + for (int k = 0; k < 6; ++k) + sum[k] = scale * vas->vector[k]; +} + +static void vatom_only_test(LAMMPS::argv args, const TestConfig &cfg, double epsilon) +{ + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = nullptr; + try { + lmp = init_lammps(args, cfg, true); + } catch (std::exception &e) { + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (full_neigh_unsupported(e.what())) GTEST_SKIP() << e.what(); + FAIL() << e.what(); + } + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (!lmp) GTEST_SKIP(); + + // exception safety matters here: leaving the capturer active on a + // throw aborts the whole test program at the next captured section + ::testing::internal::CaptureStdout(); + double sum[6], reference[6]; + for (int k = 0; k < 6; ++k) + sum[k] = reference[k] = 0.0; + try { + // the "nofdotr" token in skip_tests marks styles whose global virial + // from ev_tally() differs from the fdotr one, because they have force + // contributions that are not tallied (random or dissipative forces). + // for those the per-atom virial can only be compared with the global + // virial that ev_tally() accumulates, so request that one here + if (cfg.skip_tests.count("nofdotr")) lmp->input->one("pair_modify nofdotr"); + lmp->input->one("compute vaonly all stress/atom NULL pair"); + lmp->input->one("compute vasum all reduce sum c_vaonly[1] c_vaonly[2] c_vaonly[3] " + "c_vaonly[4] c_vaonly[5] c_vaonly[6]"); + lmp->input->one("run 0 post no"); + vatom_sum(lmp, sum); + for (int k = 0; k < 6; ++k) + reference[k] = lmp->force->pair->virial[k]; + } catch (std::exception &e) { + std::string errout = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << errout; + cleanup_lammps(lmp, cfg); + FAIL() << e.what(); + } + cleanup_lammps(lmp, cfg); + ::testing::internal::GetCapturedStdout(); + + double scale = 1.0; + for (int k = 0; k < 6; ++k) + if (fabs(reference[k]) > scale) scale = fabs(reference[k]); + + const char *label[6] = {"xx", "yy", "zz", "xy", "xz", "yz"}; + for (int k = 0; k < 6; ++k) + EXPECT_NEAR(sum[k], reference[k], scale * epsilon) + << "sum of the per-atom virial differs from the global virial " + << "for the " << label[k] << " component"; +} + +TEST(PairStyle, vatom_only) +{ + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; + vatom_only_test(args, test_config, 10.0 * test_config.epsilon); +} + +TEST(PairStyle, vatom_only_omp) +{ + if (!Info::has_package("OPENMP")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (test_config.skip_tests.count("omp")) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; + if (test_config.has_tag("single_thread")) args[8] = "1"; + vatom_only_test(args, test_config, 50.0 * test_config.epsilon); +} + +TEST(PairStyle, vatom_only_kokkos) +{ + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + // a style that cannot tally a per-atom virial at all cannot do so with + // an accelerated variant either, so the plain "vatom_only" skip entries + // apply to this test case as well + if (test_config.skip_tests.count("vatom_only")) GTEST_SKIP(); + // skip entries may also be qualified by the KOKKOS package precision, + // e.g. "vatom_only_kokkos_single" skips only single precision builds + if (test_config.skip_tests.count(std::string(test_info_->name()) + "_" + kokkos_precision())) + GTEST_SKIP(); + // skip entries qualified with "_devicerng" apply only to builds where the + // KOKKOS styles use the device random number generator + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(std::string(test_info_->name()) + "_devicerng")) + GTEST_SKIP(); + + // a style that cannot be tested with KOKKOS at all cannot have its + // per-atom virial tested with KOKKOS either, so the skip entries of the + // regular KOKKOS test case for the backend in use apply here as well + const bool kk_gpu = Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl"); + const bool kk_threads = Info::has_accelerator_feature("KOKKOS", "api", "openmp") || + Info::has_accelerator_feature("KOKKOS", "api", "pthreads"); + std::string base = "kokkos_serial"; + if (kk_gpu) + base = "kokkos_gpu"; + else if (kk_threads) + base = "kokkos_omp"; + if (test_config.skip_tests.count(base)) GTEST_SKIP(); + if (test_config.skip_tests.count(base + "_" + kokkos_precision())) GTEST_SKIP(); + if (Info::has_accelerator_feature("KOKKOS", "rng", "device") && + test_config.skip_tests.count(base + "_devicerng")) + GTEST_SKIP(); + // transparently skip when no compatible GPU device is present + if (kk_gpu && !Info::has_kokkos_gpu_device()) + GTEST_SKIP() << "No compatible GPU device available"; + + // use a half neighbor list with newton on, as in the regular KOKKOS + // test cases, so the setup matches what the input templates expect + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "1", "-sf", "kk"}; + if (kk_gpu) + args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-k", + "on", "g", "1", "-sf", "kk", "-pk", "kokkos", + "neigh", "half", "newton", "on"}; + else if (kk_threads && !test_config.has_tag("single_thread")) + args[9] = "4"; + + // relax error a lot for reduced precision KOKKOS builds + double epsilon = 50.0 * test_config.epsilon; + const std::string kk_precision = kokkos_precision(); + if (kk_precision == "mixed") + epsilon *= 2.0e9; + else if (kk_precision == "single") + epsilon *= 1.0e10; + vatom_only_test(args, test_config, epsilon); +} + TEST(PairStyle, kokkos_omp) { if (!Info::has_package("KOKKOS")) GTEST_SKIP(); diff --git a/unittest/force-styles/tests/kspace-pppm_dipole_spin.yaml b/unittest/force-styles/tests/kspace-pppm_dipole_spin.yaml index 47f959b128c..cadd57b47c2 100644 --- a/unittest/force-styles/tests/kspace-pppm_dipole_spin.yaml +++ b/unittest/force-styles/tests/kspace-pppm_dipole_spin.yaml @@ -3,7 +3,7 @@ lammps_version: 4 Jul 2026 tags: spin unstable date_generated: Fri Jul 10 16:53:00 2026 epsilon: 5e-13 -skip_tests: +skip_tests: vatom_only prerequisites: | atom spin pair spin/dipole/long From 5de515774f71581a60853fb8698dd997e749eba0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 4 Sep 2026 22:10:24 +0000 Subject: [PATCH 064/120] unittest: let the environment add package kokkos settings to the test cases The KOKKOS test cases of the force style drivers hardcode their command line, so the suite always runs with the accelerator settings chosen when the case was written. A build configured with -D KOKKOS_DEBUG_SYNC=on, which checks the host/device transfers, needs the settings a GPU would pick - communication, atom sorting and the atom map on the device - or the transfers it exists to check are never made and the run comes out clean whatever the truth is. Append the words of LAMMPS_KOKKOS_ARGS to the command line of the KOKKOS cases, the way LAMMPS_ACCELERATOR_ARGS already works for the command and format tests, so the same references can be re-run with LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" Unset, which it is in CI, this changes nothing. --- unittest/force-styles/test_angle_style.cpp | 17 +++++++++++++++ unittest/force-styles/test_bond_style.cpp | 17 +++++++++++++++ unittest/force-styles/test_dihedral_style.cpp | 17 +++++++++++++++ unittest/force-styles/test_fix_timestep.cpp | 17 +++++++++++++++ unittest/force-styles/test_improper_style.cpp | 17 +++++++++++++++ unittest/force-styles/test_min_style.cpp | 21 +++++++++++++++++++ unittest/force-styles/test_output_style.cpp | 20 ++++++++++++++++++ unittest/force-styles/test_pair_style.cpp | 18 ++++++++++++++++ 8 files changed, 144 insertions(+) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index 653e3580611..d7ebf34a42c 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -583,8 +583,25 @@ static std::string kokkos_precision() // arguments select: with "-pk kokkos neigh full" the KOKKOS package rejects // "newton on", so the run re-reading the data file must use newton off as well +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) { + append_kokkos_env_args(args); + ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 7e4db4cf92e..cc3600c10ad 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -579,8 +579,25 @@ static std::string kokkos_precision() return "double"; } +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_kokkos_test(LAMMPS::argv &args) { + append_kokkos_env_args(args); + ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 8dc7a106016..d1bd46957c0 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -598,8 +598,25 @@ static std::string kokkos_precision() return "double"; } +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_kokkos_test(LAMMPS::argv &args) { + append_kokkos_env_args(args); + ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 5391bd04c14..cd5434a6a0e 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -964,8 +964,25 @@ static std::string kokkos_precision() return "double"; } +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_kokkos_test(LAMMPS::argv &args) { + append_kokkos_env_args(args); + ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 442978e3a7b..0b9b5b038be 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -573,8 +573,25 @@ static std::string kokkos_precision() return "double"; } +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_kokkos_test(LAMMPS::argv &args) { + append_kokkos_env_args(args); + ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index 811652967e6..3320288a9e7 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -50,6 +50,7 @@ #include "modify.h" #include +#include #include #include #include @@ -202,6 +203,21 @@ static void run_minimize(LAMMPS *lmp) lmp->input->one("run 0 post no"); } +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_min_test(LAMMPS::argv &args, double epsilon) { ::testing::internal::CaptureStdout(); @@ -334,6 +350,7 @@ TEST(MinStyle, kokkos_omp) LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", "-k", "on", "t", "4", "-sf", "kk"}; + append_kokkos_env_args(args); run_min_test(args, kokkos_epsilon()); } @@ -382,6 +399,7 @@ TEST(MinStyle, kokkos_omp_full) "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; kokkos_full_neigh = true; + append_kokkos_env_args(args); run_min_test(args, kokkos_epsilon()); kokkos_full_neigh = false; } @@ -415,6 +433,7 @@ TEST(MinStyle, kokkos_serial) LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", "-k", "on", "t", "1", "-sf", "kk"}; + append_kokkos_env_args(args); run_min_test(args, kokkos_epsilon()); } @@ -466,6 +485,7 @@ TEST(MinStyle, kokkos_serial_full) "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; kokkos_full_neigh = true; + append_kokkos_env_args(args); run_min_test(args, kokkos_epsilon()); kokkos_full_neigh = false; } @@ -499,6 +519,7 @@ TEST(MinStyle, kokkos_gpu) "g", "1", "-sf", "kk", "-pk", "kokkos", "neigh", "half", "newton", "on"}; + append_kokkos_env_args(args); run_min_test(args, kokkos_epsilon()); } diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index 58f55e60bda..d1b01f59f50 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -290,6 +290,21 @@ static void compare_rows(const std::string &name, } } +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_output_test(LAMMPS::argv &args, double epsilon, bool kokkos) { ::testing::internal::CaptureStdout(); @@ -412,6 +427,7 @@ TEST(OutputStyle, kokkos_omp) LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", "-k", "on", "t", "4", "-sf", "kk"}; + append_kokkos_env_args(args); run_output_test(args, kokkos_epsilon(), true); } @@ -460,6 +476,7 @@ TEST(OutputStyle, kokkos_omp_full) "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; kokkos_full_neigh = true; + append_kokkos_env_args(args); run_output_test(args, kokkos_epsilon(), true); kokkos_full_neigh = false; } @@ -493,6 +510,7 @@ TEST(OutputStyle, kokkos_serial) LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", "-k", "on", "t", "1", "-sf", "kk"}; + append_kokkos_env_args(args); run_output_test(args, kokkos_epsilon(), true); } @@ -544,6 +562,7 @@ TEST(OutputStyle, kokkos_serial_full) "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; kokkos_full_neigh = true; + append_kokkos_env_args(args); run_output_test(args, kokkos_epsilon(), true); kokkos_full_neigh = false; } @@ -576,6 +595,7 @@ TEST(OutputStyle, kokkos_gpu) "-k", "on", "g", "1", "-sf", "kk", "-pk", "kokkos", "neigh", "half", "newton", "on"}; + append_kokkos_env_args(args); run_output_test(args, kokkos_epsilon(), true); } diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 3f1df0bc647..f8a63eb8168 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -34,6 +34,7 @@ #include "update.h" #include +#include #include #include @@ -751,8 +752,25 @@ static std::string kokkos_precision() // arguments select: with "-pk kokkos neigh full" the KOKKOS package rejects // "newton on", so the restarted run has to be set up with newton off as well +// append the words of the LAMMPS_KOKKOS_ARGS environment variable to the +// command line of the KOKKOS test cases. this lets the whole suite be re-run +// with the "package kokkos" settings a GPU would choose -- +// LAMMPS_KOKKOS_ARGS="-pk kokkos comm device sort device atom/map device gpu/aware on" +// -- which is what the host/device transfer checking of a build configured with +// -D KOKKOS_DEBUG_SYNC=on needs in order to see anything + +static void append_kokkos_env_args(LAMMPS_NS::LAMMPS::argv &args) +{ + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!extra || (extra[0] == '\0')) return; + auto words = LAMMPS_NS::utils::split_words(extra); + args.insert(args.end(), words.begin(), words.end()); +} + static void run_kokkos_test(LAMMPS::argv &args, bool newton = true) { + append_kokkos_env_args(args); + ::testing::internal::CaptureStdout(); LAMMPS *lmp = nullptr; try { From 2f7e64a35e642b95b17d13452b09c7429b3ee2e7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 02:05:22 +0000 Subject: [PATCH 065/120] unittest: run the whole suite through each package kokkos setting once The KOKKOS accelerator settings a run can vary fall into two groups. neigh and newton pick which kernel template of a style runs, so they interact with the style and are already varied per reference: every KOKKOS case exists as "kokkos_*" (half list, newton on) and "kokkos_*_full" (full list, newton off). comm, sort, atom/map and gpu/aware instead pick which framework path runs - the per-atom packing of AtomVec, the atom sorting, the atom map, the MPI buffer placement - and that code is the same whatever style is loaded, so those never varied at all. Add six named profiles and, behind -D ENABLE_KOKKOS_PROFILE_TESTS=on, a variant of every force style reference for each of them. They start from the two defaults the package picks for itself, cpudefault and gpudefault, and add four cross terms, so that between them every value of comm, sort, atom/map and gpu/aware and both values of neigh and newton is used at least once. That is a covering set, not a cross product: the full product of the settings would be hundreds of configurations per reference and would test nothing the covering set does not. A build configured with -D KOKKOS_DEBUG_SYNC=on needs exactly this. Left at the host defaults its atom exchange, border builds, sort and atom map never touch a device view, so the host/device transfers it exists to check are not made and the run comes out clean whatever the truth is. The option is off by default, so the normal suite is unchanged. A style that refuses one of the settings now skips instead of failing, the way the full neighbor list cases already do, so a profile run reports what the styles support rather than failing on what they do not. --- unittest/force-styles/CMakeLists.txt | 89 +++++++++++++++++++ unittest/force-styles/test_angle_style.cpp | 8 +- unittest/force-styles/test_bond_style.cpp | 8 +- unittest/force-styles/test_dihedral_style.cpp | 8 +- unittest/force-styles/test_fix_timestep.cpp | 8 +- unittest/force-styles/test_improper_style.cpp | 8 +- unittest/force-styles/test_min_style.cpp | 8 +- unittest/force-styles/test_output_style.cpp | 8 +- unittest/force-styles/test_pair_style.cpp | 8 +- 9 files changed, 145 insertions(+), 8 deletions(-) diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt index 11f65620fc3..4fa15307aa1 100644 --- a/unittest/force-styles/CMakeLists.txt +++ b/unittest/force-styles/CMakeLists.txt @@ -354,3 +354,92 @@ endif() add_executable(test_pair_list test_pair_list.cpp) target_link_libraries(test_pair_list PRIVATE lammps GTest::GMockMain) add_test(NAME TestPairList COMMAND test_pair_list) + +######################################################################## +# "package kokkos" profiles +# +# The KOKKOS package has several accelerator settings a run may vary (neigh, +# newton, comm, sort, atom/map, gpu/aware), and testing their cross product +# would mean hundreds of configurations per reference. That is not needed, +# because the settings fall into two groups: +# +# - neigh and newton pick which kernel template of a style runs, so they +# interact with the style and are varied per reference already: every +# KOKKOS test case exists twice, as "kokkos_*" (half list, newton on) and +# as "kokkos_*_full" (full list, newton off). +# - comm, sort, atom/map and gpu/aware pick which framework path runs - the +# per-atom packing of AtomVec, the atom sorting, the atom map, the MPI +# buffer placement - and that code is the same whatever style is loaded. +# +# The profiles below are a covering set rather than a cross product: they +# start from the two defaults - the ones a CPU build and a GPU build of the +# package choose for themselves - and add cross terms, so that between them +# every value of comm, sort, atom/map and gpu/aware, and both values of neigh +# and newton, is used at least once. A style that refuses one of the +# settings skips instead of failing, so a profile run reports what the styles +# do support. +# +# They are off by default because they multiply the number of test entries. +# Turn them on to run the whole suite through every setting once, which is +# what a build configured with -D KOKKOS_DEBUG_SYNC=on needs: with the host +# defaults the atom exchange, the border builds, the sort and the atom map +# never touch a device view, so the transfers that build exists to check are +# not made at all. +######################################################################## + +option(ENABLE_KOKKOS_PROFILE_TESTS "Run every force style test through each package kokkos setting once" OFF) +mark_as_advanced(ENABLE_KOKKOS_PROFILE_TESTS) + +if(PKG_KOKKOS AND ENABLE_KOKKOS_PROFILE_TESTS) + # the two named profiles are the defaults "package kokkos" itself picks, + # spelled out: cpudefault is what a build without a GPU gets, gpudefault + # what a build with one gets. the cross profiles then vary one group of + # settings against the other group's default. + set(KOKKOS_PROFILE_NAMES cpudefault gpudefault + cross-hostpath cross-devicehalf + cross-nogpuaware cross-nosort) + set(KOKKOS_PROFILE_cpudefault "-pk kokkos comm no sort no atom/map no neigh half newton on") + set(KOKKOS_PROFILE_gpudefault "-pk kokkos comm device sort device atom/map device gpu/aware on neigh full newton off") + set(KOKKOS_PROFILE_cross-hostpath "-pk kokkos comm host sort host atom/map host neigh half newton off") + set(KOKKOS_PROFILE_cross-devicehalf "-pk kokkos comm device sort device atom/map device gpu/aware on neigh half newton on") + set(KOKKOS_PROFILE_cross-nogpuaware "-pk kokkos comm device sort device atom/map device gpu/aware off neigh full newton off") + set(KOKKOS_PROFILE_cross-nosort "-pk kokkos comm device sort no atom/map no neigh full newton on") + + # the prefix, the driver and the file name pattern of every reference group, + # in the same order the groups are registered above + set(KOKKOS_PROFILE_GROUPS + "MolPairStyle|test_pair_style|mol-pair-" + "AtomicPairStyle|test_pair_style|atomic-pair-" + "ManybodyPairStyle|test_pair_style|manybody-pair-" + "BondStyle|test_bond_style|bond-" + "AngleStyle|test_angle_style|angle-" + "DihedralStyle|test_dihedral_style|dihedral-" + "ImproperStyle|test_improper_style|improper-" + "FixTimestep|test_fix_timestep|fix-timestep-" + "MinStyle|test_min_style|min-") + + foreach(GROUP ${KOKKOS_PROFILE_GROUPS}) + string(REPLACE "|" ";" PARTS ${GROUP}) + list(GET PARTS 0 GPREFIX) + list(GET PARTS 1 GDRIVER) + list(GET PARTS 2 GPATTERN) + file(GLOB GTESTS LIST_DIRECTORIES false CONFIGURE_DEPENDS ${TEST_INPUT_FOLDER}/${GPATTERN}*.yaml) + foreach(TEST ${GTESTS}) + get_filename_component(TBASE ${TEST} NAME_WE) + string(REPLACE "${GPATTERN}" "" TSHORT ${TBASE}) + extract_tags(TEST_TAGS ${TEST}) + list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) + if(_SKIPME GREATER_EQUAL 0) + continue() + endif() + foreach(PROFILE ${KOKKOS_PROFILE_NAMES}) + set(TNAME "${GPREFIX}:${TSHORT}:kk-${PROFILE}") + add_test(NAME ${TNAME} COMMAND ${GDRIVER} ${TEST}) + set(PROFILE_ENV ${FORCE_TEST_ENVIRONMENT}) + list(APPEND PROFILE_ENV "LAMMPS_KOKKOS_ARGS=${KOKKOS_PROFILE_${PROFILE}}") + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${PROFILE_ENV}") + set_tests_properties(${TNAME} PROPERTIES LABELS "kokkos_profile;${TEST_TAGS}") + endforeach() + endforeach() + endforeach() +endif() diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index d7ebf34a42c..86dee71cc22 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -66,7 +66,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index cc3600c10ad..05435905f04 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -66,7 +66,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index d1bd46957c0..63727fc2a80 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -66,7 +66,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index cd5434a6a0e..21aa1b3b1a9 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -68,7 +68,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 0b9b5b038be..afe9f7c872f 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -66,7 +66,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index 3320288a9e7..a7c0bb2cdf4 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -85,7 +85,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index d1b01f59f50..57541fd8175 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -81,7 +81,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index f8a63eb8168..52c726368a2 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -72,7 +72,13 @@ static void enforce_kokkos_full_neigh(LAMMPS *lmp) static bool full_neigh_unsupported(const std::string &errmsg) { - if (!kokkos_full_neigh) return false; + // a style that refuses the neighbor list or the newton setting asked for + // skips rather than fails. that applies to the full neighbor list cases + // and to any accelerator settings supplied through LAMMPS_KOKKOS_ARGS: a + // run of the suite under a different "package kokkos" profile is meant to + // report what a style does support, not to fail on what it does not + const char *extra = std::getenv("LAMMPS_KOKKOS_ARGS"); + if (!kokkos_full_neigh && (!extra || (extra[0] == '\0'))) return false; return (LAMMPS_NS::utils::strmatch(errmsg, "newton") || LAMMPS_NS::utils::strmatch(errmsg, "half neighbor list")); } From caa62528a21c66ce89b682eeced81e130fa0e765 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 02:05:30 +0000 Subject: [PATCH 066/120] KOKKOS: stop copying the velocities for the wall fixes fix wall/lj93, lj126, lj1043, morse, harmonic and harmonic/outside declare V_MASK in datamask_read, so the package copies the velocities between the host and the device around every call of these fixes. None of them reads a velocity: the wall force depends on the distance to the wall alone, and neither the KOKKOS kernels nor the CPU base class ever touch atom->v. Found by comparing the declared masks of every KOKKOS style against the arrays it actually references, while looking through the reports of a build configured with -D KOKKOS_DEBUG_SYNC=on. --- src/KOKKOS/fix_wall_harmonic_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_harmonic_outside_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_lj1043_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_lj126_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_lj93_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_morse_kokkos.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/fix_wall_harmonic_kokkos.cpp b/src/KOKKOS/fix_wall_harmonic_kokkos.cpp index fb3c1a90b29..d710ce995c7 100644 --- a/src/KOKKOS/fix_wall_harmonic_kokkos.cpp +++ b/src/KOKKOS/fix_wall_harmonic_kokkos.cpp @@ -30,7 +30,7 @@ FixWallHarmonicKokkos::FixWallHarmonicKokkos(LAMMPS *lmp, int narg, kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK; datamask_modify = F_MASK; } diff --git a/src/KOKKOS/fix_wall_harmonic_outside_kokkos.cpp b/src/KOKKOS/fix_wall_harmonic_outside_kokkos.cpp index 50d1047d16c..e60f545e0e4 100644 --- a/src/KOKKOS/fix_wall_harmonic_outside_kokkos.cpp +++ b/src/KOKKOS/fix_wall_harmonic_outside_kokkos.cpp @@ -29,7 +29,7 @@ FixWallHarmonicOutsideKokkos::FixWallHarmonicOutsideKokkos(LAMMPS *l kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK; datamask_modify = F_MASK; } diff --git a/src/KOKKOS/fix_wall_lj1043_kokkos.cpp b/src/KOKKOS/fix_wall_lj1043_kokkos.cpp index d18baf32028..6803f07ae94 100644 --- a/src/KOKKOS/fix_wall_lj1043_kokkos.cpp +++ b/src/KOKKOS/fix_wall_lj1043_kokkos.cpp @@ -34,7 +34,7 @@ FixWallLJ1043Kokkos::FixWallLJ1043Kokkos(LAMMPS *lmp, int narg, char kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK; datamask_modify = F_MASK; memoryKK->create_kokkos(k_cutoff, 6, "wall_lj1043:cutoff"); diff --git a/src/KOKKOS/fix_wall_lj126_kokkos.cpp b/src/KOKKOS/fix_wall_lj126_kokkos.cpp index a2704bc4010..85f6266ce16 100644 --- a/src/KOKKOS/fix_wall_lj126_kokkos.cpp +++ b/src/KOKKOS/fix_wall_lj126_kokkos.cpp @@ -30,7 +30,7 @@ FixWallLJ126Kokkos::FixWallLJ126Kokkos(LAMMPS *lmp, int narg, char * kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK; datamask_modify = F_MASK; memoryKK->create_kokkos(k_cutoff, 6, "wall_lj126:cutoff"); diff --git a/src/KOKKOS/fix_wall_lj93_kokkos.cpp b/src/KOKKOS/fix_wall_lj93_kokkos.cpp index f7c4c6f8539..769e48334e3 100644 --- a/src/KOKKOS/fix_wall_lj93_kokkos.cpp +++ b/src/KOKKOS/fix_wall_lj93_kokkos.cpp @@ -37,7 +37,7 @@ FixWallLJ93Kokkos::FixWallLJ93Kokkos(LAMMPS *lmp, int narg, char **a kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK; datamask_modify = F_MASK; memoryKK->create_kokkos(k_cutoff,6,"wall_lj93:cutoff"); diff --git a/src/KOKKOS/fix_wall_morse_kokkos.cpp b/src/KOKKOS/fix_wall_morse_kokkos.cpp index 396422eff4a..a0543f29994 100644 --- a/src/KOKKOS/fix_wall_morse_kokkos.cpp +++ b/src/KOKKOS/fix_wall_morse_kokkos.cpp @@ -32,7 +32,7 @@ FixWallMorseKokkos::FixWallMorseKokkos(LAMMPS *lmp, int narg, char * kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK; datamask_modify = F_MASK; memoryKK->create_kokkos(k_cutoff, 6, "wall_morse:cutoff"); From 3d9dc2123ea9780702784b4751b54708a11caa73 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 4 Sep 2026 23:24:57 -0400 Subject: [PATCH 067/120] remove reference to obsolete atc package --- doc/src/Packages.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/Packages.rst b/doc/src/Packages.rst index 7a376954fc3..ccc09e2ee03 100644 --- a/doc/src/Packages.rst +++ b/doc/src/Packages.rst @@ -45,8 +45,8 @@ consistent with the rest of LAMMPS. The "Examples" column is a subdirectory in the examples directory of the distribution which has one or more input scripts that use the package. -E.g. ``peptide`` refers to the ``examples/peptide`` directory; ``PACKAGES/atc`` refers -to the ``examples/PACKAGES/atc`` directory. The "Lib" column indicates`` +E.g. ``peptide`` refers to the ``examples/peptide`` directory; ``PACKAGES/fep`` refers +to the ``examples/PACKAGES/fep`` directory. The "Lib" column indicates`` whether an extra library is needed to build and use the package: * no = no library From 7ba5243c2b013fa08467cc2bcd77d6be97c68c36 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 03:44:16 +0000 Subject: [PATCH 068/120] KOKKOS: sync the crossterm lists of fix cmap before a restart is written FixCMAPKokkos keeps the per-atom crossterm lists in dual views, and overrides grow_arrays, copy_arrays, set_arrays and the exchange packing so that those stay coherent - but not size_restart, pack_restart and unpack_restart. Those three are inherited from the CPU class, which reads and writes the lists through the plain pointers behind the dual views, so a restart written from a run whose device side is newer stores whatever the host copy happens to hold, and a restart read back leaves the device copy authoritative over the values just unpacked. Found by the poison mode of a build configured with -D KOKKOS_DEBUG_SYNC=on and -D KOKKOS_DEBUG_SYNC_ASAN=on, which marks the stale copy of every array off limits: write_restart faulted inside FixCMAP::size_restart() reading num_crossterm, and again in pack_restart() and unpack_restart(). Override the three, so the host side is brought up to date before the base class runs and claimed again after it has written. --- src/KOKKOS/fix_cmap_kokkos.cpp | 52 ++++++++++++++++++++++++++++++++++ src/KOKKOS/fix_cmap_kokkos.h | 6 ++++ 2 files changed, 58 insertions(+) diff --git a/src/KOKKOS/fix_cmap_kokkos.cpp b/src/KOKKOS/fix_cmap_kokkos.cpp index 8e16cfa8145..b5ce40a6e39 100644 --- a/src/KOKKOS/fix_cmap_kokkos.cpp +++ b/src/KOKKOS/fix_cmap_kokkos.cpp @@ -574,6 +574,58 @@ void FixCMAPKokkos::operator()(TagFixCmapPostForce, const int n, EV_ } } +/* ---------------------------------------------------------------------- + the restart methods of the base class read and write the crossterm lists + through the plain pointers behind the dual views, so the host side has to + hold the current values first, and unpacking has to claim it afterwards +------------------------------------------------------------------------- */ + +template +void FixCMAPKokkos::sync_crossterm_host() +{ + k_num_crossterm.sync_host(); + k_crossterm_type.sync_host(); + k_crossterm_atom1.sync_host(); + k_crossterm_atom2.sync_host(); + k_crossterm_atom3.sync_host(); + k_crossterm_atom4.sync_host(); + k_crossterm_atom5.sync_host(); +} + +template +void FixCMAPKokkos::modify_crossterm_host() +{ + k_num_crossterm.modify_host(); + k_crossterm_type.modify_host(); + k_crossterm_atom1.modify_host(); + k_crossterm_atom2.modify_host(); + k_crossterm_atom3.modify_host(); + k_crossterm_atom4.modify_host(); + k_crossterm_atom5.modify_host(); +} + +template +int FixCMAPKokkos::size_restart(int nlocal) +{ + sync_crossterm_host(); + return FixCMAP::size_restart(nlocal); +} + +template +int FixCMAPKokkos::pack_restart(int i, double *buf) +{ + sync_crossterm_host(); + return FixCMAP::pack_restart(i,buf); +} + +template +void FixCMAPKokkos::unpack_restart(int nlocal, int nth) +{ + sync_crossterm_host(); + FixCMAP::unpack_restart(nlocal,nth); + modify_crossterm_host(); +} + /* ---------------------------------------------------------------------- allocate atom-based array ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_cmap_kokkos.h b/src/KOKKOS/fix_cmap_kokkos.h index 4b95a174e3c..5d1033b12a2 100644 --- a/src/KOKKOS/fix_cmap_kokkos.h +++ b/src/KOKKOS/fix_cmap_kokkos.h @@ -60,6 +60,12 @@ class FixCMAPKokkos : public FixCMAP, public KokkosBase { void set_arrays(int) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; + int size_restart(int) override; + int pack_restart(int, double *) override; + void unpack_restart(int, int) override; + + void sync_crossterm_host(); + void modify_crossterm_host(); int pack_exchange_kokkos(const int &nsend,DAT::tdual_double_2d_lr &buf, DAT::tdual_int_1d k_sendlist, From 914865ed5db790ec8b8dd4ac8730adba026ee315 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 03:44:17 +0000 Subject: [PATCH 069/120] unittest: complete the prerequisites of the two new langevin references fix-timestep-langevin_omega uses in.dipole, whose atom style comes from the DIPOLE package, and fix-timestep-langevin_angmom integrates with fix nve/asphere from the ASPHERE package. Neither was declared, so in a build without those packages the two did not skip but failed while setting up. --- unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml | 1 + unittest/force-styles/tests/fix-timestep-langevin_omega.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml b/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml index 065d4f04da0..04a34c1c236 100644 --- a/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml +++ b/unittest/force-styles/tests/fix-timestep-langevin_angmom.yaml @@ -6,6 +6,7 @@ epsilon: 5e-13 skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom ellipsoid + fix nve/asphere fix langevin pre_commands: "" post_commands: | diff --git a/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml b/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml index 28864f74976..ccd74c7d139 100644 --- a/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml +++ b/unittest/force-styles/tests/fix-timestep-langevin_omega.yaml @@ -6,6 +6,7 @@ epsilon: 5e-14 skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom full + atom dipole atom sphere fix langevin pre_commands: "" From 90600a7d52f239d38885d85965efc275236215f3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 04:20:21 +0000 Subject: [PATCH 070/120] KOKKOS: sync the forces back to the device inside the minimizer The KOKKOS line search and the cg and sd minimizers read the positions and the forces through xvec and fvec, raw views over the device side of the two dual views, built once at the start of the run. Between those reads they call code that may run on the host: MinKokkos::energy_force() evaluates every force style, and a style without a KOKKOS variant leaves datamask_modify at ALL_MASK with execution_space Host, so the host side of the forces is claimed; ModifyKokkos::max_alpha() does the same for the positions through a fix such as fix box/relax. Nothing brought the device side back before the next kernel, so the minimizer read a copy one force evaluation out of date. The three functions that already do this correctly - fnorm_sqr(), fnorm_inf() and fnorm_max() - sync immediately before their reduction. Do the same at the four remaining places: after modify->max_alpha() and after alpha_step() in linemin_quadratic(), and after linemin() returns in the cg and sd iterate(). It cannot be seen on a CPU, where both sides are the same memory. It was found with the poison mode of a build configured with -D KOKKOS_DEBUG_SYNC=on and -D KOKKOS_DEBUG_SYNC_ASAN=on, which marks the stale copy of every array off limits: five of the twelve minimizer references faulted, at exactly the seven reads these four calls now cover, and a deck whose force field is entirely KOKKOS produces no fault at all. --- src/KOKKOS/min_cg_kokkos.cpp | 7 +++++++ src/KOKKOS/min_linesearch_kokkos.cpp | 12 ++++++++++++ src/KOKKOS/min_sd_kokkos.cpp | 7 +++++++ 3 files changed, 26 insertions(+) diff --git a/src/KOKKOS/min_cg_kokkos.cpp b/src/KOKKOS/min_cg_kokkos.cpp index 69fb29c5b7e..e501720c05a 100644 --- a/src/KOKKOS/min_cg_kokkos.cpp +++ b/src/KOKKOS/min_cg_kokkos.cpp @@ -104,6 +104,13 @@ int MinCGKokkos::iterate(int maxiter) fail = (this->*linemin)(ecurrent,alpha_final); if (fail) return fail; + // the line search ends with a force evaluation, and with + // modify->min_reset_ref() when there are extra global dof. the styles and + // fixes it runs may be non-KOKKOS ones, which claim the host side of f and + // leave the device view fvec reads below stale + + atomKK->sync(Device,F_MASK); + // function evaluation criterion if (neval >= update->max_eval) return MAXEVAL; diff --git a/src/KOKKOS/min_linesearch_kokkos.cpp b/src/KOKKOS/min_linesearch_kokkos.cpp index 3b628c5baf7..f92c8e32d08 100644 --- a/src/KOKKOS/min_linesearch_kokkos.cpp +++ b/src/KOKKOS/min_linesearch_kokkos.cpp @@ -240,6 +240,12 @@ int MinLineSearchKokkos::linemin_quadratic(double eoriginal, double &alpha) if (hmaxall == 0.0) return ZEROFORCE; + // modify->max_alpha() above runs the fixes with extra global dof, and a + // non-KOKKOS one (e.g. fix box/relax) runs on the host and claims the host + // side of x, which leaves the device view xvec reads below stale + + atomKK->sync(Device,X_MASK); + // store box and values of all dof at start of linesearch { @@ -275,6 +281,12 @@ int MinLineSearchKokkos::linemin_quadratic(double eoriginal, double &alpha) while (true) { ecurrent = alpha_step(alpha,1); + // the force styles and fixes evaluated by alpha_step() may be non-KOKKOS + // ones: those run on the host and claim the host side of f, which leaves + // the device view fvec reads below stale + + atomKK->sync(Device,F_MASK); + // compute new fh, alpha, delfh s_KK_double2 sdot; diff --git a/src/KOKKOS/min_sd_kokkos.cpp b/src/KOKKOS/min_sd_kokkos.cpp index af4794c3d6a..de781ba40c3 100644 --- a/src/KOKKOS/min_sd_kokkos.cpp +++ b/src/KOKKOS/min_sd_kokkos.cpp @@ -100,6 +100,13 @@ int MinSDKokkos::iterate(int maxiter) fail = (this->*linemin)(ecurrent,alpha_final); if (fail) return fail; + // the line search ends with a force evaluation, and with + // modify->min_reset_ref() when there are extra global dof. the styles and + // fixes it runs may be non-KOKKOS ones, which claim the host side of f and + // leave the device view fvec read by set_search_direction() below stale + + atomKK->sync(Device,F_MASK); + // function evaluation criterion if (neval >= update->max_eval) return MAXEVAL; From 86571ec05e1f9d0287e30ce720f9e92449faa94a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 07:30:25 +0000 Subject: [PATCH 071/120] KOKKOS: bring the crossterm lists of fix cmap to the device The crossterm lists are filled by the base class from the CMAP section of the data file, through the plain host pointers. FixCMAPKokkos marks the host side of those dual views modified around every other path that writes them - the restart pack and unpack, the per-atom exchange, the sort - but not around the data file, so nothing ever recorded that the host held the only copy. The device side was therefore never brought up to date, and the kernel of pre_neighbor() built the crossterm list from whatever the device buffers happened to contain. Override read_data_section() to claim the host writes, and sync the seven lists to the device in pre_neighbor() before the kernel that reads them, next to the syncs already there for the positions, the atom map and sametag. It cannot be seen on a CPU, where the two sides are the same memory. Under the poison mode of a build configured with -D KOKKOS_DEBUG_SYNC=on and -D KOKKOS_DEBUG_SYNC_ASAN=on the reference reported 42 faults inside that kernel with the host defaults of package kokkos and 3 with the GPU defaults; it now reports none from LAMMPS code under either. --- src/KOKKOS/fix_cmap_kokkos.cpp | 37 ++++++++++++++++++++++++++++++++++ src/KOKKOS/fix_cmap_kokkos.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/KOKKOS/fix_cmap_kokkos.cpp b/src/KOKKOS/fix_cmap_kokkos.cpp index b5ce40a6e39..a611d355aea 100644 --- a/src/KOKKOS/fix_cmap_kokkos.cpp +++ b/src/KOKKOS/fix_cmap_kokkos.cpp @@ -181,6 +181,26 @@ void FixCMAPKokkos::pre_neighbor() atomKK->k_sametag.sync(); d_sametag = atomKK->k_sametag.view(); + // the crossterm lists are filled on the host, by the data file reader and by + // the unpack methods that move them between processors, so the device side + // the kernel below reads has to be brought up to date first + + k_num_crossterm.template sync(); + k_crossterm_type.template sync(); + k_crossterm_atom1.template sync(); + k_crossterm_atom2.template sync(); + k_crossterm_atom3.template sync(); + k_crossterm_atom4.template sync(); + k_crossterm_atom5.template sync(); + + d_num_crossterm = k_num_crossterm.template view(); + d_crossterm_type = k_crossterm_type.template view(); + d_crossterm_atom1 = k_crossterm_atom1.template view(); + d_crossterm_atom2 = k_crossterm_atom2.template view(); + d_crossterm_atom3 = k_crossterm_atom3.template view(); + d_crossterm_atom4 = k_crossterm_atom4.template view(); + d_crossterm_atom5 = k_crossterm_atom5.template view(); + copymode = 1; Kokkos::parallel_scan(Kokkos::RangePolicy(0,nlocal),*this,ncrosstermlist); copymode = 0; @@ -592,6 +612,23 @@ void FixCMAPKokkos::sync_crossterm_host() k_crossterm_atom5.sync_host(); } +/* ---------------------------------------------------------------------- + the base class fills the crossterm lists from the data file through the + plain host pointers, so the device side has to be marked out of date + afterwards - without this nothing ever copies them across and the kernel of + pre_neighbor() builds its list from whatever the device buffers hold +------------------------------------------------------------------------- */ + +template +void FixCMAPKokkos::read_data_section(char *keyword, int n, char *buf, tagint id_offset) +{ + sync_crossterm_host(); + FixCMAP::read_data_section(keyword,n,buf,id_offset); + modify_crossterm_host(); +} + +/* ---------------------------------------------------------------------- */ + template void FixCMAPKokkos::modify_crossterm_host() { diff --git a/src/KOKKOS/fix_cmap_kokkos.h b/src/KOKKOS/fix_cmap_kokkos.h index 5d1033b12a2..d11f91c073a 100644 --- a/src/KOKKOS/fix_cmap_kokkos.h +++ b/src/KOKKOS/fix_cmap_kokkos.h @@ -64,6 +64,8 @@ class FixCMAPKokkos : public FixCMAP, public KokkosBase { int pack_restart(int, double *) override; void unpack_restart(int, int) override; + void read_data_section(char *, int, char *, tagint) override; + void sync_crossterm_host(); void modify_crossterm_host(); From 364a5b08a2dd4f832c23bd16e156906fb87cfff6 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 09:31:54 +0000 Subject: [PATCH 072/120] KOKKOS: tally the Wolf/DSF self energy in a device kernel pair born/coul/wolf/kk, born/coul/wolf/cs/kk, lj/cut/coul/wolf/kk, born/coul/dsf/kk and born/coul/dsf/cs/kk computed the self-energy contribution of every local atom in a host loop over atom->q[i], while the current charges live on the device. On a GPU (or in a build with separate host and device buffers) that loop reads a stale host copy of the charges: the energy is silently wrong whenever the charges have been updated on the device since the last host synchronization. The per-atom part had the same problem, and it was added to eatom[] after k_eatom.sync_host() without marking the host side modified, so a later device synchronization dropped it again. Compute the self energy in a Kokkos kernel instead, as pair coul/wolf/kk and pair coul/dsf/kk already do, tallying both the global and the per-atom energy on the device. The kernel is guarded by eflag, which also stops the styles from accumulating into eng_coul when no energy was requested. Verified against the CPU styles: the global pair energy and the sum of "compute pe/atom pair" now agree to roundoff for all five styles, and the mol-pair-born_coul_wolf, born_coul_wolf_cs, lj_cut_coul_wolf, born_coul_dsf and born_coul_dsf_cs tests pass unchanged. --- src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp | 45 +++++++++++++++----- src/KOKKOS/pair_born_coul_dsf_cs_kokkos.h | 7 +++ src/KOKKOS/pair_born_coul_dsf_kokkos.cpp | 45 +++++++++++++++----- src/KOKKOS/pair_born_coul_dsf_kokkos.h | 7 +++ src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp | 45 +++++++++++++++----- src/KOKKOS/pair_born_coul_wolf_cs_kokkos.h | 7 +++ src/KOKKOS/pair_born_coul_wolf_kokkos.cpp | 45 +++++++++++++++----- src/KOKKOS/pair_born_coul_wolf_kokkos.h | 7 +++ src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp | 45 +++++++++++++++----- src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.h | 7 +++ 10 files changed, 205 insertions(+), 55 deletions(-) diff --git a/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp b/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp index 381e5cea7ec..17088dbc3a7 100644 --- a/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp @@ -121,16 +121,21 @@ void PairBornCoulDSFCSKokkos::compute(int eflag_in, int vflag_in) qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; - // damped-shifted-force self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; - } - EV_FLOAT ev; copymode = 1; + // self energy of every local atom, tallied in a device kernel so that the + // charges and the per-atom energy stay resident on the device + + if (eflag) { + d_ilist = ((NeighListKokkos*) list)->d_ilist; + KK_ACC_FLOAT e_self_sum = 0.0; + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,list->inum), + *this,e_self_sum); + if (eflag_global) eng_coul += static_cast(e_self_sum); + } + ev = pair_compute,void> (this,(NeighListKokkos*)list); @@ -150,11 +155,6 @@ void PairBornCoulDSFCSKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); k_eatom.sync_host(); - // add the self-energy to the per-atom energy after the device sync - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eatom[i] += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; - } } if (vflag_atom) { @@ -289,6 +289,29 @@ compute_ecoul(const KK_FLOAT& rsq_in, const int& /*i*/, const int& j, return ecoul; } +/* ---------------------------------------------------------------------- + self energy contribution of atom i; mirrors the ev_tally(i,i,...) call of + the CPU style + ---------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +void PairBornCoulDSFCSKokkos::operator()(TagPairBornCoulDSFCSSelfEnergy, + const int &ii, KK_ACC_FLOAT &e_self_sum) const +{ + const KK_FLOAT alf_kk = static_cast(alpha); + const KK_FLOAT e_shift_kk = static_cast(e_shift); + + const int i = d_ilist[ii]; + const KK_FLOAT qtmp = q(i); + const KK_FLOAT e_self = -(e_shift_kk/static_cast(2.0) + + alf_kk/static_cast(MY_PIS)) * qtmp*qtmp*qqrd2e; + + if (eflag_global) e_self_sum += static_cast(e_self); + if (eflag_atom) d_eatom[i] += static_cast(e_self); +} + /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.h b/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.h index a79bcabe9a2..df734902809 100644 --- a/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.h +++ b/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.h @@ -29,6 +29,8 @@ PairStyle(born/coul/dsf/cs/kk/host,PairBornCoulDSFCSKokkos); namespace LAMMPS_NS { +struct TagPairBornCoulDSFCSSelfEnergy{}; + template class PairBornCoulDSFCSKokkos : public PairBornCoulDSFCS { public: @@ -43,6 +45,10 @@ class PairBornCoulDSFCSKokkos : public PairBornCoulDSFCS { void init_style() override; double init_one(int, int) override; + // NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + void operator()(TagPairBornCoulDSFCSSelfEnergy, const int&, KK_ACC_FLOAT&) const; + struct params_born_wolf { // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION @@ -95,6 +101,7 @@ class PairBornCoulDSFCSKokkos : public PairBornCoulDSFCS { typename AT::t_kkacc_1d_3 f; typename AT::t_int_1d_randomread type; typename AT::t_kkfloat_1d_randomread q; + typename AT::t_int_1d_randomread d_ilist; DAT::ttransform_kkacc_1d k_eatom; DAT::ttransform_kkacc_1d_6 k_vatom; diff --git a/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp index 6580e66c6f8..fc5a6161261 100644 --- a/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp @@ -116,16 +116,21 @@ void PairBornCoulDSFKokkos::compute(int eflag_in, int vflag_in) qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; - // damped-shifted-force self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; - } - EV_FLOAT ev; copymode = 1; + // self energy of every local atom, tallied in a device kernel so that the + // charges and the per-atom energy stay resident on the device + + if (eflag) { + d_ilist = ((NeighListKokkos*) list)->d_ilist; + KK_ACC_FLOAT e_self_sum = 0.0; + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,list->inum), + *this,e_self_sum); + if (eflag_global) eng_coul += static_cast(e_self_sum); + } + ev = pair_compute,void> (this,(NeighListKokkos*)list); @@ -145,11 +150,6 @@ void PairBornCoulDSFKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); k_eatom.sync_host(); - // add the self-energy to the per-atom energy after the device sync - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eatom[i] += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; - } } if (vflag_atom) { @@ -264,6 +264,29 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, return ecoul; } +/* ---------------------------------------------------------------------- + self energy contribution of atom i; mirrors the ev_tally(i,i,...) call of + the CPU style + ---------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +void PairBornCoulDSFKokkos::operator()(TagPairBornCoulDSFSelfEnergy, + const int &ii, KK_ACC_FLOAT &e_self_sum) const +{ + const KK_FLOAT alf_kk = static_cast(alpha); + const KK_FLOAT e_shift_kk = static_cast(e_shift); + + const int i = d_ilist[ii]; + const KK_FLOAT qtmp = q(i); + const KK_FLOAT e_self = -(e_shift_kk/static_cast(2.0) + + alf_kk/static_cast(MY_PIS)) * qtmp*qtmp*qqrd2e; + + if (eflag_global) e_self_sum += static_cast(e_self); + if (eflag_atom) d_eatom[i] += static_cast(e_self); +} + /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_born_coul_dsf_kokkos.h b/src/KOKKOS/pair_born_coul_dsf_kokkos.h index 3f968286444..a1715c7f716 100644 --- a/src/KOKKOS/pair_born_coul_dsf_kokkos.h +++ b/src/KOKKOS/pair_born_coul_dsf_kokkos.h @@ -29,6 +29,8 @@ PairStyle(born/coul/dsf/kk/host,PairBornCoulDSFKokkos); namespace LAMMPS_NS { +struct TagPairBornCoulDSFSelfEnergy{}; + template class PairBornCoulDSFKokkos : public PairBornCoulDSF { public: @@ -43,6 +45,10 @@ class PairBornCoulDSFKokkos : public PairBornCoulDSF { void init_style() override; double init_one(int, int) override; + // NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + void operator()(TagPairBornCoulDSFSelfEnergy, const int&, KK_ACC_FLOAT&) const; + struct params_born_wolf { // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION @@ -95,6 +101,7 @@ class PairBornCoulDSFKokkos : public PairBornCoulDSF { typename AT::t_kkacc_1d_3 f; typename AT::t_int_1d_randomread type; typename AT::t_kkfloat_1d_randomread q; + typename AT::t_int_1d_randomread d_ilist; DAT::ttransform_kkacc_1d k_eatom; DAT::ttransform_kkacc_1d_6 k_vatom; diff --git a/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp b/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp index 46fd72f7733..917de002473 100644 --- a/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp @@ -121,16 +121,21 @@ void PairBornCoulWolfCSKokkos::compute(int eflag_in, int vflag_in) qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; - // Wolf self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); - } - EV_FLOAT ev; copymode = 1; + // self energy of every local atom, tallied in a device kernel so that the + // charges and the per-atom energy stay resident on the device + + if (eflag) { + d_ilist = ((NeighListKokkos*) list)->d_ilist; + KK_ACC_FLOAT e_self_sum = 0.0; + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,list->inum), + *this,e_self_sum); + if (eflag_global) eng_coul += static_cast(e_self_sum); + } + ev = pair_compute,void> (this,(NeighListKokkos*)list); @@ -150,11 +155,6 @@ void PairBornCoulWolfCSKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); k_eatom.sync_host(); - // Add Wolf self-energy to per-atom energy after device sync - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eatom[i] += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); - } } if (vflag_atom) { @@ -282,6 +282,29 @@ compute_ecoul(const KK_FLOAT& rsq_in, const int& /*i*/, const int& j, return ecoul; } +/* ---------------------------------------------------------------------- + self energy contribution of atom i; mirrors the ev_tally(i,i,...) call of + the CPU style + ---------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +void PairBornCoulWolfCSKokkos::operator()(TagPairBornCoulWolfCSSelfEnergy, + const int &ii, KK_ACC_FLOAT &e_self_sum) const +{ + const KK_FLOAT alf_kk = static_cast(m_alf); + const KK_FLOAT e_shift_kk = static_cast(e_shift); + + const int i = d_ilist[ii]; + const KK_FLOAT qtmp = q(i); + const KK_FLOAT e_self = -(e_shift_kk/static_cast(2.0) + + alf_kk/static_cast(MY_PIS)) * qtmp*qtmp*qqrd2e; + + if (eflag_global) e_self_sum += static_cast(e_self); + if (eflag_atom) d_eatom[i] += static_cast(e_self); +} + /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.h b/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.h index 08a7b68d8b1..b78e238768e 100644 --- a/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.h +++ b/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.h @@ -29,6 +29,8 @@ PairStyle(born/coul/wolf/cs/kk/host,PairBornCoulWolfCSKokkos); namespace LAMMPS_NS { +struct TagPairBornCoulWolfCSSelfEnergy{}; + template class PairBornCoulWolfCSKokkos : public PairBornCoulWolfCS { public: @@ -43,6 +45,10 @@ class PairBornCoulWolfCSKokkos : public PairBornCoulWolfCS { void init_style() override; double init_one(int, int) override; + // NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + void operator()(TagPairBornCoulWolfCSSelfEnergy, const int&, KK_ACC_FLOAT&) const; + struct params_born_wolf { // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION @@ -95,6 +101,7 @@ class PairBornCoulWolfCSKokkos : public PairBornCoulWolfCS { typename AT::t_kkacc_1d_3 f; typename AT::t_int_1d_randomread type; typename AT::t_kkfloat_1d_randomread q; + typename AT::t_int_1d_randomread d_ilist; DAT::ttransform_kkacc_1d k_eatom; DAT::ttransform_kkacc_1d_6 k_vatom; diff --git a/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp index 72edf6434d7..6bd8b38be8a 100644 --- a/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp @@ -116,16 +116,21 @@ void PairBornCoulWolfKokkos::compute(int eflag_in, int vflag_in) qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; - // Wolf self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); - } - EV_FLOAT ev; copymode = 1; + // self energy of every local atom, tallied in a device kernel so that the + // charges and the per-atom energy stay resident on the device + + if (eflag) { + d_ilist = ((NeighListKokkos*) list)->d_ilist; + KK_ACC_FLOAT e_self_sum = 0.0; + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,list->inum), + *this,e_self_sum); + if (eflag_global) eng_coul += static_cast(e_self_sum); + } + ev = pair_compute,void> (this,(NeighListKokkos*)list); @@ -145,11 +150,6 @@ void PairBornCoulWolfKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); k_eatom.sync_host(); - // Add Wolf self-energy to per-atom energy after device sync - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eatom[i] += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); - } } if (vflag_atom) { @@ -257,6 +257,29 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, return ecoul; } +/* ---------------------------------------------------------------------- + self energy contribution of atom i; mirrors the ev_tally(i,i,...) call of + the CPU style + ---------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +void PairBornCoulWolfKokkos::operator()(TagPairBornCoulWolfSelfEnergy, + const int &ii, KK_ACC_FLOAT &e_self_sum) const +{ + const KK_FLOAT alf_kk = static_cast(m_alf); + const KK_FLOAT e_shift_kk = static_cast(e_shift); + + const int i = d_ilist[ii]; + const KK_FLOAT qtmp = q(i); + const KK_FLOAT e_self = -(e_shift_kk/static_cast(2.0) + + alf_kk/static_cast(MY_PIS)) * qtmp*qtmp*qqrd2e; + + if (eflag_global) e_self_sum += static_cast(e_self); + if (eflag_atom) d_eatom[i] += static_cast(e_self); +} + /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_born_coul_wolf_kokkos.h b/src/KOKKOS/pair_born_coul_wolf_kokkos.h index ac2cce81a83..5c0514ac2ba 100644 --- a/src/KOKKOS/pair_born_coul_wolf_kokkos.h +++ b/src/KOKKOS/pair_born_coul_wolf_kokkos.h @@ -29,6 +29,8 @@ PairStyle(born/coul/wolf/kk/host,PairBornCoulWolfKokkos); namespace LAMMPS_NS { +struct TagPairBornCoulWolfSelfEnergy{}; + template class PairBornCoulWolfKokkos : public PairBornCoulWolf { public: @@ -43,6 +45,10 @@ class PairBornCoulWolfKokkos : public PairBornCoulWolf { void init_style() override; double init_one(int, int) override; + // NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + void operator()(TagPairBornCoulWolfSelfEnergy, const int&, KK_ACC_FLOAT&) const; + struct params_born_wolf { // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION @@ -95,6 +101,7 @@ class PairBornCoulWolfKokkos : public PairBornCoulWolf { typename AT::t_kkacc_1d_3 f; typename AT::t_int_1d_randomread type; typename AT::t_kkfloat_1d_randomread q; + typename AT::t_int_1d_randomread d_ilist; DAT::ttransform_kkacc_1d k_eatom; DAT::ttransform_kkacc_1d_6 k_vatom; diff --git a/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp index af085530a92..847b876dd80 100644 --- a/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp @@ -116,16 +116,21 @@ void PairLJCutCoulWolfKokkos::compute(int eflag_in, int vflag_in) qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; - // Wolf self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); - } - EV_FLOAT ev; copymode = 1; + // self energy of every local atom, tallied in a device kernel so that the + // charges and the per-atom energy stay resident on the device + + if (eflag) { + d_ilist = ((NeighListKokkos*) list)->d_ilist; + KK_ACC_FLOAT e_self_sum = 0.0; + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,list->inum), + *this,e_self_sum); + if (eflag_global) eng_coul += static_cast(e_self_sum); + } + ev = pair_compute,void> (this,(NeighListKokkos*)list); @@ -145,11 +150,6 @@ void PairLJCutCoulWolfKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); k_eatom.sync_host(); - // Add Wolf self-energy to per-atom energy after device sync - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eatom[i] += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); - } } if (vflag_atom) { @@ -247,6 +247,29 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, return ecoul; } +/* ---------------------------------------------------------------------- + self energy contribution of atom i; mirrors the ev_tally(i,i,...) call of + the CPU style + ---------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +void PairLJCutCoulWolfKokkos::operator()(TagPairLJCutCoulWolfSelfEnergy, + const int &ii, KK_ACC_FLOAT &e_self_sum) const +{ + const KK_FLOAT alf_kk = static_cast(m_alf); + const KK_FLOAT e_shift_kk = static_cast(e_shift); + + const int i = d_ilist[ii]; + const KK_FLOAT qtmp = q(i); + const KK_FLOAT e_self = -(e_shift_kk/static_cast(2.0) + + alf_kk/static_cast(MY_PIS)) * qtmp*qtmp*qqrd2e; + + if (eflag_global) e_self_sum += static_cast(e_self); + if (eflag_atom) d_eatom[i] += static_cast(e_self); +} + /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.h b/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.h index 552c45220df..5e352c03abe 100644 --- a/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.h +++ b/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.h @@ -29,6 +29,8 @@ PairStyle(lj/cut/coul/wolf/kk/host,PairLJCutCoulWolfKokkos); namespace LAMMPS_NS { +struct TagPairLJCutCoulWolfSelfEnergy{}; + template class PairLJCutCoulWolfKokkos : public PairLJCutCoulWolf { public: @@ -43,6 +45,10 @@ class PairLJCutCoulWolfKokkos : public PairLJCutCoulWolf { void init_style() override; double init_one(int, int) override; + // NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + void operator()(TagPairLJCutCoulWolfSelfEnergy, const int&, KK_ACC_FLOAT&) const; + protected: template // NOLINTNEXTLINE @@ -83,6 +89,7 @@ class PairLJCutCoulWolfKokkos : public PairLJCutCoulWolf { typename AT::t_kkacc_1d_3 f; typename AT::t_int_1d_randomread type; typename AT::t_kkfloat_1d_randomread q; + typename AT::t_int_1d_randomread d_ilist; DAT::ttransform_kkacc_1d k_eatom; DAT::ttransform_kkacc_1d_6 k_vatom; From 183e896f070d517a1ce227f650432612f83d9a4e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 5 Sep 2026 05:38:15 -0400 Subject: [PATCH 073/120] export macOS architecture and deployment settings to LAMMPS-GUI external project --- cmake/Modules/Tools.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index 6a20c0ba928..0c70b480225 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -67,6 +67,8 @@ if(BUILD_LAMMPS_GUI) -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D CMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -D CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + -D CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + -D CMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} DEPENDS lammps BUILD_BYPRODUCTS /bin/lammps-gui ) From b3df59c808b53abc592a8050d41fabef96b2af64 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 09:51:37 +0000 Subject: [PATCH 074/120] KOKKOS: restore the contact history of fix NEIGH_HISTORY from a restart The KOKKOS version of the internal fix NEIGH_HISTORY keeps the partner lists of every atom in dual views, but it did not override the three restart methods of the base class. Two things went wrong with that: write_restart() calls pre_exchange(), which fills the partner lists on the device and leaves the host copies behind, and pack_restart() and size_restart() then read those stale host copies, so the restart file gets whatever the host arrays happened to hold. unpack_restart() of the base class hands out a ragged row per atom from its page allocators and stores the pointer in partner[i], which for this class is a row of a rectangular dual view. The values read back from the restart file therefore ended up in the pages, never reached the device copy, and were dropped at the next resize of the dual view. Add the three overrides: the two packing methods synchronize the host side first, and unpack_restart() writes the values into the dual views and widens them when an atom has more contacts than any atom seen so far, the same way pre_exchange() does when its device loop runs out of room. Checked with a granular run (fcc lattice of overlapping spheres, pair gran/hooke/history) that builds up a tangential history over 20 steps, writes a restart file and is continued from it in a fresh process: the forces after the restart now agree with the ones of the plain styles to roundoff, where before the fix they were off by 9 percent. --- src/KOKKOS/fix_neigh_history_kokkos.cpp | 83 +++++++++++++++++++++++++ src/KOKKOS/fix_neigh_history_kokkos.h | 3 + 2 files changed, 86 insertions(+) diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index b8ed571545f..c2199a1ef63 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -22,6 +22,8 @@ #include "atom_vec_kokkos.h" #include "atom_masks.h" +#include + using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ @@ -535,6 +537,87 @@ int FixNeighHistoryKokkos::unpack_exchange(int nlocal, double *buf) return n; } +/* ---------------------------------------------------------------------- + pack values in local atom-based arrays for restart file +------------------------------------------------------------------------- */ + +template +int FixNeighHistoryKokkos::pack_restart(int i, double *buf) +{ + k_npartner.sync_host(); + k_partner.sync_host(); + k_valuepartner.sync_host(); + + return FixNeighHistory::pack_restart(i,buf); +} + +/* ---------------------------------------------------------------------- + unpack values from atom->extra array to restart the fix + + the base class hands out a ragged row per atom from its page allocators, + while this class keeps the partner lists in rectangular dual views. + unpacking through the base class would replace the row pointers of those + views with pointers into the pages, so that the values read back from the + restart file never reach the device copy and are lost at the next resize +------------------------------------------------------------------------- */ + +template +void FixNeighHistoryKokkos::unpack_restart(int nlocal, int nth) +{ + k_npartner.sync_host(); + k_partner.sync_host(); + k_valuepartner.sync_host(); + + // skip to Nth set of extra values + // unpack the Nth first values this way because other fixes pack them + + double **extra = atom->extra; + + int m = 0; + for (int i = 0; i < nth; i++) m += static_cast(extra[nlocal][m]); + m++; + + const int np = static_cast(extra[nlocal][m++]); + + // widen the partner lists when this atom has more contacts than any atom + // seen so far, the same way pre_exchange() does when the device loop runs + // out of room + + if (np > maxpartner) { + maxpartner = np; + memoryKK->grow_kokkos(k_partner,partner,atom->nmax,maxpartner, + "neighbor_history:partner"); + memoryKK->grow_kokkos(k_valuepartner,valuepartner,atom->nmax,dnum*maxpartner, + "neighbor_history:valuepartner"); + d_partner = k_partner.template view(); + d_valuepartner = k_valuepartner.template view(); + maxexchange = (dnum+1)*maxpartner + 2; + } + + npartner[nlocal] = np; + for (int n = 0; n < np; n++) { + partner[nlocal][n] = static_cast(ubuf(extra[nlocal][m++]).i); + memcpy(&valuepartner[nlocal][dnum*n],&extra[nlocal][m],dnumbytes); + m += dnum; + } + + k_npartner.modify_host(); + k_partner.modify_host(); + k_valuepartner.modify_host(); +} + +/* ---------------------------------------------------------------------- + size of atom nlocal's restart data +------------------------------------------------------------------------- */ + +template +int FixNeighHistoryKokkos::size_restart(int nlocal) +{ + k_npartner.sync_host(); + + return FixNeighHistory::size_restart(nlocal); +} + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_neigh_history_kokkos.h b/src/KOKKOS/fix_neigh_history_kokkos.h index d1115d5403f..9e48d9c275a 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.h +++ b/src/KOKKOS/fix_neigh_history_kokkos.h @@ -51,6 +51,9 @@ class FixNeighHistoryKokkos : public FixNeighHistory, public KokkosBase { void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; + int pack_restart(int, double *) override; + void unpack_restart(int, int) override; + int size_restart(int) override; double memory_usage() override; // NOLINTNEXTLINE From 27e7f3e11b6ecddc5181c0588a2c68ddfb5affad Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 10:13:35 +0000 Subject: [PATCH 075/120] unittest: keep the "sort no" kokkos profile on the half neighbor list "package kokkos neigh full" requires "newton off", so the cross-nosort profile of the package option matrix was rejected by every test case and the whole profile silently skipped instead of running. Pair the sorting and atom map settings it varies with the half list and newton on. --- unittest/force-styles/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt index 4fa15307aa1..be785b66bf6 100644 --- a/unittest/force-styles/CMakeLists.txt +++ b/unittest/force-styles/CMakeLists.txt @@ -403,7 +403,8 @@ if(PKG_KOKKOS AND ENABLE_KOKKOS_PROFILE_TESTS) set(KOKKOS_PROFILE_cross-hostpath "-pk kokkos comm host sort host atom/map host neigh half newton off") set(KOKKOS_PROFILE_cross-devicehalf "-pk kokkos comm device sort device atom/map device gpu/aware on neigh half newton on") set(KOKKOS_PROFILE_cross-nogpuaware "-pk kokkos comm device sort device atom/map device gpu/aware off neigh full newton off") - set(KOKKOS_PROFILE_cross-nosort "-pk kokkos comm device sort no atom/map no neigh full newton on") + # "neigh full" requires "newton off", so this profile keeps the half list + set(KOKKOS_PROFILE_cross-nosort "-pk kokkos comm device sort no atom/map no neigh half newton on") # the prefix, the driver and the file name pattern of every reference group, # in the same order the groups are registered above From 7039b3d642d7b485d3cdddea5b30299ea6c8ab68 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 5 Sep 2026 06:41:08 -0400 Subject: [PATCH 076/120] alternate approach to export multi-arch settings to external project --- cmake/Modules/Tools.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index 0c70b480225..170d9fd8fb1 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -51,12 +51,17 @@ if(BUILD_LAMMPS_GUI) if(NOT BUILD_SHARED_LIBS) message(FATAL_ERROR "Building LAMMPS-GUI currently requires setting -D BUILD_SHARED_LIBS=ON") endif() + # hack to support multi-arch builds for external project + if("${CMAKE_SYSTEM_NAME}" STEQUAL "Darwin") + list(JOIN CMAKE_OSX_ARCHITECTURES , MACOSX_ARCHS) + endif() # When building LAMMPS-GUI with LAMMPS we don't support plugin mode and don't include docs. ExternalProject_Add(lammps-gui_build GIT_REPOSITORY https://github.com/akohlmey/lammps-gui.git GIT_TAG main GIT_SHALLOW TRUE GIT_PROGRESS TRUE + LIST_SEPARATOR , CMAKE_ARGS -D BUILD_DOC=OFF -D LAMMPS_GUI_USE_PLUGIN=OFF -D LAMMPS_SOURCE_DIR=${LAMMPS_SOURCE_DIR} @@ -67,7 +72,7 @@ if(BUILD_LAMMPS_GUI) -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D CMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -D CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} - -D CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + -D CMAKE_OSX_ARCHITECTURES=${MACOSX_ARCHS} -D CMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} DEPENDS lammps BUILD_BYPRODUCTS /bin/lammps-gui From dc34baceba6f1142cd5c2f5278f7746e589d34ce Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 5 Sep 2026 06:43:11 -0400 Subject: [PATCH 077/120] fix typo --- cmake/Modules/Tools.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index 170d9fd8fb1..a29f15337e7 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -52,7 +52,7 @@ if(BUILD_LAMMPS_GUI) message(FATAL_ERROR "Building LAMMPS-GUI currently requires setting -D BUILD_SHARED_LIBS=ON") endif() # hack to support multi-arch builds for external project - if("${CMAKE_SYSTEM_NAME}" STEQUAL "Darwin") + if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") list(JOIN CMAKE_OSX_ARCHITECTURES , MACOSX_ARCHS) endif() # When building LAMMPS-GUI with LAMMPS we don't support plugin mode and don't include docs. From 8345f4db997f3bc44f44702dc8478ee55729852f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Sat, 5 Sep 2026 10:46:15 +0000 Subject: [PATCH 078/120] KOKKOS: stop copying arrays the styles never read Fourteen dihedral styles carry Q_MASK in their datamask_read, copied from dihedral charmm/kk, which needs the charges for its 1-4 coulomb term. None of them touches the charges. pair coul/dsf/kk, coul/wolf/kk, coul/wolf/cs/kk and pppm/kk likewise declare TYPE_MASK without having an atom type view at all: they have a single cutoff and no per-type parameters. Drop the unused bits, so that the framework does not move those arrays to the device for them. Also add tools/regression-tests/config_kokkos_serial.yaml, the KOKKOS Serial counterpart of config_kokkos_openmp.yaml: on the Serial backend most styles do the same arithmetic in the same order as the plain CPU code, so the tolerances are much tighter and a difference beyond roundoff points at a real difference between a style and its KOKKOS variant. --- src/KOKKOS/dihedral_class2_kokkos.cpp | 2 +- src/KOKKOS/dihedral_class2xe_kokkos.cpp | 2 +- .../dihedral_cosine_shift_exp_kokkos.cpp | 2 +- ...edral_cosine_squared_restricted_kokkos.cpp | 2 +- src/KOKKOS/dihedral_fourier_kokkos.cpp | 2 +- src/KOKKOS/dihedral_harmonic_kokkos.cpp | 2 +- src/KOKKOS/dihedral_helix_kokkos.cpp | 2 +- src/KOKKOS/dihedral_multi_harmonic_kokkos.cpp | 2 +- src/KOKKOS/dihedral_nharmonic_kokkos.cpp | 2 +- src/KOKKOS/dihedral_opls_kokkos.cpp | 2 +- src/KOKKOS/dihedral_quadratic_kokkos.cpp | 2 +- src/KOKKOS/dihedral_spherical_kokkos.cpp | 2 +- src/KOKKOS/dihedral_table_cut_kokkos.cpp | 2 +- src/KOKKOS/dihedral_table_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_wolf_cs_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_wolf_kokkos.cpp | 2 +- src/KOKKOS/pppm_kokkos.cpp | 2 +- .../config_kokkos_serial.yaml | 71 +++++++++++++++++++ 19 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 tools/regression-tests/config_kokkos_serial.yaml diff --git a/src/KOKKOS/dihedral_class2_kokkos.cpp b/src/KOKKOS/dihedral_class2_kokkos.cpp index 4050803c4be..c46276ebf68 100644 --- a/src/KOKKOS/dihedral_class2_kokkos.cpp +++ b/src/KOKKOS/dihedral_class2_kokkos.cpp @@ -42,7 +42,7 @@ DihedralClass2Kokkos::DihedralClass2Kokkos(LAMMPS *lmp) : DihedralCl atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_class2xe_kokkos.cpp b/src/KOKKOS/dihedral_class2xe_kokkos.cpp index d38511a978b..00cdd8e7409 100644 --- a/src/KOKKOS/dihedral_class2xe_kokkos.cpp +++ b/src/KOKKOS/dihedral_class2xe_kokkos.cpp @@ -43,7 +43,7 @@ DihedralClass2xeKokkos::DihedralClass2xeKokkos(LAMMPS *lmp) : Dihedr atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_cosine_shift_exp_kokkos.cpp b/src/KOKKOS/dihedral_cosine_shift_exp_kokkos.cpp index 586cc7c7c63..d4cd7b0bbfc 100644 --- a/src/KOKKOS/dihedral_cosine_shift_exp_kokkos.cpp +++ b/src/KOKKOS/dihedral_cosine_shift_exp_kokkos.cpp @@ -43,7 +43,7 @@ DihedralCosineShiftExpKokkos::DihedralCosineShiftExpKokkos(LAMMPS *l atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_cosine_squared_restricted_kokkos.cpp b/src/KOKKOS/dihedral_cosine_squared_restricted_kokkos.cpp index 7235530b9e9..2e881a7990d 100644 --- a/src/KOKKOS/dihedral_cosine_squared_restricted_kokkos.cpp +++ b/src/KOKKOS/dihedral_cosine_squared_restricted_kokkos.cpp @@ -45,7 +45,7 @@ DihedralCosineSquaredRestrictedKokkos::DihedralCosineSquaredRestrict atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_fourier_kokkos.cpp b/src/KOKKOS/dihedral_fourier_kokkos.cpp index 47522fe7783..72d6ade92bc 100644 --- a/src/KOKKOS/dihedral_fourier_kokkos.cpp +++ b/src/KOKKOS/dihedral_fourier_kokkos.cpp @@ -43,7 +43,7 @@ DihedralFourierKokkos::DihedralFourierKokkos(LAMMPS *lmp) : Dihedral atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_harmonic_kokkos.cpp b/src/KOKKOS/dihedral_harmonic_kokkos.cpp index b5aa96a9266..bba115a75f9 100644 --- a/src/KOKKOS/dihedral_harmonic_kokkos.cpp +++ b/src/KOKKOS/dihedral_harmonic_kokkos.cpp @@ -41,7 +41,7 @@ DihedralHarmonicKokkos::DihedralHarmonicKokkos(LAMMPS *lmp) : Dihedr atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_helix_kokkos.cpp b/src/KOKKOS/dihedral_helix_kokkos.cpp index 5987fee5964..32810d4ca3b 100644 --- a/src/KOKKOS/dihedral_helix_kokkos.cpp +++ b/src/KOKKOS/dihedral_helix_kokkos.cpp @@ -46,7 +46,7 @@ DihedralHelixKokkos::DihedralHelixKokkos(LAMMPS *lmp) : DihedralHeli atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_multi_harmonic_kokkos.cpp b/src/KOKKOS/dihedral_multi_harmonic_kokkos.cpp index 86a15cffbe5..aab9635d544 100644 --- a/src/KOKKOS/dihedral_multi_harmonic_kokkos.cpp +++ b/src/KOKKOS/dihedral_multi_harmonic_kokkos.cpp @@ -42,7 +42,7 @@ DihedralMultiHarmonicKokkos::DihedralMultiHarmonicKokkos(LAMMPS *lmp atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_nharmonic_kokkos.cpp b/src/KOKKOS/dihedral_nharmonic_kokkos.cpp index a484f7300d1..6cea4d44448 100644 --- a/src/KOKKOS/dihedral_nharmonic_kokkos.cpp +++ b/src/KOKKOS/dihedral_nharmonic_kokkos.cpp @@ -43,7 +43,7 @@ DihedralNHarmonicKokkos::DihedralNHarmonicKokkos(LAMMPS *lmp) : Dihe atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_opls_kokkos.cpp b/src/KOKKOS/dihedral_opls_kokkos.cpp index 728192bef34..dac47d27bdf 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.cpp +++ b/src/KOKKOS/dihedral_opls_kokkos.cpp @@ -43,7 +43,7 @@ DihedralOPLSKokkos::DihedralOPLSKokkos(LAMMPS *lmp) : DihedralOPLS(l atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_quadratic_kokkos.cpp b/src/KOKKOS/dihedral_quadratic_kokkos.cpp index 45039fca116..72659978638 100644 --- a/src/KOKKOS/dihedral_quadratic_kokkos.cpp +++ b/src/KOKKOS/dihedral_quadratic_kokkos.cpp @@ -46,7 +46,7 @@ DihedralQuadraticKokkos::DihedralQuadraticKokkos(LAMMPS *lmp) : Dihe atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_spherical_kokkos.cpp b/src/KOKKOS/dihedral_spherical_kokkos.cpp index fea9835d4df..749d253b336 100644 --- a/src/KOKKOS/dihedral_spherical_kokkos.cpp +++ b/src/KOKKOS/dihedral_spherical_kokkos.cpp @@ -42,7 +42,7 @@ DihedralSphericalKokkos::DihedralSphericalKokkos(LAMMPS *lmp) : Dihe atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_table_cut_kokkos.cpp b/src/KOKKOS/dihedral_table_cut_kokkos.cpp index f5cdeead64b..0a28d38b0eb 100644 --- a/src/KOKKOS/dihedral_table_cut_kokkos.cpp +++ b/src/KOKKOS/dihedral_table_cut_kokkos.cpp @@ -45,7 +45,7 @@ DihedralTableCutKokkos::DihedralTableCutKokkos(LAMMPS *lmp) : Dihedr atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); diff --git a/src/KOKKOS/dihedral_table_kokkos.cpp b/src/KOKKOS/dihedral_table_kokkos.cpp index a81b099add5..bc0593a6e58 100644 --- a/src/KOKKOS/dihedral_table_kokkos.cpp +++ b/src/KOKKOS/dihedral_table_kokkos.cpp @@ -45,7 +45,7 @@ DihedralTableKokkos::DihedralTableKokkos(LAMMPS *lmp) : DihedralTabl atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index 2b1de2f3ca2..fa72e322f83 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -45,7 +45,7 @@ PairCoulDSFKokkos::PairCoulDSFKokkos(LAMMPS *lmp) : PairCoulDSF(lmp) kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; } diff --git a/src/KOKKOS/pair_coul_wolf_cs_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_cs_kokkos.cpp index 9f3586c10d5..1fc308756c0 100644 --- a/src/KOKKOS/pair_coul_wolf_cs_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_cs_kokkos.cpp @@ -48,7 +48,7 @@ PairCoulWolfCSKokkos::PairCoulWolfCSKokkos(LAMMPS *lmp) : PairCoulWo kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; } diff --git a/src/KOKKOS/pair_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_kokkos.cpp index 3df662e3228..1d83a5356a3 100644 --- a/src/KOKKOS/pair_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_kokkos.cpp @@ -43,7 +43,7 @@ PairCoulWolfKokkos::PairCoulWolfKokkos(LAMMPS *lmp) : PairCoulWolf(l kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; } diff --git a/src/KOKKOS/pppm_kokkos.cpp b/src/KOKKOS/pppm_kokkos.cpp index 61aeb62787d..42b7b4853eb 100644 --- a/src/KOKKOS/pppm_kokkos.cpp +++ b/src/KOKKOS/pppm_kokkos.cpp @@ -56,7 +56,7 @@ PPPMKokkos::PPPMKokkos(LAMMPS *lmp) : PPPM(lmp) kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | Q_MASK; + datamask_read = X_MASK | F_MASK | Q_MASK; datamask_modify = F_MASK; group_group_enable = 0; diff --git a/tools/regression-tests/config_kokkos_serial.yaml b/tools/regression-tests/config_kokkos_serial.yaml new file mode 100644 index 00000000000..e27fe112e7a --- /dev/null +++ b/tools/regression-tests/config_kokkos_serial.yaml @@ -0,0 +1,71 @@ +--- + # Run the examples through the KOKKOS package on the Serial backend and + # compare with reference log files produced by the plain styles. The Serial + # backend does the same arithmetic in the same order as the plain CPU code + # in most styles, so the tolerances are much tighter than the ones of the + # GPU and OpenMP KOKKOS configurations: a difference beyond roundoff points + # at a real difference between a style and its KOKKOS variant. + lmp_binary: "" + nprocs: "1" + args: "-cite none -k on t 1 -sf kk" + kokkos: true + mpiexec: "" + mpiexec_numproc_flag: "" + tolerance: + PotEng: + abs: 1e-8 + rel: 1e-10 + TotEng: + abs: 1e-8 + rel: 1e-10 + Press: + abs: 1e-6 + rel: 1e-10 + Temp: + abs: 1e-8 + rel: 1e-10 + E_vdwl: + abs: 1e-8 + rel: 1e-10 + skip: + [ + in.*pod.InP, + in.dimer.mp, + in.disp, + in.disp2, + in.dos, + in.dsring2, + in.*_imd*, + in.bucky-plus-cnt*, + in.gREM, + in.peptide-plumed, + in.mliap.pytorch*, + in.mliap.unified*, + in.pod.compute, + in.widom.spce, + # the KOKKOS variants of these styles draw their random numbers from the + # device generator, so their trajectories cannot match the plain styles + in.dpdrx-shardlow, + in.spin.iron-nve, + in.spin.nvt_lattice, + in.spin.nvt_spin, + ] + + timeout: 240 + # input scripts in these folders must be run by the same worker in the listed + # order, since they read files written by another input script in the folder + # or would overwrite each other's output files + keep_together: + [ + PACKAGES/bocs/4_sites_LD_SG, + PACKAGES/rhok, + SPIN/read_restart, + ] + + # input scripts without a reference log file cannot be checked against anything, so + # they are only tested for not crashing, with their run commands shortened to this + # many steps (0 or empty: run them unchanged) + smoke_steps: 100 + + nugget: 1.0 + epsilon: 1e-16 From ad042bed98e48e7ca12c4ffd098920d9f3ebe2b7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 8 Sep 2026 04:30:37 -0400 Subject: [PATCH 079/120] use modern syntax --- src/lammps.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lammps.h b/src/lammps.h index e60e866209d..1422a8dcbf7 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -102,9 +102,9 @@ class LAMMPS { private: void help(); /// Default constructor. Declared private to prohibit its use - LAMMPS() {}; + LAMMPS() = default; /// Copy constructor. Declared private to prohibit its use - LAMMPS(const LAMMPS &) {}; + LAMMPS(const LAMMPS &) = default; }; } // namespace LAMMPS_NS From bc3965e9df5e46c4a611ed904a6dd5573bec13f7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:41:07 +0000 Subject: [PATCH 080/120] granular: keep the contact history fix id stable across a restart The granular pair styles that store a contact history name their internal fix NEIGH_HISTORY_HH and NEIGH_HISTORY_GRANULAR, with n taken from Pair::instance_me. That counter counts every Pair object ever created in the process, so it depends on how many pair styles a run happened to create before it read a restart file. When the number differs from the run that wrote the file, the fix gets an id that does not match the one stored there, Modify cannot match the per-atom data to a fix, and the run silently continues with an empty contact history. The only trace is Unused restart file peratom fix info: fix style: NEIGH_HISTORY, fix ID: NEIGH_HISTORY_HH0 Reading a restart file of a "pair gran/hooke/history" run right after a "pair_style zero" and a "clear" was enough to lose the history: the sum of the squared forces differed by 2.4 percent from the same file read as the first command of a process. Number the styles by their position in the simulation instead: a pair style that is not a hybrid sub-style is 0, and a sub-style takes its position in the sub-style list plus one. PairHybrid hands each sub-style that index when it creates it, so it is the same whenever the same pair style is set up again. The numbers are the ones a fresh process produced with instance_me -- the hybrid itself was 0 and its sub-styles followed -- so restart files written before this are still read correctly. Also give the KOKKOS twin of a unit test its own working directory: it runs the same executable as the plain entry, and the two overwrote each other's scratch files when ctest ran them in parallel. Checked: the reproducer above now gives the same result on both paths for the plain and the KOKKOS styles, and the note about unused restart information is gone; a hybrid of gran/hooke/history and gran/hertz/history keeps the ids NEIGH_HISTORY_HH1 and HH2 whether or not another pair style was created first; ctest is 1072/1081 with the nine failures all environmental (mpirun as root, and two tests that assume an unreadable file stays unreadable). --- src/GRANULAR/pair_gran_hooke_history.cpp | 26 ++++++++++++++++--- src/GRANULAR/pair_gran_hooke_history.h | 2 ++ src/GRANULAR/pair_granular.cpp | 13 +++++++++- src/KOKKOS/pair_gran_hertz_history_kokkos.cpp | 3 ++- src/KOKKOS/pair_gran_hooke_history_kokkos.cpp | 3 ++- src/pair.cpp | 23 ++++++++++++++++ src/pair.h | 6 +++++ src/pair_hybrid.cpp | 6 +++++ unittest/CMakeLists.txt | 7 ++++- 9 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 62d15abb3f9..7948e8d94df 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -68,6 +68,7 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : // this is so final order of Modify:fix will conform to input script fix_history = nullptr; + id_history = nullptr; fix_dummy = dynamic_cast( modify->add_fix("NEIGH_HISTORY_HH_DUMMY" + std::to_string(instance_me) + " all DUMMY")); } @@ -83,7 +84,8 @@ PairGranHookeHistory::~PairGranHookeHistory() if (!fix_history) modify->delete_fix("NEIGH_HISTORY_HH_DUMMY" + std::to_string(instance_me)); else - modify->delete_fix("NEIGH_HISTORY_HH" + std::to_string(instance_me)); + modify->delete_fix(id_history); + delete[] id_history; if (allocated) { memory->destroy(setflag); @@ -427,6 +429,21 @@ void PairGranHookeHistory::coeff(int narg, char **arg) if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients" + utils::errorurl(21)); } +/* ---------------------------------------------------------------------- + build the id of the fix that stores the contact history + + the id has to be the same in the run that writes a restart file and in the + run that reads it back, otherwise the per-atom history in the file cannot + be matched to the fix and is silently dropped, so it is built from the + position of this pair style in the simulation and not from instance_me +------------------------------------------------------------------------- */ + +void PairGranHookeHistory::set_history_id() +{ + delete[] id_history; + id_history = utils::strdup(fmt::format("NEIGH_HISTORY_HH{}", instance_index())); +} + /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ @@ -456,7 +473,8 @@ void PairGranHookeHistory::init_style() // this is so its order in the fix list is preserved if (history && (fix_history == nullptr)) { - auto cmd = fmt::format("NEIGH_HISTORY_HH{} all NEIGH_HISTORY {}", instance_me, size_history); + set_history_id(); + auto cmd = fmt::format("{} all NEIGH_HISTORY {}", id_history, size_history); fix_history = dynamic_cast( modify->replace_fix("NEIGH_HISTORY_HH_DUMMY" + std::to_string(instance_me), cmd, 1)); fix_history->pair = this; @@ -525,8 +543,8 @@ void PairGranHookeHistory::init_style() // set fix which stores history info if (history) { - fix_history = dynamic_cast( - modify->get_fix_by_id("NEIGH_HISTORY_HH" + std::to_string(instance_me))); + set_history_id(); + fix_history = dynamic_cast(modify->get_fix_by_id(id_history)); if (!fix_history) error->all(FLERR, "Could not find pair fix neigh history ID"); } } diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/GRANULAR/pair_gran_hooke_history.h index 90b5e312bb4..03aba5e01a9 100644 --- a/src/GRANULAR/pair_gran_hooke_history.h +++ b/src/GRANULAR/pair_gran_hooke_history.h @@ -59,6 +59,8 @@ class PairGranHookeHistory : public Pair { class FixDummy *fix_dummy; class FixNeighHistory *fix_history; + char *id_history; // id of fix_history, kept so that it survives a restart + void set_history_id(); // storage of rigid body masses for use in granular interactions diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 689800ba5f4..eb10c564933 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -82,7 +82,13 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp), fix_rigid(nullptr) // this is so final order of Modify:fix will conform to input script id_dummy = utils::strdup(std::string("NEIGH_HISTORY_GRANULAR_DUMMY") + std::to_string(instance_me)); -id_history = utils::strdup(std::string("NEIGH_HISTORY_GRANULAR") + std::to_string(instance_me)); + + // the id of the history fix is built in init_style() and not here: it has to + // be the same in the run that writes a restart file and in the run that reads + // it back, so it cannot come from instance_me, which counts every Pair ever + // created in the process, and the hybrid sub-style list is not populated yet + + id_history = nullptr; cutoff_global = -1.0; fix_history = nullptr; @@ -491,6 +497,11 @@ void PairGranular::init_style() // it replaces FixDummy, created in the constructor // this is so its order in the fix list is preserved + if (use_history) { + delete[] id_history; + id_history = utils::strdup(fmt::format("NEIGH_HISTORY_GRANULAR{}", instance_index())); + } + if (use_history && fix_history == nullptr) { fix_history = dynamic_cast(modify->replace_fix(id_dummy, fmt::format("{} all NEIGH_HISTORY {}", id_history, size_history),0)); fix_history->pair = this; diff --git a/src/KOKKOS/pair_gran_hertz_history_kokkos.cpp b/src/KOKKOS/pair_gran_hertz_history_kokkos.cpp index cd2bd4df6ba..5eead1bab24 100644 --- a/src/KOKKOS/pair_gran_hertz_history_kokkos.cpp +++ b/src/KOKKOS/pair_gran_hertz_history_kokkos.cpp @@ -68,7 +68,8 @@ void PairGranHertzHistoryKokkos::init_style() // this is so its order in the fix list is preserved if (history && fix_history == nullptr) { - auto cmd = std::string("NEIGH_HISTORY_HH") + std::to_string(instance_me) + " all "; + this->set_history_id(); + auto cmd = std::string(this->id_history) + " all "; if (execution_space == Device) cmd += "NEIGH_HISTORY/KK/DEVICE 3"; else diff --git a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp index 09960b03206..fb2aa271b50 100644 --- a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp +++ b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp @@ -68,7 +68,8 @@ void PairGranHookeHistoryKokkos::init_style() // this is so its order in the fix list is preserved if (history && fix_history == nullptr) { - auto cmd = std::string("NEIGH_HISTORY_HH") + std::to_string(instance_me) + " all "; + this->set_history_id(); + auto cmd = std::string(this->id_history) + " all "; if (execution_space == Device) cmd += "NEIGH_HISTORY/KK/DEVICE 3"; else diff --git a/src/pair.cpp b/src/pair.cpp index 604ccf0031e..8c6a3b14dfc 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -67,6 +67,8 @@ Pair::Pair(LAMMPS *lmp) : list_tally_compute(nullptr), elements(nullptr), elem1param(nullptr), elem2param(nullptr), elem3param(nullptr), map(nullptr) { + hybrid_index = -1; + instance_me = instance_total++; eng_vdwl = eng_coul = 0.0; @@ -153,6 +155,27 @@ Pair::~Pair() memory->destroy(cvatom); } +/* ---------------------------------------------------------------------- + index of this pair style within the current simulation + + a pair style that keeps state in an internal fix has to find that fix + again when a restart file written by an earlier run is read back, so the + fix id must be the same in both runs. instance_me cannot be used for it: + it counts every Pair ever created in the process, so it depends on how + many pair styles a run happened to create before it read the restart file. + the position in the sub-style list of a hybrid does not depend on that + history and is reproduced whenever the same pair style is set up again. + + the numbering is the one a fresh process produces with instance_me -- the + hybrid itself is 0 and its sub-styles follow -- so that restart files + written before this became deterministic are still read correctly +------------------------------------------------------------------------- */ + +int Pair::instance_index() +{ + return (hybrid_index >= 0) ? hybrid_index + 1 : 0; +} + // clang-format off /* ---------------------------------------------------------------------- diff --git a/src/pair.h b/src/pair.h index 55e42cd3b7f..8f6062f3ab4 100644 --- a/src/pair.h +++ b/src/pair.h @@ -238,12 +238,18 @@ class Pair : protected Pointers { class Compute **list_tally_compute; public: + // position in the sub-style list of the hybrid that owns this pair style, -1 + // when it is not a sub-style. set by PairHybrid, read by instance_index() + + int hybrid_index; + virtual void add_tally_callback(class Compute *); virtual void del_tally_callback(class Compute *); [[nodiscard]] bool did_tally_callback() const { return did_tally_flag != 0; } protected: int instance_me; // which Pair class instantiation I am + int instance_index(); // position within the current simulation, for internal fix ids int special_lj[4]; // copied from force->special_lj for Kokkos // pair_modify settings diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index f8f93d08416..a335653df0d 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -330,6 +330,12 @@ void PairHybrid::settings(int narg, char **arg) error->all(FLERR,"Pair style {} cannot have none as a sub-style", mystyle); styles[nstyles] = force->new_pair(arg[iarg],1,dummy); + + // a sub-style that keeps state in an internal fix builds the fix id from + // this position, so that the id is the same in a run that writes a restart + // file and in the run that reads it back + + styles[nstyles]->hybrid_index = nstyles; keywords[nstyles] = force->store_style(arg[iarg],0); special_lj[nstyles] = special_coul[nstyles] = nullptr; compute_tally[nstyles] = 1; diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 3f80a8b53d6..e9856e556b3 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -130,8 +130,13 @@ function(add_kokkos_test) add_test(NAME ${KKTEST_NAME}Kokkos COMMAND ${KKTEST_COMMAND}) set(KKTEST_ENV "${KOKKOS_TEST_ENVIRONMENT}") list(APPEND KKTEST_ENV ${KKTEST_ENVIRONMENT}) + # the KOKKOS entry runs the same executable as the plain one, so it needs a + # working directory of its own: the two would otherwise overwrite each + # other's scratch files when ctest runs them in parallel + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${KKTEST_NAME}Kokkos) set_tests_properties(${KKTEST_NAME}Kokkos PROPERTIES LABELS "kokkos" - ENVIRONMENT "${KKTEST_ENV}") + ENVIRONMENT "${KKTEST_ENV}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${KKTEST_NAME}Kokkos) endfunction() # incorporate categories of specific tests from subdirectories From 90e57c947ea5cdaedd9b6191defb53f0676f89bc Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:57:33 +0000 Subject: [PATCH 081/120] Fix the force expression in pair style lj/expand/sphere The pair force was formed as forcelj * rshift / r, but the gradient of the shifted Lennard-Jones potential requires a division: with r6inv = 1/rshift^6, forcelj is -rshift * dE/drshift, so the scalar is forcelj / rshift / r. The parent style has it right (src/pair_lj_expand.cpp:115); the sphere variant inverted the operator and the /omp and /kk variants inherited it by copy-adapt, so no accelerator-vs-reference comparison could see it. Every force in the style was off by a factor of rshift^2 and did not match the tallied energy. Demonstrated without relying on the derivation: lj/expand/sphere with every radius set to d/2 is by construction the same potential as lj/expand with shift = d. On identical coordinates the two agree on potential energy to every digit and disagree on force by more than an order of magnitude; after the fix they agree on both. The reference fixture was generated from the defective code and is regenerated here. Before regeneration it failed for exactly the three variants changed -- plain, omp and kokkos_omp -- and for no others. Note that PairStyle.single is skipped for this style, so the matching fix in single() is not covered by the fixture. --- src/EXTRA-PAIR/pair_lj_expand_sphere.cpp | 4 +- src/KOKKOS/pair_lj_expand_sphere_kokkos.cpp | 2 +- src/OPENMP/pair_lj_expand_sphere_omp.cpp | 2 +- .../tests/atomic-pair-lj_expand_sphere.yaml | 158 +++++++++--------- 4 files changed, 83 insertions(+), 83 deletions(-) diff --git a/src/EXTRA-PAIR/pair_lj_expand_sphere.cpp b/src/EXTRA-PAIR/pair_lj_expand_sphere.cpp index 568e17cf34a..a3335dcbb0e 100644 --- a/src/EXTRA-PAIR/pair_lj_expand_sphere.cpp +++ b/src/EXTRA-PAIR/pair_lj_expand_sphere.cpp @@ -119,7 +119,7 @@ void PairLJExpandSphere::compute(int eflag, int vflag) r6inv = r2inv * r2inv * r2inv; forcelj = r6inv * (lj1[itype][jtype] * r6inv - lj2[itype][jtype]); - fpair = factor_lj * forcelj * rshift / r; + fpair = factor_lj * forcelj / rshift / r; f[i][0] += delx * fpair; f[i][1] += dely * fpair; @@ -393,7 +393,7 @@ double PairLJExpandSphere::single(int i, int j, int itype, int jtype, double rsq r2inv = 1.0 / rshiftsq; r6inv = r2inv * r2inv * r2inv; forcelj = r6inv * (lj1[itype][jtype] * r6inv - lj2[itype][jtype]); - fforce = factor_lj * forcelj * rshift / r; + fforce = factor_lj * forcelj / rshift / r; philj = r6inv * (lj3[itype][jtype] * r6inv - lj4[itype][jtype]); if (offset_flag && (rshiftsq > 0.0)) { diff --git a/src/KOKKOS/pair_lj_expand_sphere_kokkos.cpp b/src/KOKKOS/pair_lj_expand_sphere_kokkos.cpp index 0ef7d556d9a..b6bfb034e65 100644 --- a/src/KOKKOS/pair_lj_expand_sphere_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_sphere_kokkos.cpp @@ -151,7 +151,7 @@ compute_fpair(const KK_FLOAT &rsq, const int &i, const int &j, const int &itype, const KK_FLOAT r2inv = static_cast(1.0) / (rshift*rshift); const KK_FLOAT r6inv = r2inv*r2inv*r2inv; - return r6inv*(lj1*r6inv - lj2) * rshift / r; + return r6inv*(lj1*r6inv - lj2) / rshift / r; } template diff --git a/src/OPENMP/pair_lj_expand_sphere_omp.cpp b/src/OPENMP/pair_lj_expand_sphere_omp.cpp index 66c6df5a746..0f9921f4653 100644 --- a/src/OPENMP/pair_lj_expand_sphere_omp.cpp +++ b/src/OPENMP/pair_lj_expand_sphere_omp.cpp @@ -146,7 +146,7 @@ void PairLJExpandSphereOMP::eval(int iifrom, int iito, ThrData *const thr) r6inv = r2inv * r2inv * r2inv; forcelj = r6inv * (lj1i[jtype] * r6inv - lj2i[jtype]); - fpair = factor_lj * forcelj * rshift / r; + fpair = factor_lj * forcelj / rshift / r; fxtmp += delx * fpair; fytmp += dely * fpair; diff --git a/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml b/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml index d929544809d..ef32e8b76db 100644 --- a/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml +++ b/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml @@ -1,13 +1,13 @@ --- -lammps_version: 28 Mar 2023 -date_generated: Fri Apr 7 18:07:13 2023 -tags: unstable +lammps_version: 2 Sep 2026 +tags: unstable generated +date_generated: Sat Sep 5 03:36:37 2026 epsilon: 7.5e-13 skip_tests: single -prerequisites: ! | +prerequisites: | pair lj/expand/sphere atom sphere -pre_commands: ! | +pre_commands: | echo screen atom_modify map array units lj @@ -20,86 +20,86 @@ pre_commands: ! | set group all diameter 0.5 set group all mass 1.0 velocity all create 3.0 4534624 loop geom -post_commands: ! "" +post_commands: "" input_file: in.empty pair_style: lj/expand/sphere 2.5 -pair_coeff: ! | +pair_coeff: | 1 1 1.0 0.5 -extract: ! | +extract: | epsilon 2 natoms: 32 init_vdwl: 282.83046925312897 init_coul: 0 -init_stress: ! |2- - 5.2775506240383015e+02 5.5367409865906279e+02 6.2263752488530645e+02 2.6414790726818893e+02 3.1054978131997751e+02 -1.5540736245498357e+02 -init_forces: ! |2 - 1 -3.0973407716749557e+02 -4.6493895260237184e+02 6.0862541594954507e+01 - 2 3.1392834710065119e+02 3.8492578008218243e+02 8.1027729045577274e+01 - 3 -3.8794009044930213e+01 1.1084188792919051e+01 -4.1834624277257859e+01 - 4 3.2843948883486142e+01 8.0025194771293044e+01 -4.4984695744755555e+01 - 5 1.9212297620739340e+00 9.7400781133880443e+00 -9.2814594282607015e+00 - 6 3.5850791934111306e+00 -1.6217163808025699e+01 7.0050375415432100e+00 - 7 -3.9577682854166774e+01 -3.5996981686635650e+01 -6.4860915678438538e+00 - 8 -1.5945733143265088e+02 -3.2767110280519341e+02 2.3305435312517460e+02 - 9 1.2930906846861396e+00 -8.5410269738501476e+00 -5.7545582440593197e+00 - 10 2.6352163547107894e+00 1.2706911205328020e+00 -3.6876035369971829e+00 - 11 -3.2926604449154610e+01 3.4603493695727707e+01 1.2229405795851829e+00 - 12 -8.7655206306522782e-01 7.2369100588872630e+00 1.2743003029880130e+01 - 13 -2.0502855572417326e+02 2.1217050721158157e+02 -5.5551689327598285e+02 - 14 8.5045346311108261e-01 -1.8876992428080808e+00 -1.3287140663855337e+00 - 15 3.9397857357740878e+02 9.1512006702422354e+01 3.1988432909847364e+02 - 16 1.2024726068893671e-01 -6.4479994906666143e+00 9.8119981533709399e+00 - 17 8.3450867344361601e+00 -4.3064169083842366e+01 5.0696514462952543e+01 - 18 1.2469320277383257e+01 -1.7092535174071564e+01 2.3108650365793970e+00 - 19 2.5516035336657449e+01 -8.5592576038828927e+00 -3.0035720938622955e+01 - 20 -2.9406958888230676e+01 9.0992453423433545e+01 -1.0973566121483356e+02 - 21 3.5820389309115235e+01 -1.1913507535366119e+01 4.4134664089233887e+01 - 22 2.9914634597023113e+01 -4.0600291690862164e+01 9.9523541097824730e-01 - 23 -2.3898077456468680e+01 3.9397894453343604e+01 6.9866614856267804e+00 - 24 -3.4546166344294194e-01 -4.6000354891830879e+00 -4.9075478349482848e+00 - 25 -1.2403968554522221e+01 1.1352325143145988e+01 -1.7323992572082201e+00 - 26 7.4076846095557780e-01 2.8431653574870919e+00 7.5794842230142401e-01 - 27 4.0253909180451319e-01 -4.7173478162652616e-01 -1.0777843607667181e-01 - 28 1.7904029784263514e+02 1.1945100452224533e+01 2.0561835906855745e+02 - 29 -3.2753076565692659e+01 4.0864923925097976e+01 6.1889228039680899e-01 - 30 -1.5690380260674604e+02 -5.2868262234426325e+01 -2.1085100078738611e+02 - 31 -2.8667945827588186e+00 1.1449358804961459e+01 -1.1166681463143947e+01 - 32 1.5676951232600058e+00 -5.4335190581604254e-01 -3.1964235142334058e-01 -run_vdwl: 274.2990918208642 +init_stress: |2- + 3.7628612501872740e+03 3.8353513428988877e+03 4.2810059740327461e+03 1.8787767132453598e+03 2.0317820725844836e+03 -9.0751079978557004e+02 +init_forces: |2 + 1 -2.1362662096601016e+03 -3.1563141875504180e+03 2.1732112275069264e+02 + 2 2.1615276962423914e+03 2.7007996714379397e+03 5.1203296929966291e+02 + 3 -1.8616902279963261e+02 5.6998689490989257e+01 -2.1089460050366313e+02 + 4 1.5743985242178951e+02 3.8589308743136206e+02 -2.2046698065178180e+02 + 5 6.6614950727078694e+00 3.5347792765191898e+01 -3.4317583757296859e+01 + 6 1.0236063486632005e+01 -5.7007956623202091e+01 2.5900292994472803e+01 + 7 -1.8367046793719436e+02 -1.7351194212544951e+02 -2.2502659519445842e+01 + 8 -1.0009220015794934e+03 -2.0042036805024077e+03 1.5330781011933925e+03 + 9 2.1464808197985201e+00 -3.0889139191599071e+01 -2.3852803039728816e+01 + 10 7.3092495721323454e+00 2.1571706582984236e+00 -1.3825543334311950e+01 + 11 -1.5287199632764265e+02 1.6825438094870137e+02 1.9168871333822992e+01 + 12 -2.4250232798475002e-01 2.5759734243662606e+01 4.5964492017445949e+01 + 13 -1.4113299629351168e+03 1.3622941157471091e+03 -3.7461381394384061e+03 + 14 -3.9708631349320861e-01 -5.4633878024937266e+00 -1.7475842955774508e+00 + 15 2.5565989811878717e+03 5.1175302271263342e+02 2.1948295198370179e+03 + 16 1.7444213032632687e+00 -2.4332677177732425e+01 3.6893586749288019e+01 + 17 3.3026213091343365e+01 -2.1137696472390377e+02 2.4004826645800637e+02 + 18 4.9907366172647421e+01 -6.4247362466584647e+01 8.6317560947764598e+00 + 19 1.0894839564136240e+02 -3.6839838416992997e+01 -1.3509465002682430e+02 + 20 -1.3391940086497948e+02 4.9852793185413913e+02 -5.8853381745277773e+02 + 21 1.7780827885707288e+02 -5.8019793107381396e+01 2.1716256056992233e+02 + 22 1.4120083791229646e+02 -1.8981232430163490e+02 4.3815757944698861e+00 + 23 -1.0724298362126513e+02 1.6752786540908781e+02 2.7039527208784452e+01 + 24 -4.4949713115911748e-02 -1.6652248714142040e+01 -1.7560619727290625e+01 + 25 -4.8900448250958270e+01 4.6016426237489014e+01 -5.0701734331221200e+00 + 26 1.2134201227223429e+00 6.9803036468343631e+00 7.6874298790833673e-01 + 27 6.1627392146156934e-01 -1.2811189883765481e+00 1.1245221957965730e+00 + 28 1.0922969857660023e+03 1.2173768885766606e+02 1.2805642383132119e+03 + 29 -1.5041483748647616e+02 1.9271433571034476e+02 7.7977679156159785e-01 + 30 -9.9227615863676476e+02 -2.9371460425897425e+02 -1.3023490763743280e+03 + 31 -9.1656542229907814e+00 4.2776448829748830e+01 -4.0363682301023552e+01 + 32 5.1516710857143933e+00 -1.8714400299016762e+00 -2.9720087346563866e+00 +run_vdwl: 269.727714879717 run_coul: 0 -run_stress: ! |2- - 5.1714409572652460e+02 5.3625773716054277e+02 6.1690607575918318e+02 2.5070481857095862e+02 3.1143040329966658e+02 -1.4890074896238198e+02 -run_forces: ! |2 - 1 -2.9872137697246637e+02 -4.4766107419413584e+02 6.0647333893132199e+01 - 2 3.0255191699296199e+02 3.6998601385805796e+02 7.9218020317854240e+01 - 3 -3.9071135071710799e+01 1.1163950343554788e+01 -4.2325217924175810e+01 - 4 3.0566863724080982e+01 7.7876413009085582e+01 -4.5074124503041318e+01 - 5 1.8214256173824062e+00 9.6607230357436435e+00 -9.1198100800425159e+00 - 6 3.6081721576481876e+00 -1.5727386373912156e+01 6.6824240084413100e+00 - 7 -3.7124263393562941e+01 -3.3702121585802473e+01 -6.3324667407146373e+00 - 8 -1.5083044754066393e+02 -3.1596504088057020e+02 2.2443496411725829e+02 - 9 1.2358475516778165e+00 -8.6837956350058576e+00 -5.8230926194515256e+00 - 10 2.8763375476058268e+00 1.2888785166531662e+00 -3.9998914713111398e+00 - 11 -3.2874608506261680e+01 3.4814746969569462e+01 1.1158915828410489e+00 - 12 -1.0500802364781463e+00 7.3052869560239344e+00 1.3149505813954047e+01 - 13 -2.0295169708042584e+02 2.0451471889002184e+02 -5.4211284120727498e+02 - 14 8.0167713625652437e-01 -1.9038388558174164e+00 -1.2776126600613640e+00 - 15 3.8350783987497169e+02 8.7329404069189408e+01 3.1484944924644219e+02 - 16 6.8729717021472417e-02 -6.4823162177404479e+00 9.7051676735870398e+00 - 17 8.1837934233145226e+00 -4.3213842298296228e+01 5.0610428999728768e+01 - 18 1.2819373021880899e+01 -1.7465566612856481e+01 2.3100950500010926e+00 - 19 2.5476508502944384e+01 -8.6214834818888786e+00 -3.0032900448302939e+01 - 20 -2.9150000205294297e+01 8.8457001197613096e+01 -1.0750638056744367e+02 - 21 3.6173690433418692e+01 -1.1928633930432888e+01 4.4388764049564671e+01 - 22 3.0844439206742976e+01 -4.1984766054712672e+01 1.1349887570818860e+00 - 23 -2.3820927358539908e+01 3.9964873580113945e+01 7.6090205042666987e+00 - 24 -3.3666623155217118e-01 -4.6280716644500020e+00 -4.8936311631597302e+00 - 25 -1.2792833076985820e+01 1.1688222849014467e+01 -1.7238158536564625e+00 - 26 7.3526288881015733e-01 2.9377073950706922e+00 8.1452444851379469e-01 - 27 4.0398472595622142e-01 -4.2438395733587897e-01 -1.3243893641134002e-01 - 28 1.8498452849481993e+02 1.3462056267007117e+01 2.1237099014664119e+02 - 29 -3.3822718427774774e+01 4.2333161151161541e+01 7.1365964586470942e-01 - 30 -1.6280809441169345e+02 -5.4866903520831791e+01 -2.1822217598346288e+02 - 31 -2.8933602001305254e+00 1.1023778731650578e+01 -1.0845998952084912e+01 - 32 1.5878176960462480e+00 -5.4771155574196739e-01 -3.3282914457770202e-01 +run_stress: |2- + 3.6360061594803633e+03 3.6549658113290093e+03 4.1873259775097977e+03 1.7491515319576399e+03 2.0110781345239016e+03 -8.5547584186171741e+02 +run_forces: |2 + 1 -2.0096043018155447e+03 -2.9705631141959707e+03 2.2358696523081517e+02 + 2 2.0318659561236625e+03 2.5337617756579584e+03 4.8730456174636362e+02 + 3 -1.8761979669868435e+02 5.7314908669725618e+01 -2.1287928962274958e+02 + 4 1.4456632861281483e+02 3.7343613312294633e+02 -2.2070979650590553e+02 + 5 6.3206583645037693e+00 3.4960581645609629e+01 -3.3666214258990273e+01 + 6 1.0213355909120629e+01 -5.4786279407874190e+01 2.4503129068480458e+01 + 7 -1.7005624752968757e+02 -1.6050818578212650e+02 -2.1757282323774369e+01 + 8 -9.2868966040322300e+02 -1.8961140304106812e+03 1.4463465815756863e+03 + 9 1.9561564139981744e+00 -3.1455634036009045e+01 -2.4161196368280368e+01 + 10 8.2347075023567111e+00 2.2241764818839287e+00 -1.5033498653758429e+01 + 11 -1.5249666899753842e+02 1.6896747527870764e+02 1.8702066069457342e+01 + 12 -9.5889966623400014e-01 2.6102895106853826e+01 4.7568200369334249e+01 + 13 -1.3696867307819887e+03 1.2861948849539215e+03 -3.5844445408615429e+03 + 14 -5.4809617954501277e-01 -5.4794038122304825e+00 -1.5786327274690723e+00 + 15 2.4434429649977023e+03 4.7930713954086900e+02 2.1190262098118578e+03 + 16 1.4918638305671736e+00 -2.4402870414110339e+01 3.6484171675109728e+01 + 17 3.2351969790662963e+01 -2.1189609333035776e+02 2.3948563613324140e+02 + 18 5.1582619029677971e+01 -6.5955577497842683e+01 8.5790610376584855e+00 + 19 1.0879532747717288e+02 -3.6935870311761882e+01 -1.3489315754925926e+02 + 20 -1.3124569377237276e+02 4.7898731781314655e+02 -5.6959176526257318e+02 + 21 1.7950107880405872e+02 -5.8101547680334512e+01 2.1836526436238205e+02 + 22 1.4632333154689670e+02 -1.9731611266847170e+02 5.0646113472243490e+00 + 23 -1.0646594913631708e+02 1.6980193621321226e+02 2.9986134117238048e+01 + 24 -2.4890346653355461e-02 -1.6844810304302133e+01 -1.7605639907603635e+01 + 25 -5.0676867636126111e+01 4.7582026111057750e+01 -5.0356399128382083e+00 + 26 1.1772942066452421e+00 7.2783655103384950e+00 9.7777102985728526e-01 + 27 6.3555864930012496e-01 -1.1005992324234783e+00 1.0130780042539462e+00 + 28 1.1273196718766237e+03 1.3043281496376107e+02 1.3205518076393721e+03 + 29 -1.5604253910779303e+02 2.0048592906462849e+02 9.6009450289829579e-01 + 30 -1.0276525059194719e+03 -3.0436785402773239e+02 -1.3452774237446026e+03 + 31 -9.2244695411252753e+00 4.0852099746314032e+01 -3.8875089690704243e+01 + 32 5.2144743965406288e+00 -1.8624767687059889e+00 -2.9961763311744232e+00 ... From 6c73f28a7b8c4706931d2184e192304ac5f49f99 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:57:33 +0000 Subject: [PATCH 082/120] Fix inner-cutoff indexing in compute sna/grid and sna/grid/local sinnerelem and dinnerelem are allocated with ntypes+1 entries and filled at indices 1..ntypes, i.e. indexed by atom type. Both files then read them with jelem, the 0-based element index. In a single-element run jelem is 0 and the read lands on a slot that is never written; with several elements it is the wrong entry. Every sibling in the package -- compute_snap, compute_sna_atom, compute_snad_atom, compute_snav_atom -- reads sinnerelem[itype]/[jtype], and the neighbouring lines in these same files already use jtype for wjelem and radelem. Only these two lines used jelem. The KOKKOS grid computes had a different defect on the same line: they index by type correctly but averaged in d_sinnerelem[itype], where itype is a hardcoded 1 because a grid point has no atom type. That is the pair-snap convention applied where there is no central atom; they now use the neighbour's value alone, matching the CPU. --- src/KOKKOS/compute_sna_grid_kokkos_impl.h | 226 ++++++++------ .../compute_sna_grid_local_kokkos_impl.h | 275 +++++++++--------- src/ML-SNAP/compute_sna_grid.cpp | 4 +- src/ML-SNAP/compute_sna_grid_local.cpp | 4 +- 4 files changed, 276 insertions(+), 233 deletions(-) diff --git a/src/KOKKOS/compute_sna_grid_kokkos_impl.h b/src/KOKKOS/compute_sna_grid_kokkos_impl.h index 5c3e047cb4d..8ce5b6a7eff 100644 --- a/src/KOKKOS/compute_sna_grid_kokkos_impl.h +++ b/src/KOKKOS/compute_sna_grid_kokkos_impl.h @@ -36,8 +36,6 @@ #include #include -#include - #define MAXLINE 1024 #define MAXWORD 3 @@ -61,26 +59,21 @@ ComputeSNAGridKokkos::ComputeS host_flag = (execution_space == HostKK); - // TODO: Extract cutsq in double loop below, no need for cutsq_tmp - - cutsq_tmp = cutsq[1][1]; + const int n = atom->ntypes; - for (int i = 1; i <= atom->ntypes; i++) { - for (int j = 1; j <= atom->ntypes; j++){ - k_cutsq.view_host()(i,j) = k_cutsq.view_host()(j,i) = cutsq_tmp; - k_cutsq.modify_host(); - } - } + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) + k_cutsq.view_host()(i,j) = k_cutsq.view_host()(j,i) = cutsq[i][j]; + k_cutsq.modify_host(); - // Set up element lists - MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridKokkos::radelem",nelements); - MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridKokkos:wjelem",nelements); - MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridKokkos:sinnerelem",nelements); - MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridKokkos:dinnerelem",nelements); - // test - MemKK::realloc_kokkos(d_test, "ComputeSNAGridKokkos::test", nelements); + // Unlike pair style snap, the grid computes index radelem, wjelem, sinnerelem + // and dinnerelem by atom type (1 to ntypes), not by element, so these views + // are sized and filled accordingly. - int n = atom->ntypes; + MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridKokkos::radelem",n+1); + MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridKokkos::wjelem",n+1); + MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridKokkos::sinnerelem",n+1); + MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridKokkos::dinnerelem",n+1); MemKK::realloc_kokkos(d_map,"ComputeSNAGridKokkos::map",n+1); auto h_radelem = Kokkos::create_mirror_view(d_radelem); @@ -88,37 +81,31 @@ ComputeSNAGridKokkos::ComputeS auto h_sinnerelem = Kokkos::create_mirror_view(d_sinnerelem); auto h_dinnerelem = Kokkos::create_mirror_view(d_dinnerelem); auto h_map = Kokkos::create_mirror_view(d_map); - // test - auto h_test = Kokkos::create_mirror_view(d_test); - h_test(0) = 2.0; - - // start from index 1 because of how compute sna/grid is - for (int i = 1; i <= atom->ntypes; i++) { - h_radelem(i-1) = static_cast(radelem[i]); - h_wjelem(i-1) = static_cast(wjelem[i]); - if (switchinnerflag){ + + // index 0 is unused by the type-indexed lookups, but is initialized so that + // no kernel can ever read an uninitialized value + + h_radelem(0) = h_wjelem(0) = static_cast(0.0); + h_sinnerelem(0) = h_dinnerelem(0) = static_cast(0.0); + h_map(0) = 0; + + for (int i = 1; i <= n; i++) { + h_radelem(i) = static_cast(radelem[i]); + h_wjelem(i) = static_cast(wjelem[i]); + if (switchinnerflag) { h_sinnerelem(i) = static_cast(sinnerelem[i]); h_dinnerelem(i) = static_cast(dinnerelem[i]); + } else { + h_sinnerelem(i) = h_dinnerelem(i) = static_cast(0.0); } - } - - // In pair snap some things like `map` get allocated regardless of chem flag. - if (chemflag){ - for (int i = 1; i <= atom->ntypes; i++) { - h_map(i) = map[i]; - } + h_map(i) = chemflag ? map[i] : 0; } Kokkos::deep_copy(d_radelem,h_radelem); Kokkos::deep_copy(d_wjelem,h_wjelem); - if (switchinnerflag){ - Kokkos::deep_copy(d_sinnerelem,h_sinnerelem); - Kokkos::deep_copy(d_dinnerelem,h_dinnerelem); - } - if (chemflag){ - Kokkos::deep_copy(d_map,h_map); - } - Kokkos::deep_copy(d_test,h_test); + Kokkos::deep_copy(d_sinnerelem,h_sinnerelem); + Kokkos::deep_copy(d_dinnerelem,h_dinnerelem); + Kokkos::deep_copy(d_map,h_map); snaKK = SNAKokkos(*this); snaKK.grow_rij(0,0,padding_factor); @@ -151,6 +138,18 @@ void ComputeSNAGridKokkos::set { // Do not call ComputeGrid::setup(), we don't wanna allocate the grid array there. // Instead, call ComputeGrid::set_grid_global and set_grid_local to set the n indices. + // ComputeGrid::deallocate() cannot be used either, since it would call free() on the + // Kokkos-owned storage behind "grid", so release the arrays the same way the + // destructor does. This has to happen before set_grid_local() changes the bounds + // that destroy4d_offset() needs. + + memoryKK->destroy_kokkos(k_grid, grid); + memory->destroy(gridall); + if (gridlocal_allocated) { + gridlocal_allocated = 0; + memory->destroy4d_offset(gridlocal, nzlo, nylo, nxlo); + } + array = nullptr; ComputeGrid::set_grid_global(); ComputeGrid::set_grid_local(); @@ -174,7 +173,9 @@ template::compute_array() { if (host_flag) { + atomKK->sync(Host,X_MASK|TYPE_MASK|MASK_MASK); ComputeSNAGrid::compute_array(); + k_grid.modify_host(); return; } @@ -185,14 +186,17 @@ void ComputeSNAGridKokkos::com xlen = nxhi-nxlo+1; total_range = (nzhi-nzlo+1)*(nyhi-nylo+1)*(nxhi-nxlo+1); - atomKK->sync(execution_space,X_MASK|F_MASK|TYPE_MASK); + atomKK->sync(execution_space,X_MASK|F_MASK|TYPE_MASK|MASK_MASK); x = atomKK->k_x.view(); type = atomKK->k_type.view(); + mask = atomKK->k_mask.view(); k_cutsq.template sync(); Kokkos::deep_copy(d_grid,0.0); - // max_neighs is defined here - think of more elaborate methods. + // initial guess for the number of atoms within the cutoff of a grid point; + // the ComputeNeigh launch below grows this if a grid point needs more + max_neighs = 100; // Pair snap/kk uses grow_ij with some max number of neighs but compute sna/grid uses total @@ -201,11 +205,13 @@ void ComputeSNAGridKokkos::com ntotal = atomKK->nlocal + atomKK->nghost; // Allocate view for number of neighbors per grid point MemKK::realloc_kokkos(d_ninside,"ComputeSNAGridKokkos:ninside",total_range); + auto h_ninside = Kokkos::create_mirror_view(d_ninside); // "chunksize" variable is default 32768 in compute_sna_grid.cpp, and set by user // `total_range` is the number of grid points which may be larger than chunk size. chunk_size = MIN(chunksize, total_range); chunk_offset = 0; + const int chunk_size_max = chunk_size; snaKK.grow_rij(chunk_size, max_neighs, padding_factor); // Pre-compute ceil(chunk_size / vector_length) for code cleanliness @@ -231,12 +237,29 @@ void ComputeSNAGridKokkos::com //ComputeNeigh { - int scratch_size = scratch_size_helper(team_size_compute_neigh * max_neighs); //ntotal); + // The kernel records the true neighbor count of every grid point but stores at + // most max_neighs neighbors. If any grid point in this chunk has more, grow the + // SNA neighbor arrays and repeat, rather than overrunning them. + + for (int attempt = 0; attempt < 2; attempt++) { + int scratch_size = scratch_size_helper(team_size_compute_neigh * max_neighs); + + SnapAoSoATeamPolicy + policy_neigh(chunk_size, team_size_compute_neigh, vector_length); + policy_neigh = policy_neigh.set_scratch_size(0, Kokkos::PerTeam(scratch_size)); + Kokkos::parallel_for("ComputeNeigh",policy_neigh,*this); - SnapAoSoATeamPolicy - policy_neigh(chunk_size, team_size_compute_neigh, vector_length); - policy_neigh = policy_neigh.set_scratch_size(0, Kokkos::PerTeam(scratch_size)); - Kokkos::parallel_for("ComputeNeigh",policy_neigh,*this); + Kokkos::deep_copy(h_ninside, d_ninside); + int max_ninside = 0; + for (int ii = 0; ii < chunk_size; ii++) + if (h_ninside(ii) > max_ninside) max_ninside = h_ninside(ii); + + if (max_ninside <= max_neighs) break; + + max_neighs = max_ninside; + // grow with the full chunk size so a short final chunk cannot shrink the arrays + snaKK.grow_rij(chunk_size_max, max_neighs, padding_factor); + } } //ComputeCayleyKlein @@ -423,65 +446,63 @@ void ComputeSNAGridKokkos::ope const KK_FLOAT ytmp = xgrid[1]; const KK_FLOAT ztmp = xgrid[2]; - // currently, all grid points are type 1 - // not clear what a better choice would be - - const int itype = 1; - int ielem = 0; - if (chemflag) ielem = d_map[itype]; - //const KK_FLOAT radi = d_radelem[ielem]; - // Compute the number of neighbors, store rsq int ninside = 0; // Looping over ntotal for now. + // The cutoff test uses cutsq(jtype,jtype), matching ComputeSNAGrid::compute_array(): + // a grid point takes on the radius of the neighbor it is being compared against. for (int j = 0; j < ntotal; j++){ + + // check that j is in compute group + + if (!(mask(j) & groupbit)) continue; + const double dx = static_cast(x(j,0) - xtmp); const double dy = static_cast(x(j,1) - ytmp); const double dz = static_cast(x(j,2) - ztmp); - int jtype = type(j); + const int jtype = type(j); const double rsq = dx*dx + dy*dy + dz*dz; // don't include atoms that share location with grid point - if (rsq >= rnd_cutsq(itype,jtype) || rsq < 1e-20) { - jtype = -1; // use -1 to signal it's outside the radius - } - - if (jtype >= 0) + if (rsq < rnd_cutsq(jtype,jtype) && rsq > 1e-20) ninside++; } d_ninside(ii) = ninside; - // TODO: Adjust for multi-element, currently we set jelem = 0 regardless of type. int offset = 0; for (int j = 0; j < ntotal; j++){ - //const int jtype = type_cache[j]; - //if (jtype >= 0) { + + // check that j is in compute group + + if (!(mask(j) & groupbit)) continue; + const double dx = static_cast(x(j,0) - xtmp); const double dy = static_cast(x(j,1) - ytmp); const double dz = static_cast(x(j,2) - ztmp); const double rsq = dx*dx + dy*dy + dz*dz; - int jtype = type(j); - if (rsq < rnd_cutsq(itype,jtype) && rsq > 1e-20) { - int jelem = 0; - if (chemflag) jelem = d_map[jtype]; - snaKK.rij(ii,offset,0) = static_cast(dx); - snaKK.rij(ii,offset,1) = static_cast(dy); - snaKK.rij(ii,offset,2) = static_cast(dz); - // pair snap uses jelem here, but we use jtype, see compute_sna_grid.cpp - // actually since the views here have values starting at 0, let's use jelem - snaKK.wj(ii,offset) = static_cast(d_wjelem[jelem]); - snaKK.rcutij(ii,offset) = static_cast((2.0 * static_cast(d_radelem[jelem]))*rcutfac); - snaKK.inside(ii,offset) = j; - if (switchinnerflag) { - snaKK.sinnerij(ii,offset) = static_cast(0.5)*(d_sinnerelem[ielem] + d_sinnerelem[jelem]); - snaKK.dinnerij(ii,offset) = static_cast(0.5)*(d_dinnerelem[ielem] + d_dinnerelem[jelem]); - } - if (chemflag) + const int jtype = type(j); + if (rsq < rnd_cutsq(jtype,jtype) && rsq > 1e-20) { + // a chunk with more neighbors than the arrays were grown for is detected + // on the host, which then grows the arrays and re-runs this kernel + if (offset < max_neighs) { + int jelem = 0; + if (chemflag) jelem = d_map[jtype]; + snaKK.rij(ii,offset,0) = static_cast(dx); + snaKK.rij(ii,offset,1) = static_cast(dy); + snaKK.rij(ii,offset,2) = static_cast(dz); + // weights, radii and inner cutoffs are per atom type here, not per + // element, see ComputeSNAGrid::compute_array() + snaKK.wj(ii,offset) = d_wjelem[jtype]; + snaKK.rcutij(ii,offset) = static_cast((2.0 * static_cast(d_radelem[jtype]))*rcutfac); + snaKK.inside(ii,offset) = j; + if (switchinnerflag) { + snaKK.sinnerij(ii,offset) = d_sinnerelem[jtype]; + snaKK.dinnerij(ii,offset) = d_dinnerelem[jtype]; + } snaKK.element(ii,offset) = jelem; - else - snaKK.element(ii,offset) = 0; + } offset++; } } @@ -517,8 +538,10 @@ void ComputeSNAGridKokkos::ope const int iatom = iatom_mod + iatom_div * vector_length; if (iatom >= chunk_size) return; - int itype = type(iatom); - int ielem = d_map[itype]; + // all grid points are type 1, iatom is a grid index and must not be used + // to look up an atom type, see ComputeSNAGrid::compute_array() + const int itype = 1; + const int ielem = chemflag ? d_map[itype] : 0; snaKK.pre_ui(iatom, j, ielem); } @@ -529,8 +552,10 @@ KOKKOS_INLINE_FUNCTION void ComputeSNAGridKokkos::operator() (TagCSNAGridPreUi, const int& iatom, const int& j) const { if (iatom >= chunk_size) return; - int itype = type(iatom); - int ielem = d_map[itype]; + // all grid points are type 1, iatom is a grid index and must not be used + // to look up an atom type, see ComputeSNAGrid::compute_array() + const int itype = 1; + const int ielem = chemflag ? d_map[itype] : 0; snaKK.pre_ui(iatom, j, ielem); } @@ -541,8 +566,10 @@ KOKKOS_INLINE_FUNCTION void ComputeSNAGridKokkos::operator() (TagCSNAGridPreUi, const int& iatom) const { if (iatom >= chunk_size) return; - const int itype = type(iatom); - const int ielem = d_map[itype]; + // all grid points are type 1, iatom is a grid index and must not be used + // to look up an atom type, see ComputeSNAGrid::compute_array() + const int itype = 1; + const int ielem = chemflag ? d_map[itype] : 0; for (int j = 0; j <= twojmax; j++) snaKK.pre_ui(iatom, j, ielem); @@ -676,7 +703,10 @@ void ComputeSNAGridKokkos::ope const int iatom = iatom_mod + iatom_div * vector_length; if (iatom >= chunk_size) return; if (jjb >= snaKK.idxb_max) return; - snaKK.template compute_bi(iatom, jjb); + // all grid points are type 1, see ComputeSNAGrid::compute_array() + const int itype = 1; + const Kokkos::Array ielem = {{ chemflag ? d_map[itype] : 0 }}; + snaKK.template compute_bi(iatom, jjb, ielem); } template @@ -684,7 +714,10 @@ template KOKKOS_INLINE_FUNCTION void ComputeSNAGridKokkos::operator() (TagCSNAGridComputeBi, const int& iatom, const int& jjb) const { if (iatom >= chunk_size) return; - snaKK.template compute_bi(iatom, jjb); + // all grid points are type 1, see ComputeSNAGrid::compute_array() + const int itype = 1; + const Kokkos::Array ielem = {{ chemflag ? d_map[itype] : 0 }}; + snaKK.template compute_bi(iatom, jjb, ielem); } template @@ -692,8 +725,11 @@ template KOKKOS_INLINE_FUNCTION void ComputeSNAGridKokkos::operator() (TagCSNAGridComputeBi, const int& iatom) const { if (iatom >= chunk_size) return; + // all grid points are type 1, see ComputeSNAGrid::compute_array() + const int itype = 1; + const Kokkos::Array ielem = {{ chemflag ? d_map[itype] : 0 }}; for (int jjb = 0; jjb < snaKK.idxb_max; jjb++) - snaKK.template compute_bi(iatom, jjb); + snaKK.template compute_bi(iatom, jjb, ielem); } template diff --git a/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h b/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h index 34f613b9a08..c4442ab1846 100644 --- a/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h +++ b/src/KOKKOS/compute_sna_grid_local_kokkos_impl.h @@ -35,8 +35,6 @@ #include #include -#include - #define MAXLINE 1024 #define MAXWORD 3 @@ -60,26 +58,21 @@ ComputeSNAGridLocalKokkos::Com host_flag = (execution_space == HostKK); - // TODO: Extract cutsq in double loop below, no need for cutsq_tmp + const int n = atom->ntypes; - cutsq_tmp = cutsq[1][1]; + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) + k_cutsq.view_host()(i,j) = k_cutsq.view_host()(j,i) = cutsq[i][j]; + k_cutsq.modify_host(); - for (int i = 1; i <= atom->ntypes; i++) { - for (int j = 1; j <= atom->ntypes; j++){ - k_cutsq.view_host()(i,j) = k_cutsq.view_host()(j,i) = cutsq_tmp; - k_cutsq.modify_host(); - } - } + // Unlike pair style snap, the grid computes index radelem, wjelem, sinnerelem + // and dinnerelem by atom type (1 to ntypes), not by element, so these views + // are sized and filled accordingly. - // Set up element lists - MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridLocalKokkos::radelem",nelements); - MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridLocalKokkos:wjelem",nelements); - MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridLocalKokkos:sinnerelem",nelements); - MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridLocalKokkos:dinnerelem",nelements); - // test - MemKK::realloc_kokkos(d_test, "ComputeSNAGridLocalKokkos::test", nelements); - - int n = atom->ntypes; + MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridLocalKokkos::radelem",n+1); + MemKK::realloc_kokkos(d_wjelem,"ComputeSNAGridLocalKokkos::wjelem",n+1); + MemKK::realloc_kokkos(d_sinnerelem,"ComputeSNAGridLocalKokkos::sinnerelem",n+1); + MemKK::realloc_kokkos(d_dinnerelem,"ComputeSNAGridLocalKokkos::dinnerelem",n+1); MemKK::realloc_kokkos(d_map,"ComputeSNAGridLocalKokkos::map",n+1); auto h_radelem = Kokkos::create_mirror_view(d_radelem); @@ -87,37 +80,31 @@ ComputeSNAGridLocalKokkos::Com auto h_sinnerelem = Kokkos::create_mirror_view(d_sinnerelem); auto h_dinnerelem = Kokkos::create_mirror_view(d_dinnerelem); auto h_map = Kokkos::create_mirror_view(d_map); - // test - auto h_test = Kokkos::create_mirror_view(d_test); - h_test(0) = 2.0; - - // start from index 1 because of how compute sna/grid is - for (int i = 1; i <= atom->ntypes; i++) { - h_radelem(i-1) = static_cast(radelem[i]); - h_wjelem(i-1) = static_cast(wjelem[i]); - if (switchinnerflag){ + + // index 0 is unused by the type-indexed lookups, but is initialized so that + // no kernel can ever read an uninitialized value + + h_radelem(0) = h_wjelem(0) = static_cast(0.0); + h_sinnerelem(0) = h_dinnerelem(0) = static_cast(0.0); + h_map(0) = 0; + + for (int i = 1; i <= n; i++) { + h_radelem(i) = static_cast(radelem[i]); + h_wjelem(i) = static_cast(wjelem[i]); + if (switchinnerflag) { h_sinnerelem(i) = static_cast(sinnerelem[i]); h_dinnerelem(i) = static_cast(dinnerelem[i]); + } else { + h_sinnerelem(i) = h_dinnerelem(i) = static_cast(0.0); } - } - - // In pair snap some things like `map` get allocated regardless of chem flag. - if (chemflag){ - for (int i = 1; i <= atom->ntypes; i++) { - h_map(i) = map[i]; - } + h_map(i) = chemflag ? map[i] : 0; } Kokkos::deep_copy(d_radelem,h_radelem); Kokkos::deep_copy(d_wjelem,h_wjelem); - if (switchinnerflag){ - Kokkos::deep_copy(d_sinnerelem,h_sinnerelem); - Kokkos::deep_copy(d_dinnerelem,h_dinnerelem); - } - if (chemflag){ - Kokkos::deep_copy(d_map,h_map); - } - Kokkos::deep_copy(d_test,h_test); + Kokkos::deep_copy(d_sinnerelem,h_sinnerelem); + Kokkos::deep_copy(d_dinnerelem,h_dinnerelem); + Kokkos::deep_copy(d_map,h_map); snaKK = SNAKokkos(*this); snaKK.grow_rij(0,0,padding_factor); @@ -142,13 +129,28 @@ ComputeSNAGridLocalKokkos::~Co template void ComputeSNAGridLocalKokkos::setup() { + // Do not call ComputeGridLocal::setup(), it allocates alocal with memory->create() + // and sets gridlocal_allocated, so the next setup() (and the base destructor) would + // call free() on the Kokkos-owned storage installed below. Only the grid indices + // are taken from the base class. - ComputeGridLocal::setup(); + memoryKK->destroy_kokkos(k_alocal, alocal); + array_local = nullptr; + + ComputeGridLocal::set_grid_global(); + ComputeGridLocal::set_grid_local(); // allocate arrays memoryKK->create_kokkos(k_alocal, alocal, size_local_rows, size_local_cols, "grid:alocal"); array_local = alocal; d_alocal = k_alocal.template view(); + + // fill the coordinate columns and run the subdomain check ComputeGridLocal::setup() + // would have done; the device kernel overwrites them, the host fallback does not + + ComputeGridLocal::assign_coords(); + k_alocal.modify_host(); + k_alocal.template sync(); } // Compute @@ -156,8 +158,13 @@ void ComputeSNAGridLocalKokkos template void ComputeSNAGridLocalKokkos::compute_local() { + invoked_local = update->ntimestep; + if (host_flag) { - ComputeSNAGridLocal::compute_array(); + // ComputeSNAGridLocal implements compute_local(), not compute_array() + atomKK->sync(Host,X_MASK|TYPE_MASK|MASK_MASK); + ComputeSNAGridLocal::compute_local(); + k_alocal.modify_host(); return; } @@ -168,12 +175,15 @@ void ComputeSNAGridLocalKokkos xlen = nxhi-nxlo+1; total_range = (nzhi-nzlo+1)*(nyhi-nylo+1)*(nxhi-nxlo+1); - atomKK->sync(execution_space,X_MASK|F_MASK|TYPE_MASK); + atomKK->sync(execution_space,X_MASK|F_MASK|TYPE_MASK|MASK_MASK); x = atomKK->k_x.view(); type = atomKK->k_type.view(); + mask = atomKK->k_mask.view(); k_cutsq.template sync(); - // max_neighs is defined here - think of more elaborate methods. + // initial guess for the number of atoms within the cutoff of a grid point; + // the ComputeNeigh launch below grows this if a grid point needs more + max_neighs = 100; // Pair snap/kk uses grow_ij with some max number of neighs but compute sna/grid uses total @@ -182,11 +192,13 @@ void ComputeSNAGridLocalKokkos ntotal = atomKK->nlocal + atomKK->nghost; // Allocate view for number of neighbors per grid point MemKK::realloc_kokkos(d_ninside,"ComputeSNAGridLocalKokkos:ninside",total_range); + auto h_ninside = Kokkos::create_mirror_view(d_ninside); // "chunksize" variable is default 32768 in compute_sna_grid.cpp, and set by user // `total_range` is the number of grid points which may be larger than chunk size. chunk_size = MIN(chunksize, total_range); chunk_offset = 0; + const int chunk_size_max = chunk_size; //snaKK.grow_rij(chunk_size, ntotal); snaKK.grow_rij(chunk_size, max_neighs, padding_factor); @@ -215,12 +227,29 @@ void ComputeSNAGridLocalKokkos //ComputeNeigh { - int scratch_size = scratch_size_helper(team_size_compute_neigh * max_neighs); //ntotal); + // The kernel records the true neighbor count of every grid point but stores at + // most max_neighs neighbors. If any grid point in this chunk has more, grow the + // SNA neighbor arrays and repeat, rather than overrunning them. + + for (int attempt = 0; attempt < 2; attempt++) { + int scratch_size = scratch_size_helper(team_size_compute_neigh * max_neighs); + + SnapAoSoATeamPolicy + policy_neigh(chunk_size, team_size_compute_neigh, vector_length); + policy_neigh = policy_neigh.set_scratch_size(0, Kokkos::PerTeam(scratch_size)); + Kokkos::parallel_for("ComputeNeigh",policy_neigh,*this); - SnapAoSoATeamPolicy - policy_neigh(chunk_size, team_size_compute_neigh, vector_length); - policy_neigh = policy_neigh.set_scratch_size(0, Kokkos::PerTeam(scratch_size)); - Kokkos::parallel_for("ComputeNeigh",policy_neigh,*this); + Kokkos::deep_copy(h_ninside, d_ninside); + int max_ninside = 0; + for (int ii = 0; ii < chunk_size; ii++) + if (h_ninside(ii) > max_ninside) max_ninside = h_ninside(ii); + + if (max_ninside <= max_neighs) break; + + max_neighs = max_ninside; + // grow with the full chunk size so a short final chunk cannot shrink the arrays + snaKK.grow_rij(chunk_size_max, max_neighs, padding_factor); + } } //ComputeCayleyKlein @@ -423,65 +452,63 @@ void ComputeSNAGridLocalKokkos d_alocal(igrid, 4) = ytmp; d_alocal(igrid, 5) = ztmp; - // currently, all grid points are type 1 - // not clear what a better choice would be - - const int itype = 1; - int ielem = 0; - if (chemflag) ielem = d_map[itype]; - //const double radi = d_radelem[ielem]; - // Compute the number of neighbors, store rsq int ninside = 0; // Looping over ntotal for now. + // The cutoff test uses cutsq(jtype,jtype), matching ComputeSNAGridLocal::compute_local(): + // a grid point takes on the radius of the neighbor it is being compared against. for (int j = 0; j < ntotal; j++){ + + // check that j is in compute group + + if (!(mask(j) & groupbit)) continue; + const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; - int jtype = type(j); + const int jtype = type(j); const double rsq = dx*dx + dy*dy + dz*dz; // don't include atoms that share location with grid point - if (rsq >= rnd_cutsq(itype,jtype) || rsq < 1e-20) { - jtype = -1; // use -1 to signal it's outside the radius - } - - if (jtype >= 0) + if (rsq < rnd_cutsq(jtype,jtype) && rsq > 1e-20) ninside++; } d_ninside(ii) = ninside; - // TODO: Adjust for multi-element, currently we set jelem = 0 regardless of type. int offset = 0; for (int j = 0; j < ntotal; j++){ - //const int jtype = type_cache[j]; - //if (jtype >= 0) { + + // check that j is in compute group + + if (!(mask(j) & groupbit)) continue; + const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; const double rsq = dx*dx + dy*dy + dz*dz; - int jtype = type(j); - if (rsq < rnd_cutsq(itype,jtype) && rsq > 1e-20) { - int jelem = 0; - if (chemflag) jelem = d_map[jtype]; - snaKK.rij(ii,offset,0) = static_cast(dx); - snaKK.rij(ii,offset,1) = static_cast(dy); - snaKK.rij(ii,offset,2) = static_cast(dz); - // pair snap uses jelem here, but we use jtype, see compute_sna_grid.cpp - // actually since the views here have values starting at 0, let's use jelem - snaKK.wj(ii,offset) = static_cast(d_wjelem[jelem]); - snaKK.rcutij(ii,offset) = static_cast((2.0 * static_cast(d_radelem[jelem]))*rcutfac); - snaKK.inside(ii,offset) = j; - if (switchinnerflag) { - snaKK.sinnerij(ii,offset) = static_cast(0.5)*(d_sinnerelem[ielem] + d_sinnerelem[jelem]); - snaKK.dinnerij(ii,offset) = static_cast(0.5)*(d_dinnerelem[ielem] + d_dinnerelem[jelem]); - } - if (chemflag) + const int jtype = type(j); + if (rsq < rnd_cutsq(jtype,jtype) && rsq > 1e-20) { + // a chunk with more neighbors than the arrays were grown for is detected + // on the host, which then grows the arrays and re-runs this kernel + if (offset < max_neighs) { + int jelem = 0; + if (chemflag) jelem = d_map[jtype]; + snaKK.rij(ii,offset,0) = static_cast(dx); + snaKK.rij(ii,offset,1) = static_cast(dy); + snaKK.rij(ii,offset,2) = static_cast(dz); + // weights, radii and inner cutoffs are per atom type here, not per + // element, see ComputeSNAGridLocal::compute_local() + snaKK.wj(ii,offset) = d_wjelem[jtype]; + snaKK.rcutij(ii,offset) = static_cast((2.0 * static_cast(d_radelem[jtype]))*rcutfac); + snaKK.inside(ii,offset) = j; + if (switchinnerflag) { + snaKK.sinnerij(ii,offset) = d_sinnerelem[jtype]; + snaKK.dinnerij(ii,offset) = d_dinnerelem[jtype]; + } snaKK.element(ii,offset) = jelem; - else - snaKK.element(ii,offset) = 0; + } offset++; } } @@ -517,8 +544,10 @@ void ComputeSNAGridLocalKokkos const int iatom = iatom_mod + iatom_div * vector_length; if (iatom >= chunk_size) return; - int itype = type(iatom); - int ielem = d_map[itype]; + // all grid points are type 1, iatom is a grid index and must not be used + // to look up an atom type, see ComputeSNAGridLocal::compute_local() + const int itype = 1; + const int ielem = chemflag ? d_map[itype] : 0; snaKK.pre_ui(iatom, j, ielem); } @@ -529,8 +558,10 @@ KOKKOS_INLINE_FUNCTION void ComputeSNAGridLocalKokkos::operator() (TagCSNAGridLocalPreUi, const int& iatom, const int& j) const { if (iatom >= chunk_size) return; - int itype = type(iatom); - int ielem = d_map[itype]; + // all grid points are type 1, iatom is a grid index and must not be used + // to look up an atom type, see ComputeSNAGridLocal::compute_local() + const int itype = 1; + const int ielem = chemflag ? d_map[itype] : 0; snaKK.pre_ui(iatom, j, ielem); } @@ -541,8 +572,10 @@ KOKKOS_INLINE_FUNCTION void ComputeSNAGridLocalKokkos::operator() (TagCSNAGridLocalPreUi, const int& iatom) const { if (iatom >= chunk_size) return; - const int itype = type(iatom); - const int ielem = d_map[itype]; + // all grid points are type 1, iatom is a grid index and must not be used + // to look up an atom type, see ComputeSNAGridLocal::compute_local() + const int itype = 1; + const int ielem = chemflag ? d_map[itype] : 0; for (int j = 0; j <= twojmax; j++) snaKK.pre_ui(iatom, j, ielem); @@ -678,7 +711,10 @@ void ComputeSNAGridLocalKokkos const int iatom = iatom_mod + iatom_div * vector_length; if (iatom >= chunk_size) return; if (jjb >= snaKK.idxb_max) return; - snaKK.template compute_bi(iatom, jjb); + // all grid points are type 1, see ComputeSNAGridLocal::compute_local() + const int itype = 1; + const Kokkos::Array ielem = {{ chemflag ? d_map[itype] : 0 }}; + snaKK.template compute_bi(iatom, jjb, ielem); } template @@ -686,7 +722,10 @@ template KOKKOS_INLINE_FUNCTION void ComputeSNAGridLocalKokkos::operator() (TagCSNAGridLocalComputeBi, const int& iatom, const int& jjb) const { if (iatom >= chunk_size) return; - snaKK.template compute_bi(iatom, jjb); + // all grid points are type 1, see ComputeSNAGridLocal::compute_local() + const int itype = 1; + const Kokkos::Array ielem = {{ chemflag ? d_map[itype] : 0 }}; + snaKK.template compute_bi(iatom, jjb, ielem); } template @@ -694,8 +733,11 @@ template KOKKOS_INLINE_FUNCTION void ComputeSNAGridLocalKokkos::operator() (TagCSNAGridLocalComputeBi, const int& iatom) const { if (iatom >= chunk_size) return; + // all grid points are type 1, see ComputeSNAGridLocal::compute_local() + const int itype = 1; + const Kokkos::Array ielem = {{ chemflag ? d_map[itype] : 0 }}; for (int jjb = 0; jjb < snaKK.idxb_max; jjb++) - snaKK.template compute_bi(iatom, jjb); + snaKK.template compute_bi(iatom, jjb, ielem); } template @@ -703,44 +745,9 @@ template::operator() (TagCSNAGridLocal2Fill, const int& ii) const { - // extract grid index - int igrid = ii + chunk_offset; - - // convert to grid indices - - int iz = igrid/(xlen*ylen); - int i2 = igrid - (iz*xlen*ylen); - int iy = i2/xlen; - int ix = i2 % xlen; - iz += nzlo; - iy += nylo; - ix += nxlo; - - KK_FLOAT xgrid[3]; - - // index ii already captures the proper grid point - // int igrid = iz * (nx * ny) + iy * nx + ix; - // printf("ii igrid: %d %d\n", ii, igrid); - - // grid2x converts igrid to ix,iy,iz like we've done before - //grid2x(igrid, xgrid); - xgrid[0] = static_cast(ix * delx); - xgrid[1] = static_cast(iy * dely); - xgrid[2] = static_cast(iz * delz); - if (triclinic) { - - // Do a conversion on `xgrid` here like we do in the CPU version. - - // Can't do this: - // domainKK->lamda2x(xgrid, xgrid); - // Because calling a __host__ function("lamda2x") from a __host__ __device__ function("operator()") is not allowed - - // Using domainKK-> gives segfault, use domain-> instead since we're just accessing floats. - xgrid[0] = h0*xgrid[0] + h5*xgrid[1] + h4*xgrid[2] + lo0; - xgrid[1] = h1*xgrid[1] + h3*xgrid[2] + lo1; - xgrid[2] = h2*xgrid[2] + lo2; - } + // extract grid index; the coordinate columns were already filled by ComputeNeigh + const int igrid = ii + chunk_offset; const auto idxb_max = snaKK.idxb_max; diff --git a/src/ML-SNAP/compute_sna_grid.cpp b/src/ML-SNAP/compute_sna_grid.cpp index 95c3fa70a8c..229a493474d 100644 --- a/src/ML-SNAP/compute_sna_grid.cpp +++ b/src/ML-SNAP/compute_sna_grid.cpp @@ -263,8 +263,8 @@ void ComputeSNAGrid::compute_array() snaptr->wj[ninside] = wjelem[jtype]; snaptr->rcutij[ninside] = 2.0 * radelem[jtype] * rcutfac; if (switchinnerflag) { - snaptr->sinnerij[ninside] = sinnerelem[jelem]; - snaptr->dinnerij[ninside] = dinnerelem[jelem]; + snaptr->sinnerij[ninside] = sinnerelem[jtype]; + snaptr->dinnerij[ninside] = dinnerelem[jtype]; } if (chemflag) snaptr->element[ninside] = jelem; ninside++; diff --git a/src/ML-SNAP/compute_sna_grid_local.cpp b/src/ML-SNAP/compute_sna_grid_local.cpp index db490639207..fe87733b543 100644 --- a/src/ML-SNAP/compute_sna_grid_local.cpp +++ b/src/ML-SNAP/compute_sna_grid_local.cpp @@ -260,8 +260,8 @@ void ComputeSNAGridLocal::compute_local() snaptr->wj[ninside] = wjelem[jtype]; snaptr->rcutij[ninside] = 2.0 * radelem[jtype] * rcutfac; if (switchinnerflag) { - snaptr->sinnerij[ninside] = sinnerelem[jelem]; - snaptr->dinnerij[ninside] = dinnerelem[jelem]; + snaptr->sinnerij[ninside] = sinnerelem[jtype]; + snaptr->dinnerij[ninside] = dinnerelem[jtype]; } if (chemflag) snaptr->element[ninside] = jelem; // element index for multi-element snap From 01e20d87cb79dd0bd0daf44290f7615aaea1fa76 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:57:33 +0000 Subject: [PATCH 083/120] Fix wrong mask index in AtomVec::pack_comm_vel and pack_border_vel Both loops run j = list[i], pack every field from j -- including mask[j] on the line immediately above -- and then decide whether to apply the fix deform velocity remap with "if (mask[i] & deform_groupbit)". i is the position in the send list, not an atom index, so for a send list of length n the remap is applied according to the masks of atoms 0..n-1 whatever the list contains. Only fix deform with remap v and a deform group other than all is affected, which is why it has survived: with group all every mask matches. It also needs a pair style that reads ghost velocities before the wrong values reach a result. domain.cpp, domain_omp.cpp and domain_kokkos.cpp all use mask[i] correctly -- there i really is the atom index. RHEO/compute_rheo_grad.cpp:345 shows the correct form for a packing loop. The KOKKOS pack functor mirrored the CPU defect and is fixed with it. --- src/KOKKOS/atom_vec_kokkos.cpp | 17 +++++++++++++---- src/atom_vec.cpp | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/atom_vec_kokkos.cpp b/src/KOKKOS/atom_vec_kokkos.cpp index 070ff92e450..e276c064f74 100644 --- a/src/KOKKOS/atom_vec_kokkos.cpp +++ b/src/KOKKOS/atom_vec_kokkos.cpp @@ -808,6 +808,8 @@ struct AtomVecKokkos_PackCommVel { const uint64_t &datamask): _x(atomKK->k_x.view()), _mask(atomKK->k_mask.view()), + _mu(atomKK->k_mu.view()), + _sp(atomKK->k_sp.view()), _v(atomKK->k_v.view()), _angmom(atomKK->k_angmom.view()), _omega(atomKK->k_omega.view()), @@ -1846,10 +1848,17 @@ struct AtomVecKokkos_PackBorderVel { _buf(i,m++) = d_ubuf(_mask(j)).d; if constexpr (DEFORM_VREMAP) { - if (_mask(i) & _deform_groupbit) { + if (_mask(j) & _deform_groupbit) { _buf(i,m++) = static_cast(_v(j,0)) + _dvx; _buf(i,m++) = static_cast(_v(j,1)) + _dvy; _buf(i,m++) = static_cast(_v(j,2)) + _dvz; + } else { + // atoms outside the deform group still contribute three velocity slots; + // without this the buffer is short by three doubles for every such atom + // and every field packed after it is misaligned + _buf(i,m++) = static_cast(_v(j,0)); + _buf(i,m++) = static_cast(_v(j,1)); + _buf(i,m++) = static_cast(_v(j,2)); } } else { _buf(i,m++) = static_cast(_v(j,0)); @@ -2128,7 +2137,7 @@ void AtomVecKokkos::unpack_border_vel_kokkos( atomKK->sync(space,datamask_border_vel); if (space == HostKK) { - if (!ncomm_vel) { + if (!nborder_vel) { struct AtomVecKokkos_UnpackBorderVel f( atomKK, buf.view_host(), @@ -2142,7 +2151,7 @@ void AtomVecKokkos::unpack_border_vel_kokkos( Kokkos::parallel_for(n,f); } } else { - if (!ncomm_vel) { + if (!nborder_vel) { struct AtomVecKokkos_UnpackBorderVel f( atomKK, buf.view_device(), @@ -2953,7 +2962,7 @@ int AtomVecKokkos::field2size(std::string field) else if (field == "num_bond") return 1+2*atom->bond_per_atom; else if (field == "num_angle") return 1+4*atom->angle_per_atom; else if (field == "num_dihedral") return 1+5*atom->dihedral_per_atom; - else if (field == "num_improper") return 1+5*atom->dihedral_per_atom; + else if (field == "num_improper") return 1+5*atom->improper_per_atom; else if (field == "sp") return 4; else if (field == "fm") return 3; else if (field == "fm_long") return 3; diff --git a/src/atom_vec.cpp b/src/atom_vec.cpp index ad8f8d669b6..a4c366765d3 100644 --- a/src/atom_vec.cpp +++ b/src/atom_vec.cpp @@ -487,7 +487,7 @@ int AtomVec::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, int *pbc buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; - if (mask[i] & deform_groupbit) { + if (mask[j] & deform_groupbit) { buf[m++] = v[j][0] + dvx; buf[m++] = v[j][1] + dvy; buf[m++] = v[j][2] + dvz; @@ -948,7 +948,7 @@ int AtomVec::pack_border_vel(int n, int *list, double *buf, int pbc_flag, int *p buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; - if (mask[i] & deform_groupbit) { + if (mask[j] & deform_groupbit) { buf[m++] = v[j][0] + dvx; buf[m++] = v[j][1] + dvy; buf[m++] = v[j][2] + dvz; From 461f1f9e4f25f1918f51d70e387a70e1d7521a2b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:57:33 +0000 Subject: [PATCH 084/120] Widen Pair::special_lj to double special_lj was declared int, so the special-bonds factors copied from force->special_lj for the KOKKOS styles were truncated: any fractional value became 0 or 1. Four styles that do not shadow the member with their own declaration read the truncated values. --- src/pair.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pair.h b/src/pair.h index 55e42cd3b7f..400c19683b8 100644 --- a/src/pair.h +++ b/src/pair.h @@ -244,7 +244,7 @@ class Pair : protected Pointers { protected: int instance_me; // which Pair class instantiation I am - int special_lj[4]; // copied from force->special_lj for Kokkos + double special_lj[4]; // copied from force->special_lj for Kokkos // pair_modify settings int offset_flag, mix_flag; // flags for offset and mixing From d010bd0618751a9e1d2a7e49e7371002a9311d4c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:57:33 +0000 Subject: [PATCH 085/120] Detect a temp/region bias compute with a suffix The three finite-size temperature computes identify a temp/region bias with an exact strcmp on tbias->style, which stops matching as soon as the bias compute is promoted to its /kk variant. The bias is then treated as an ordinary one, and dof_remove is reached in a state it does not expect; with the KOKKOS package active this segfaults in ComputeTempRegion::dof_remove. Use utils::strmatch(tbias->style, "^temp/region") so any suffixed variant is recognised. --- src/ASPHERE/compute_temp_asphere.cpp | 4 +++- src/BODY/compute_temp_body.cpp | 4 +++- src/compute_temp_sphere.cpp | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ASPHERE/compute_temp_asphere.cpp b/src/ASPHERE/compute_temp_asphere.cpp index 68e784059c0..401c2e64d63 100644 --- a/src/ASPHERE/compute_temp_asphere.cpp +++ b/src/ASPHERE/compute_temp_asphere.cpp @@ -27,6 +27,7 @@ #include "math_extra.h" #include "modify.h" #include "update.h" +#include "utils.h" #include @@ -119,7 +120,8 @@ void ComputeTempAsphere::init() error->all(FLERR,"Bias compute {} does not calculate a velocity bias", id_bias); if (tbias->igroup != igroup) error->all(FLERR,"Bias compute group does not match compute group"); - if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; + // match the accelerated variants too (see compute_temp_sphere.cpp) + if (utils::strmatch(tbias->style,"^temp/region")) tempbias = 2; else tempbias = 1; // init and setup bias compute because diff --git a/src/BODY/compute_temp_body.cpp b/src/BODY/compute_temp_body.cpp index 920dd9db007..e023b8ff4cd 100644 --- a/src/BODY/compute_temp_body.cpp +++ b/src/BODY/compute_temp_body.cpp @@ -27,6 +27,7 @@ #include "math_extra.h" #include "modify.h" #include "update.h" +#include "utils.h" #include @@ -110,7 +111,8 @@ void ComputeTempBody::init() error->all(FLERR,"Bias compute {} does not calculate a velocity bias", id_bias); if (tbias->igroup != igroup) error->all(FLERR,"Bias compute group does not match compute group"); - if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; + // match the accelerated variants too (see compute_temp_sphere.cpp) + if (utils::strmatch(tbias->style,"^temp/region")) tempbias = 2; else tempbias = 1; // init and setup bias compute because diff --git a/src/compute_temp_sphere.cpp b/src/compute_temp_sphere.cpp index 0ca479acf5d..49592a4ebf9 100644 --- a/src/compute_temp_sphere.cpp +++ b/src/compute_temp_sphere.cpp @@ -21,6 +21,7 @@ #include "group.h" #include "modify.h" #include "update.h" +#include "utils.h" #include @@ -103,7 +104,10 @@ void ComputeTempSphere::init() if (tbias->tempbias == 0) error->all(FLERR, "Bias compute does not calculate a velocity bias"); if (tbias->igroup != igroup) error->all(FLERR, "Bias compute group does not match compute group"); - if (strcmp(tbias->style, "temp/region") == 0) + // match the accelerated variants too: with -sf kk the bias compute is + // instantiated as temp/region/kk, which an exact strcmp would miss, + // leaving tempbias = 1 and sending dof_remove() an index of -1 + if (utils::strmatch(tbias->style, "^temp/region")) tempbias = 2; else tempbias = 1; From 9ef5ff223bd7be3c2b1d6ebcc805d796352a2e95 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:57:48 +0000 Subject: [PATCH 086/120] KOKKOS: fix neighbor list build defects Several independent problems in the KOKKOS neighbour builds: Special-bond cutoffs were truncated. xprd_half, yprd_half and zprd_half were declared int in npair_kokkos.h and npair_ssa_kokkos.h, and cutsq_custom was declared int in npair_skip_kokkos.h by sharing a declaration with two integer members. All are now double. The cutsq_trim fallback added upstream in 47cea8e1ba to src/npair.cpp, npair_halffull.cpp, npair_skip.cpp and npair_trim.cpp was never mirrored into the KOKKOS builds, so a trim request carrying no custom cutoff trimmed against cutsq_custom == 0 and discarded every pair. Ported: each build now falls back to the pairwise neighbour cutoff, which needs the type view and d_cutneighsq and TYPE_MASK added to the sync. npair_skip_kokkos did not mark k_ilist modified on the device after build(). npair_trim_kokkos did not set atomKK or execution_space in its constructor. npair_halffull_kokkos registered the tri/trim/skip device style with the TRI = 0 class. npair_ssa_kokkos derived inum from h_ssa_phaseLen(ct-1)-1, which is -1 when the last phase is empty; it now searches back for the last non-empty phase. Two dead debug blocks under DEBUG_SSA_BUILD_LOCALS are removed: they sit inside a KOKKOS_INLINE_FUNCTION, use fprintf, and one references a variable that is out of scope there, so they could never have compiled. --- src/KOKKOS/npair_halffull_kokkos.cpp | 20 ++++++++++++--- src/KOKKOS/npair_halffull_kokkos.h | 4 ++- src/KOKKOS/npair_kokkos.h | 4 +-- src/KOKKOS/npair_skip_kokkos.cpp | 13 +++++++++- src/KOKKOS/npair_skip_kokkos.h | 4 ++- src/KOKKOS/npair_ssa_kokkos.cpp | 37 +++++++++------------------- src/KOKKOS/npair_ssa_kokkos.h | 4 +-- src/KOKKOS/npair_trim_kokkos.cpp | 19 +++++++++++--- src/KOKKOS/npair_trim_kokkos.h | 2 ++ 9 files changed, 68 insertions(+), 39 deletions(-) diff --git a/src/KOKKOS/npair_halffull_kokkos.cpp b/src/KOKKOS/npair_halffull_kokkos.cpp index cd9486273d8..326e9e2c378 100644 --- a/src/KOKKOS/npair_halffull_kokkos.cpp +++ b/src/KOKKOS/npair_halffull_kokkos.cpp @@ -20,6 +20,7 @@ #include "domain.h" #include "force.h" #include "neigh_list_kokkos.h" +#include "neighbor_kokkos.h" #include @@ -47,7 +48,12 @@ void NPairHalffullKokkos::build(NeighList *list) { if (NEWTON || TRIM) { x = atomKK->k_x.view(); - atomKK->sync(execution_space,X_MASK); + type = atomKK->k_type.view(); + atomKK->sync(execution_space,X_MASK|TYPE_MASK); + + NeighborKokkos* neighborKK = (NeighborKokkos*) neighbor; + neighborKK->k_cutneighsq.template sync(); + d_cutneighsq = neighborKK->k_cutneighsq.template view(); } nlocal = atom->nlocal; @@ -135,7 +141,11 @@ void NPairHalffullKokkos::operator()(TagNPairHalfful const double delz = ztmp - static_cast(x(j,2)); const double rsq = delx*delx + dely*dely + delz*delz; - if (rsq > cutsq_custom) continue; + // a trim list whose own request carries no custom cutoff must fall back + // to the pairwise neighbour cutoff, as NPairHalffull::build() does + const double cutsq_trim = (cutsq_custom > 0.0) ? cutsq_custom : + static_cast(d_cutneighsq(type(i),type(j))); + if (rsq > cutsq_trim) continue; } neighbors_i(n++) = joriginal; @@ -147,7 +157,11 @@ void NPairHalffullKokkos::operator()(TagNPairHalfful const double delz = ztmp - static_cast(x(j,2)); const double rsq = delx*delx + dely*dely + delz*delz; - if (rsq > cutsq_custom) continue; + // a trim list whose own request carries no custom cutoff must fall back + // to the pairwise neighbour cutoff, as NPairHalffull::build() does + const double cutsq_trim = (cutsq_custom > 0.0) ? cutsq_custom : + static_cast(d_cutneighsq(type(i),type(j))); + if (rsq > cutsq_trim) continue; } neighbors_i(n++) = joriginal; diff --git a/src/KOKKOS/npair_halffull_kokkos.h b/src/KOKKOS/npair_halffull_kokkos.h index 517b96a60cf..2c265cee22b 100644 --- a/src/KOKKOS/npair_halffull_kokkos.h +++ b/src/KOKKOS/npair_halffull_kokkos.h @@ -218,7 +218,7 @@ NPairStyle(halffull/newton/tri/trim/kk/host, using NPairKokkosHalffullNewtonTriTrimDevice = NPairHalffullKokkos; NPairStyle(halffull/newton/tri/trim/skip/kk/device, - NPairKokkosHalffullNewtonTrimDevice, + NPairKokkosHalffullNewtonTriTrimDevice, NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_KOKKOS_DEVICE); @@ -366,6 +366,8 @@ class NPairHalffullKokkos : public NPair { double cutsq_custom,delta; typename AT::t_kkfloat_1d_3_lr_randomread x; + typename AT::t_int_1d_randomread type; + typename AT::t_kkfloat_2d d_cutneighsq; typename AT::t_neighbors_2d_const d_neighbors_full; typename AT::t_int_1d_const d_ilist_full; diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index ae62e2ce294..7073729c014 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -258,7 +258,7 @@ class NeighborKokkosExecute HAT::t_int_scalar h_new_maxneighs; const int xperiodic, yperiodic, zperiodic; - const int xprd_half, yprd_half, zprd_half; + const double xprd_half, yprd_half, zprd_half; // GRANULAR required member variables const double skin; @@ -300,7 +300,7 @@ class NeighborKokkosExecute const typename AT::t_int_1d_const & _ex_mol_intra, const double *_bboxhi, const double* _bboxlo, const int & _xperiodic, const int & _yperiodic, const int & _zperiodic, - const int & _xprd_half, const int & _yprd_half, const int & _zprd_half, + const double & _xprd_half, const double & _yprd_half, const double & _zprd_half, const double _skin, const typename AT::t_int_scalar _resize, const HAT::t_int_scalar _h_resize, diff --git a/src/KOKKOS/npair_skip_kokkos.cpp b/src/KOKKOS/npair_skip_kokkos.cpp index b3244aee75d..01f588d5073 100644 --- a/src/KOKKOS/npair_skip_kokkos.cpp +++ b/src/KOKKOS/npair_skip_kokkos.cpp @@ -17,6 +17,7 @@ #include "atom_kokkos.h" #include "atom_masks.h" #include "neigh_list_kokkos.h" +#include "neighbor_kokkos.h" using namespace LAMMPS_NS; @@ -47,6 +48,10 @@ void NPairSkipKokkos::build(NeighList *list) if (TRIM) { x = atomKK->k_x.view(); atomKK->sync(execution_space,X_MASK); + + NeighborKokkos* neighborKK = (NeighborKokkos*) neighbor; + neighborKK->k_cutneighsq.template sync(); + d_cutneighsq = neighborKK->k_cutneighsq.template view(); cutsq_custom = cutoff_custom*cutoff_custom; } @@ -102,6 +107,8 @@ void NPairSkipKokkos::build(NeighList *list) list->gnum = inum - num; } copymode = 0; + + k_list->k_ilist.template modify(); } template @@ -141,7 +148,11 @@ void NPairSkipKokkos::operator()(TagNPairSkipCompute, const int const double dely = ytmp - static_cast(x(j,1)); const double delz = ztmp - static_cast(x(j,2)); const double rsq = delx*delx + dely*dely + delz*delz; - if (rsq > cutsq_custom) continue; + // a skip list inherits the parent's cutoff, so cutoff_custom is 0 here; + // fall back to the pairwise neighbour cutoff as NPairSkip::build() does + const double cutsq_trim = (cutsq_custom > 0.0) ? cutsq_custom : + static_cast(d_cutneighsq(itype,type(j))); + if (rsq > cutsq_trim) continue; } neighbors_i(n++) = joriginal; diff --git a/src/KOKKOS/npair_skip_kokkos.h b/src/KOKKOS/npair_skip_kokkos.h index 360e8440435..c23b155af6f 100644 --- a/src/KOKKOS/npair_skip_kokkos.h +++ b/src/KOKKOS/npair_skip_kokkos.h @@ -103,9 +103,11 @@ class NPairSkipKokkos : public NPair { void operator()(TagNPairSkipCountLocal, const int&, int&) const; private: - int nlocal,num_skip,cutsq_custom; + int nlocal,num_skip; + double cutsq_custom; typename AT::t_kkfloat_1d_3_lr_randomread x; + typename AT::t_kkfloat_2d d_cutneighsq; typename AT::t_int_1d_randomread type; typename AT::t_int_scalar d_inum; diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index d92dee8ce08..2a5143661fc 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -467,8 +467,17 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu k_ssa_itemLoc.sync_host(); k_ssa_itemLen.sync_host(); k_ssa_phaseLen.sync_host(); - data.neigh_list.inum = h_ssa_itemLoc(ssa_phaseCt-1,h_ssa_phaseLen(ssa_phaseCt-1)-1) + - h_ssa_itemLen(ssa_phaseCt-1,h_ssa_phaseLen(ssa_phaseCt-1)-1); + // a work phase records only the work items that got at least one atom, + // so trailing phases can be empty. Search back for the last used phase + // instead of indexing phase ssa_phaseCt-1 with a length of zero. + int lastPhase = ssa_phaseCt - 1; + while ((lastPhase >= 0) && (h_ssa_phaseLen(lastPhase) == 0)) --lastPhase; + if (lastPhase < 0) data.neigh_list.inum = 0; + else { + const int lastItem = h_ssa_phaseLen(lastPhase) - 1; + data.neigh_list.inum = h_ssa_itemLoc(lastPhase,lastItem) + + h_ssa_itemLen(lastPhase,lastItem); + } // loop over AIR ghost atoms, storing their local neighbors Kokkos::parallel_for(Kokkos::RangePolicy(0,ssa_gphaseCt), @@ -615,20 +624,6 @@ void NPairSSAKokkosExecute::build_locals_onePhase(const bool firstTr } } } -#ifdef DEBUG_SSA_BUILD_LOCALS - int len = inum - inum_start; - if (len != d_ssa_itemLen(workPhase, workItem + skippedItems)) { -fprintf(stdout, "Leng%03d workphase (%2d,%3d,%3d): len = %4d, but ssa_itemLen = %4d%s\n" - ,me - ,workPhase - ,workItem - ,workItem + skippedItems - ,len - ,d_ssa_itemLen(workPhase, workItem + skippedItems) - ,(len > d_ssa_itemLen(workPhase, workItem + skippedItems)) ? " OVERFLOW" : "" -); - } -#endif if (inum > inum_start) { d_ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist d_ssa_itemLen(workPhase,workItem) = inum - inum_start; // record actual workItem length @@ -638,16 +633,6 @@ fprintf(stdout, "Leng%03d workphase (%2d,%3d,%3d): len = %4d, but ssa_itemLen = } } -#ifdef DEBUG_SSA_BUILD_LOCALS -fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = %3d, inums/workItems = %g\n" - ,me - ,workPhase - ,inum - d_ssa_itemLoc(workPhase, 0) - ,workItem - ,skippedItems - ,(inum - d_ssa_itemLoc(workPhase, 0)) / (double) workItem -); -#endif // record where workPhase actually ends if (firstTry) { d_ssa_phaseLen(workPhase) = workItem; diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index dafe3f85828..ca7db65d6a4 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -172,7 +172,7 @@ class NPairSSAKokkosExecute HAT::t_int_scalar h_new_maxneighs; const int xperiodic, yperiodic, zperiodic; - const int xprd_half, yprd_half, zprd_half; + const double xprd_half, yprd_half, zprd_half; // SSA Work plan data structures int ssa_phaseCt; @@ -234,7 +234,7 @@ class NPairSSAKokkosExecute const typename AT::t_int_1d_const & _ex_mol_intra, const double *_bboxhi, const double* _bboxlo, const int & _xperiodic, const int & _yperiodic, const int & _zperiodic, - const int & _xprd_half, const int & _yprd_half, const int & _zprd_half): + const double & _xprd_half, const double & _yprd_half, const double & _zprd_half): neigh_list(_neigh_list), cutneighsq(_cutneighsq), exclude(_exclude),nex_type(_nex_type), ex1_type(_ex1_type),ex2_type(_ex2_type),ex_type(_ex_type), diff --git a/src/KOKKOS/npair_trim_kokkos.cpp b/src/KOKKOS/npair_trim_kokkos.cpp index ae6e80bbc4a..9011ffa523e 100644 --- a/src/KOKKOS/npair_trim_kokkos.cpp +++ b/src/KOKKOS/npair_trim_kokkos.cpp @@ -16,6 +16,7 @@ #include "atom_kokkos.h" #include "atom_masks.h" #include "neigh_list_kokkos.h" +#include "neighbor_kokkos.h" #include "my_page.h" #include "error.h" @@ -24,7 +25,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ template -NPairTrimKokkos::NPairTrimKokkos(LAMMPS *lmp) : NPair(lmp) {} +NPairTrimKokkos::NPairTrimKokkos(LAMMPS *lmp) : NPair(lmp) { + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; +} /* ---------------------------------------------------------------------- create list which is simply a copy of parent list @@ -54,7 +58,12 @@ template void NPairTrimKokkos::trim_to_kokkos(NeighList *list) { x = atomKK->k_x.view(); - atomKK->sync(execution_space,X_MASK); + type = atomKK->k_type.view(); + atomKK->sync(execution_space,X_MASK|TYPE_MASK); + + NeighborKokkos* neighborKK = (NeighborKokkos*) neighbor; + neighborKK->k_cutneighsq.template sync(); + d_cutneighsq = neighborKK->k_cutneighsq.template view(); cutsq_custom = cutoff_custom*cutoff_custom; @@ -110,7 +119,11 @@ void NPairTrimKokkos::operator()(TagNPairTrim, const int &ii) const const double delz = ztmp - static_cast(x(j,2)); const double rsq = delx*delx + dely*dely + delz*delz; - if (rsq > cutsq_custom) continue; + // a trim list whose own request carries no custom cutoff must fall back to + // the pairwise neighbour cutoff, as NPairTrim::build() does + const double cutsq_trim = (cutsq_custom > 0.0) ? cutsq_custom : + static_cast(d_cutneighsq(type(i),type(j))); + if (rsq > cutsq_trim) continue; neighbors_i(n++) = joriginal; } diff --git a/src/KOKKOS/npair_trim_kokkos.h b/src/KOKKOS/npair_trim_kokkos.h index 5b7b9937ce6..907825471c6 100644 --- a/src/KOKKOS/npair_trim_kokkos.h +++ b/src/KOKKOS/npair_trim_kokkos.h @@ -51,6 +51,8 @@ class NPairTrimKokkos : public NPair { double cutsq_custom; typename AT::t_kkfloat_1d_3_lr_randomread x; + typename AT::t_int_1d_randomread type; + typename AT::t_kkfloat_2d d_cutneighsq; typename AT::t_neighbors_2d_const d_neighbors_copy; typename AT::t_int_1d_const d_ilist_copy; From 4bed7e3f93ebbe628ee4e18261ecf4f9bfebaf1b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:58:08 +0000 Subject: [PATCH 087/120] KOKKOS: give dual_hash_type a clear_sync_state and use it in map_clear AtomKokkos::map_clear() gained a device branch without a matching clear_sync_state(). A preceding map_one() leaves the host side dirty, and the modify_device() below it then trips dual_hash_type's concurrent-modification abort: Kokkos::abort: Concurrent modification of host and device hashes Special::dedup() walks exactly that sequence, so any molecular system with special bonds aborts when the atom map lives on the device -- which is the default on a GPU build, and reproducible on a CPU build with "package kokkos atom/map device". dual_hash_type had no clear_sync_state() at all; it is added alongside the one the array branch already uses. The whole hash is cleared either way, so releasing both sides first is correct rather than merely expedient. Also move the sametag reallocation in map_set_device() after the map_init(0) block, which must run first. --- src/KOKKOS/atom_map_kokkos.cpp | 26 +++++++++++++++----------- src/KOKKOS/kokkos_type.h | 9 +++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/KOKKOS/atom_map_kokkos.cpp b/src/KOKKOS/atom_map_kokkos.cpp index daee57ab161..09e71fddb92 100644 --- a/src/KOKKOS/atom_map_kokkos.cpp +++ b/src/KOKKOS/atom_map_kokkos.cpp @@ -137,6 +137,10 @@ void AtomKokkos::map_clear() k_map_array.modify_device(); } } else { + // same reasoning as the array branch above: the whole hash is cleared, so release + // both sides first. without this a preceding map_one() leaves the host side dirty + // and the modify_device() below trips dual_hash_type's concurrent-modification abort + k_map_hash.clear_sync_state(); if (lmp->kokkos->atom_map_legacy) { Atom::map_clear(); k_map_hash.view_host().clear(); @@ -172,25 +176,25 @@ void AtomKokkos::map_set_device() { int nall = nlocal + nghost; - // possible reallocation of sametag must come before loop over atoms - // since loop sets sametag - - if (nall > max_same) { - max_same = nall + EXTRA; - memoryKK->destroy_kokkos(k_sametag, sametag); - memoryKK->create_kokkos(k_sametag, sametag, max_same, "atom:sametag"); - } - if (map_style == MAP_HASH) { // if this proc has more atoms than hash table size, call map_init() // call with 0 since max atomID in system has not changed - // possible reallocation of sametag must come after map_init(), - // b/c map_init() may invoke map_delete(), whacking sametag if (nall > map_nhash) map_init(0); } + // possible reallocation of sametag must come before the loop over atoms + // since the loop sets sametag, and after map_init() above, because + // map_init() may invoke map_delete(), whacking sametag. Atom::map_set() + // observes the same ordering. + + if (nall > max_same) { + max_same = nall + EXTRA; + memoryKK->destroy_kokkos(k_sametag, sametag); + memoryKK->create_kokkos(k_sametag, sametag, max_same, "atom:sametag"); + } + atomKK->sync(Device, TAG_MASK); int map_style_array = (map_style == MAP_ARRAY); diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index 65b77a1fa23..78811755592 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -677,6 +677,15 @@ struct dual_hash_type { } } + // release both sides without copying. needed where the whole hash is about to be + // overwritten, so neither side's contents matter and a pending flag on the other + // side would otherwise make the next modify_*() abort. mirrors DualView. + void clear_sync_state() + { + modified_device = false; + modified_host = false; + } + template std::enable_if_t<(std::is_same::value || Kokkos::SpaceAccessibility::accessible),void> sync() {sync_device();} From 1c367b03886e3ecaaf78647f7915e9c192fe69f6 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:58:08 +0000 Subject: [PATCH 088/120] KOKKOS: fix core infrastructure defects comm_tiled_kokkos dropped the self-send: the data was packed and never unpacked. comm_kokkos carried a map_clear guard that is no longer needed now that map_clear releases both sides of the hash. verlet_kokkos overwrote rather than merged the host force contribution. When a transform is needed the legacy host array behind atom->f and the Kokkos host view are separate allocations and a run can have a contribution in each, so the legacy buffer is now added in and both are zeroed before the host styles accumulate. kokkos.cpp had the pair/only guard negated, and did not check ngpus > 0 before using the SLURM-provided device count. min_sd_kokkos read device forces that a host style may have written without syncing F_MASK first. min_kokkos needed no change: every fnorm_* path already syncs, and force_clear() calls clear_sync_state() and overwrites f. min_linesearch_kokkos widened s_KK_double2 to double, and memory_kokkos.h loses a dead create4d_offset_kokkos. --- src/KOKKOS/atom_kokkos.cpp | 3 +- src/KOKKOS/comm_kokkos.cpp | 24 +++++++++---- src/KOKKOS/comm_tiled_kokkos.cpp | 3 +- src/KOKKOS/kokkos.cpp | 30 ++++++++++------ src/KOKKOS/memory_kokkos.h | 57 ++---------------------------- src/KOKKOS/min_linesearch_kokkos.h | 7 +++- src/KOKKOS/min_sd_kokkos.cpp | 6 ++++ src/KOKKOS/verlet_kokkos.cpp | 39 +++++++++++--------- 8 files changed, 78 insertions(+), 91 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index cef9d75968f..245263d2a49 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -165,7 +165,8 @@ void AtomKokkos::update_property_atom() std::vector prop_atom_fixes; for (auto &ifix : modify->get_fix_by_style("^property/atom")) { if (!ifix->kokkosable) - error->all(FLERR, "KOKKOS package requires a Kokkos-enabled version of fix property/atom"); + error->all(FLERR, "Fix property/atom {} must use the Kokkos-enabled style " + "property/atom/kk when running with the KOKKOS package", ifix->id); ++nprop_atom; prop_atom_fixes.push_back(ifix); diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index d78f47ab0d1..7221a97699a 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -1111,8 +1111,11 @@ void CommKokkos::exchange_device() // new ghosts are created in borders() // map_set() is done at end of borders() - if (lmp->kokkos->atom_map_legacy) - if (map_style != Atom::MAP_NONE) atom->map_clear(); + // AtomKokkos::map_clear() clears the host or the device map itself, so this + // must not be limited to the legacy map: map_set_device() only clears the + // hash, leaving a MAP_ARRAY map full of stale indices for migrated atoms + + if (map_style != Atom::MAP_NONE) atom->map_clear(); // clear ghost count and any ghost bonus data internal to AtomVec @@ -1283,10 +1286,10 @@ void CommKokkos::exchange_device() icopy--; } } - } - k_exchange_copylist_bonus.modify_host(); - k_exchange_copylist_bonus.sync(); + k_exchange_copylist_bonus.modify_host(); + k_exchange_copylist_bonus.sync(); + } if (nsend > maxsend) grow_send_kokkos(nsend,0); nsend = @@ -1866,8 +1869,14 @@ void CommKokkos::grow_recv(int n) void CommKokkos::grow_send_kokkos(int n, int flag, ExecutionSpace space) { + // bufextra, not the bare BUFEXTRA constant: CommBrick::exchange() packs one + // atom of up to maxexchange doubles beyond maxsend before it grows the + // buffer again, and rounding up keeps the truncating division from handing + // back less than the caller asked for + maxsend = static_cast (BUFFACTOR * n); - int maxsend_border = (maxsend+Comm::BUFEXTRA)/atomKK->avecKK->size_border; + int maxsend_border = (maxsend + bufextra + atomKK->avecKK->size_border - 1)/ + atomKK->avecKK->size_border; if (flag) { if (space == Device) k_buf_send.modify_device(); @@ -1903,7 +1912,8 @@ void CommKokkos::grow_send_kokkos(int n, int flag, ExecutionSpace space) void CommKokkos::grow_recv_kokkos(int n, ExecutionSpace /*space*/) { maxrecv = static_cast (BUFFACTOR * n); - int maxrecv_border = (maxrecv+Comm::BUFEXTRA)/atomKK->avecKK->size_border; + int maxrecv_border = (maxrecv + Comm::BUFEXTRA + atomKK->avecKK->size_border - 1)/ + atomKK->avecKK->size_border; MemoryKokkos::realloc_kokkos(k_buf_recv,"comm:k_buf_recv",maxrecv_border, atomKK->avecKK->size_border); diff --git a/src/KOKKOS/comm_tiled_kokkos.cpp b/src/KOKKOS/comm_tiled_kokkos.cpp index d3d2cc6c632..92a79f74a8c 100644 --- a/src/KOKKOS/comm_tiled_kokkos.cpp +++ b/src/KOKKOS/comm_tiled_kokkos.cpp @@ -232,8 +232,9 @@ void CommTiledKokkos::forward_comm_device() } if (sendself[iswap]) { auto k_sendlist_small = Kokkos::subview(k_sendlist,iswap,nsend,Kokkos::ALL); - n = atomKK->avecKK->pack_comm_kokkos(sendnum[iswap][nsend],k_sendlist_small, + atomKK->avecKK->pack_comm_kokkos(sendnum[iswap][nsend],k_sendlist_small, k_buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); + atomKK->avecKK->unpack_comm_kokkos(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],k_buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index ec3dea33962..2ecb4819453 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -71,7 +71,7 @@ static const char cite_kokkos_package[] = " year = 2025,\n" " booktitle = {Proceedings of the SC '25 Workshops of the International Conference for High Performance Computing,\n" " Networking, Storage and Analysis},\n" - " pages = {1217–1232},\n" + " pages = {1217--1232},\n" "}\n\n"; int KokkosLMP::is_finalized = 0; @@ -221,10 +221,12 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) int set_flag = 0; char *str; if ((str = getenv("SLURM_LOCALID"))) { - int local_rank = std::stoi(str); - device = local_rank % ngpus; - if (device >= skip_gpu) device++; - set_flag = 1; + if (ngpus > 0) { + int local_rank = std::stoi(str); + device = local_rank % ngpus; + if (device >= skip_gpu) device++; + set_flag = 1; + } } if ((str = getenv("FLUX_TASK_LOCAL_ID"))) { if (ngpus > 0) { @@ -281,6 +283,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) } else if (strcmp(arg[iarg],"t") == 0 || strcmp(arg[iarg],"threads") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Invalid Kokkos command-line args"); nthreads = utils::inumeric(FLERR, arg[iarg+1], false, lmp); if (nthreads <= 0) @@ -296,12 +299,16 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) Kokkos::InitializationSettings args; - if (args.has_num_threads()) { - if ((args.get_num_threads() != nthreads) || (args.get_device_id() != device)) + // the settings object was just created, so it has nothing to compare against. + // ask the library itself whether it is already running, which is the case when + // a second LAMMPS instance is created in the same process + + if (Kokkos::is_initialized()) { + if ((Kokkos::num_threads() != nthreads) || (Kokkos::device_id() != device)) if (me == 0) error->warning(FLERR,"Kokkos package already initalized. Cannot change parameters"); - nthreads = args.get_num_threads(); - device = args.get_device_id(); + nthreads = Kokkos::num_threads(); + device = Kokkos::device_id(); ngpus = init_ngpus; } else { args.set_num_threads(nthreads); @@ -821,7 +828,10 @@ void KokkosLMP::accelerator(int narg, char **arg) } } - if (lmp->pair_only_flag) { + // if "pair/only off" and the sort and atom map flags were changed previously, + // change them back + + if (!lmp->pair_only_flag) { if (sort_changed) { sort_legacy = 0; sort_changed = 0; diff --git a/src/KOKKOS/memory_kokkos.h b/src/KOKKOS/memory_kokkos.h index bf8567f81bd..8b8b8db2aa4 100644 --- a/src/KOKKOS/memory_kokkos.h +++ b/src/KOKKOS/memory_kokkos.h @@ -121,59 +121,6 @@ TYPE create_kokkos(TYPE &data, typename TYPE::value_type **&array, return data; } -/* ---------------------------------------------------------------------- - create a 4d array with indices 2,3,4 offset, but not first - 2nd index from n2lo to n2hi inclusive - 3rd index from n3lo to n3hi inclusive - 4th index from n4lo to n4hi inclusive - cannot grow it -------------------------------------------------------------------------- */ - -template -TYPE create4d_offset_kokkos(TYPE &data, typename TYPE::value_type ****&array, - int n1, int n2lo, int n2hi, int n3lo, int n3hi, int n4lo, int n4hi, - const char *name) -{ - static_assert(std::is_same_v, - "A Kokkos view must have LayoutRight to alias with legacy data structures"); - - //if (n1 <= 0 || n2lo > n2hi || n3lo > n3hi || n4lo > n4hi) array = nullptr; - - printf("^^^^^ memoryKK->create_4d_offset_kokkos\n"); - - int n2 = n2hi - n2lo + 1; - int n3 = n3hi - n3lo + 1; - int n4 = n4hi - n4lo + 1; - data = TYPE(std::string(name),n1,n2,n3,n4); - bigint nbytes = ((bigint) sizeof(typename TYPE::value_type ***)) * n1; - array = (typename TYPE::value_type ****) smalloc(nbytes,name); - - for (int i = 0; i < n1; i++) { - if (n2 == 0) { - array[i] = nullptr; - } else { - nbytes = ((bigint) sizeof(typename TYPE::value_type **)) * n2; - array[i] = (typename TYPE::value_type ***) smalloc(nbytes,name); - for (int j = 0; j < n2; j++){ - if (n3 == 0){ - array[i][j] = nullptr; - } else { - nbytes = ((bigint) sizeof(typename TYPE::value_type *)) * n3; - array[i][j] = (typename TYPE::value_type **) smalloc(nbytes, name); - for (int k = 0; k < n3; k++){ - if (n4 == 0) - array[i][j][k] = nullptr; - else - array[i][j][k] = &data.view_host()(i,j,k,0); - } - } - } - } - } - - return data; -} - template TYPE create_kokkos(TYPE &data, HTYPE &h_data, typename TYPE::value_type **&array, int n1, int n2, @@ -324,7 +271,7 @@ template static_assert(std::is_same_v, "A Kokkos view must have LayoutRight to alias with legacy data structures"); - data = TYPE(std::string(name),n1,n2); + data = TYPE(std::string(name),n1,n2,n3); h_data = Kokkos::create_mirror_view(data); bigint nbytes = ((bigint) sizeof(typename TYPE::value_type *)) * n1 * n2; typename TYPE::value_type **plane = (typename TYPE::value_type **) smalloc(nbytes,name); @@ -343,7 +290,7 @@ template if (n3 == 0) array[i][j] = nullptr; else - array[i][j] = &data.view_host()(i,j,0); + array[i][j] = &h_data(i,j,0); } } } diff --git a/src/KOKKOS/min_linesearch_kokkos.h b/src/KOKKOS/min_linesearch_kokkos.h index b821911f73b..63ee1b8aeb6 100644 --- a/src/KOKKOS/min_linesearch_kokkos.h +++ b/src/KOKKOS/min_linesearch_kokkos.h @@ -19,8 +19,13 @@ namespace LAMMPS_NS { + // the two accumulators must stay double: this is a sum over all local + // degrees of freedom, and the force tolerance test and the Polak-Ribiere + // beta are computed from it, so a float sum in a single- or mixed-precision + // build would decide convergence + struct s_KK_double2 { - KK_FLOAT d0, d1; + double d0, d1; // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION s_KK_double2() { diff --git a/src/KOKKOS/min_sd_kokkos.cpp b/src/KOKKOS/min_sd_kokkos.cpp index af4794c3d6a..5cb62aba9af 100644 --- a/src/KOKKOS/min_sd_kokkos.cpp +++ b/src/KOKKOS/min_sd_kokkos.cpp @@ -123,6 +123,12 @@ int MinSDKokkos::iterate(int maxiter) // set new search direction h to f = -Grad(x) + // a force style without a KOKKOS variant leaves the device copy stale, + // and energy_force() only pushes it back for newton on or a min_post_force + // fix, so the force array has to be claimed here before it is read + + atomKK->sync(Device,F_MASK); + set_search_direction(); // output for thermo, dump, restart files diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 140723963f5..6a0df76c507 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -347,18 +347,11 @@ void VerletKokkos::run(int n) comm->forward_comm(); timer->stamp(Timer::COMM); } else { - // added debug - //atomKK->sync(Host,ALL_MASK); - //atomKK->modified(Host,ALL_MASK); - if (n_pre_exchange) { timer->stamp(); modify->pre_exchange(); timer->stamp(Timer::MODIFY); } - // debug - //atomKK->sync(Host,ALL_MASK); - //atomKK->modified(Host,ALL_MASK); if (triclinic) domain->x2lamda(atomKK->nlocal); domain->pbc(); if (domain->box_change) { @@ -368,18 +361,10 @@ void VerletKokkos::run(int n) } timer->stamp(); - // added debug - //atomKK->sync(Device,ALL_MASK); - //atomKK->modified(Device,ALL_MASK); - comm->exchange(); if (sortflag && ntimestep >= atomKK->nextsort) atomKK->sort(); comm->borders(); - // added debug - //atomKK->sync(Host,ALL_MASK); - //atomKK->modified(Host,ALL_MASK); - if (triclinic) domain->lamda2x(atomKK->nlocal+atomKK->nghost); timer->stamp(Timer::COMM); @@ -457,6 +442,15 @@ void VerletKokkos::run(int n) force->pair->execution_space != Host)) { Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_hostkk(),0.0); atomKK->k_f.modify_hostkk_legacy(); + + // a force style without KOKKOS support (execution_space == Host) adds + // into the legacy host array, which is a separate allocation whenever + // the two host views need a transform, so it has to be cleared for the + // same reason. Without this, fusing force_clear() into the pair style + // leaves it stale and its contents are re-added on every step. + + if (atomKK->k_f.NEED_TRANSFORM) + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_host(),0.0); } } @@ -510,7 +504,20 @@ void VerletKokkos::run(int n) if (f_merge_copy.extent(0) < atomKK->k_f.extent(0)) f_merge_copy = DAT::t_kkacc_1d_3("VerletKokkos::f_merge_copy",atomKK->k_f.extent(0)); f = atomKK->k_f.view_device(); - atomKK->k_f.sync_legacy_to_hostkk(); + + // both host copies can hold a contribution: a /kk/host style accumulates + // into the Kokkos host view, a style without KOKKOS support into the + // legacy host array behind atom->f, which is a separate allocation when + // the two need a transform. Add the legacy one in. sync_legacy_to_hostkk() + // cannot be used here: it would copy one buffer over the other, and it is + // a no-op anyway since F_MASK is excluded from the modified() calls above. + + if (atomKK->k_f.NEED_TRANSFORM) { + auto h_f_kk = atomKK->k_f.view_hostkk(); + auto h_f_legacy = atomKK->k_f.view_host(); + Kokkos::parallel_for(Kokkos::RangePolicy(0,atomKK->k_f.extent(0)), + ForceAdder(h_f_kk,h_f_legacy)); + } Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.view_hostkk()); Kokkos::parallel_for(atomKK->k_f.extent(0), ForceAdder(atomKK->k_f.view_device(),f_merge_copy)); From 490ba8b9d0787d578b64b523c3cda04dae3140fc Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:58:09 +0000 Subject: [PATCH 089/120] KOKKOS: fix pppm, tip4p and the phonon drivers pppm_kokkos unpacked the reverse-comm buffer with the wrong stride, leaked fft2, had no reset_grid() override, and silently accepted "kspace_modify slab auto", which needs an iteration the port does not implement and would otherwise apply the slab correction with no vacuum inserted. It now rejects that combination. pppm_tip4p_kokkos and pair_tip4p_cut_kokkos were missing the typeH checks the CPU styles perform. third_order_kokkos and dynamical_matrix_kokkos treated a HostKK style as a device style: its data mask was never added to the host sync and its contribution was never merged back. They also deep-copied one host force buffer over the other rather than adding, which drops a contribution whenever the legacy and Kokkos host views are separate allocations. --- src/KOKKOS/dynamical_matrix_kokkos.cpp | 52 +++++++++++++---- src/KOKKOS/pppm_kokkos.cpp | 79 ++++++++++++++++++++++++-- src/KOKKOS/pppm_kokkos.h | 1 + src/KOKKOS/pppm_tip4p_kokkos.cpp | 15 ++++- src/KOKKOS/third_order_kokkos.cpp | 50 +++++++++++++--- 5 files changed, 170 insertions(+), 27 deletions(-) diff --git a/src/KOKKOS/dynamical_matrix_kokkos.cpp b/src/KOKKOS/dynamical_matrix_kokkos.cpp index c37e185b9b5..7db815c2f26 100644 --- a/src/KOKKOS/dynamical_matrix_kokkos.cpp +++ b/src/KOKKOS/dynamical_matrix_kokkos.cpp @@ -149,8 +149,6 @@ void DynamicalMatrixKokkos::update_force() lmp->kokkos->auto_sync = 0; - f_merge_copy = DAT::t_kkacc_1d_3("DynamicalMatrixKokkos::f_merge_copy",atomKK->k_f.extent(0)); - atomKK->modified(Host,X_MASK); atomKK->sync(Device,X_MASK); @@ -170,37 +168,43 @@ void DynamicalMatrixKokkos::update_force() uint64_t datamask_read_host = 0; if (pair_compute_flag) { - if (force->pair->execution_space==Host) { + if (force->pair->execution_space==Host || + force->pair->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->pair->datamask_read; } } if (atomKK->molecular && force->bond) { - if (force->bond->execution_space==Host) { + if (force->bond->execution_space==Host || + force->bond->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->bond->datamask_read; } } if (atomKK->molecular && force->angle) { - if (force->angle->execution_space==Host) { + if (force->angle->execution_space==Host || + force->angle->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->angle->datamask_read; } } if (atomKK->molecular && force->dihedral) { - if (force->dihedral->execution_space==Host) { + if (force->dihedral->execution_space==Host || + force->dihedral->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->dihedral->datamask_read; } } if (atomKK->molecular && force->improper) { - if (force->improper->execution_space==Host) { + if (force->improper->execution_space==Host || + force->improper->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->improper->datamask_read; } } if (kspace_compute_flag) { - if (force->kspace->execution_space==Host) { + if (force->kspace->execution_space==Host || + force->kspace->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->kspace->datamask_read; } @@ -228,8 +232,21 @@ void DynamicalMatrixKokkos::update_force() if (pair_compute_flag && force->pair->datamask_modify!=(F_MASK | ENERGY_MASK | VIRIAL_MASK)) Kokkos::fence(); atomKK->sync_pinned(Host,~(~datamask_read_host|(F_MASK | ENERGY_MASK | VIRIAL_MASK)),1); - if (pair_compute_flag && force->pair->execution_space!=Host) { - Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_host(),0.0); + + // zero the host-side force buffers before the host styles accumulate into + // them, so the merge below does not re-add stale values. skip this only + // when the pair style itself runs on the host, since then the pair force + // we want to merge already lives in them. a /kk/host style accumulates + // into the Kokkos host view, a style without KOKKOS support into the + // legacy host array behind it, which is a separate allocation whenever the + // two need a transform + + if (!pair_compute_flag || (force->pair->execution_space!=Host && + force->pair->execution_space!=HostKK)) { + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_hostkk(),0.0); + atomKK->k_f.modify_hostkk_legacy(); + if (atomKK->k_f.NEED_TRANSFORM) + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_host(),0.0); } } @@ -284,7 +301,20 @@ void DynamicalMatrixKokkos::update_force() f_merge_copy = DAT::t_kkacc_1d_3("DynamicalMatrixKokkos::f_merge_copy",atomKK->k_f.extent(0)); } f = atomKK->k_f.view_device(); - Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.view_host()); + + // both host copies can hold a contribution: a /kk/host style accumulates + // into the Kokkos host view, a style without KOKKOS support into the legacy + // host array behind atom->f. Add the legacy one in and copy through the + // Kokkos host view, which is the one that matches f_merge_copy in value + // type and layout + + if (atomKK->k_f.NEED_TRANSFORM) { + auto h_f_kk = atomKK->k_f.view_hostkk(); + auto h_f_legacy = atomKK->k_f.view_host(); + Kokkos::parallel_for(Kokkos::RangePolicy(0,atomKK->k_f.extent(0)), + ForceAdder(h_f_kk,h_f_legacy)); + } + Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.view_hostkk()); Kokkos::parallel_for(atomKK->k_f.extent(0), ForceAdder(atomKK->k_f.view_device(),f_merge_copy)); atomKK->k_f.clear_sync_state(); // special case diff --git a/src/KOKKOS/pppm_kokkos.cpp b/src/KOKKOS/pppm_kokkos.cpp index 61aeb62787d..97a7b278096 100644 --- a/src/KOKKOS/pppm_kokkos.cpp +++ b/src/KOKKOS/pppm_kokkos.cpp @@ -145,6 +145,14 @@ void PPPMKokkos::init() if (differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use PPPM Kokkos with 'kspace_modify diff ad'"); + // the automatic slab volume factor of the base class needs the iteration in + // PPPM::init(), which is not implemented here. Without it slab_volfactor + // stays at 1.0, no vacuum is inserted, and the slab correction is applied to + // the unmodified box, so this must be rejected rather than ignored. + + if (slabflag == 1 && slab_auto) + error->all(FLERR,"Cannot (yet) use PPPM Kokkos with 'kspace_modify slab auto'"); + triclinic_check(); if (triclinic != domain->triclinic) @@ -557,6 +565,50 @@ void PPPMKokkos::operator()(TagPPPM_setup_triclinic2, const int &n) } } +/* ---------------------------------------------------------------------- + reset local grid arrays and communication stencils + called by fix balance b/c it changed sizes of processor sub-domains + + PPPM::reset_grid() cannot be inherited here: it works on the base class + grid and charge distribution coefficients, which a KOKKOS run leaves + unallocated, and compute_rho_coeff() is not virtual +------------------------------------------------------------------------- */ + +template +void PPPMKokkos::reset_grid() +{ + // free all arrays previously allocated + + deallocate(); + if (peratom_allocate_flag) deallocate_peratom(); + + // reset portion of global grid that each proc owns + + set_grid_local(); + + // reallocate K-space dependent memory + // check if grid communication is now overlapping if not allowed + // don't invoke allocate_peratom(), will be allocated when needed + + allocate(); + + if (!overlap_allowed && !gc->ghost_adjacent()) + error->all(FLERR,"PPPM grid stencil extends beyond nearest neighbor processor"); + + // pre-compute Green's function denomiator expansion + // pre-compute 1d charge distribution coefficients + + compute_gf_denom(); + compute_rho_coeff(); + + k_rho_coeff.modify_host(); + k_rho_coeff.template sync(); + + // pre-compute volume-dependent coeffs for portion of grid I now own + + setup(); +} + /* ---------------------------------------------------------------------- compute the PPPM long-range force, energy, virial ------------------------------------------------------------------------- */ @@ -618,6 +670,11 @@ void PPPMKokkos::compute(int eflag, int vflag) boxlo[2] = domain->boxlo_lamda[2]; domain->x2lamda(atomKK->nlocal); + + // DomainKokkos converts on the device and claims X there, so the host + // instantiation would otherwise keep reading un-converted coordinates + + atomKK->sync(execution_space,X_MASK); } boxlo_kk[0] = static_cast(boxlo[0]); @@ -737,7 +794,10 @@ void PPPMKokkos::compute(int eflag, int vflag) // convert atoms back from lamda to box coords // must precede slabcorr(), which needs Cartesian z-coordinates - if (triclinic) domain->lamda2x(atom->nlocal); + if (triclinic) { + domain->lamda2x(atom->nlocal); + atomKK->sync(execution_space,X_MASK); + } // 2d slab correction @@ -903,14 +963,21 @@ void PPPMKokkos::deallocate() memory->destroy(gc_buf1); memory->destroy(gc_buf2); - memoryKK->destroy_kokkos(d_density_fft,density_fft); - memoryKK->destroy_kokkos(d_work1,work1); - memoryKK->destroy_kokkos(d_work2,work2); + // release through the DualViews the buffers were created from, and drop the + // derived device handles as well: either one left holding a reference keeps + // the old allocation alive until allocate() overwrites it + + memoryKK->destroy_kokkos(k_density_fft,density_fft); + memoryKK->destroy_kokkos(k_work1,work1); + memoryKK->destroy_kokkos(k_work2,work2); + d_density_fft = typename FFT_AT::t_FFT_SCALAR_1d(); + d_work1 = typename FFT_AT::t_FFT_SCALAR_1d(); + d_work2 = typename FFT_AT::t_FFT_SCALAR_1d(); delete fft1; fft1 = nullptr; delete fft2; - fft1 = nullptr; + fft2 = nullptr; delete remap; remap = nullptr; } @@ -2415,7 +2482,7 @@ void PPPMKokkos::operator()(TagPPPM_unpack_forward2, const int &i) c const int iz = static_cast(dlist/(nx*ny)); const int iy = static_cast((dlist - iz*nx*ny)/nx); const int ix = d_list_index[i] - iz*nx*ny - iy*nx; - if (eflag_atom) d_u_brick(iz,iy,ix) = d_buf[7*i]; + if (eflag_atom) d_u_brick(iz,iy,ix) = d_buf[7*i + unpack_offset]; if (vflag_atom) { d_v0_brick(iz,iy,ix) = d_buf[7*i+1 + unpack_offset]; d_v1_brick(iz,iy,ix) = d_buf[7*i+2 + unpack_offset]; diff --git a/src/KOKKOS/pppm_kokkos.h b/src/KOKKOS/pppm_kokkos.h index 88103a24f18..f9f0f93d12e 100644 --- a/src/KOKKOS/pppm_kokkos.h +++ b/src/KOKKOS/pppm_kokkos.h @@ -108,6 +108,7 @@ class PPPMKokkos : public PPPM, public KokkosBaseFFT { ~PPPMKokkos() override; void init() override; void setup() override; + void reset_grid() override; void compute(int, int) override; int timing_1d(int, double &) override; int timing_3d(int, double &) override; diff --git a/src/KOKKOS/pppm_tip4p_kokkos.cpp b/src/KOKKOS/pppm_tip4p_kokkos.cpp index 0f37648d212..70b8d6613ad 100644 --- a/src/KOKKOS/pppm_tip4p_kokkos.cpp +++ b/src/KOKKOS/pppm_tip4p_kokkos.cpp @@ -100,8 +100,11 @@ void PPPMTIP4PKokkos::compute_newsites() k_tip4p_flag.template modify(); k_tip4p_flag.sync_host(); - if (k_tip4p_flag.view_host()()) + const int tip4p_flag = k_tip4p_flag.view_host()(); + if (tip4p_flag == 1) this->error->one(FLERR,"TIP4P hydrogen is missing"); + else if (tip4p_flag == 2) + this->error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); } template @@ -118,6 +121,16 @@ void PPPMTIP4PKokkos::operator()(TagPPPMTIP4P_findM, const int &i) c d_xM(i,0) = x(i,0); d_xM(i,1) = x(i,1); d_xM(i,2) = x(i,2); return; } + + // the two atoms following the oxygen must really be the hydrogens, + // the same check PPPMTIP4P::find_M() makes + + if (d_type(iH1) != typeH_kk || d_type(iH2) != typeH_kk) { + k_tip4p_flag.template view()() = 2; + d_iH1(i) = i; d_iH2(i) = i; + d_xM(i,0) = x(i,0); d_xM(i,1) = x(i,1); d_xM(i,2) = x(i,2); + return; + } iH1 = closest_image(i,iH1); iH2 = closest_image(i,iH2); d_iH1(i) = iH1; diff --git a/src/KOKKOS/third_order_kokkos.cpp b/src/KOKKOS/third_order_kokkos.cpp index 2ee6f9e8117..77795d7dca4 100644 --- a/src/KOKKOS/third_order_kokkos.cpp +++ b/src/KOKKOS/third_order_kokkos.cpp @@ -170,37 +170,43 @@ void ThirdOrderKokkos::update_force() uint64_t datamask_read_host = 0; if (pair_compute_flag) { - if (force->pair->execution_space==Host) { + if (force->pair->execution_space==Host || + force->pair->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->pair->datamask_read; } } if (atomKK->molecular && force->bond) { - if (force->bond->execution_space==Host) { + if (force->bond->execution_space==Host || + force->bond->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->bond->datamask_read; } } if (atomKK->molecular && force->angle) { - if (force->angle->execution_space==Host) { + if (force->angle->execution_space==Host || + force->angle->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->angle->datamask_read; } } if (atomKK->molecular && force->dihedral) { - if (force->dihedral->execution_space==Host) { + if (force->dihedral->execution_space==Host || + force->dihedral->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->dihedral->datamask_read; } } if (atomKK->molecular && force->improper) { - if (force->improper->execution_space==Host) { + if (force->improper->execution_space==Host || + force->improper->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->improper->datamask_read; } } if (kspace_compute_flag) { - if (force->kspace->execution_space==Host) { + if (force->kspace->execution_space==Host || + force->kspace->execution_space==HostKK) { execute_on_host = true; datamask_read_host |= force->kspace->datamask_read; } @@ -228,8 +234,21 @@ void ThirdOrderKokkos::update_force() if (pair_compute_flag && force->pair->datamask_modify!=(F_MASK | ENERGY_MASK | VIRIAL_MASK)) Kokkos::fence(); atomKK->sync_pinned(Host,~(~datamask_read_host|(F_MASK | ENERGY_MASK | VIRIAL_MASK)),1); - if (pair_compute_flag && force->pair->execution_space!=Host) { - Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_host(),0.0); + + // zero the host-side force buffers before the host styles accumulate into + // them, so the merge below does not re-add stale values. skip this only + // when the pair style itself runs on the host, since then the pair force + // we want to merge already lives in them. a /kk/host style accumulates + // into the Kokkos host view, a style without KOKKOS support into the + // legacy host array behind it, which is a separate allocation whenever the + // two need a transform + + if (!pair_compute_flag || (force->pair->execution_space!=Host && + force->pair->execution_space!=HostKK)) { + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_hostkk(),0.0); + atomKK->k_f.modify_hostkk_legacy(); + if (atomKK->k_f.NEED_TRANSFORM) + Kokkos::deep_copy(LMPHostType(),atomKK->k_f.view_host(),0.0); } } @@ -284,7 +303,20 @@ void ThirdOrderKokkos::update_force() f_merge_copy = DAT::t_kkacc_1d_3("ThirdOrderKokkos::f_merge_copy",atomKK->k_f.extent(0)); } f = atomKK->k_f.view_device(); - Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.view_host()); + + // both host copies can hold a contribution: a /kk/host style accumulates + // into the Kokkos host view, a style without KOKKOS support into the legacy + // host array behind atom->f. Add the legacy one in and copy through the + // Kokkos host view, which is the one that matches f_merge_copy in value + // type and layout + + if (atomKK->k_f.NEED_TRANSFORM) { + auto h_f_kk = atomKK->k_f.view_hostkk(); + auto h_f_legacy = atomKK->k_f.view_host(); + Kokkos::parallel_for(Kokkos::RangePolicy(0,atomKK->k_f.extent(0)), + ForceAdder(h_f_kk,h_f_legacy)); + } + Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.view_hostkk()); Kokkos::parallel_for(atomKK->k_f.extent(0), ForceAdder(atomKK->k_f.view_device(),f_merge_copy)); atomKK->k_f.clear_sync_state(); // special case From d02f7de4ac3ed72d9283dfecc3b2f7a89cf5d454 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:58:21 +0000 Subject: [PATCH 090/120] KOKKOS: fix bonded style defects The three hybrid styles left centroidstressflag at its base-class value instead of CENTROID_NOTAVAIL, claiming a centroid virial they do not compute. bond_hybrid_kokkos did not perform the orig_map write-back that BondHybrid::compute() does: a sub-style that deletes a bond writes type 0 into the sub-style list, and without the write-back that never reaches neighbor->bondlist, so compute bond/local, compute bond and dump local see the stale type for the rest of the reneighbour interval. The write-back is done on the host because bond_quartic_kokkos writes its zeros into the host mirror. The three fene styles raced on a plain store to the error flag; they now use Kokkos::atomic_max. improper_fourier_kokkos reallocated its warning-flag DualView every step, and angle_mm3_kokkos destroyed and recreated k_eatom/k_vatom every step. Both now follow the pattern of their harmonic siblings. These two are allocation fixes, not correctness fixes. --- src/KOKKOS/angle_cosine_shift_exp_kokkos.cpp | 4 +- src/KOKKOS/angle_fourier_simple_kokkos.cpp | 2 +- src/KOKKOS/angle_gaussian_kokkos.cpp | 54 +++++++++++++----- src/KOKKOS/angle_hybrid_kokkos.cpp | 5 ++ src/KOKKOS/angle_mm3_kokkos.cpp | 18 ++++-- src/KOKKOS/angle_spica_kokkos.cpp | 59 ++++++++++---------- src/KOKKOS/angle_spica_kokkos.h | 7 +-- src/KOKKOS/bond_fene_expand_kokkos.cpp | 4 +- src/KOKKOS/bond_fene_kokkos.cpp | 4 +- src/KOKKOS/bond_fene_nm_kokkos.cpp | 4 +- src/KOKKOS/bond_hybrid_kokkos.cpp | 50 ++++++++++++++++- src/KOKKOS/bond_hybrid_kokkos.h | 2 + src/KOKKOS/bond_quartic_kokkos.cpp | 4 ++ src/KOKKOS/dihedral_fourier_kokkos.cpp | 17 ++++++ src/KOKKOS/dihedral_hybrid_kokkos.cpp | 5 ++ src/KOKKOS/dihedral_nharmonic_kokkos.cpp | 11 ++++ src/KOKKOS/improper_cvff_kokkos.cpp | 2 +- src/KOKKOS/improper_fourier_kokkos.cpp | 12 ++-- src/KOKKOS/improper_hybrid_kokkos.cpp | 5 ++ src/KOKKOS/improper_umbrella_kokkos.cpp | 7 ++- 20 files changed, 202 insertions(+), 74 deletions(-) diff --git a/src/KOKKOS/angle_cosine_shift_exp_kokkos.cpp b/src/KOKKOS/angle_cosine_shift_exp_kokkos.cpp index 4a5a6b5fae1..8283adf7dd1 100644 --- a/src/KOKKOS/angle_cosine_shift_exp_kokkos.cpp +++ b/src/KOKKOS/angle_cosine_shift_exp_kokkos.cpp @@ -31,6 +31,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +static constexpr double SMALL = 0.001; + /* ---------------------------------------------------------------------- */ template @@ -186,7 +188,7 @@ void AngleCosineShiftExpKokkos::operator()(TagAngleCosineShiftExpCom if (c < static_cast(-1.0)) c = static_cast(-1.0); KK_FLOAT s = Kokkos::sqrt(static_cast(1.0) - c*c); - if (s < static_cast(1e-12)) s = static_cast(1e-12); + if (s < static_cast(SMALL)) s = static_cast(SMALL); const KK_FLOAT cccpsss = c*d_cost[type] + s*d_sint[type]; const KK_FLOAT cssmscc = c*d_sint[type] - s*d_cost[type]; diff --git a/src/KOKKOS/angle_fourier_simple_kokkos.cpp b/src/KOKKOS/angle_fourier_simple_kokkos.cpp index ab1a2e9a9ae..5e3b8ca20d4 100644 --- a/src/KOKKOS/angle_fourier_simple_kokkos.cpp +++ b/src/KOKKOS/angle_fourier_simple_kokkos.cpp @@ -183,7 +183,7 @@ void AngleFourierSimpleKokkos::operator()(TagAngleFourierSimpleCompu sgn = static_cast(1.0); } else { term = static_cast(1.0) + c; - sgn = (fmod(static_cast(d_N[type]), 2.0) == 0.0) ? + sgn = (Kokkos::fmod(d_N[type], static_cast(2.0)) == static_cast(0.0)) ? static_cast(-1.0) : static_cast(1.0); } a = d_N[type] + d_N[type] * (static_cast(1.0) - d_N[type]*d_N[type]) * term / static_cast(3.0); diff --git a/src/KOKKOS/angle_gaussian_kokkos.cpp b/src/KOKKOS/angle_gaussian_kokkos.cpp index 9dcde567845..638fe383785 100644 --- a/src/KOKKOS/angle_gaussian_kokkos.cpp +++ b/src/KOKKOS/angle_gaussian_kokkos.cpp @@ -23,12 +23,12 @@ #include "neighbor_kokkos.h" #include +#include using namespace LAMMPS_NS; using namespace MathConst; static constexpr double SMALL = 0.001; -static constexpr double SMALLG = 2.3e-308; /* ---------------------------------------------------------------------- */ @@ -70,9 +70,24 @@ void AngleGaussianKokkos::allocate_kokkos() k_width = DAT::tdual_kkfloat_2d("AngleGaussian::width",n+1,nterms_max); k_theta0 = DAT::tdual_kkfloat_2d("AngleGaussian::theta0",n+1,nterms_max); } else { + + // make the host side the newest before resizing: Kokkos grows the side + // that was last modified, and growing on the device replaces the host + // mirror with a fresh zero-filled allocation and leaves the device marked + // modified, which makes the modify_host() in coeff() below abort with a + // concurrent modification error + + k_nterms.sync_host(); + k_nterms.modify_host(); k_nterms.resize(n+1); + k_alpha.sync_host(); + k_alpha.modify_host(); k_alpha.resize(n+1,nterms_max); + k_width.sync_host(); + k_width.modify_host(); k_width.resize(n+1,nterms_max); + k_theta0.sync_host(); + k_theta0.modify_host(); k_theta0.resize(n+1,nterms_max); } @@ -172,6 +187,11 @@ template KOKKOS_INLINE_FUNCTION void AngleGaussianKokkos::operator()(TagAngleGaussianCompute, const int &n, EV_FLOAT& ev) const { + // smallest normalized value of the accumulation type so the underflow guard + // below works at any precision (casting the 2.3e-308 of the base class to + // float gives 0.0) + static constexpr KK_ACC_FLOAT SMALL_KK = std::numeric_limits::min(); + Kokkos::View::value,Kokkos::MemoryTraits > a_f = f; const int i1 = anglelist(n,0); @@ -203,31 +223,35 @@ void AngleGaussianKokkos::operator()(TagAngleGaussianCompute(SMALL)) s = static_cast(SMALL); s = static_cast(1.0)/s; - const KK_FLOAT theta = Kokkos::acos(c); + const KK_ACC_FLOAT theta = static_cast(Kokkos::acos(c)); + + // the sums of the Gaussian terms must use the accumulation precision: + // far out in the tails the individual terms underflow to zero in single + // precision and log(sum_g_i) below would give -inf - KK_FLOAT sum_g_i = static_cast(0.0); - KK_FLOAT sum_numerator = static_cast(0.0); + KK_ACC_FLOAT sum_g_i = static_cast(0.0); + KK_ACC_FLOAT sum_numerator = static_cast(0.0); const int nt = d_nterms[type]; for (int i = 0; i < nt; i++) { - const KK_FLOAT dtheta = theta - d_theta0(type,i); - const KK_FLOAT w = d_width(type,i); - const KK_FLOAT prefactor = d_alpha(type,i) / (w * Kokkos::sqrt(static_cast(MY_PI2))); - const KK_FLOAT exponent = static_cast(-2.0) * dtheta * dtheta / (w * w); - const KK_FLOAT g_i = prefactor * Kokkos::exp(exponent); + const KK_ACC_FLOAT dtheta = theta - static_cast(d_theta0(type,i)); + const KK_ACC_FLOAT w = static_cast(d_width(type,i)); + const KK_ACC_FLOAT prefactor = static_cast(d_alpha(type,i)) / (w * Kokkos::sqrt(static_cast(MY_PI2))); + const KK_ACC_FLOAT exponent = static_cast(-2.0) * dtheta * dtheta / (w * w); + const KK_ACC_FLOAT g_i = prefactor * Kokkos::exp(exponent); sum_g_i += g_i; sum_numerator += g_i * dtheta / (w * w); } // avoid overflow - if (sum_g_i < sum_numerator * static_cast(SMALLG)) - sum_g_i = sum_numerator * static_cast(SMALLG); + if (sum_g_i < sum_numerator * SMALL_KK) sum_g_i = sum_numerator * SMALL_KK; - const KK_FLOAT kbt = boltz * d_angle_temperature[type]; + const KK_ACC_FLOAT kbt = static_cast(boltz) * static_cast(d_angle_temperature[type]); KK_FLOAT eangle = static_cast(0.0); - if (eflag) eangle = -kbt * Kokkos::log(sum_g_i); + if (eflag) eangle = static_cast(-kbt * Kokkos::log(sum_g_i)); - const KK_FLOAT a = static_cast(-4.0) * kbt * (sum_numerator / sum_g_i) * s; + const KK_FLOAT a = static_cast(-static_cast(4.0) * kbt * + (sum_numerator / sum_g_i) * static_cast(s)); const KK_FLOAT a11 = a*c / rsq1; const KK_FLOAT a12 = -a / (r1*r2); const KK_FLOAT a22 = a*c / rsq2; @@ -298,7 +322,7 @@ void AngleGaussianKokkos::coeff(int narg, char **arg) allocate_kokkos(); int ilo,ihi; - utils::bounds(FLERR,arg[0],1,atom->ndihedraltypes,ilo,ihi,error); + utils::bounds(FLERR,arg[0],1,atom->nangletypes,ilo,ihi,error); for (int i = ilo; i <= ihi; i++) { k_nterms.view_host()[i] = nterms[i]; diff --git a/src/KOKKOS/angle_hybrid_kokkos.cpp b/src/KOKKOS/angle_hybrid_kokkos.cpp index 2b92d4ddbcc..41ab662f288 100644 --- a/src/KOKKOS/angle_hybrid_kokkos.cpp +++ b/src/KOKKOS/angle_hybrid_kokkos.cpp @@ -34,6 +34,11 @@ AngleHybridKokkos::AngleHybridKokkos(LAMMPS *lmp) : AngleHybrid(lmp) { kokkosable = 1; + // every KOKKOS sub-style sets CENTROID_NOTAVAIL, so the hybrid style cannot + // offer a centroid virial either - otherwise cvatom is never allocated and the + // per-substyle accumulation dereferences a null pointer + centroidstressflag = CENTROID_NOTAVAIL; + atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; diff --git a/src/KOKKOS/angle_mm3_kokkos.cpp b/src/KOKKOS/angle_mm3_kokkos.cpp index 7020a50f8e1..4b2333ebfad 100644 --- a/src/KOKKOS/angle_mm3_kokkos.cpp +++ b/src/KOKKOS/angle_mm3_kokkos.cpp @@ -69,15 +69,21 @@ void AngleMM3Kokkos::compute(int eflag_in, int vflag_in) 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,"angle:eatom"); - d_eatom = k_eatom.template view(); + if ((int)k_eatom.extent(0) < maxeatom) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"angle:eatom"); + d_eatom = k_eatom.template view(); + } else Kokkos::deep_copy(d_eatom,0.0); } if (vflag_atom) { - memoryKK->destroy_kokkos(k_vatom,vatom); - memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"angle:vatom"); - d_vatom = k_vatom.template view(); + if ((int)k_vatom.extent(0) < maxvatom) { + memoryKK->destroy_kokkos(k_vatom,vatom); + memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"angle:vatom"); + d_vatom = k_vatom.template view(); + } else Kokkos::deep_copy(d_vatom,0.0); } k_theta0.template sync(); diff --git a/src/KOKKOS/angle_spica_kokkos.cpp b/src/KOKKOS/angle_spica_kokkos.cpp index 1097f640a09..e05a7573629 100644 --- a/src/KOKKOS/angle_spica_kokkos.cpp +++ b/src/KOKKOS/angle_spica_kokkos.cpp @@ -44,6 +44,7 @@ static constexpr double SMALL = 0.001; template AngleSPICAKokkos::AngleSPICAKokkos(LAMMPS *lmp) : AngleSPICA(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -77,19 +78,22 @@ void AngleSPICAKokkos::compute(int eflag_in, int vflag_in) // reallocate per-atom arrays if necessary if (eflag_atom) { + if ((int)k_eatom.extent(0) < maxeatom) { memoryKK->destroy_kokkos(k_eatom,eatom); memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"angle:eatom"); d_eatom = k_eatom.template view(); + } else Kokkos::deep_copy(d_eatom,0.0); } if (vflag_atom) { + if ((int)k_vatom.extent(0) < maxvatom) { memoryKK->destroy_kokkos(k_vatom,vatom); memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"angle:vatom"); d_vatom = k_vatom.template view(); + } else Kokkos::deep_copy(d_vatom,0.0); } k_k.template sync(); k_theta0.template sync(); - k_repscale.template sync(); k_lj_type.template sync(); k_lj1.template sync(); k_lj2.template sync(); @@ -331,13 +335,9 @@ void AngleSPICAKokkos::allocate() int nangletypes = atom->nangletypes; k_k = DAT::tdual_kkfloat_1d("AngleSPICA::k",nangletypes+1); k_theta0 = DAT::tdual_kkfloat_1d("AngleSPICA::theta0",nangletypes+1); - k_repscale = DAT::tdual_kkfloat_1d("AngleSPICA::repscale",nangletypes+1); - k_setflag = DAT::tdual_int_1d("AngleSPICA::setflag",nangletypes+1); d_k = k_k.template view(); d_theta0 = k_theta0.template view(); - d_repscale = k_repscale.template view(); - d_setflag = k_setflag.template view(); int ntypes = atom->ntypes; k_lj_type = DAT::tdual_int_2d("AngleSPICA::lj_type",ntypes+1,ntypes+1); @@ -376,26 +376,31 @@ void AngleSPICAKokkos::init_style() error->all(FLERR,"Cannot use Kokkos pair style with rRESPA inner/middle"); } - int ntypes = atom->ntypes; - for (int i = 1; i <= ntypes; i++) { - for (int j = 1; j <= ntypes; j++) { - k_lj_type.view_host()(i,j) = lj_type[i][j]; - k_lj1.view_host()(i,j) = static_cast(lj1[i][j]); - k_lj2.view_host()(i,j) = static_cast(lj2[i][j]); - k_lj3.view_host()(i,j) = static_cast(lj3[i][j]); - k_lj4.view_host()(i,j) = static_cast(lj4[i][j]); - k_rminsq.view_host()(i,j) = static_cast(rminsq[i][j]); - k_emin.view_host()(i,j) = static_cast(emin[i][j]); + // AngleSPICA::init_style() only extracts the pair style parameters when the + // 1-3 repulsion is used; without it they are still null pointers + + if (repflag) { + int ntypes = atom->ntypes; + for (int i = 1; i <= ntypes; i++) { + for (int j = 1; j <= ntypes; j++) { + k_lj_type.view_host()(i,j) = lj_type[i][j]; + k_lj1.view_host()(i,j) = static_cast(lj1[i][j]); + k_lj2.view_host()(i,j) = static_cast(lj2[i][j]); + k_lj3.view_host()(i,j) = static_cast(lj3[i][j]); + k_lj4.view_host()(i,j) = static_cast(lj4[i][j]); + k_rminsq.view_host()(i,j) = static_cast(rminsq[i][j]); + k_emin.view_host()(i,j) = static_cast(emin[i][j]); + } } - } - k_lj_type.modify_host(); - k_lj1.modify_host(); - k_lj2.modify_host(); - k_lj3.modify_host(); - k_lj4.modify_host(); - k_rminsq.modify_host(); - k_emin.modify_host(); + k_lj_type.modify_host(); + k_lj1.modify_host(); + k_lj2.modify_host(); + k_lj3.modify_host(); + k_lj4.modify_host(); + k_rminsq.modify_host(); + k_emin.modify_host(); + } } /* ---------------------------------------------------------------------- @@ -413,14 +418,10 @@ void AngleSPICAKokkos::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k_k.view_host()[i] = static_cast(k[i]); k_theta0.view_host()[i] = static_cast(theta0[i]); - k_repscale.view_host()[i] = static_cast(repscale[i]); - k_setflag.view_host()[i] = setflag[i]; } k_k.modify_host(); k_theta0.modify_host(); - k_repscale.modify_host(); - k_setflag.modify_host(); } /* ---------------------------------------------------------------------- @@ -436,14 +437,10 @@ void AngleSPICAKokkos::read_restart(FILE *fp) for (int i = 1; i <= n; i++) { k_k.view_host()[i] = static_cast(k[i]); k_theta0.view_host()[i] = static_cast(theta0[i]); - k_repscale.view_host()[i] = static_cast(repscale[i]); - k_setflag.view_host()[i] = setflag[i]; } k_k.modify_host(); k_theta0.modify_host(); - k_repscale.modify_host(); - k_setflag.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/angle_spica_kokkos.h b/src/KOKKOS/angle_spica_kokkos.h index df89be67b50..54fb8a93fab 100644 --- a/src/KOKKOS/angle_spica_kokkos.h +++ b/src/KOKKOS/angle_spica_kokkos.h @@ -89,11 +89,10 @@ class AngleSPICAKokkos : public AngleSPICA { int nlocal,newton_bond; int eflag,vflag; - DAT::tdual_int_1d k_setflag; - typename AT::t_int_1d d_setflag, d_type; + typename AT::t_int_1d d_type; - DAT::tdual_kkfloat_1d k_k, k_theta0, k_repscale; - typename AT::t_kkfloat_1d d_k, d_theta0, d_repscale; + DAT::tdual_kkfloat_1d k_k, k_theta0; + typename AT::t_kkfloat_1d d_k, d_theta0; DAT::tdual_int_2d k_lj_type; typename AT::t_int_2d d_lj_type; diff --git a/src/KOKKOS/bond_fene_expand_kokkos.cpp b/src/KOKKOS/bond_fene_expand_kokkos.cpp index c9229e2dc7a..6f03531f79b 100644 --- a/src/KOKKOS/bond_fene_expand_kokkos.cpp +++ b/src/KOKKOS/bond_fene_expand_kokkos.cpp @@ -190,9 +190,9 @@ void BondFENEExpandKokkos::operator()(TagBondFENEExpandCompute(0.1)) { if (rlogarg <= static_cast(-3.0)) - d_flag() = 2; + Kokkos::atomic_max(&d_flag(), 2); else - d_flag() = 1; + Kokkos::atomic_max(&d_flag(), 1); rlogarg = static_cast(0.1); } diff --git a/src/KOKKOS/bond_fene_kokkos.cpp b/src/KOKKOS/bond_fene_kokkos.cpp index 980a6d5e44b..8d4e193e2e5 100644 --- a/src/KOKKOS/bond_fene_kokkos.cpp +++ b/src/KOKKOS/bond_fene_kokkos.cpp @@ -199,9 +199,9 @@ void BondFENEKokkos::operator()(TagBondFENECompute(0.1)) { if (rlogarg <= static_cast(-3.0)) - d_flag() = 2; + Kokkos::atomic_max(&d_flag(), 2); else - d_flag() = 1; + Kokkos::atomic_max(&d_flag(), 1); rlogarg = static_cast(0.1); } diff --git a/src/KOKKOS/bond_fene_nm_kokkos.cpp b/src/KOKKOS/bond_fene_nm_kokkos.cpp index 3ee06ee3054..42d406ae49c 100644 --- a/src/KOKKOS/bond_fene_nm_kokkos.cpp +++ b/src/KOKKOS/bond_fene_nm_kokkos.cpp @@ -173,9 +173,9 @@ void BondFENENMKokkos::operator()(TagBondFENENMCompute(0.02)) { if (rlogarg <= static_cast(-0.21)) - d_flag() = 2; + Kokkos::atomic_max(&d_flag(), 2); else - d_flag() = 1; + Kokkos::atomic_max(&d_flag(), 1); rlogarg = static_cast(0.02); } diff --git a/src/KOKKOS/bond_hybrid_kokkos.cpp b/src/KOKKOS/bond_hybrid_kokkos.cpp index b193b9fe1b5..87fe1480609 100644 --- a/src/KOKKOS/bond_hybrid_kokkos.cpp +++ b/src/KOKKOS/bond_hybrid_kokkos.cpp @@ -91,6 +91,14 @@ void BondHybridKokkos::compute(int eflag, int vflag) MemKK::realloc_kokkos(k_bondlist, "bond_hybrid:bondlist", nstyles, maxbond_all, 3); auto d_bondlist = k_bondlist.view_device(); + // sub-styles that can delete a bond by setting its type to zero need to + // know which entry of the original bondlist each sub-style bond came from + + const int partial = partial_flag; + if (partial && ((int)k_orig_map.view_device().extent(1) < maxbond_all)) + MemKK::realloc_kokkos(k_orig_map, "bond_hybrid:orig_map", nstyles, maxbond_all); + auto d_orig_map = k_orig_map.view_device(); + Kokkos::deep_copy(d_nbondlist,0); Kokkos::parallel_for(nbondlist_orig,LAMMPS_LAMBDA(int i) { @@ -100,7 +108,24 @@ void BondHybridKokkos::compute(int eflag, int vflag) d_bondlist(m,n,0) = d_bondlist_orig(i,0); d_bondlist(m,n,1) = d_bondlist_orig(i,1); d_bondlist(m,n,2) = d_bondlist_orig(i,2); + if (partial) d_orig_map(m,n) = i; }); + + if (partial) { + k_orig_map.modify_device(); + k_orig_map.sync_host(); + } + + // the sub-style lists were just rebuilt on the device. The subviews + // handed to the sub-styles below share these modified flags, so the + // device side is marked newest here and only here: on the other steps + // a sub-style may have marked the host side newest (bond quartic/kk + // zeroes broken bonds in the host mirror) and that must survive to the + // next step, and marking the device modified on top of it would abort + // with a concurrent modification error + + k_bondlist.clear_sync_state(); + k_bondlist.modify_device(); } // call each sub-style's compute function @@ -115,7 +140,6 @@ void BondHybridKokkos::compute(int eflag, int vflag) for (int m = 0; m < nstyles; m++) { neighbor->nbondlist = h_nbondlist[m]; auto k_bondlist_m = Kokkos::subview(k_bondlist,m,Kokkos::ALL,Kokkos::ALL); - k_bondlist_m.modify_device(); neighborKK->k_bondlist = k_bondlist_m; auto style = styles[m]; @@ -142,6 +166,29 @@ void BondHybridKokkos::compute(int eflag, int vflag) } } + // a sub-style that can delete bonds (bond style quartic) does so by setting + // the bond type to zero in the sub-style bondlist it was handed. Copy those + // zeroes back into the original bondlist, as BondHybrid::compute() does, + // otherwise the deletion is lost when the sub-style lists are rebuilt at the + // next reneighboring. The sub-style writes them on the host, so do the same + // here rather than round-tripping the lists through the device. + + if (partial_flag) { + k_bondlist.sync_host(); + k_orig_map.sync_host(); + k_bondlist_orig.sync_host(); + auto h_bondlist = k_bondlist.view_host(); + auto h_orig_map = k_orig_map.view_host(); + auto h_bondlist_orig = k_bondlist_orig.view_host(); + + for (int m = 0; m < nstyles; m++) + for (int i = 0; i < h_nbondlist[m]; i++) + if (h_bondlist(m,i,2) <= 0) + h_bondlist_orig(h_orig_map(m,i),2) = h_bondlist(m,i,2); + + k_bondlist_orig.modify_host(); + } + // restore ptrs to original bondlist neighbor->nbondlist = nbondlist_orig; @@ -209,6 +256,7 @@ double BondHybridKokkos::memory_usage() double bytes = (double) maxeatom * sizeof(double); bytes += (double) maxvatom * 6 * sizeof(double); for (int m = 0; m < nstyles; m++) bytes += (double) maxbond_all * 3 * sizeof(int); + if (partial_flag) bytes += (double) nstyles * maxbond_all * sizeof(int); for (int m = 0; m < nstyles; m++) if (styles[m]) bytes += styles[m]->memory_usage(); return bytes; diff --git a/src/KOKKOS/bond_hybrid_kokkos.h b/src/KOKKOS/bond_hybrid_kokkos.h index 8594d211f74..dc2a95f1adf 100644 --- a/src/KOKKOS/bond_hybrid_kokkos.h +++ b/src/KOKKOS/bond_hybrid_kokkos.h @@ -47,6 +47,8 @@ class BondHybridKokkos : public BondHybrid { DAT::tdual_int_1d k_map; // which style each bond type points to DAT::tdual_int_1d k_nbondlist; // # of bonds in sub-style bondlists DAT::tdual_int_3d_lr k_bondlist; // bondlist for each sub-style + DAT::tdual_int_2d_lr k_orig_map; // index in the original bondlist of each + // sub-style bond (only when partial_flag) void allocate() override; void deallocate() override; diff --git a/src/KOKKOS/bond_quartic_kokkos.cpp b/src/KOKKOS/bond_quartic_kokkos.cpp index 14058d8a142..c3c0ea35886 100644 --- a/src/KOKKOS/bond_quartic_kokkos.cpp +++ b/src/KOKKOS/bond_quartic_kokkos.cpp @@ -173,6 +173,10 @@ void BondQuarticKokkos::compute(int eflag_in, int vflag_in) atomKK->sync(Host, X_MASK | F_MASK | BOND_MASK | TAG_MASK | TYPE_MASK); atomKK->k_f.modify_host(); + // the kernel wrote the broken bond flags on the device, so the dual view + // must be marked modified there or sync_host() below does nothing + + k_brokenflag.template modify(); k_brokenflag.sync_host(); // host-side post-processing: bond breaking and pair correction diff --git a/src/KOKKOS/dihedral_fourier_kokkos.cpp b/src/KOKKOS/dihedral_fourier_kokkos.cpp index 47522fe7783..a7211cc13a9 100644 --- a/src/KOKKOS/dihedral_fourier_kokkos.cpp +++ b/src/KOKKOS/dihedral_fourier_kokkos.cpp @@ -354,10 +354,27 @@ void DihedralFourierKokkos::allocate_kokkos() k_multiplicity = DAT::tdual_int_2d("DihedralFourier::multiplicity",n+1,nterms_max); k_nterms = DAT::tdual_int_1d("DihedralFourier::nterms",n+1); } else { + + // make the host side the newest before resizing: Kokkos grows the side + // that was last modified, and growing on the device replaces the host + // mirror with a fresh zero-filled allocation and leaves the device marked + // modified, which makes the modify_host() in coeff() below abort with a + // concurrent modification error + + k_k.sync_host(); + k_k.modify_host(); k_k.resize(n+1,nterms_max); + k_cos_shift.sync_host(); + k_cos_shift.modify_host(); k_cos_shift.resize(n+1,nterms_max); + k_sin_shift.sync_host(); + k_sin_shift.modify_host(); k_sin_shift.resize(n+1,nterms_max); + k_multiplicity.sync_host(); + k_multiplicity.modify_host(); k_multiplicity.resize(n+1,nterms_max); + k_nterms.sync_host(); + k_nterms.modify_host(); k_nterms.resize(n+1); } diff --git a/src/KOKKOS/dihedral_hybrid_kokkos.cpp b/src/KOKKOS/dihedral_hybrid_kokkos.cpp index fa6b3357791..03cbfa7849b 100644 --- a/src/KOKKOS/dihedral_hybrid_kokkos.cpp +++ b/src/KOKKOS/dihedral_hybrid_kokkos.cpp @@ -34,6 +34,11 @@ DihedralHybridKokkos::DihedralHybridKokkos(LAMMPS *lmp) : DihedralHybrid(lmp) { kokkosable = 1; + // every KOKKOS sub-style sets CENTROID_NOTAVAIL, so the hybrid style cannot + // offer a centroid virial either - otherwise cvatom is never allocated and the + // per-substyle accumulation dereferences a null pointer + centroidstressflag = CENTROID_NOTAVAIL; + atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; diff --git a/src/KOKKOS/dihedral_nharmonic_kokkos.cpp b/src/KOKKOS/dihedral_nharmonic_kokkos.cpp index a484f7300d1..4cec3a94620 100644 --- a/src/KOKKOS/dihedral_nharmonic_kokkos.cpp +++ b/src/KOKKOS/dihedral_nharmonic_kokkos.cpp @@ -346,7 +346,18 @@ void DihedralNHarmonicKokkos::allocate_kokkos() k_a = DAT::tdual_kkfloat_2d("DihedralNHarmonic::a",n+1,nterms_max); k_nterms = DAT::tdual_int_1d("DihedralNHarmonic::nterms",n+1); } else { + + // make the host side the newest before resizing: Kokkos grows the side + // that was last modified, and growing on the device replaces the host + // mirror with a fresh zero-filled allocation and leaves the device marked + // modified, which makes the modify_host() in coeff() below abort with a + // concurrent modification error + + k_a.sync_host(); + k_a.modify_host(); k_a.resize(n+1,nterms_max); + k_nterms.sync_host(); + k_nterms.modify_host(); k_nterms.resize(n+1); } diff --git a/src/KOKKOS/improper_cvff_kokkos.cpp b/src/KOKKOS/improper_cvff_kokkos.cpp index c7020cb0f9e..597274dbf9e 100644 --- a/src/KOKKOS/improper_cvff_kokkos.cpp +++ b/src/KOKKOS/improper_cvff_kokkos.cpp @@ -275,7 +275,7 @@ void ImproperCvffKokkos::operator()(TagImproperCvffCompute(0.0); } - if (sign[type] == -1) { + if (d_sign[type] == -1) { p = static_cast(2.0) - p; pd = -pd; } diff --git a/src/KOKKOS/improper_fourier_kokkos.cpp b/src/KOKKOS/improper_fourier_kokkos.cpp index 689bf3c84ab..da1507b1242 100644 --- a/src/KOKKOS/improper_fourier_kokkos.cpp +++ b/src/KOKKOS/improper_fourier_kokkos.cpp @@ -43,6 +43,10 @@ ImproperFourierKokkos::ImproperFourierKokkos(LAMMPS *lmp) : Improper datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + k_warning_flag = DAT::tdual_int_scalar("ImproperFourier:warning_flag"); + d_warning_flag = k_warning_flag.template view(); + h_warning_flag = k_warning_flag.view_host(); + centroidstressflag = CENTROID_NOTAVAIL; } @@ -97,9 +101,7 @@ void ImproperFourierKokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; // zero warning flag - k_warning_flag = DAT::tdual_int_scalar("ImproperFourier::warning_flag"); - d_warning_flag = k_warning_flag.template view(); - h_warning_flag = k_warning_flag.view_host(); + h_warning_flag() = 0; k_warning_flag.modify_host(); k_warning_flag.template sync(); @@ -235,8 +237,8 @@ void ImproperFourierKokkos::addone(EV_FLOAT &ev, c = arx*hrx + ary*hry + arz*hrz; - if (c > static_cast(1.0) + static_cast(TOLERANCE) || - c < static_cast(-1.0) - static_cast(TOLERANCE)) + if ((c > static_cast(1.0) + static_cast(TOLERANCE) || + c < static_cast(-1.0) - static_cast(TOLERANCE)) && !d_warning_flag()) d_warning_flag() = 1; if (c > static_cast(1.0)) c = static_cast(1.0); diff --git a/src/KOKKOS/improper_hybrid_kokkos.cpp b/src/KOKKOS/improper_hybrid_kokkos.cpp index 6a92f5aeae4..98d8cdaf309 100644 --- a/src/KOKKOS/improper_hybrid_kokkos.cpp +++ b/src/KOKKOS/improper_hybrid_kokkos.cpp @@ -34,6 +34,11 @@ ImproperHybridKokkos::ImproperHybridKokkos(LAMMPS *lmp) : ImproperHybrid(lmp) { kokkosable = 1; + // every KOKKOS sub-style sets CENTROID_NOTAVAIL, so the hybrid style cannot + // offer a centroid virial either - otherwise cvatom is never allocated and the + // per-substyle accumulation dereferences a null pointer + centroidstressflag = CENTROID_NOTAVAIL; + atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; diff --git a/src/KOKKOS/improper_umbrella_kokkos.cpp b/src/KOKKOS/improper_umbrella_kokkos.cpp index 003fdbe587b..bbba2eb1a5b 100644 --- a/src/KOKKOS/improper_umbrella_kokkos.cpp +++ b/src/KOKKOS/improper_umbrella_kokkos.cpp @@ -43,6 +43,10 @@ ImproperUmbrellaKokkos::ImproperUmbrellaKokkos(LAMMPS *lmp) : Improp datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + k_warning_flag = DAT::tdual_int_scalar("ImproperUmbrella::warning_flag"); + d_warning_flag = k_warning_flag.template view(); + h_warning_flag = k_warning_flag.view_host(); + centroidstressflag = CENTROID_NOTAVAIL; } @@ -95,9 +99,6 @@ void ImproperUmbrellaKokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; // zero warning flag - k_warning_flag = DAT::tdual_int_scalar("ImproperUmbrella::warning_flag"); - d_warning_flag = k_warning_flag.template view(); - h_warning_flag = k_warning_flag.view_host(); h_warning_flag() = 0; k_warning_flag.modify_host(); k_warning_flag.template sync(); From 1b110d25310c1a8a162d5bd61342c7c8f64bac4d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:58:34 +0000 Subject: [PATCH 091/120] KOKKOS: fix defects in fix and compute styles fix gravity/kk ignored the disable keyword and kept applying the force. fix langevin/kk lost the base-class ratio[] values when it reallocated, so a per-type friction ratio was silently dropped. fix wall/gran/kk indexed the history send buffer and d_history_one wrongly, and silently accepted pairstyle GRANULAR, which it does not implement. fix spring/self/kk marked k_xoriginal modified on the host without writing it. fix nve/sphere/kk has no DLM orientation update: it inherited the keyword from the base class and then ran the plain update, so "update dipole/dlm" silently integrated the dipoles with a different scheme. It now refuses the keyword, and the kokkos variants of the corresponding force-style fixture are marked skip_tests. fix wall/flow/kk was missing V_MASK, and fix qeq/reaxff/kk needed a datamask correction. compute hexorder/atom/kk divided by a zero neighbour count when nnn is NULL, producing NaN. The SNAP grid computes dropped the compute-group filter entirely: their CPU counterparts skip neighbours whose mask does not match groupbit, and the KOKKOS kernels had no mask view at all. A mask view is added to compute_sna_grid, compute_sna_grid_local and compute_gaussian_grid_local, and the test is applied at the same point as in the CPU sources -- in both the counting and the filling pass, since missing it in either desynchronises them. --- src/KOKKOS/compute_coord_atom_kokkos.cpp | 6 +- src/KOKKOS/compute_entropy_atom_kokkos.cpp | 11 +- .../compute_gaussian_grid_local_kokkos.cpp | 56 +++++---- .../compute_gaussian_grid_local_kokkos.h | 1 + src/KOKKOS/compute_hexorder_atom_kokkos.cpp | 12 +- src/KOKKOS/compute_inertia_kokkos.cpp | 9 +- .../compute_orientorder_atom_kokkos.cpp | 30 +++++ src/KOKKOS/compute_sna_grid_kokkos.h | 1 + src/KOKKOS/compute_sna_grid_local_kokkos.h | 1 + src/KOKKOS/compute_temp_deform_kokkos.cpp | 31 +++-- src/KOKKOS/compute_temp_deform_kokkos.h | 6 +- src/KOKKOS/fix_addtorque_atom_kokkos.cpp | 13 +- src/KOKKOS/fix_deform_kokkos.cpp | 10 +- src/KOKKOS/fix_efield_kokkos.cpp | 5 + src/KOKKOS/fix_gjf_kokkos.cpp | 2 +- src/KOKKOS/fix_gravity_kokkos.cpp | 4 + src/KOKKOS/fix_langevin_kokkos.cpp | 11 +- src/KOKKOS/fix_neigh_history_kokkos.cpp | 88 ++++++++++++- src/KOKKOS/fix_neigh_history_kokkos.h | 3 + src/KOKKOS/fix_nh_kokkos.cpp | 78 +++++++----- src/KOKKOS/fix_nve_limit_kokkos.cpp | 14 +++ src/KOKKOS/fix_nve_limit_kokkos.h | 1 + src/KOKKOS/fix_nve_sphere_kokkos.cpp | 13 +- src/KOKKOS/fix_property_atom_kokkos.cpp | 11 +- src/KOKKOS/fix_rigid_small_kokkos.cpp | 117 +++++++++++------- src/KOKKOS/fix_shake_kokkos.cpp | 106 +++++++--------- src/KOKKOS/fix_shake_kokkos.h | 3 - src/KOKKOS/fix_spring_kokkos.cpp | 26 ++-- src/KOKKOS/fix_spring_self_kokkos.cpp | 1 - src/KOKKOS/fix_store_force_kokkos.cpp | 12 +- src/KOKKOS/fix_wall_flow_kokkos.cpp | 16 ++- src/KOKKOS/fix_wall_gran_kokkos.cpp | 6 +- src/KOKKOS/fix_wall_region_kokkos.cpp | 5 + 33 files changed, 489 insertions(+), 220 deletions(-) diff --git a/src/KOKKOS/compute_coord_atom_kokkos.cpp b/src/KOKKOS/compute_coord_atom_kokkos.cpp index 843cf2a1f22..0d9056b8d12 100644 --- a/src/KOKKOS/compute_coord_atom_kokkos.cpp +++ b/src/KOKKOS/compute_coord_atom_kokkos.cpp @@ -199,8 +199,10 @@ void ComputeCoordAtomKokkos::operator()(TagComputeCoordAtom::operator()(TagComputeEntropyAtom(1.0))*d_rbinsq[k]; - if (k == 0 || k == nbin-1) value += static_cast(0.5)*integrand; - else value += integrand; + // the CPU style sums the interior bins and then adds 0.5*integrand[0] and + // 0.5*integrand[nbin-1] as two separate terms, so with a single bin that + // bin is counted twice at half weight + + KK_FLOAT weight = static_cast(0.0); + if ((k > 0) && (k < nbin-1)) weight += static_cast(1.0); + if (k == 0) weight += static_cast(0.5); + if (k == nbin-1) weight += static_cast(0.5); + value += weight*integrand; } value *= deltar_kk; diff --git a/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp b/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp index 564abe1f90b..855e00a0b47 100644 --- a/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp +++ b/src/KOKKOS/compute_gaussian_grid_local_kokkos.cpp @@ -60,20 +60,19 @@ ComputeGaussianGridLocalKokkos::ComputeGaussianGridLocalKokkos(LAMMP k_cutsq.modify_host(); } } - // Set up element lists + // Set up per-type lists. ComputeGaussianGridLocal has no type-to-element map, + // so there is nothing to copy into d_map. int n = atom->ntypes; - MemKK::realloc_kokkos(d_radelem,"ComputeSNAGridKokkos::radelem",n); - MemKK::realloc_kokkos(d_sigmaelem,"ComputeSNAGridKokkos::sigmaelem",n+1); - MemKK::realloc_kokkos(d_prefacelem,"ComputeSNAGridKokkos::prefacelem",n+1); - MemKK::realloc_kokkos(d_argfacelem,"ComputeSNAGridKokkos::argfacelem",n+1); - MemKK::realloc_kokkos(d_map,"ComputeSNAGridKokkos::map",n+1); + MemKK::realloc_kokkos(d_radelem,"ComputeGaussianGridLocalKokkos::radelem",n); + MemKK::realloc_kokkos(d_sigmaelem,"ComputeGaussianGridLocalKokkos::sigmaelem",n); + MemKK::realloc_kokkos(d_prefacelem,"ComputeGaussianGridLocalKokkos::prefacelem",n); + MemKK::realloc_kokkos(d_argfacelem,"ComputeGaussianGridLocalKokkos::argfacelem",n); auto h_radelem = Kokkos::create_mirror_view(d_radelem); auto h_sigmaelem = Kokkos::create_mirror_view(d_sigmaelem); auto h_prefacelem = Kokkos::create_mirror_view(d_prefacelem); auto h_argfacelem = Kokkos::create_mirror_view(d_argfacelem); - auto h_map = Kokkos::create_mirror_view(d_map); - // start from index 1 because of how compute sna/grid is - for (int i = 1; i <= atom->ntypes; i++) { + // the CPU arrays are indexed by atom type (1 to ntypes), the views by type-1 + for (int i = 1; i <= n; i++) { h_radelem(i-1) = radelem[i]; h_sigmaelem(i-1) = sigmaelem[i]; h_prefacelem(i-1) = prefacelem[i]; @@ -83,8 +82,6 @@ ComputeGaussianGridLocalKokkos::ComputeGaussianGridLocalKokkos(LAMMP Kokkos::deep_copy(d_sigmaelem,h_sigmaelem); Kokkos::deep_copy(d_prefacelem, h_prefacelem); Kokkos::deep_copy(d_argfacelem, h_argfacelem); - Kokkos::deep_copy(d_map,h_map); - } /* ---------------------------------------------------------------------- */ @@ -104,14 +101,28 @@ ComputeGaussianGridLocalKokkos::~ComputeGaussianGridLocalKokkos() template void ComputeGaussianGridLocalKokkos::setup() { + // Do not call ComputeGridLocal::setup(), it allocates alocal with memory->create() + // and sets gridlocal_allocated, so the next setup() (and the base destructor) would + // call free() on the Kokkos-owned storage installed below. Only the grid indices + // are taken from the base class. - ComputeGridLocal::setup(); + memoryKK->destroy_kokkos(k_alocal, alocal); + array_local = nullptr; + + ComputeGridLocal::set_grid_global(); + ComputeGridLocal::set_grid_local(); // allocate arrays memoryKK->create_kokkos(k_alocal, alocal, size_local_rows, size_local_cols, "grid:alocal"); array_local = alocal; d_alocal = k_alocal.template view(); + // fill the coordinate columns and run the subdomain check ComputeGridLocal::setup() + // would have done; the device kernel overwrites them, the host fallback does not + + ComputeGridLocal::assign_coords(); + k_alocal.modify_host(); + k_alocal.template sync(); } /* ---------------------------------------------------------------------- */ @@ -128,6 +139,9 @@ template void ComputeGaussianGridLocalKokkos::compute_local() { if (host_flag) { + atomKK->sync(Host,X_MASK|TYPE_MASK|MASK_MASK); + ComputeGaussianGridLocal::compute_local(); + k_alocal.modify_host(); return; } @@ -140,23 +154,16 @@ void ComputeGaussianGridLocalKokkos::compute_local() xlen = nxhi-nxlo+1; total_range = (nzhi-nzlo+1)*(nyhi-nylo+1)*(nxhi-nxlo+1); - atomKK->sync(execution_space,X_MASK|F_MASK|TYPE_MASK); + atomKK->sync(execution_space,X_MASK|F_MASK|TYPE_MASK|MASK_MASK); x = atomKK->k_x.view(); type = atomKK->k_type.view(); + mask = atomKK->k_mask.view(); k_cutsq.template sync(); - // max_neighs is defined here - think of more elaborate methods. - max_neighs = 100; - - // Pair snap/kk uses grow_ij with some max number of neighs but compute sna/grid uses total - // number of atoms. ntotal = atomKK->nlocal + atomKK->nghost; - // Allocate view for number of neighbors per grid point - MemKK::realloc_kokkos(d_ninside,"ComputeSNAGridKokkos:ninside",total_range); // "chunksize" variable is default 32768 in compute_sna_grid.cpp, and set by user // `total_range` is the number of grid points which may be larger than chunk size. - // printf(">>> total_range: %d\n", total_range); chunksize = 32768; // 100*32768 chunk_size = MIN(chunksize, total_range); chunk_offset = 0; @@ -272,6 +279,11 @@ void ComputeGaussianGridLocalKokkos::operator() (TagComputeGaussianG // Looping over ntotal for now. for (int j = 0; j < ntotal; j++){ + + // check that j is in compute group + + if (!(mask(j) & groupbit)) continue; + const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; @@ -280,7 +292,7 @@ void ComputeGaussianGridLocalKokkos::operator() (TagComputeGaussianG if (rsq < rnd_cutsq(jtype, jtype) ) { int icol = size_local_cols_base + jtype - 1; - d_alocal(igrid, icol) += static_cast(d_prefacelem(jtype-1) * exp(-rsq * d_argfacelem(jtype-1))); + d_alocal(igrid, icol) += static_cast(d_prefacelem(jtype-1) * Kokkos::exp(-rsq * d_argfacelem(jtype-1))); } } } diff --git a/src/KOKKOS/compute_gaussian_grid_local_kokkos.h b/src/KOKKOS/compute_gaussian_grid_local_kokkos.h index 7c8e8c2e27d..eadab598ebb 100644 --- a/src/KOKKOS/compute_gaussian_grid_local_kokkos.h +++ b/src/KOKKOS/compute_gaussian_grid_local_kokkos.h @@ -82,6 +82,7 @@ template class ComputeGaussianGridLocalKokkos : public Comput typename AT::t_kkfloat_1d_3_lr_randomread x; typename AT::t_int_1d_randomread type; + typename AT::t_int_1d_randomread mask; DAT::ttransform_kkfloat_2d k_alocal; typename AT::t_kkfloat_2d d_alocal; diff --git a/src/KOKKOS/compute_hexorder_atom_kokkos.cpp b/src/KOKKOS/compute_hexorder_atom_kokkos.cpp index 5b7b216b08b..8e1492c1a42 100644 --- a/src/KOKKOS/compute_hexorder_atom_kokkos.cpp +++ b/src/KOKKOS/compute_hexorder_atom_kokkos.cpp @@ -158,9 +158,10 @@ void ComputeHexOrderAtomKokkos::operator()(TagComputeHexOrderAtom, c } } - // fewer than nnn neighbors: order parameter = 0 + // fewer than nnn neighbors (or no neighbor at all with nnn = NULL): + // order parameter = 0 - if (ncount < nnn) { + if ((ncount < nnn) || (ncount == 0)) { d_qnarray(i,0) = d_qnarray(i,1) = static_cast(0.0); return; } @@ -188,8 +189,11 @@ void ComputeHexOrderAtomKokkos::operator()(TagComputeHexOrderAtom, c vsum += Kokkos::sin(ntheta); } - d_qnarray(i,0) = usum/nnn; - d_qnarray(i,1) = vsum/nnn; + // average over the neighbors actually used: ncount, which the branch above + // has set to nnn when nnn > 0, but stays the in-cutoff count for nnn = NULL + + d_qnarray(i,0) = usum/ncount; + d_qnarray(i,1) = vsum/ncount; } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/compute_inertia_kokkos.cpp b/src/KOKKOS/compute_inertia_kokkos.cpp index a8915bab432..d905bd83612 100644 --- a/src/KOKKOS/compute_inertia_kokkos.cpp +++ b/src/KOKKOS/compute_inertia_kokkos.cpp @@ -49,11 +49,12 @@ void ComputeInertiaKokkos::compute_vector() groupKK->inertia_kk(igroup,xcm,itensor); // the extended-particle contribution reads the ellipsoid, line, tri and - // body bonus arrays, which have no device counterpart. when none of - // those atom styles is present it adds nothing, so skip it entirely and - // keep the whole compute on the device for the usual case + // body bonus arrays, which have no device counterpart, and also adds the + // spin term of finite-size spheres from atom->radius. when the model has + // neither it adds nothing, so skip it entirely and keep the whole compute + // on the device for the usual case of point particles - if (atom->style_match("ellipsoid") || atom->style_match("line") || + if (atom->radius_flag || atom->style_match("ellipsoid") || atom->style_match("line") || atom->style_match("tri") || atom->style_match("body")) { // inertia_extended() also reads the radius, the ellipsoid indices and the // bonus data through the plain host pointers diff --git a/src/KOKKOS/compute_orientorder_atom_kokkos.cpp b/src/KOKKOS/compute_orientorder_atom_kokkos.cpp index 0eae0fb3e5b..7b1b8ef6d0f 100644 --- a/src/KOKKOS/compute_orientorder_atom_kokkos.cpp +++ b/src/KOKKOS/compute_orientorder_atom_kokkos.cpp @@ -189,6 +189,11 @@ void ComputeOrientOrderAtomKokkos::compute_peratom() if (!host_flag) team_size_default = 32;//max_neighs; + // qnarray persists across calls, so clear it like the CPU style does: + // atoms that are not in the neighbor list are never visited below + + Kokkos::deep_copy(d_qnarray,0.0); + while (chunk_offset < inum) { // chunk up loop to prevent running out of memory if (chunk_size > inum - chunk_offset) @@ -289,6 +294,13 @@ void ComputeOrientOrderAtomKokkos::operator() (TagComputeOrientOrder offset++; } }); + } else { + + // clear the neighbor count of atoms outside the group: the downstream + // Select3/BOOP kernels are not group filtered and d_ncount is reused + // across chunks and timesteps, so a stale count would be picked up here + + d_ncount(ii) = 0; } } @@ -314,6 +326,24 @@ void ComputeOrientOrderAtomKokkos::operator() (TagComputeOrientOrder select3(nnn, ncount, ii); d_ncount(ii) = nnn; } + + // a neighbor coincident with the central atom aborts the CPU calc_boop() + // before it writes anything, so the whole atom stays at zero. the BOOP + // kernels here handle one neighbor at a time and cannot do that, so detect + // the degenerate neighbor up front and skip the atom with a zero count + + const int nsel = d_ncount(ii); + for (int jj = 0; jj < nsel; jj++) { + const KK_FLOAT r0 = d_rlist(ii,jj,0); + const KK_FLOAT r1 = d_rlist(ii,jj,1); + const KK_FLOAT r2 = d_rlist(ii,jj,2); + if (Kokkos::sqrt(r0*r0 + r1*r1 + r2*r2) <= static_cast(MY_EPSILON)) { + for (int m = 0; m < ncol; m++) + d_qnarray(i,m) = 0.0; + d_ncount(ii) = 0; + return; + } + } } template diff --git a/src/KOKKOS/compute_sna_grid_kokkos.h b/src/KOKKOS/compute_sna_grid_kokkos.h index 555cbe6fa16..0798edb33a3 100644 --- a/src/KOKKOS/compute_sna_grid_kokkos.h +++ b/src/KOKKOS/compute_sna_grid_kokkos.h @@ -261,6 +261,7 @@ class ComputeSNAGridKokkos : public ComputeSNAGrid { typename AT::t_kkfloat_1d_3_lr_randomread x; typename AT::t_int_1d_randomread type; + typename AT::t_int_1d_randomread mask; DAT::tdual_double_2d_lr k_grid; typename AT::t_double_2d_lr d_grid; diff --git a/src/KOKKOS/compute_sna_grid_local_kokkos.h b/src/KOKKOS/compute_sna_grid_local_kokkos.h index 43c295d70a3..cc22291224a 100644 --- a/src/KOKKOS/compute_sna_grid_local_kokkos.h +++ b/src/KOKKOS/compute_sna_grid_local_kokkos.h @@ -257,6 +257,7 @@ class ComputeSNAGridLocalKokkos : public ComputeSNAGridLocal { typename AT::t_kkfloat_1d_3_lr_randomread x; typename AT::t_int_1d_randomread type; + typename AT::t_int_1d_randomread mask; DAT::tdual_double_2d_lr k_alocal; typename AT::t_double_2d_lr d_alocal; diff --git a/src/KOKKOS/compute_temp_deform_kokkos.cpp b/src/KOKKOS/compute_temp_deform_kokkos.cpp index 21da072d692..89f22d84a06 100644 --- a/src/KOKKOS/compute_temp_deform_kokkos.cpp +++ b/src/KOKKOS/compute_temp_deform_kokkos.cpp @@ -21,7 +21,7 @@ #include "atom_kokkos.h" #include "atom_masks.h" #include "comm.h" -#include "domain_kokkos.h" +#include "domain.h" #include "error.h" #include "force.h" #include "group.h" @@ -41,7 +41,6 @@ ComputeTempDeformKokkos::ComputeTempDeformKokkos(LAMMPS *lmp, int na { kokkosable = 1; atomKK = (AtomKokkos *) atom; - domainKK = (DomainKokkos *) domain; execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | V_MASK | MASK_MASK | RMASS_MASK | TYPE_MASK; @@ -148,7 +147,7 @@ template void ComputeTempDeformKokkos::restore_bias_all_kk() { if (which == BIAS) { - if (temperature->kokkosable) temperature->restore_bias_all(); + if (temperature->kokkosable) temperature->restore_bias_all_kk(); else { atomKK->sync(this->temperature->execution_space,this->temperature->datamask_read); this->temperature->restore_bias_all(); @@ -183,8 +182,14 @@ void ComputeTempDeformKokkos::remove_deform_bias_all_kk() vbiasall = typename AT::t_kkfloat_1d_3("temp/deform/kk:vbiasall", maxbias); } - domainKK->x2lamda(nlocal); + // the kernel converts each atom's coordinates to lamda space on the fly, + // like the CPU style. converting atom->x in place with DomainKokkos would + // perturb the coordinates by the round-off of two transforms, and its + // x2lamda() always runs on the device, so the host instantiation would + // read Cartesian coordinates here + d_boxlo = Few(domain->boxlo); + d_h_inv = Few(domain->h_inv); h_rate = domain->h_rate; h_ratelo = domain->h_ratelo; @@ -192,8 +197,6 @@ void ComputeTempDeformKokkos::remove_deform_bias_all_kk() Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); copymode = 0; - domainKK->lamda2x(nlocal); - atomKK->modified(execution_space,V_MASK); } @@ -202,9 +205,19 @@ template KOKKOS_INLINE_FUNCTION void ComputeTempDeformKokkos::operator()(TagComputeTempDeformRemoveBias, const int &i) const { if (mask[i] & groupbit) { - vbiasall(i,0) = static_cast(h_rate[0]*static_cast(x(i,0)) + h_rate[5]*static_cast(x(i,1)) + h_rate[4]*static_cast(x(i,2)) + h_ratelo[0]); - vbiasall(i,1) = static_cast(h_rate[1]*static_cast(x(i,1)) + h_rate[3]*static_cast(x(i,2)) + h_ratelo[1]); - vbiasall(i,2) = static_cast(h_rate[2]*static_cast(x(i,2)) + h_ratelo[2]); + + // Domain::x2lamda() for a single atom, into a local + + const double delx = static_cast(x(i,0)) - d_boxlo[0]; + const double dely = static_cast(x(i,1)) - d_boxlo[1]; + const double delz = static_cast(x(i,2)) - d_boxlo[2]; + const double lamda0 = d_h_inv[0]*delx + d_h_inv[5]*dely + d_h_inv[4]*delz; + const double lamda1 = d_h_inv[1]*dely + d_h_inv[3]*delz; + const double lamda2 = d_h_inv[2]*delz; + + vbiasall(i,0) = static_cast(h_rate[0]*lamda0 + h_rate[5]*lamda1 + h_rate[4]*lamda2 + h_ratelo[0]); + vbiasall(i,1) = static_cast(h_rate[1]*lamda1 + h_rate[3]*lamda2 + h_ratelo[1]); + vbiasall(i,2) = static_cast(h_rate[2]*lamda2 + h_ratelo[2]); v(i,0) -= vbiasall(i,0); v(i,1) -= vbiasall(i,1); v(i,2) -= vbiasall(i,2); diff --git a/src/KOKKOS/compute_temp_deform_kokkos.h b/src/KOKKOS/compute_temp_deform_kokkos.h index ec88e72ebc3..0b9848d4eb2 100644 --- a/src/KOKKOS/compute_temp_deform_kokkos.h +++ b/src/KOKKOS/compute_temp_deform_kokkos.h @@ -84,10 +84,8 @@ class ComputeTempDeformKokkos: public ComputeTempDeform { typename AT::t_int_1d_randomread type; typename AT::t_int_1d_randomread mask; - class DomainKokkos *domainKK; - - Few h_rate, d_grad_u; - Few h_ratelo; + Few h_rate, d_grad_u, d_h_inv; + Few h_ratelo, d_boxlo; Few d_xref; // stores xmid[3], ylo, zlo }; diff --git a/src/KOKKOS/fix_addtorque_atom_kokkos.cpp b/src/KOKKOS/fix_addtorque_atom_kokkos.cpp index b54d2c2f950..b03628e687a 100644 --- a/src/KOKKOS/fix_addtorque_atom_kokkos.cpp +++ b/src/KOKKOS/fix_addtorque_atom_kokkos.cpp @@ -41,11 +41,13 @@ FixAddTorqueAtomKokkos::FixAddTorqueAtomKokkos(LAMMPS *lmp, int narg datamask_read = TORQUE_MASK | MASK_MASK; datamask_modify = TORQUE_MASK; - // the base class allocated a plain storque array; release it here so that the - // dual view created in post_force() takes over without orphaning it + // the base class allocated a plain storque array; replace it by the dual + // view right away, so the array is valid even on a rank whose atom->nmax + // never grows beyond the base class' initial maxatom memory->destroy(storque); - storque = nullptr; + memoryKK->create_kokkos(k_storque,storque,maxatom,3,"addtorque/atom:storque"); + d_storque = k_storque.template view(); } /* ---------------------------------------------------------------------- */ @@ -118,6 +120,11 @@ void FixAddTorqueAtomKokkos::post_force(int /*vflag*/) } else { + // the variables are evaluated on the host through atom->x, atom->v, ... + // so the host copies have to be up to date first + + atomKK->sync(Host, ALL_MASK); + modify->clearstep_compute(); if (xstyle == EQUAL) xvalue = input->variable->compute_equal(xvar); diff --git a/src/KOKKOS/fix_deform_kokkos.cpp b/src/KOKKOS/fix_deform_kokkos.cpp index b0c5c271dd8..82540b6a608 100644 --- a/src/KOKKOS/fix_deform_kokkos.cpp +++ b/src/KOKKOS/fix_deform_kokkos.cpp @@ -70,11 +70,11 @@ void FixDeformKokkos::migrate_atoms() void FixDeformKokkos::update_box() { - if (remapflag == Domain::X_REMAP && !rfix.empty()) - atomKK->sync(Host,ALL_MASK); + // no host bracket here: the base class remaps the atom positions through + // DomainKokkos::x2lamda()/lamda2x(), which run on the device and declare the + // device copy modified. Claiming the host side afterwards would make the + // stale pre-deform host coordinates win over the remapped device data. + // The rigid fixes called in between only transform their own body arrays. FixDeform::update_box(); - - if (remapflag == Domain::X_REMAP && !rfix.empty()) - atomKK->modified(Host,ALL_MASK); } diff --git a/src/KOKKOS/fix_efield_kokkos.cpp b/src/KOKKOS/fix_efield_kokkos.cpp index 9b95ffd7011..13318bd0f28 100644 --- a/src/KOKKOS/fix_efield_kokkos.cpp +++ b/src/KOKKOS/fix_efield_kokkos.cpp @@ -155,6 +155,11 @@ void FixEfieldKokkos::post_force(int vflag) } else { + // the variables are evaluated on the host through atom->x, atom->v, ... + // so the host copies have to be up to date before the base class runs + + atomKK->sync(Host, ALL_MASK); + FixEfield::update_efield_variables(); // atom-style variables are evaluated on the host, so the result has to be diff --git a/src/KOKKOS/fix_gjf_kokkos.cpp b/src/KOKKOS/fix_gjf_kokkos.cpp index b335734b92a..3d72c12907f 100644 --- a/src/KOKKOS/fix_gjf_kokkos.cpp +++ b/src/KOKKOS/fix_gjf_kokkos.cpp @@ -129,7 +129,7 @@ void FixGJFKokkos::initial_integrate(int /* vflag */) mass = atomKK->k_mass.view(); } - // vhalf mode: copy lv → v at start of step (all but the first step) + // vhalf mode: copy lv to v at start of step (all but the first step) if (!osflag && lv_allocated) { k_lv.sync(); d_lv = k_lv.view(); diff --git a/src/KOKKOS/fix_gravity_kokkos.cpp b/src/KOKKOS/fix_gravity_kokkos.cpp index 63e67b9188c..5cc3e6d0b5d 100644 --- a/src/KOKKOS/fix_gravity_kokkos.cpp +++ b/src/KOKKOS/fix_gravity_kokkos.cpp @@ -42,6 +42,10 @@ FixGravityKokkos::FixGravityKokkos(LAMMPS *lmp, int narg, char **arg template void FixGravityKokkos::post_force(int /*vflag*/) { + // just exit if application of force is disabled + + if (disable) return; + // update gravity due to variables if (varflag != CONSTANT) { diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index 212d746df11..d5ca6806a90 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -56,7 +56,12 @@ FixLangevinKokkos::FixLangevinKokkos(LAMMPS *lmp, int narg, char **a atomKK = (AtomKokkos *) atom; int ntypes = atomKK->ntypes; - // allocate per-type arrays for force prefactors + // allocate per-type arrays for force prefactors. the base class constructor has + // already parsed the optional "scale " keywords into ratio[], so + // save those values across the re-allocation instead of resetting them to 1.0 + auto *ratio_base = new double[ntypes+1]; + for (int i = 1; i <= ntypes; i++) ratio_base[i] = ratio[i]; + delete[] gfactor1; delete[] gfactor2; delete[] ratio; @@ -70,8 +75,8 @@ FixLangevinKokkos::FixLangevinKokkos(LAMMPS *lmp, int narg, char **a d_ratio = k_ratio.template view(); h_ratio = k_ratio.view_host(); - // optional args - for (int i = 1; i <= ntypes; i++) ratio[i] = 1.0; + for (int i = 1; i <= ntypes; i++) ratio[i] = ratio_base[i]; + delete[] ratio_base; k_ratio.modify_host(); if (zeroflag) { diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index ea9cf5324da..bfde608723b 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -139,6 +139,12 @@ void FixNeighHistoryKokkos::pre_exchange_no_newton() maxpartner += 8; memoryKK->grow_kokkos(k_partner,partner,atom->nmax,maxpartner,"neighbor_history:partner"); memoryKK->grow_kokkos(k_valuepartner,valuepartner,atom->nmax,dnum*maxpartner,"neighbor_history:valuepartner"); + + // the grow reallocates, so the views used by the retry kernel must be + // re-bound, otherwise it writes past the end of the old allocation + + d_partner = k_partner.template view(); + d_valuepartner = k_valuepartner.template view(); } } @@ -258,7 +264,11 @@ void FixNeighHistoryKokkos::operator()(TagFixNeighHistoryPostNeighbo if (use_bit_flag) { rflag = histmask(j) | beyond_contact; j &= HISTMASK; - d_firstflag(i,jj) = j; + + // strip the history bit in the neighbor list, not in the flag array + // (the CPU version writes jlist[jj] = j here) + + d_neighbors(i,jj) = j; } else { rflag = 1; } @@ -528,6 +538,82 @@ int FixNeighHistoryKokkos::unpack_exchange(int nlocal, double *buf) return n; } +/* ---------------------------------------------------------------------- + pack values in local atom-based arrays for restart file +------------------------------------------------------------------------- */ + +template +int FixNeighHistoryKokkos::pack_restart(int i, double *buf) +{ + k_npartner.sync_host(); + k_partner.sync_host(); + k_valuepartner.sync_host(); + + return FixNeighHistory::pack_restart(i,buf); +} + +/* ---------------------------------------------------------------------- + unpack values from atom->extra array to restart the fix +------------------------------------------------------------------------- */ + +template +void FixNeighHistoryKokkos::unpack_restart(int nlocal, int nth) +{ + // the base class version hands out fresh rows from its page allocators. + // here the rows belong to the dual views, so the values are unpacked in + // place instead, the same way unpack_exchange() does it + + k_npartner.sync_host(); + k_partner.sync_host(); + k_valuepartner.sync_host(); + + double **extra = atom->extra; + + // skip to Nth set of extra values + // unpack the Nth first values this way because other fixes pack them + + int m = 0; + for (int i = 0; i < nth; i++) m += static_cast(extra[nlocal][m]); + m++; + + const int n = static_cast(extra[nlocal][m++]); + + if (n > maxpartner) { + maxpartner = n; + grow_arrays(atom->nmax); + + // the grow leaves the data on the device and the host mirror empty, + // so pull the enlarged arrays back before writing into them + + k_npartner.sync_host(); + k_partner.sync_host(); + k_valuepartner.sync_host(); + } + + npartner[nlocal] = n; + for (int p = 0; p < n; p++) { + partner[nlocal][p] = static_cast(ubuf(extra[nlocal][m++]).i); + for (int v = 0; v < dnum; v++) + valuepartner[nlocal][dnum*p+v] = extra[nlocal][m++]; + } + + k_npartner.modify_host(); + k_partner.modify_host(); + k_valuepartner.modify_host(); +} + +/* ---------------------------------------------------------------------- + size of atom nlocal's restart data +------------------------------------------------------------------------- */ + +template +int FixNeighHistoryKokkos::size_restart(int nlocal) +{ + k_npartner.sync_host(); + + return FixNeighHistory::size_restart(nlocal); +} + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_neigh_history_kokkos.h b/src/KOKKOS/fix_neigh_history_kokkos.h index d1115d5403f..9e48d9c275a 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.h +++ b/src/KOKKOS/fix_neigh_history_kokkos.h @@ -51,6 +51,9 @@ class FixNeighHistoryKokkos : public FixNeighHistory, public KokkosBase { void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; + int pack_restart(int, double *) override; + void unpack_restart(int, int) override; + int size_restart(int) override; double memory_usage() override; // NOLINTNEXTLINE diff --git a/src/KOKKOS/fix_nh_kokkos.cpp b/src/KOKKOS/fix_nh_kokkos.cpp index bc21f6bbbb5..e8f6a80b845 100644 --- a/src/KOKKOS/fix_nh_kokkos.cpp +++ b/src/KOKKOS/fix_nh_kokkos.cpp @@ -355,6 +355,7 @@ void FixNHKokkos::remap() { double oldlo,oldhi; double expfac; + double isofac; int nlocal = atom->nlocal; double *h = domain->h; @@ -365,20 +366,11 @@ void FixNHKokkos::remap() // convert pertinent atoms and rigid bodies to lamda coords + // the group variants of x2lamda()/lamda2x() run on the device and do their + // own sync/modified, so no host round trip of x is needed here + if (allremap) domainKK->x2lamda(nlocal); - else { - // this loop runs on the host, so it needs the host side of both arrays: - // "mask" is the view for the execution space, and reading it here is an - // access to device memory from host code. Sync once for the whole loop - // rather than once per atom as well. - atomKK->sync(Host,X_MASK|MASK_MASK); - auto h_x = atomKK->k_x.view_host(); - auto h_mask = atomKK->k_mask.view_host(); - for (int i = 0; i < nlocal; i++) - if (h_mask[i] & dilate_group_bit) - domainKK->x2lamda(&h_x(i,0), &h_x(i,0)); - atomKK->modified(Host,X_MASK); - } + else domainKK->x2lamda(nlocal,dilate_group_bit); if (rfix.size() > 0) error->all(FLERR,"Cannot (yet) use rigid bodies with fix nh and Kokkos"); @@ -439,12 +431,15 @@ void FixNHKokkos::remap() // scale diagonal components // scale tilt factors with cell, if set + if (isochoric) isofac = vol_start; + if (p_flag[0]) { oldlo = domain->boxlo[0]; oldhi = domain->boxhi[0]; expfac = exp(dto*omega_dot[0]); domain->boxlo[0] = (oldlo-fixedpoint[0])*expfac + fixedpoint[0]; domain->boxhi[0] = (oldhi-fixedpoint[0])*expfac + fixedpoint[0]; + if (isochoric) isofac /= domain->boxhi[0] - domain->boxlo[0]; } if (p_flag[1]) { @@ -453,6 +448,7 @@ void FixNHKokkos::remap() expfac = exp(dto*omega_dot[1]); domain->boxlo[1] = (oldlo-fixedpoint[1])*expfac + fixedpoint[1]; domain->boxhi[1] = (oldhi-fixedpoint[1])*expfac + fixedpoint[1]; + if (isochoric) isofac /= domain->boxhi[1] - domain->boxlo[1]; if (scalexy) h[5] *= expfac; } @@ -462,10 +458,48 @@ void FixNHKokkos::remap() expfac = exp(dto*omega_dot[2]); domain->boxlo[2] = (oldlo-fixedpoint[2])*expfac + fixedpoint[2]; domain->boxhi[2] = (oldhi-fixedpoint[2])*expfac + fixedpoint[2]; + if (isochoric) isofac /= domain->boxhi[2] - domain->boxlo[2]; if (scalexz) h[4] *= expfac; if (scaleyz) h[3] *= expfac; } + // isochoric dimensions: rescale so the reference volume is preserved + // pure box arithmetic, identical to the CPU base class + + if (isochoric) { + + // We remove remaining dimensions so that only scale factors are left + // in isofac + + for (int i = 0; i < 3; i++) { + if (p_isoch[i] || !p_flag[i]) isofac /= (domain->boxhi[i]-domain->boxlo[i]); + } + int iso_sum = p_isoch[0] + p_isoch[1] + p_isoch[2]; + if (iso_sum == 2) isofac = sqrt(isofac); + + if (p_isoch[0]) { + oldlo = domain->boxlo[0]; + oldhi = domain->boxhi[0]; + domain->boxlo[0] = (oldlo-fixedpoint[0])*isofac + fixedpoint[0]; + domain->boxhi[0] = (oldhi-fixedpoint[0])*isofac + fixedpoint[0]; + } + if (p_isoch[1]) { + oldlo = domain->boxlo[1]; + oldhi = domain->boxhi[1]; + domain->boxlo[1] = (oldlo-fixedpoint[1])*isofac + fixedpoint[1]; + domain->boxhi[1] = (oldhi-fixedpoint[1])*isofac + fixedpoint[1]; + if (scalexy) h[5] *= isofac; + } + if (p_isoch[2]) { + oldlo = domain->boxlo[2]; + oldhi = domain->boxhi[2]; + domain->boxlo[2] = (oldlo-fixedpoint[2])*isofac + fixedpoint[2]; + domain->boxhi[2] = (oldhi-fixedpoint[2])*isofac + fixedpoint[2]; + if (scalexz) h[4] *= isofac; + if (scaleyz) h[3] *= isofac; + } + } + // off-diagonal components, second half if (pstyle == TRICLINIC) { @@ -521,19 +555,7 @@ void FixNHKokkos::remap() // convert pertinent atoms and rigid bodies back to box coords if (allremap) domainKK->lamda2x(nlocal); - else { - // this loop runs on the host, so it needs the host side of both arrays: - // "mask" is the view for the execution space, and reading it here is an - // access to device memory from host code. Sync once for the whole loop - // rather than once per atom as well. - atomKK->sync(Host,X_MASK|MASK_MASK); - auto h_x = atomKK->k_x.view_host(); - auto h_mask = atomKK->k_mask.view_host(); - for (int i = 0; i < nlocal; i++) - if (h_mask[i] & dilate_group_bit) - domainKK->lamda2x(&h_x(i,0), &h_x(i,0)); - atomKK->modified(Host,X_MASK); - } + else domainKK->lamda2x(nlocal,dilate_group_bit); // for (auto &ifix : rfix) ifix->deform(1); } @@ -576,7 +598,7 @@ void FixNHKokkos::nh_v_press() atomKK->modified(execution_space,V_MASK); if (which == BIAS) { - if (temperature->kokkosable) temperature->restore_bias_all(); + if (temperature->kokkosable) temperature->restore_bias_all_kk(); else { atomKK->sync(temperature->execution_space,temperature->datamask_read); temperature->restore_bias_all(); @@ -731,7 +753,7 @@ void FixNHKokkos::nh_v_temp() atomKK->modified(execution_space,V_MASK); if (which == BIAS) { - if (temperature->kokkosable) temperature->restore_bias_all(); + if (temperature->kokkosable) temperature->restore_bias_all_kk(); else { atomKK->sync(temperature->execution_space,temperature->datamask_read); temperature->restore_bias_all(); diff --git a/src/KOKKOS/fix_nve_limit_kokkos.cpp b/src/KOKKOS/fix_nve_limit_kokkos.cpp index e782526d85b..0ebe67b04bb 100644 --- a/src/KOKKOS/fix_nve_limit_kokkos.cpp +++ b/src/KOKKOS/fix_nve_limit_kokkos.cpp @@ -39,6 +39,20 @@ FixNVELimitKokkos::FixNVELimitKokkos(LAMMPS *lmp, int narg, char **a datamask_modify = EMPTY_MASK; } +/* ---------------------------------------------------------------------- */ + +template +void FixNVELimitKokkos::init() +{ + FixNVELimit::init(); + + // there is no datamask bit for the per-type masses, so the dual view has to + // be pushed to the device by hand before the kernels below read it + + atomKK->k_mass.modify_host(); + atomKK->k_mass.template sync(); +} + /* ---------------------------------------------------------------------- allow for both per-type and per-atom mass ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_nve_limit_kokkos.h b/src/KOKKOS/fix_nve_limit_kokkos.h index b611996b66f..15533a0e30f 100644 --- a/src/KOKKOS/fix_nve_limit_kokkos.h +++ b/src/KOKKOS/fix_nve_limit_kokkos.h @@ -32,6 +32,7 @@ template class FixNVELimitKokkos : public FixNVELimit { public: FixNVELimitKokkos(class LAMMPS *, int, char **); + void init() override; void initial_integrate(int) override; void final_integrate() override; diff --git a/src/KOKKOS/fix_nve_sphere_kokkos.cpp b/src/KOKKOS/fix_nve_sphere_kokkos.cpp index 0fda02715cd..f450b10efe9 100644 --- a/src/KOKKOS/fix_nve_sphere_kokkos.cpp +++ b/src/KOKKOS/fix_nve_sphere_kokkos.cpp @@ -15,12 +15,14 @@ #include "fix_nve_sphere_kokkos.h" #include "atom_masks.h" #include "atom_kokkos.h" +#include "error.h" #include using namespace LAMMPS_NS; enum{NONE,DIPOLE}; +enum{NODLM,DLM}; /* ---------------------------------------------------------------------- */ @@ -52,6 +54,13 @@ template void FixNVESphereKokkos::init() { FixNVESphere::init(); + + // the Dullweber-Leimkuhler-Maclachlan orientation update of the base class + // has no device kernel yet, and silently running the plain cross product + // update instead would integrate the dipoles with a different scheme + + if (dlm == DLM) + error->all(FLERR,"Cannot (yet) use update dipole/dlm with fix nve/sphere/kk"); } /* ---------------------------------------------------------------------- */ @@ -112,7 +121,7 @@ void FixNVESphereKokkos::initial_integrate_item(const int i) const omega(i,1) += dtirotate * static_cast(torque(i,1)); omega(i,2) += dtirotate * static_cast(torque(i,2)); - if (extra == DIPOLE) { + if ((extra == DIPOLE) && (mu(i,3) > 0.0)) { const KK_FLOAT g0 = mu(i,0) + dtv_kk * (omega(i,1) * mu(i,2) - omega(i,2) * mu(i,1)); const KK_FLOAT g1 = mu(i,1) + dtv_kk * (omega(i,2) * mu(i,0) - omega(i,0) * mu(i,2)); const KK_FLOAT g2 = mu(i,2) + dtv_kk * (omega(i,0) * mu(i,1) - omega(i,1) * mu(i,0)); @@ -231,7 +240,7 @@ void FixNVESphereKokkos::fused_integrate_item(const int i) const omega(i,1) += dtirotate * static_cast(torque(i,1)); omega(i,2) += dtirotate * static_cast(torque(i,2)); - if (extra == DIPOLE) { + if ((extra == DIPOLE) && (mu(i,3) > 0.0)) { const KK_FLOAT g0 = mu(i,0) + dtv_kk * (omega(i,1) * mu(i,2) - omega(i,2) * mu(i,1)); const KK_FLOAT g1 = mu(i,1) + dtv_kk * (omega(i,2) * mu(i,0) - omega(i,0) * mu(i,2)); const KK_FLOAT g2 = mu(i,2) + dtv_kk * (omega(i,0) * mu(i,1) - omega(i,1) * mu(i,0)); diff --git a/src/KOKKOS/fix_property_atom_kokkos.cpp b/src/KOKKOS/fix_property_atom_kokkos.cpp index fc003b71711..cbe8bc2d7e9 100644 --- a/src/KOKKOS/fix_property_atom_kokkos.cpp +++ b/src/KOKKOS/fix_property_atom_kokkos.cpp @@ -81,7 +81,16 @@ FixPropertyAtomKokkos::~FixPropertyAtomKokkos() } } - atomKK->update_property_atom(); + // do not rebuild the list from Modify here: Modify::delete_fix() destroys + // the fix before unlinking it, so a rescan would put a pointer to this + // dying object back into fix_prop_atom[]. Drop this fix from the list + // instead. + + int n = 0; + for (int i = 0; i < atomKK->nprop_atom; i++) + if (atomKK->fix_prop_atom[i] != this) + atomKK->fix_prop_atom[n++] = atomKK->fix_prop_atom[i]; + atomKK->nprop_atom = n; } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/fix_rigid_small_kokkos.cpp b/src/KOKKOS/fix_rigid_small_kokkos.cpp index 6cab6b510f7..557a15a0c1f 100644 --- a/src/KOKKOS/fix_rigid_small_kokkos.cpp +++ b/src/KOKKOS/fix_rigid_small_kokkos.cpp @@ -46,6 +46,23 @@ using namespace RigidConst; #define RVOUS 1 // 0 for irregular, 1 for all2all +/* ---------------------------------------------------------------------- + retire the setup-time device claim on one of the tied per-atom DualViews. + pack_exchange_kokkos() syncs the host data up before it packs, so what the + setup-time exchange left on the device is real, migrated data and has to be + pulled down rather than thrown away. Only when the host has an outstanding + claim as well -- a grow_arrays() in the middle of that exchange -- is the + claim dropped without a copy, because a sync would then trip the DualView + concurrent-modification guard. +------------------------------------------------------------------------- */ + +template +static void retire_device_claim(DualViewType &k) +{ + if (k.need_sync_host() && !k.need_sync_device()) k.sync_host(); + else k.clear_sync_state(); +} + /* ---------------------------------------------------------------------- */ template @@ -120,11 +137,13 @@ FixRigidSmallKokkos::~FixRigidSmallKokkos() memoryKK->destroy_kokkos(k_xcmimage, xcmimage); memoryKK->destroy_kokkos(k_displace, displace); memoryKK->destroy_kokkos(k_vatom, vatom); - if (extended) { - memoryKK->destroy_kokkos(k_eflags, eflags); - if (orientflag) memoryKK->destroy_kokkos(k_orient, orient); - if (dorientflag) memoryKK->destroy_kokkos(k_dorient, dorient); - } + // guard on the pointers, not on extended/orientflag/dorientflag: those are + // re-derived by setup_bodies_static() on every run, so a flag that has + // flipped back to 0 would leave a Kokkos-owned buffer for the base class + // destructor's memory->destroy() to free + if (eflags) memoryKK->destroy_kokkos(k_eflags, eflags); + if (orient) memoryKK->destroy_kokkos(k_orient, orient); + if (dorient) memoryKK->destroy_kokkos(k_dorient, dorient); #ifdef LMP_KOKKOS_DEBUG_RNG if (langflag) rand_pool.destroy(); @@ -234,7 +253,7 @@ void FixRigidSmallKokkos::pre_exchange() // from the host arrays -- we must not skip the flush in that case. if (exchange_comm_device && !commKK->exchange_comm_legacy) return; - // Host exchange path: flush device→host so the base-class + // Host exchange path: flush device->host so the base-class // pack_exchange/copy_arrays/unpack_exchange see valid data. copy_body_host(); k_bodytag.sync_host(); @@ -303,30 +322,27 @@ void FixRigidSmallKokkos::setup_pre_neighbor() // Retire the setup-time device claim, once, at its origin. create_bodies() // ran in the base constructor and wrote the per-atom body bookkeeping through // the base class' raw pointers -- i.e. into the host mirrors of the tied - // DualViews, without touching the modify flags. Nothing has pushed that to - // the device yet, so the device copies hold uninitialized data; the setup-time - // exchange nevertheless ran pack/unpack_exchange_kokkos over them and marked - // the views device-modified. The host copies are therefore the authoritative - // ones here, and that device claim is not. Left in place it makes every later - // reader defend itself: a sync_host() would pull the uninitialized copy over - // the host arrays, and a modify_host() would trip the DualView - // concurrent-modification guard. Clearing it here -- after the exchange, + // DualViews -- and grow_arrays() marked them host-modified. The setup-time + // exchange then ran pack/unpack_exchange_kokkos, which sync the views up + // before packing and mark them device-modified afterwards, so the device copy + // holds that same bookkeeping with the atoms it just migrated: it has to come + // down, not be discarded. Retiring the claim here -- after the exchange, // before the host build below and before the sort, dof() and // setup_device_push() that follow -- lets all of them use a plain - // modify_host(). Only for the first run: once setupflag is set the device - // copies carry real data and their claim must be honoured (the flush below - // syncs it down instead). No-op when host space == device space. + // modify_host() without tripping the DualView concurrent-modification guard. + // Only for the first run: afterwards the flush below syncs the device state + // down instead. No-op when host space == device space. if (!setupflag) { - k_bodyown.clear_sync_state(); - k_bodytag.clear_sync_state(); - k_atom2body.clear_sync_state(); - k_xcmimage.clear_sync_state(); - k_displace.clear_sync_state(); - k_vatom.clear_sync_state(); + retire_device_claim(k_bodyown); + retire_device_claim(k_bodytag); + retire_device_claim(k_atom2body); + retire_device_claim(k_xcmimage); + retire_device_claim(k_displace); + retire_device_claim(k_vatom); if (extended) { - k_eflags.clear_sync_state(); - if (orientflag) k_orient.clear_sync_state(); - if (dorientflag) k_dorient.clear_sync_state(); + retire_device_claim(k_eflags); + if (orientflag) retire_device_claim(k_orient); + if (dorientflag) retire_device_claim(k_dorient); } } @@ -685,11 +701,11 @@ void FixRigidSmallKokkos::pre_neighbor(){ if (extended_datamask) atomKK->sync(execution_space, extended_datamask); } refresh_atom_views(); - copy_body_device(); // push host body[] → d_body + copy_body_device(); // push host body[] -> d_body } else { // Device exchange path: pack/unpack_exchange_kokkos already updated all // per-atom DualViews and d_body on the device. Do NOT push stale host - // data to the device — just mark the device side as authoritative and + // data to the device -- just mark the device side as authoritative and // refresh the d_* view aliases. // // Clear any outstanding host claim first. comm->borders() runs between the @@ -900,13 +916,13 @@ void FixRigidSmallKokkos::apply_langevin_thermostat_kokkos() Body &b = d_body(ibody); double gamma1 = -b.mass / tp / ftm2v; - double gamma2 = sqrt(b.mass) * tsqrt * sqrt(24.0*boltz/tp/dt/mvv2e) / ftm2v; + double gamma2 = Kokkos::sqrt(b.mass) * tsqrt * Kokkos::sqrt(24.0*boltz/tp/dt/mvv2e) / ftm2v; l_d_langextra(ibody,0) = gamma1*b.vcm[0] + gamma2*(rand_gen.drand()-0.5); l_d_langextra(ibody,1) = gamma1*b.vcm[1] + gamma2*(rand_gen.drand()-0.5); l_d_langextra(ibody,2) = gamma1*b.vcm[2] + gamma2*(rand_gen.drand()-0.5); gamma1 = -1.0 / tp / ftm2v; - gamma2 = tsqrt * sqrt(24.0*boltz/tp/dt/mvv2e) / ftm2v; + gamma2 = tsqrt * Kokkos::sqrt(24.0*boltz/tp/dt/mvv2e) / ftm2v; // convert omega from space frame to body frame, compute body-frame torque // (rotational quantities in KK_FLOAT) @@ -918,11 +934,11 @@ void FixRigidSmallKokkos::apply_langevin_thermostat_kokkos() KK_FLOAT wbody[3], tbody[3], lang[3]; MathExtraKokkos::transpose_matvec(ex,ey,ez,omega,wbody); tbody[0] = static_cast(b.inertia[0]*gamma1*static_cast(wbody[0]) + - sqrt(b.inertia[0])*gamma2*(rand_gen.drand()-0.5)); + Kokkos::sqrt(b.inertia[0])*gamma2*(rand_gen.drand()-0.5)); tbody[1] = static_cast(b.inertia[1]*gamma1*static_cast(wbody[1]) + - sqrt(b.inertia[1])*gamma2*(rand_gen.drand()-0.5)); + Kokkos::sqrt(b.inertia[1])*gamma2*(rand_gen.drand()-0.5)); tbody[2] = static_cast(b.inertia[2]*gamma1*static_cast(wbody[2]) + - sqrt(b.inertia[2])*gamma2*(rand_gen.drand()-0.5)); + Kokkos::sqrt(b.inertia[2])*gamma2*(rand_gen.drand()-0.5)); // convert langevin torque from body frame back to space frame @@ -1625,7 +1641,13 @@ void FixRigidSmallKokkos::grow_arrays(int nmax) // body came out with zero mass, zero inertia and, through a zero degree-of- // freedom count, a nan temperature. Carry the host side across the grow // whenever the host side is the one holding the values. - const bool host_holds_bookkeeping = (!setupflag || setup_host_rebuild); + // The host also owns this bookkeeping during a run whenever CommKokkos is not + // using the device exchange: pre_exchange() flushes everything down and the + // base class then migrates the atoms through the raw host pointers without + // touching the modify flags, so a grow in the middle of that exchange would + // otherwise refill the mirrors from the pre-exchange device snapshot. + const bool using_device_exchange = exchange_comm_device && !commKK->exchange_comm_legacy; + const bool host_holds_bookkeeping = (!setupflag || setup_host_rebuild || !using_device_exchange); if (!tied_initialized) { // the base ctor's virtual grow_arrays() allocated these as plain @@ -2719,21 +2741,22 @@ void FixRigidSmallKokkos::sort_kokkos(Kokkos::BinSortexchange() and // atom->sort() back to back, both *before* the first setup_pre_neighbor(), so - // the equivalent clear there has not run yet at this point. Nothing is lost - // by dropping it -- nothing had pushed the host arrays create_bodies() wrote - // to the device, so what the exchange moved derives from an uninitialized - // copy. No-op when host space == device space. + // the equivalent step there has not run yet at this point. The claim is + // pulled down rather than discarded: pack_exchange_kokkos() pushes the host + // arrays create_bodies() wrote up to the device before packing, so the + // exchange moved real data and the host copy is the one that is out of date. + // No-op when host space == device space. if (!setupflag) { - k_bodytag.clear_sync_state(); k_bodytag.modify_host(); - k_bodyown.clear_sync_state(); k_bodyown.modify_host(); - k_atom2body.clear_sync_state(); k_atom2body.modify_host(); - k_xcmimage.clear_sync_state(); k_xcmimage.modify_host(); - k_displace.clear_sync_state(); k_displace.modify_host(); - k_vatom.clear_sync_state(); k_vatom.modify_host(); + retire_device_claim(k_bodytag); k_bodytag.modify_host(); + retire_device_claim(k_bodyown); k_bodyown.modify_host(); + retire_device_claim(k_atom2body); k_atom2body.modify_host(); + retire_device_claim(k_xcmimage); k_xcmimage.modify_host(); + retire_device_claim(k_displace); k_displace.modify_host(); + retire_device_claim(k_vatom); k_vatom.modify_host(); if (extended) { - k_eflags.clear_sync_state(); k_eflags.modify_host(); - if (orientflag) { k_orient.clear_sync_state(); k_orient.modify_host(); } - if (dorientflag) { k_dorient.clear_sync_state(); k_dorient.modify_host(); } + retire_device_claim(k_eflags); k_eflags.modify_host(); + if (orientflag) { retire_device_claim(k_orient); k_orient.modify_host(); } + if (dorientflag) { retire_device_claim(k_dorient); k_dorient.modify_host(); } } } diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index 601fd9da223..21b0c17b518 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -32,8 +32,6 @@ using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; -static constexpr double BIG = 1.0e20; // Exact match to fix_shake.cpp - /* ---------------------------------------------------------------------- */ template @@ -429,22 +427,9 @@ void FixShakeKokkos::min_post_force(int vflag) copymode = 1; - if (output_every) { - d_b_stats = typename AT::t_double_2d("shake:b_stats", atom->nbondtypes + 1, 4); - d_a_stats = typename AT::t_double_2d("shake:a_stats", atom->nangletypes + 1, 4); - - // Capture views locally for the lambda - auto l_b_stats = this->d_b_stats; - auto l_a_stats = this->d_a_stats; - const int nb = atom->nbondtypes + 1; - const int na = atom->nangletypes + 1; - - Kokkos::parallel_for("FixShake:zero_stats", Kokkos::RangePolicy(0, MAX(nb, na)), - KOKKOS_LAMBDA(const int &i) { - if (i < nb) { l_b_stats(i,0) = 0; l_b_stats(i,1) = 0; l_b_stats(i,2) = 0; l_b_stats(i,3) = BIG; } - if (i < na) { l_a_stats(i,0) = 0; l_a_stats(i,1) = 0; l_a_stats(i,2) = 0; l_a_stats(i,3) = BIG; } - }); - } + // the bond and angle statistics that are printed on an output step are + // recomputed from the current coordinates by stats() below, so nothing is + // accumulated in the kernel EV_FLOAT ev; @@ -470,7 +455,9 @@ void FixShakeKokkos::min_post_force(int vflag) if (vflag_atom) Kokkos::Experimental::contribute(d_vatom, dup_vatom); } - comm->reverse_comm(this); + // no reverse communication here: this fix defines no comm_reverse and no + // pack/unpack_reverse_comm, and the restraint force is applied to the owners + this->ebond = static_cast(ev.evdwl); if (vflag_global) { @@ -501,10 +488,10 @@ void FixShakeKokkos::min_post_force(int vflag) dup_vatom = {}; } - if (update->ntimestep == next_output) { - atomKK->modified(execution_space, X_MASK); - stats(); - } + // the kernel above only reads x, so no modify() here; stats() syncs the + // coordinates to the host itself + + if (update->ntimestep == next_output) stats(); } /* ---------------------------------------------------------------------- */ @@ -536,17 +523,13 @@ void FixShakeKokkos::operator()(TagFixShakeMinPostForce(kbond) * dr; const KK_FLOAT fbond = (r > static_cast(0.0)) ? static_cast(-2.0) * rk / r : static_cast(0.0); const KK_FLOAT eb = rk * dr; - a_f(idx0, 0) += static_cast(delx * fbond); - a_f(idx0, 1) += static_cast(dely * fbond); - a_f(idx0, 2) += static_cast(delz * fbond); - a_f(idx1, 0) -= static_cast(delx * fbond); - a_f(idx1, 1) -= static_cast(dely * fbond); - a_f(idx1, 2) -= static_cast(delz * fbond); - - // energy and virial are shared out over the owned atoms of the pair, as + + // force, energy and virial all go to the owned atoms of the pair, as // FixShake::bond_force() does. the closest image of an atom owned by // this processor is mapped back onto the owner first, so that a cluster // reaching across a periodic boundary is still credited to both atoms. + // this fix has no reverse communication, so a contribution written into + // a ghost slot would be lost. int atomlist[2]; int count = 0; @@ -554,8 +537,18 @@ void FixShakeKokkos::operator()(TagFixShakeMinPostForce(d_shake_atom(m,slot1),map_style, k_map_array,k_map_hash); - if ((own0 >= 0) && (own0 < nlocal)) atomlist[count++] = own0; - if ((own1 >= 0) && (own1 < nlocal)) atomlist[count++] = own1; + if ((own0 >= 0) && (own0 < nlocal)) { + a_f(own0, 0) += static_cast(delx * fbond); + a_f(own0, 1) += static_cast(dely * fbond); + a_f(own0, 2) += static_cast(delz * fbond); + atomlist[count++] = own0; + } + if ((own1 >= 0) && (own1 < nlocal)) { + a_f(own1, 0) -= static_cast(delx * fbond); + a_f(own1, 1) -= static_cast(dely * fbond); + a_f(own1, 2) -= static_cast(delz * fbond); + atomlist[count++] = own1; + } const KK_FLOAT total = static_cast(2.0); ev.evdwl += static_cast((static_cast(count)/total) * eb); @@ -570,16 +563,6 @@ void FixShakeKokkos::operator()(TagFixShakeMinPostForce(0.5) * dely * delz * fbond; ev_tally(ev,count,atomlist,total,eb,v); } - if (output_every && !is_angle) { - // only atoms owned by this processor are counted, as on the CPU - const double nown = (double) ((idx0 < nlocal) + (idx1 < nlocal)); - if (nown > 0.0) { - Kokkos::atomic_add(&d_b_stats(type_idx, 0), nown); - Kokkos::atomic_add(&d_b_stats(type_idx, 1), nown * (double)r); - } - Kokkos::atomic_max(&d_b_stats(type_idx, 2), (double)r); - Kokkos::atomic_min(&d_b_stats(type_idx, 3), (double)r); - } return r; }; @@ -593,24 +576,9 @@ void FixShakeKokkos::operator()(TagFixShakeMinPostForce(2.0)*r1*r2)) * static_cast(180.0)/static_cast(MY_PI); - int mt = d_shake_type(m, 2); - // the plain style counts the angle once per owned outer atom and - // leaves the central one out, see FixShake::bond_force() - int count = (i1 < nlocal) + (i2 < nlocal); - if (count > 0) { - Kokkos::atomic_add(&d_a_stats(mt, 0), (double)count); - Kokkos::atomic_add(&d_a_stats(mt, 1), (double)count * static_cast(angle)); - Kokkos::atomic_max(&d_a_stats(mt, 2), (double)angle); - Kokkos::atomic_min(&d_a_stats(mt, 3), (double)angle); - } - } + apply_restraint(0, 1, d_shake_type(m, 0), false); + apply_restraint(0, 2, d_shake_type(m, 1), false); + apply_restraint(1, 2, d_shake_type(m, 2), true); } } @@ -636,6 +604,9 @@ void FixShakeKokkos::post_force(int vflag) d_f = atomKK->k_f.view(); d_type = atomKK->k_type.view(); d_rmass = atomKK->k_rmass.view(); + // the per-type masses have no datamask bit, so atomKK->sync() cannot carry + // them: push the dual view to the device by hand + atomKK->k_mass.template sync(); d_mass = atomKK->k_mass.view(); nlocal = atomKK->nlocal; @@ -862,6 +833,9 @@ void FixShakeKokkos::unconstrained_update() d_f = atomKK->k_f.view(); d_type = atomKK->k_type.view(); d_rmass = atomKK->k_rmass.view(); + // the per-type masses have no datamask bit, so atomKK->sync() cannot carry + // them: push the dual view to the device by hand + atomKK->k_mass.template sync(); d_mass = atomKK->k_mass.view(); nlocal = atom->nlocal; @@ -2127,10 +2101,15 @@ int FixShakeKokkos::pack_forward_comm_kokkos(int n, DAT::tdual_int_1 dz = static_cast(pbc[2]*domain->zprd); } + copymode = 1; + if (pbc_flag) Kokkos::parallel_for(Kokkos::RangePolicy >(0,n),*this); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,n),*this); + + copymode = 0; + return n*3; } @@ -2175,8 +2154,13 @@ void FixShakeKokkos::unpack_forward_comm_kokkos(int n, int first_in, { first = first_in; d_buf = buf.view(); + + copymode = 1; + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + copymode = 0; + k_xshake.modify(); } diff --git a/src/KOKKOS/fix_shake_kokkos.h b/src/KOKKOS/fix_shake_kokkos.h index afea28d331f..62639d4c618 100644 --- a/src/KOKKOS/fix_shake_kokkos.h +++ b/src/KOKKOS/fix_shake_kokkos.h @@ -248,9 +248,6 @@ class FixShakeKokkos : public FixShake, public KokkosBase { typename AT::t_int_1d d_copylist; typename AT::t_int_1d d_indices; - typename AT::t_double_2d d_b_stats; - typename AT::t_double_2d d_a_stats; - KK_FLOAT dx,dy,dz; KK_FLOAT dtv_kk,dtfsq_kk; diff --git a/src/KOKKOS/fix_spring_kokkos.cpp b/src/KOKKOS/fix_spring_kokkos.cpp index 541ef5fff28..8960c23366d 100644 --- a/src/KOKKOS/fix_spring_kokkos.cpp +++ b/src/KOKKOS/fix_spring_kokkos.cpp @@ -18,6 +18,7 @@ #include "atom_masks.h" #include "error.h" #include "group.h" +#include "group_kokkos.h" #include "update.h" #include @@ -62,12 +63,14 @@ void FixSpringKokkos::post_force(int /*vflag*/) if (styleflag == TETHER) { - // compute center of mass of group on host + // compute center of mass of group on the device. the host-only + // Group::xcm() also reads image, type and rmass, whose host copies are + // stale during a run (DomainKokkos::pbc() rewrites the image flags on the + // device), so the unwrapped center of mass would be off by whole boxes - atomKK->sync(Host, X_MASK | MASK_MASK); - - if (group->dynamic[igroup]) masstotal = group->mass(igroup); - group->xcm(igroup, masstotal, xcm); + auto *groupKK = (GroupKokkos *) group; + if (group->dynamic[igroup]) masstotal = groupKK->mass_kk(igroup); + groupKK->xcm_kk(igroup, masstotal, xcm); // compute scalar forces from xcm displacement @@ -121,14 +124,13 @@ void FixSpringKokkos::post_force(int /*vflag*/) } else { // COUPLE - // compute both centers of mass on host - - atomKK->sync(Host, X_MASK | MASK_MASK); + // compute both centers of mass on the device (see the comment above) - if (group->dynamic[igroup]) masstotal = group->mass(igroup); - if (group->dynamic[igroup2]) masstotal2 = group->mass(igroup2); - group->xcm(igroup, masstotal, xcm); - group->xcm(igroup2, masstotal2, xcm2); + auto *groupKK = (GroupKokkos *) group; + if (group->dynamic[igroup]) masstotal = groupKK->mass_kk(igroup); + if (group->dynamic[igroup2]) masstotal2 = groupKK->mass_kk(igroup2); + groupKK->xcm_kk(igroup, masstotal, xcm); + groupKK->xcm_kk(igroup2, masstotal2, xcm2); // compute scalar forces from xcm displacement diff --git a/src/KOKKOS/fix_spring_self_kokkos.cpp b/src/KOKKOS/fix_spring_self_kokkos.cpp index d556649b2e8..f72bea5c3b6 100644 --- a/src/KOKKOS/fix_spring_self_kokkos.cpp +++ b/src/KOKKOS/fix_spring_self_kokkos.cpp @@ -102,7 +102,6 @@ void FixSpringSelfKokkos::post_force(int /*vflag*/) double espring_kk; - k_xoriginal.modify_host(); k_xoriginal.sync(); copymode = 1; diff --git a/src/KOKKOS/fix_store_force_kokkos.cpp b/src/KOKKOS/fix_store_force_kokkos.cpp index 58452e317f6..9d3c43df368 100644 --- a/src/KOKKOS/fix_store_force_kokkos.cpp +++ b/src/KOKKOS/fix_store_force_kokkos.cpp @@ -35,11 +35,19 @@ FixStoreForceKokkos::FixStoreForceKokkos(LAMMPS *lmp, int narg, char datamask_modify = EMPTY_MASK; // the base constructor allocated foriginal with Memory; redo it as a - // dual view so the kernel can fill it on the device + // dual view so the kernel can fill it on the device. allocate it right + // away and re-point array_atom at it: the base class guarantees a valid, + // zeroed per-atom array before the first post_force(), because a dump or + // an atom-style variable may read it beforehand. Kokkos value-initializes + // the new view, which supplies the zeroes. memory->destroy(foriginal); foriginal = nullptr; - nmax = 0; + + nmax = atom->nmax; + memoryKK->create_kokkos(k_foriginal,foriginal,nmax,3,"store/force:foriginal"); + d_foriginal = k_foriginal.template view(); + array_atom = foriginal; } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_wall_flow_kokkos.cpp b/src/KOKKOS/fix_wall_flow_kokkos.cpp index 2dcbff3a87c..f71f902ee6b 100644 --- a/src/KOKKOS/fix_wall_flow_kokkos.cpp +++ b/src/KOKKOS/fix_wall_flow_kokkos.cpp @@ -35,7 +35,7 @@ FixWallFlowKokkos::FixWallFlowKokkos(LAMMPS *lmp, int narg, char **a exchange_comm_device = sort_device = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | RMASS_MASK | TYPE_MASK | MASK_MASK; + datamask_read = X_MASK | V_MASK | RMASS_MASK | TYPE_MASK | MASK_MASK; datamask_modify = V_MASK; memory->destroy(current_segment); @@ -56,6 +56,13 @@ template FixWallFlowKokkos::~FixWallFlowKokkos() template void FixWallFlowKokkos::init() { + // the base class checks compatibility with triclinic boxes, rigid bodies and + // a box changing along the flow axis; its per-atom loop is redone on the + // device below + + atomKK->sync(Host, X_MASK); + FixWallFlow::init(); + atomKK->sync(execution_space, datamask_read); k_current_segment.template sync(); d_x = atomKK->k_x.template view(); @@ -282,6 +289,13 @@ void FixWallFlowKokkos::unpack_exchange_kokkos(DAT::tdual_double_2d_ int /*nrecv1*/, int /*nextrarecv1*/, ExecutionSpace /*space*/) { + // the kernel writes only the received entries, so the device copy has to be + // current before it claims the whole view below + + k_current_segment.template sync(); + k_buf.template sync(); + k_indices.template sync(); + d_buf = typename AT::t_double_1d_um(k_buf.template view().data(), k_buf.extent(0) * k_buf.extent(1)); d_indices = k_indices.view(); diff --git a/src/KOKKOS/fix_wall_gran_kokkos.cpp b/src/KOKKOS/fix_wall_gran_kokkos.cpp index 1508af0b6f2..65f6f2308a5 100644 --- a/src/KOKKOS/fix_wall_gran_kokkos.cpp +++ b/src/KOKKOS/fix_wall_gran_kokkos.cpp @@ -117,6 +117,8 @@ void FixWallGranKokkos::post_force(int /*vflag*/) Kokkos::parallel_for(Kokkos::RangePolicy>(0,nlocal),*this); } else if (pairstyle == HERTZ_HISTORY) error->all(FLERR, "Fix wall/gran/kk doesn't yet support hertz/history style"); + else if (pairstyle == GRANULAR) + error->all(FLERR, "Fix wall/gran/kk doesn't yet support granular style"); atomKK->modified(execution_space,datamask_modify); @@ -368,7 +370,7 @@ KOKKOS_INLINE_FUNCTION void FixWallGranKokkos::operator()(TagFixWallGranPackExchange, const int &mysend) const { const int i = d_sendlist(mysend); - int m = i*size_history; + int m = mysend*size_history; for (int v = 0; v < size_history; v++) d_buf(m++) = static_cast(d_history_one(i,v)); @@ -421,7 +423,7 @@ void FixWallGranKokkos::operator()(TagFixWallGranUnpackExchange, con if (index > -1) { int m = i*size_history; for (int v = 0; v < size_history; v++) - d_history_one(i,v) = static_cast(d_buf(m++)); + d_history_one(index,v) = static_cast(d_buf(m++)); } } diff --git a/src/KOKKOS/fix_wall_region_kokkos.cpp b/src/KOKKOS/fix_wall_region_kokkos.cpp index 167ac394660..c80760874eb 100644 --- a/src/KOKKOS/fix_wall_region_kokkos.cpp +++ b/src/KOKKOS/fix_wall_region_kokkos.cpp @@ -45,6 +45,11 @@ FixWallRegionKokkos::FixWallRegionKokkos(LAMMPS *lmp, int narg, char atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK; + + // the colloid wall reads the per-atom radius in the kernel; the style has + // been parsed by the base class constructor at this point + + if (style == COLLOID) datamask_read |= RADIUS_MASK; datamask_modify = F_MASK; } From a2ee70295a2c30a787344c3820d6f0e2aa06105b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:58:58 +0000 Subject: [PATCH 092/120] KOKKOS: fix wrong forces and energies in several pair styles pair dpd/ext/tstat/kk had lost the leading minus on the dissipative force, reversing it, and omitted sigmaT from the temperature-ramp loop. pair lj/cut/dipole/cut/kk computed the LJ force, virial and torque inside the "rsq < cut_coulsq" branch, so every pair with cut_coul <= r < cut_lj lost its LJ contribution entirely. Moved out of the branch in both the range and the team kernel. pair morse/kk never subtracted the offset, so pair_modify shift was ignored. pair reaxff/kk divided where it should have multiplied in the non-shielded van der Waals derivative, and left d_hb_num stale when cut_hbsq is zero. pair uf3/kk indexed its knot table in single() without first checking the pair is inside the cutoff, and did not apply factor_lj. pair coul/dsf/kk and lj/cut/coul/dsf/kk applied the special-bonds factor with the wrong sign convention, flipping the sign of the tallied Coulomb energy. pair vashishta/kk indexed the short 3-body neighbour list with the loop counter rather than the atom in its FullB path. That path is unreachable -- newton_check() forces newton pair off for a full list while the CPU init_style() requires it on -- so this is dead-code correctness. --- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 8 +- src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp | 4 +- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp | 45 +++++++--- src/KOKKOS/pair_lj_cut_dipole_cut_kokkos.cpp | 88 +++++++++++--------- src/KOKKOS/pair_morse_kokkos.cpp | 3 +- src/KOKKOS/pair_reaxff_kokkos.cpp | 4 +- src/KOKKOS/pair_uf3_kokkos.cpp | 8 +- src/KOKKOS/pair_vashishta_kokkos.cpp | 4 +- 8 files changed, 100 insertions(+), 64 deletions(-) diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index ddcb9eb21b0..502d9448076 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -257,12 +257,14 @@ void PairCoulDSFKokkos::operator()(TagPairCoulDSFKernelA(1.0)/rsq; const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT prefactor = factor_coul * qqrd2e*qtmp*q[j]/r; + const KK_FLOAT prefactor = qqrd2e*qtmp*q[j]/r; const KK_FLOAT erfcd = Kokkos::exp(-alpha_kk*alpha_kk*rsq); const KK_FLOAT t = static_cast(1.0) / (static_cast(1.0) + static_cast(EWALD_P)*alpha_kk*r); const KK_FLOAT erfcc = t * (static_cast(A1)+t*(static_cast(A2)+t*(static_cast(A3)+t*(static_cast(A4)+t*static_cast(A5))))) * erfcd; - const KK_FLOAT forcecoul = prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + + KK_FLOAT forcecoul = prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + r*f_shift_kk) * r; + if (factor_coul < static_cast(1.0)) + forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; const KK_FLOAT fpair = forcecoul * r2inv; fxtmp += static_cast(delx*fpair); @@ -279,6 +281,8 @@ void PairCoulDSFKokkos::operator()(TagPairCoulDSFKernelA(1.0)) + ecoul -= (static_cast(1.0)-factor_coul)*prefactor; ev.ecoul += static_cast((((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(1.0):static_cast(0.5))*ecoul); } diff --git a/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp b/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp index 7b2c5f665d5..f0dc02bd5c1 100644 --- a/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_ext_tstat_kokkos.cpp @@ -118,6 +118,8 @@ void PairDPDExtTstatKokkos::compute(int eflagin, int vflagin) for (int j = i; j <= atom->ntypes; j++) { k_params.view_host()(i,j).sigma = k_params.view_host()(j,i).sigma = static_cast(sqrt(2.0*boltz*temperature*gamma[i][j])); + k_params.view_host()(i,j).sigmaT = k_params.view_host()(j,i).sigmaT = + static_cast(sqrt(2.0*boltz*temperature*gammaT[i][j])); } } k_params.modify_host(); @@ -299,7 +301,7 @@ void PairDPDExtTstatKokkos::operator() (TagDPDExtTstatKokkos(rand_gen.normal()); // drag force - parallel - fpair = params(itype,jtype).gamma*wdPar*wdPar*dot*rinv; + fpair = -params(itype,jtype).gamma*wdPar*wdPar*dot*rinv; fpair *= factor_dpd; // random force - parallel diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp index d0cede05b53..64d4661e2c9 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp @@ -118,20 +118,26 @@ void PairLJCutCoulDSFKokkos::compute(int eflag_in, int vflag_in) qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; + // damped-shifted-force self-energy per atom + // the loop below reads the host copy of q, which the sync above only + // refreshed in the execution space, so bring q to the host explicitly + + if (eflag) { + atomKK->sync(Host,Q_MASK); + if (eflag_global) { + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; + } + } + } + // loop over neighbors of my atoms EV_FLOAT ev; copymode = 1; - int inum = list->inum; - - for (int ii = 0; ii < inum; ii ++) { - //int i = list->ilist[ii]; - double qtmp = atom->q[ii]; - eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qtmp*qtmp*static_cast(qqrd2e); - } - ev = pair_compute,void > (this,(NeighListKokkos*)list); @@ -151,6 +157,11 @@ void PairLJCutCoulDSFKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); k_eatom.sync_host(); + // add the self-energy to the per-atom energy after the device sync + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eatom[i] += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; + } } if (vflag_atom) { @@ -220,13 +231,17 @@ compute_fcoul(const KK_FLOAT& rsq, const int& /*i*/, const int&j, const KK_FLOAT f_shift_kk = static_cast(f_shift); const KK_FLOAT r2inv = static_cast(1.0)/rsq; const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT prefactor = factor_coul * qqrd2e * qtmp * q(j); + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) / r; const KK_FLOAT erfcd = Kokkos::exp(-alpha_kk*alpha_kk*rsq); const KK_FLOAT t = static_cast(1.0) / (static_cast(1.0) + static_cast(EWALD_P)*alpha_kk*r); const KK_FLOAT erfcc = t * (static_cast(A1)+t*(static_cast(A2)+t*(static_cast(A3)+t*(static_cast(A4)+t*static_cast(A5))))) * erfcd; - return prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + r*f_shift_kk) * - r2inv; + KK_FLOAT forcecoul = prefactor * (erfcc/r + static_cast(2.0)*alpha_kk/static_cast(MY_PIS) * erfcd + + r*f_shift_kk) * r; + if (factor_coul < static_cast(1.0)) + forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + + return forcecoul * r2inv; } /* ---------------------------------------------------------------------- @@ -245,12 +260,16 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int&j, const KK_FLOAT e_shift_kk = static_cast(e_shift); const KK_FLOAT f_shift_kk = static_cast(f_shift); const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT prefactor = factor_coul * qqrd2e * qtmp * q(j); + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) / r; const KK_FLOAT erfcd = Kokkos::exp(-alpha_kk*alpha_kk*rsq); const KK_FLOAT t = static_cast(1.0) / (static_cast(1.0) + static_cast(EWALD_P)*alpha_kk*r); const KK_FLOAT erfcc = t * (static_cast(A1)+t*(static_cast(A2)+t*(static_cast(A3)+t*(static_cast(A4)+t*static_cast(A5))))) * erfcd; - return prefactor * (erfcc - r*e_shift_kk - rsq*f_shift_kk) / r; + KK_FLOAT ecoul = prefactor * (erfcc - r*e_shift_kk - rsq*f_shift_kk); + if (factor_coul < static_cast(1.0)) + ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + + return ecoul; } diff --git a/src/KOKKOS/pair_lj_cut_dipole_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_dipole_cut_kokkos.cpp index 8f8460126ed..0416c6e605a 100644 --- a/src/KOKKOS/pair_lj_cut_dipole_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_dipole_cut_kokkos.cpp @@ -397,29 +397,6 @@ void PairLJCutDipoleCutKokkos::operator()(TagPairLJCutDipoleCutKerne tjzcoul += -pre2 * (mu(j,0)*dely - mu(j,1)*delx); } - KK_FLOAT fq = factor_coul*qqrd2e; - fx = fq*forcecoulx + delx*forcelj; - fy = fq*forcecouly + dely*forcelj; - fz = fq*forcecoulz + delz*forcelj; - - // force & torque accumulation - - fx_i += static_cast(fx); - fy_i += static_cast(fy); - fz_i += static_cast(fz); - torquex_i += static_cast(fq*tixcoul); - torquey_i += static_cast(fq*tiycoul); - torquez_i += static_cast(fq*tizcoul); - - if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { - a_f(j,0) -= static_cast(fx); - a_f(j,1) -= static_cast(fy); - a_f(j,2) -= static_cast(fz); - a_torque(j,0) += static_cast(fq*tjxcoul); - a_torque(j,1) += static_cast(fq*tjycoul); - a_torque(j,2) += static_cast(fq*tjzcoul); - } - if (EVFLAG && eflag_global) { ecoul = qtmp*qj*rinv; if (mu(i,3) > static_cast(0.0) && mu(j,3) > static_cast(0.0)) @@ -433,6 +410,34 @@ void PairLJCutDipoleCutKokkos::operator()(TagPairLJCutDipoleCutKerne } } // cutsq_coulsq_ij + // total force and torque, computed unconditionally as the CPU style does. + // the coulomb accumulators are zero-initialised above, so for + // cut_coul <= r < cut_lj this reduces to the LJ-only contribution instead + // of dropping the force and the virial altogether + + KK_FLOAT fq = factor_coul*qqrd2e; + fx = fq*forcecoulx + delx*forcelj; + fy = fq*forcecouly + dely*forcelj; + fz = fq*forcecoulz + delz*forcelj; + + // force & torque accumulation + + fx_i += static_cast(fx); + fy_i += static_cast(fy); + fz_i += static_cast(fz); + torquex_i += static_cast(fq*tixcoul); + torquey_i += static_cast(fq*tiycoul); + torquez_i += static_cast(fq*tizcoul); + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + a_f(j,0) -= static_cast(fx); + a_f(j,1) -= static_cast(fy); + a_f(j,2) -= static_cast(fz); + a_torque(j,0) += static_cast(fq*tjxcoul); + a_torque(j,1) += static_cast(fq*tjycoul); + a_torque(j,2) += static_cast(fq*tjzcoul); + } + if (EVFLAG && (eflag_atom || vflag_either)) ev_tally_xyz(ev, i, j, ecoul+evdwl, fx, fy, fz, delx, dely, delz); } // cutsq_ij @@ -638,23 +643,6 @@ void PairLJCutDipoleCutKokkos::operator()(TagPairLJCutDipoleCutKerne tjzcoul += -pre2 * (mu(j,0)*dely - mu(j,1)*delx); } - KK_FLOAT fq = factor_coul*qqrd2e; - fx = fq*forcecoulx + delx*forcelj; - fy = fq*forcecouly + dely*forcelj; - fz = fq*forcecoulz + delz*forcelj; - tx = fq*tixcoul; - ty = fq*tiycoul; - tz = fq*tizcoul; - - if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { - a_f(j,0) -= static_cast(fx); - a_f(j,1) -= static_cast(fy); - a_f(j,2) -= static_cast(fz); - a_torque(j,0) += static_cast(fq*tjxcoul); - a_torque(j,1) += static_cast(fq*tjycoul); - a_torque(j,2) += static_cast(fq*tjzcoul); - } - if (EVFLAG && eflag_global) { ecoul = qtmp*qj*rinv; if (mu(i,3) > static_cast(0.0) && mu(j,3) > static_cast(0.0)) @@ -668,6 +656,26 @@ void PairLJCutDipoleCutKokkos::operator()(TagPairLJCutDipoleCutKerne } } // cutsq_coulsq_ij + // total force and torque, computed unconditionally as the CPU style does; + // see the range kernel above + + KK_FLOAT fq = factor_coul*qqrd2e; + fx = fq*forcecoulx + delx*forcelj; + fy = fq*forcecouly + dely*forcelj; + fz = fq*forcecoulz + delz*forcelj; + tx = fq*tixcoul; + ty = fq*tiycoul; + tz = fq*tizcoul; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + a_f(j,0) -= static_cast(fx); + a_f(j,1) -= static_cast(fy); + a_f(j,2) -= static_cast(fz); + a_torque(j,0) += static_cast(fq*tjxcoul); + a_torque(j,1) += static_cast(fq*tjycoul); + a_torque(j,2) += static_cast(fq*tjzcoul); + } + if (EVFLAG && (eflag_atom || vflag_either)) ev_tally_xyz(ev, i, j, ecoul+evdwl, fx, fy, fz, delx, dely, delz); diff --git a/src/KOKKOS/pair_morse_kokkos.cpp b/src/KOKKOS/pair_morse_kokkos.cpp index 498b941e0da..cfb0c90f42b 100644 --- a/src/KOKKOS/pair_morse_kokkos.cpp +++ b/src/KOKKOS/pair_morse_kokkos.cpp @@ -173,8 +173,9 @@ compute_evdwl(const KK_FLOAT &rsq, const int &, const int &, const int &itype, c // f = -2*a*d0*[ -exp( -2*a*(x-r0) ) + exp( -a*(x-r0) ) ] * grad(r) // = +2*a*d0*[ exp( -2*a*(x-r0) ) - exp( -a*(x-r0) ) ] * grad(r) const KK_FLOAT dexp = Kokkos::exp( -aa*dr ); + const KK_FLOAT offset = STACKPARAMS ? m_params[itype][jtype].offset : params(itype,jtype).offset; - return d0 * dexp * ( dexp - static_cast(2.0) ); + return d0 * dexp * ( dexp - static_cast(2.0) ) - offset; } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_reaxff_kokkos.cpp b/src/KOKKOS/pair_reaxff_kokkos.cpp index 4c2e0ca6748..7619d9ef2fa 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.cpp +++ b/src/KOKKOS/pair_reaxff_kokkos.cpp @@ -1257,7 +1257,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeLJCoulomb(2.0)*exp2); evdwl = Tap*etmp; - fvdwl = dTap*etmp-Tap*epsilon*(alpha/r_vdw)*(exp1-exp2)*rij; + fvdwl = dTap*etmp-Tap*epsilon*(alpha/r_vdw)*(exp1-exp2)/rij; } // inner wall if (vdwflag == 2 || vdwflag == 3) { @@ -1593,7 +1593,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxZero, const int &n) con d_total_bo(n) = 0; d_CdDelta(n) = 0; d_bo_num(n) = 0; - d_hb_num(n) = 0; + if (cut_hbsq > 0.0) d_hb_num(n) = 0; for (int j = 0; j < 3; j++) d_dDeltap_self(n,j) = 0; } diff --git a/src/KOKKOS/pair_uf3_kokkos.cpp b/src/KOKKOS/pair_uf3_kokkos.cpp index 884d894e163..c3f555014a5 100644 --- a/src/KOKKOS/pair_uf3_kokkos.cpp +++ b/src/KOKKOS/pair_uf3_kokkos.cpp @@ -1616,10 +1616,11 @@ double PairUF3Kokkos::single(int /*i*/, int /*j*/, int itype, int jt double value = 0.0; double r = sqrt(rsq); int interaction_id = map2b(itype, jtype); - int start_index = 3; - while (r > static_cast(d_n2b_knot(interaction_id, start_index + 1))) start_index++; - if (r < static_cast(d_cutsq(itype, jtype))) { + fforce = 0.0; + if (rsq < static_cast(d_cutsq(itype, jtype))) { + int start_index = 3; + while (r > static_cast(d_n2b_knot(interaction_id, start_index + 1))) start_index++; double r_values[4]; r_values[0] = 1; r_values[1] = r; @@ -1654,6 +1655,7 @@ double PairUF3Kokkos::single(int /*i*/, int /*j*/, int itype, int jt fforce += static_cast(dnconstants_2b(interaction_id, start_index - 3, 6)); fforce += r_values[1] * static_cast(dnconstants_2b(interaction_id, start_index - 3, 7)); fforce += r_values[2] * static_cast(dnconstants_2b(interaction_id, start_index - 3, 8)); + fforce *= factor_lj; } return factor_lj * value; diff --git a/src/KOKKOS/pair_vashishta_kokkos.cpp b/src/KOKKOS/pair_vashishta_kokkos.cpp index baaaefa3bfa..1dad3b25514 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.cpp +++ b/src/KOKKOS/pair_vashishta_kokkos.cpp @@ -507,10 +507,10 @@ void PairVashishtaKokkos::operator()(TagPairVashishtaComputeFullB Date: Tue, 8 Sep 2026 12:58:58 +0000 Subject: [PATCH 093/120] KOKKOS: sync charges for the DSF and Wolf host self-energy loops The DSF and Wolf styles compute a self-energy term on the host from q[i] without syncing Q_MASK first, and tallied it regardless of eflag where the CPU styles tally only under it. These styles dispatch through the generic pair_compute<> machinery, which offers no per-i hook, so the loop stays on the host and the sync is added there. pair born/coul/dsf/cs/kk additionally could not use the CPU's EPSILON of 1.0e-20 when KK_FLOAT is float. The binding quantity is compute_fpair(), whose born3 term is born3 * rsq^-5; at 1.0e-20 that is 1e100 and at 1.0e-8 it is still 1e40, both infinite in single precision, and the zero special-bond factor then yields NaN instead of removing the pair. A coincident pair in a single-precision build returned a finite energy of 1e32 beside a NaN pressure. The value is 1.0e-6 for float, applied as a floor rather than an added term: a floor only changes separations already below it, so it never perturbs a normal pair, and rsq^-5 stays at 1e30. --- src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp | 68 ++++++++++++++------ src/KOKKOS/pair_born_coul_dsf_kokkos.cpp | 14 +++- src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp | 14 +++- src/KOKKOS/pair_born_coul_wolf_kokkos.cpp | 14 +++- src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp | 14 +++- 5 files changed, 93 insertions(+), 31 deletions(-) diff --git a/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp b/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp index 381e5cea7ec..0150def28af 100644 --- a/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_dsf_cs_kokkos.cpp @@ -28,13 +28,27 @@ #include "update.h" #include +#include using namespace LAMMPS_NS; -// a minimal separation so that r = 0 core/shell pairs stay finite until the -// special-bond factor removes them, taken verbatim from the CPU style - -static constexpr double EPSILON = 1.0e-20; +// A minimal separation so that r = 0 core/shell pairs stay finite until the +// special-bond factor removes them. The CPU style uses 1.0e-20, which cannot +// be carried over unchanged when KK_FLOAT is float. +// +// The quantity that has to stay in range is the steepest one the kernel forms, +// not the energy: compute_fpair() returns forceborn*r2inv, whose born3 term is +// born3 * rsq^-5. At rsq = 1.0e-20 that is 1e100 -- finite in double, infinite +// in single -- and the zero special-bond factor then gives NaN rather than +// removing the pair. 1.0e-6 puts it at 1e30, eight orders inside the range of +// float, and leaves the r^-8 energy term at 1e24. +// +// The value is applied as a floor, not as an unconditional add, so it can be +// this large without consequence: a floor only changes separations already +// below it, and never perturbs a normal pair. (An *added* 1.0e-6 would have +// perturbed one, since 1.0f + 1.0e-6f != 1.0f.) + +static constexpr double EPSILON = std::is_same_v ? 1.0e-6 : 1.0e-20; using MathConst::MY_PIS; /* ---------------------------------------------------------------------- */ @@ -122,9 +136,17 @@ void PairBornCoulDSFCSKokkos::compute(int eflag_in, int vflag_in) newton_pair = force->newton_pair; // damped-shifted-force self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; + // the loop below reads the host copy of q, which the sync above only + // refreshed in the execution space, so bring q to the host explicitly + + if (eflag) { + atomKK->sync(Host,Q_MASK); + if (eflag_global) { + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; + } + } } EV_FLOAT ev; @@ -179,10 +201,12 @@ KK_FLOAT PairBornCoulDSFCSKokkos:: compute_fpair(const KK_FLOAT& rsq_in, const int& /*i*/, const int& /*j*/, const int& itype, const int& jtype) const { - // r = 0 must stay finite here, exactly as in the CPU style, which adds - // EPSILON to rsq before evaluating either term of the pair + // r = 0 must stay finite here, as in the CPU style. Applied as a floor + // rather than an unconditional add, so that a value large enough to keep the + // single-precision kernel in range cannot perturb a normal pair - const KK_FLOAT rsq = rsq_in + static_cast(EPSILON); + const KK_FLOAT rsq = (rsq_in > static_cast(EPSILON)) ? + rsq_in : static_cast(EPSILON); const KK_FLOAT r2inv = static_cast(1.0)/rsq; const KK_FLOAT r6inv = r2inv*r2inv*r2inv; @@ -210,10 +234,12 @@ compute_fcoul(const KK_FLOAT& rsq_in, const int& /*i*/, const int& j, const int& /*itype*/, const int& /*jtype*/, const KK_FLOAT& factor_coul, const KK_FLOAT& qtmp) const { - // r = 0 must stay finite here, exactly as in the CPU style, which adds - // EPSILON to rsq before evaluating either term of the pair + // r = 0 must stay finite here, as in the CPU style. Applied as a floor + // rather than an unconditional add, so that a value large enough to keep the + // single-precision kernel in range cannot perturb a normal pair - const KK_FLOAT rsq = rsq_in + static_cast(EPSILON); + const KK_FLOAT rsq = (rsq_in > static_cast(EPSILON)) ? + rsq_in : static_cast(EPSILON); const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT r2inv = static_cast(1.0)/rsq; @@ -242,10 +268,12 @@ KK_FLOAT PairBornCoulDSFCSKokkos:: compute_evdwl(const KK_FLOAT& rsq_in, const int& /*i*/, const int& /*j*/, const int& itype, const int& jtype) const { - // r = 0 must stay finite here, exactly as in the CPU style, which adds - // EPSILON to rsq before evaluating either term of the pair + // r = 0 must stay finite here, as in the CPU style. Applied as a floor + // rather than an unconditional add, so that a value large enough to keep the + // single-precision kernel in range cannot perturb a normal pair - const KK_FLOAT rsq = rsq_in + static_cast(EPSILON); + const KK_FLOAT rsq = (rsq_in > static_cast(EPSILON)) ? + rsq_in : static_cast(EPSILON); const KK_FLOAT r2inv = static_cast(1.0)/rsq; const KK_FLOAT r6inv = r2inv*r2inv*r2inv; @@ -273,10 +301,12 @@ compute_ecoul(const KK_FLOAT& rsq_in, const int& /*i*/, const int& j, const int& /*itype*/, const int& /*jtype*/, const KK_FLOAT& factor_coul, const KK_FLOAT& qtmp) const { - // r = 0 must stay finite here, exactly as in the CPU style, which adds - // EPSILON to rsq before evaluating either term of the pair + // r = 0 must stay finite here, as in the CPU style. Applied as a floor + // rather than an unconditional add, so that a value large enough to keep the + // single-precision kernel in range cannot perturb a normal pair - const KK_FLOAT rsq = rsq_in + static_cast(EPSILON); + const KK_FLOAT rsq = (rsq_in > static_cast(EPSILON)) ? + rsq_in : static_cast(EPSILON); const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT prefactor = qqrd2e*qtmp*q(j)/r; diff --git a/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp index 6580e66c6f8..86d6dc5336a 100644 --- a/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_dsf_kokkos.cpp @@ -117,9 +117,17 @@ void PairBornCoulDSFKokkos::compute(int eflag_in, int vflag_in) newton_pair = force->newton_pair; // damped-shifted-force self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; + // the loop below reads the host copy of q, which the sync above only + // refreshed in the execution space, so bring q to the host explicitly + + if (eflag) { + atomKK->sync(Host,Q_MASK); + if (eflag_global) { + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eng_coul += -(e_shift/2.0 + alpha/MY_PIS) * qisq * force->qqrd2e; + } + } } EV_FLOAT ev; diff --git a/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp b/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp index 46fd72f7733..b1580235554 100644 --- a/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_wolf_cs_kokkos.cpp @@ -122,9 +122,17 @@ void PairBornCoulWolfCSKokkos::compute(int eflag_in, int vflag_in) newton_pair = force->newton_pair; // Wolf self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); + // the loop below reads the host copy of q, which the sync above only + // refreshed in the execution space, so bring q to the host explicitly + + if (eflag) { + atomKK->sync(Host,Q_MASK); + if (eflag_global) { + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); + } + } } EV_FLOAT ev; diff --git a/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp index 72edf6434d7..241099909a4 100644 --- a/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_born_coul_wolf_kokkos.cpp @@ -117,9 +117,17 @@ void PairBornCoulWolfKokkos::compute(int eflag_in, int vflag_in) newton_pair = force->newton_pair; // Wolf self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); + // the loop below reads the host copy of q, which the sync above only + // refreshed in the execution space, so bring q to the host explicitly + + if (eflag) { + atomKK->sync(Host,Q_MASK); + if (eflag_global) { + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); + } + } } EV_FLOAT ev; diff --git a/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp index af085530a92..9df1010a7b8 100644 --- a/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_wolf_kokkos.cpp @@ -117,9 +117,17 @@ void PairLJCutCoulWolfKokkos::compute(int eflag_in, int vflag_in) newton_pair = force->newton_pair; // Wolf self-energy per atom - for (int i = 0; i < nlocal; i++) { - double qisq = atom->q[i]*atom->q[i]; - eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); + // the loop below reads the host copy of q, which the sync above only + // refreshed in the execution space, so bring q to the host explicitly + + if (eflag) { + atomKK->sync(Host,Q_MASK); + if (eflag_global) { + for (int i = 0; i < nlocal; i++) { + double qisq = atom->q[i]*atom->q[i]; + eng_coul += -(static_cast(e_shift)/2.0 + static_cast(m_alf)/MY_PIS) * qisq * static_cast(qqrd2e); + } + } } EV_FLOAT ev; From 4afd7d4fa07f19f9c9564a2195ab864936970faa Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:59:17 +0000 Subject: [PATCH 094/120] KOKKOS: guard the global energy with eflag_global, not eflag Ten pair styles accumulated ev.evdwl or ev.ecoul into eng_vdwl/eng_coul under "if (eflag)". eflag is set for a per-atom-only energy request as well, and pair_kokkos.h accumulates under eflag_either, while ev_setup zeroes the globals only under eflag_global -- so a per-atom-only step adds into a global that was not zeroed. The line immediately below each of these already used vflag_global for the virial. The pollution is transient and no current consumer can observe it: compute_pe and compute_pair both raise "Energy was not tallied on needed timestep" unless eflag_global was set, and thermo and compute_fep set it themselves. This is therefore hardening rather than a fix for an observable defect, but it matches the CPU convention and removes a trap for any future consumer. pair coul/cut/kk and coul/debye/kk additionally set only one triangle of k_cut_ljsq and k_cut_coulsq in init_one(). --- src/KOKKOS/pair_coul_cut_kokkos.cpp | 6 +++--- src/KOKKOS/pair_coul_cut_soft_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_debye_kokkos.cpp | 4 ++-- src/KOKKOS/pair_coul_diel_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_long_soft_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_shield_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_slater_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_class2_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_sphere_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_expand_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_spica_kokkos.cpp | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/KOKKOS/pair_coul_cut_kokkos.cpp b/src/KOKKOS/pair_coul_cut_kokkos.cpp index 8cb24d5824b..fb0a5e0d321 100644 --- a/src/KOKKOS/pair_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_coul_cut_kokkos.cpp @@ -110,7 +110,7 @@ void PairCoulCutKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void > (this,(NeighListKokkos*)list); - if (eflag) eng_coul += static_cast(ev.ecoul); + if (eflag_global) eng_coul += static_cast(ev.ecoul); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); @@ -227,9 +227,9 @@ double PairCoulCutKokkos::init_one(int i, int j) } k_cutsq.view_host()(i,j) = cutone*cutone; k_cutsq.modify_host(); - k_cut_ljsq.view_host()(i,j) = static_cast(cutone*cutone); + k_cut_ljsq.view_host()(i,j) = k_cut_ljsq.view_host()(j,i) = static_cast(cutone*cutone); k_cut_ljsq.modify_host(); - k_cut_coulsq.view_host()(i,j) = static_cast(cutone*cutone); + k_cut_coulsq.view_host()(i,j) = k_cut_coulsq.view_host()(j,i) = static_cast(cutone*cutone); k_cut_coulsq.modify_host(); k_params.modify_host(); diff --git a/src/KOKKOS/pair_coul_cut_soft_kokkos.cpp b/src/KOKKOS/pair_coul_cut_soft_kokkos.cpp index c0831efbadb..45f24964729 100644 --- a/src/KOKKOS/pair_coul_cut_soft_kokkos.cpp +++ b/src/KOKKOS/pair_coul_cut_soft_kokkos.cpp @@ -110,7 +110,7 @@ void PairCoulCutSoftKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void > (this,(NeighListKokkos*)list); - if (eflag) eng_coul += static_cast(ev.ecoul); + if (eflag_global) eng_coul += static_cast(ev.ecoul); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_coul_debye_kokkos.cpp b/src/KOKKOS/pair_coul_debye_kokkos.cpp index 917012a66c7..94fc4b35c7a 100644 --- a/src/KOKKOS/pair_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_coul_debye_kokkos.cpp @@ -250,9 +250,9 @@ double PairCoulDebyeKokkos::init_one(int i, int j) } k_cutsq.view_host()(i,j) = cutone*cutone; k_cutsq.modify_host(); - k_cut_ljsq.view_host()(i,j) = static_cast(cutone*cutone); + k_cut_ljsq.view_host()(i,j) = k_cut_ljsq.view_host()(j,i) = static_cast(cutone*cutone); k_cut_ljsq.modify_host(); - k_cut_coulsq.view_host()(i,j) = static_cast(cutone*cutone); + k_cut_coulsq.view_host()(i,j) = k_cut_coulsq.view_host()(j,i) = static_cast(cutone*cutone); k_cut_coulsq.modify_host(); k_params.modify_host(); diff --git a/src/KOKKOS/pair_coul_diel_kokkos.cpp b/src/KOKKOS/pair_coul_diel_kokkos.cpp index f101578bb9d..a5384c825a8 100644 --- a/src/KOKKOS/pair_coul_diel_kokkos.cpp +++ b/src/KOKKOS/pair_coul_diel_kokkos.cpp @@ -125,7 +125,7 @@ void PairCoulDielKokkos::compute(int eflag_in, int vflag_in) ev = pair_compute,void> (this,(NeighListKokkos*)list); - if (eflag) eng_coul += static_cast(ev.ecoul); + if (eflag_global) eng_coul += static_cast(ev.ecoul); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_coul_long_soft_kokkos.cpp b/src/KOKKOS/pair_coul_long_soft_kokkos.cpp index c759c616b3c..417eb067355 100644 --- a/src/KOKKOS/pair_coul_long_soft_kokkos.cpp +++ b/src/KOKKOS/pair_coul_long_soft_kokkos.cpp @@ -113,7 +113,7 @@ void PairCoulLongSoftKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void > (this,(NeighListKokkos*)list); - if (eflag) eng_coul += static_cast(ev.ecoul); + if (eflag_global) eng_coul += static_cast(ev.ecoul); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_coul_shield_kokkos.cpp b/src/KOKKOS/pair_coul_shield_kokkos.cpp index 017a0e5e797..1f1cbbfb74f 100644 --- a/src/KOKKOS/pair_coul_shield_kokkos.cpp +++ b/src/KOKKOS/pair_coul_shield_kokkos.cpp @@ -123,7 +123,7 @@ void PairCoulShieldKokkos::compute(int eflag_in, int vflag_in) ev = pair_compute,void> (this,(NeighListKokkos*)list); - if (eflag) eng_coul += static_cast(ev.ecoul); + if (eflag_global) eng_coul += static_cast(ev.ecoul); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_coul_slater_cut_kokkos.cpp b/src/KOKKOS/pair_coul_slater_cut_kokkos.cpp index 76f8ee71d6d..d7e70809682 100644 --- a/src/KOKKOS/pair_coul_slater_cut_kokkos.cpp +++ b/src/KOKKOS/pair_coul_slater_cut_kokkos.cpp @@ -111,7 +111,7 @@ void PairCoulSlaterCutKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void > (this,(NeighListKokkos*)list); - if (eflag) eng_coul += static_cast(ev.ecoul); + if (eflag_global) eng_coul += static_cast(ev.ecoul); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_lj_class2_kokkos.cpp b/src/KOKKOS/pair_lj_class2_kokkos.cpp index c8a92020528..4951f8570c0 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_kokkos.cpp @@ -111,7 +111,7 @@ void PairLJClass2Kokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); - if (eflag) eng_vdwl += static_cast(ev.evdwl); + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_lj_cut_sphere_kokkos.cpp b/src/KOKKOS/pair_lj_cut_sphere_kokkos.cpp index 8b4284d206f..c303a64a796 100644 --- a/src/KOKKOS/pair_lj_cut_sphere_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_sphere_kokkos.cpp @@ -116,7 +116,7 @@ void PairLJCutSphereKokkos::compute(int eflag_in, int vflag_in) ev = pair_compute,void> (this,(NeighListKokkos*)list); - if (eflag) eng_vdwl += static_cast(ev.evdwl); + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_lj_expand_kokkos.cpp b/src/KOKKOS/pair_lj_expand_kokkos.cpp index 374b2357b45..a6ace02c1ae 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_kokkos.cpp @@ -112,7 +112,7 @@ void PairLJExpandKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); - if (eflag) eng_vdwl += static_cast(ev.evdwl); + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); diff --git a/src/KOKKOS/pair_lj_spica_kokkos.cpp b/src/KOKKOS/pair_lj_spica_kokkos.cpp index cb249cf83a0..b9fee0bf922 100644 --- a/src/KOKKOS/pair_lj_spica_kokkos.cpp +++ b/src/KOKKOS/pair_lj_spica_kokkos.cpp @@ -111,7 +111,7 @@ void PairLJSPICAKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); - if (eflag) eng_vdwl += static_cast(ev.evdwl); + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); From e5122f45b4e5d26f893f41ff0015be2924920d51 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:59:17 +0000 Subject: [PATCH 095/120] KOKKOS: apply the fix adapt scale factor in meam and eam meam_force read d_scale(type[i], type[i]) where the CPU reads scale[type[i]][type[j]] (src/MEAM/meam_force.cpp:92), never applied the factor to dUdrij/dUdsij/dUdrijm as the CPU does, and omitted it from the per-atom energy. d_scale was also declared t_int_2d, so any non-integral scale was truncated; it is now t_kkfloat_2d. Correcting the index exposed a latent allocation bug. PairMEAM::coeff() writes only the upper triangle of scale[][]; the lower triangle stays uninitialised until PairMEAM::init_one() mirrors it. PairMEAMKokkos::coeff() copied the whole array to the device at coeff time, so the device copy held indeterminate values below the diagonal -- harmless while only the diagonal was read, and grossly wrong forces once it was not. The device copy is now seeded with 1.0 and refreshed from an init_one() override once the values exist. Both styles gain a reinit() override so that fix adapt, which writes scale[][] through extract() and then calls Pair::reinit(), reaches the device copy at all; without it the device kept the values captured at pair_coeff time. eam gains a real k_scale/d_scale DualView applied at all three CPU sites. --- src/KOKKOS/meam_dens_final_kokkos.h | 2 +- src/KOKKOS/meam_force_kokkos.h | 14 ++++- src/KOKKOS/meam_kokkos.h | 4 +- src/KOKKOS/pair_eam_kokkos.cpp | 86 +++++++++++++++++++++++++---- src/KOKKOS/pair_eam_kokkos.h | 11 ++++ src/KOKKOS/pair_meam_kokkos.cpp | 55 +++++++++++++++++- src/KOKKOS/pair_meam_kokkos.h | 4 +- 7 files changed, 158 insertions(+), 18 deletions(-) diff --git a/src/KOKKOS/meam_dens_final_kokkos.h b/src/KOKKOS/meam_dens_final_kokkos.h index 054c2199257..49e3e1c4df9 100644 --- a/src/KOKKOS/meam_dens_final_kokkos.h +++ b/src/KOKKOS/meam_dens_final_kokkos.h @@ -22,7 +22,7 @@ using namespace LAMMPS_NS; template void MEAMKokkos::meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_atom, - typename AT::t_kkacc_1d eatom, int ntype, typename AT::t_int_1d type, typename AT::t_int_1d d_map, typename AT::t_int_2d d_scale, int& errorflag, EV_FLOAT &ev_all) + typename AT::t_kkacc_1d eatom, int ntype, typename AT::t_int_1d type, typename AT::t_int_1d d_map, typename AT::t_kkfloat_2d d_scale, int& errorflag, EV_FLOAT &ev_all) { EV_FLOAT ev; this->eflag_either = eflag_either; diff --git a/src/KOKKOS/meam_force_kokkos.h b/src/KOKKOS/meam_force_kokkos.h index a644f5224c0..114bcfb19b4 100644 --- a/src/KOKKOS/meam_force_kokkos.h +++ b/src/KOKKOS/meam_force_kokkos.h @@ -183,13 +183,14 @@ KOKKOS_INLINE_FUNCTION void MEAMKokkos::operator()(TagMEAMForce(phi_sc * sij); if (eflag_atom) { - a_eatom[i] += static_cast(static_cast(0.5) * phi * sij); - a_eatom[j] += static_cast(static_cast(0.5) * phi * sij); + a_eatom[i] += static_cast(static_cast(0.5) * phi_sc * sij); + a_eatom[j] += static_cast(static_cast(0.5) * phi_sc * sij); } } @@ -697,6 +698,13 @@ KOKKOS_INLINE_FUNCTION void MEAMKokkos::operator()(TagMEAMForce(1.0)) { + dUdrij *= scaleij; + dUdsij *= scaleij; + dUdrijm[0] *= scaleij; + dUdrijm[1] *= scaleij; + dUdrijm[2] *= scaleij; + } // Add the part of the force due to dUdrij and dUdsij force = dUdrij * recip + dUdsij * d_dscrfcn[fnoffset + jn]; diff --git a/src/KOKKOS/meam_kokkos.h b/src/KOKKOS/meam_kokkos.h index 6a3677a2003..c1ff18461d7 100644 --- a/src/KOKKOS/meam_kokkos.h +++ b/src/KOKKOS/meam_kokkos.h @@ -62,7 +62,7 @@ template class MEAMKokkos : public MEAM { typename AT::t_int_1d type; typename AT::t_int_1d d_offset; typename AT::t_int_1d d_map; - typename AT::t_int_2d d_scale; + typename AT::t_kkfloat_2d d_scale; typename AT::t_kkfloat_1d_3_lr x; typename AT::t_int_1d d_numneigh_half; typename AT::t_int_1d d_numneigh_full; @@ -86,7 +86,7 @@ template class MEAMKokkos : public MEAM { typename AT::t_int_1d, typename AT::t_neighbors_2d, typename AT::t_neighbors_2d, typename AT::t_int_1d, int, int); void meam_dens_final(int, int, int, int, typename AT::t_kkacc_1d, int, - typename AT::t_int_1d, typename AT::t_int_1d, typename AT::t_int_2d, int &, + typename AT::t_int_1d, typename AT::t_int_1d, typename AT::t_kkfloat_2d, int &, EV_FLOAT &); void meam_force(int, int, int, int, int, typename AT::t_kkacc_1d, int, typename AT::t_int_1d, typename AT::t_int_1d, typename AT::t_kkfloat_1d_3_lr, diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 5cd6d0f8c52..79cac7c399f 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -44,6 +44,13 @@ PairEAMKokkos::PairEAMKokkos(LAMMPS *lmp) : PairEAM(lmp) respa_enable = 0; single_enable = 0; + // PairEAMKokkos::array2spline() only builds the device side spline tables, + // so the host tables PairEAM::compute_atomic_energy() needs do not exist + + atomic_energy_enable = 0; + + k_beyond_rhomax = DAT::tdual_int_scalar("pair:beyond_rhomax"); + kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; @@ -135,6 +142,13 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) rhomax_kk = static_cast(rhomax); rhomin_kk = static_cast(rhomin); + + k_scale.template sync(); + + k_beyond_rhomax.view_host()() = 0; + k_beyond_rhomax.modify_host(); + k_beyond_rhomax.template sync(); + copymode = 1; // zero out density @@ -280,6 +294,19 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (need_dup) Kokkos::Experimental::contribute(f, dup_f); + if (eflag && (!exceeded_rhomax)) { + k_beyond_rhomax.template modify(); + k_beyond_rhomax.sync_host(); + int beyond_rhomax = k_beyond_rhomax.view_host()(); + MPI_Allreduce(&beyond_rhomax,&exceeded_rhomax,1,MPI_INT,MPI_SUM,world); + if (exceeded_rhomax) { + if (comm->me == 0) + error->warning(FLERR, + "A per-atom density exceeded rhomax of EAM potential table - " + "a linear extrapolation to the energy was made"); + } + } + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); @@ -336,6 +363,29 @@ void PairEAMKokkos::init_style() !std::is_same_v); request->set_kokkos_device(std::is_same_v); if (neighflag == FULL) request->enable_full(); + + const int n = atom->ntypes + 1; + if (static_cast(k_scale.extent(0)) != n) + k_scale = DAT::tdual_kkfloat_2d("pair:scale",n,n); + d_scale = k_scale.template view(); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairEAMKokkos::init_one(int i, int j) +{ + double cutone = PairEAM::init_one(i,j); + + // Pair::reinit() calls init_one() again after fix adapt has changed scale, + // so this is also the hook that carries a new scale factor to the device + + k_scale.view_host()(i,j) = k_scale.view_host()(j,i) = static_cast(scale[i][j]); + k_scale.modify_host(); + + return cutone; } /* ---------------------------------------------------------------------- @@ -645,7 +695,11 @@ void PairEAMKokkos::operator()(TagPairEAMKernelB, const int & KK_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); if (he_flag && (d_rho[i] < rhomin_kk)) phi += d_fp[i] * (d_rho[i]-rhomin_kk); - else if (d_rho[i] > rhomax_kk) phi += d_fp[i] * (d_rho[i]-rhomax_kk); + else if (d_rho[i] > rhomax_kk) { + phi += d_fp[i] * (d_rho[i]-rhomax_kk); + if (!he_flag) k_beyond_rhomax.template view()() = 1; + } + phi *= d_scale(itype,itype); if (eflag_global) ev.evdwl += static_cast(phi); if (eflag_atom) d_eatom[i] += static_cast(phi); } @@ -721,7 +775,11 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, const int KK_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); if (he_flag && (d_rho[i] < rhomin_kk)) phi += d_fp[i] * (d_rho[i]-rhomin_kk); - else if (d_rho[i] > rhomax_kk) phi += d_fp[i] * (d_rho[i]-rhomax_kk); + else if (d_rho[i] > rhomax_kk) { + phi += d_fp[i] * (d_rho[i]-rhomax_kk); + if (!he_flag) k_beyond_rhomax.template view()() = 1; + } + phi *= d_scale(itype,itype); if (eflag_global) ev.evdwl += static_cast(phi); if (eflag_atom) d_eatom[i] += static_cast(phi); } @@ -812,7 +870,9 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC(delx*fpair); fytmp += static_cast(dely*fpair); @@ -826,10 +886,10 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC((((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(1.0):static_cast(0.5))*phi); + ev.evdwl += static_cast((((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(1.0):static_cast(0.5))*evdwl); } - if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,phi,fpair,delx,dely,delz); + if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } } @@ -930,7 +990,11 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, KK_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); if (he_flag && (d_rho[i] < rhomin_kk)) phi += d_fp[i] * (d_rho[i]-rhomin_kk); - else if (d_rho[i] > rhomax_kk) phi += d_fp[i] * (d_rho[i]-rhomax_kk); + else if (d_rho[i] > rhomax_kk) { + phi += d_fp[i] * (d_rho[i]-rhomax_kk); + if (!he_flag) k_beyond_rhomax.template view()() = 1; + } + phi *= d_scale(itype,itype); if (eflag_global) ev.evdwl += static_cast(phi); if (eflag_atom) d_eatom[i] += static_cast(phi); } @@ -1002,7 +1066,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC(1.0); int m = static_cast (p); m = MIN(m,nr-1); @@ -1042,7 +1106,9 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC(delx*fpair); fytmp += static_cast(dely*fpair); @@ -1056,10 +1122,10 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC((((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(1.0):static_cast(0.5))*phi); + ev.evdwl += static_cast((((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(1.0):static_cast(0.5))*evdwl); } - if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,phi,fpair,delx,dely,delz); + if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } } diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index a7ffcc594a1..bd43cfd6ff0 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -59,6 +59,7 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { ~PairEAMKokkos() override; void compute(int, int) override; void init_style() override; + double init_one(int, int) override; // NOLINTNEXTLINE @@ -179,6 +180,16 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { HAT::t_kkfloat_1d h_rho; HAT::t_kkfloat_1d h_fp; + // set on the device when a per-atom density runs past the end of the + // embedding table, so compute() can issue the same warning as the CPU style + + DAT::tdual_int_scalar k_beyond_rhomax; + + // per type pair scale factor, settable through fix adapt + + DAT::tdual_kkfloat_2d k_scale; + typename AT::t_kkfloat_2d d_scale; + typename AT::t_int_1d d_type2frho; typename AT::t_int_2d_dl d_type2rhor; typename AT::t_int_2d_dl d_type2z2r; diff --git a/src/KOKKOS/pair_meam_kokkos.cpp b/src/KOKKOS/pair_meam_kokkos.cpp index 6f68769c34d..a1c9a2c9777 100644 --- a/src/KOKKOS/pair_meam_kokkos.cpp +++ b/src/KOKKOS/pair_meam_kokkos.cpp @@ -300,16 +300,69 @@ void PairMEAMKokkos::coeff(int narg, char **arg) auto h_map = Kokkos::create_mirror_view(d_map); auto h_scale = Kokkos::create_mirror_view(d_scale); + // PairMEAM::coeff() only writes the upper triangle of scale[][]; the lower + // triangle stays uninitialised until init_one() mirrors it. Seed the whole + // device copy with the same default instead of reading that memory here, and + // let init_one() install the real values once they exist + for (int i = 1; i <= n; i++) { h_map[i] = map[i]; for (int j = 1; j <= n; j++) - h_scale(i,j) = scale[i][j]; + h_scale(i,j) = static_cast(1.0); } Kokkos::deep_copy(d_map,h_map); Kokkos::deep_copy(d_scale,h_scale); } +/* ---------------------------------------------------------------------- + Pair::init() calls init_one() for every type pair after coeff() has run, and + PairMEAM::init_one() is what makes scale[][] symmetric. Refresh the device + copy here so it never holds the pre-symmetrised values +------------------------------------------------------------------------- */ + +template +double PairMEAMKokkos::init_one(int i, int j) +{ + const double cut = PairMEAM::init_one(i,j); + + if (d_scale.data()) { + const int n = atom->ntypes; + auto h_scale = Kokkos::create_mirror_view(d_scale); + for (int ii = 1; ii <= n; ii++) + for (int jj = 1; jj <= n; jj++) + h_scale(ii,jj) = scale[ii][jj]; + Kokkos::deep_copy(d_scale,h_scale); + } + + return cut; +} + +/* ---------------------------------------------------------------------- + refresh the device copy of scale[][] + + fix adapt writes scale[][] through PairMEAM::extract() and then calls + Pair::reinit(), so without this override the device keeps the values + captured at pair_coeff time and the requested scaling never takes effect +------------------------------------------------------------------------- */ + +template +void PairMEAMKokkos::reinit() +{ + PairMEAM::reinit(); + + if (!d_scale.data()) return; + + const int n = atom->ntypes; + auto h_scale = Kokkos::create_mirror_view(d_scale); + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) + h_scale(i,j) = scale[i][j]; + Kokkos::deep_copy(d_scale,h_scale); + + // meam_inst_kk->d_scale is refreshed from this view on the next meam_dens_final() +} + /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_meam_kokkos.h b/src/KOKKOS/pair_meam_kokkos.h index 81d95d77fdb..88639e13456 100644 --- a/src/KOKKOS/pair_meam_kokkos.h +++ b/src/KOKKOS/pair_meam_kokkos.h @@ -54,6 +54,8 @@ class PairMEAMKokkos : public PairMEAM, public KokkosBase { void compute(int, int) override; void coeff(int, char **) override; void init_style() override; + double init_one(int, int) override; + void reinit() override; // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION @@ -105,7 +107,7 @@ class PairMEAMKokkos : public PairMEAM, public KokkosBase { DAT::tdual_int_1d k_map; typename AT::t_int_1d d_map; - typename AT::t_int_2d d_scale; + typename AT::t_kkfloat_2d d_scale; typename AT::t_int_1d d_ilist_half; typename AT::t_int_1d d_numneigh_half; typename AT::t_neighbors_2d d_neighbors_half; From aca8a8fcf457bfd8a6816c46a4ef91ef8ffdfc2e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:59:40 +0000 Subject: [PATCH 096/120] KOKKOS: fix the bzero shift and the central-atom lookup in SNAP SNA::compute_bi (src/ML-SNAP/sna.cpp) subtracts bzero[j] from the single element triple keyed on the central atom's element when bzeroflag is set and wselfallflag is not. The KOKKOS evaluate_bi subtracted it from every diagonal triple. Reachable with chemflag 1, nelements > 1, bzeroflag 1 and wselfallflag 0 -- all defaults except chemflag -- and masked in practice only because the shipped InP_JCPA2020.snapparam sets wselfallflag 1. A scalar ielem does not work here: TagPairSNAPComputeBi processes yi_batch atoms per thread and those atoms can have different elements, so the argument is a per-batch array, the same shape SNAIntel::compute_bi already uses. The condition also needs its !chem_flag short-circuit: with chemflag 0 but several element types SNAKokkos::nelements is 1 while a caller's d_map[itype] can be nonzero, and the CPU passes 0 in that case. Separately, all three TagPairSNAPPreUi overloads derived the element with type(iatom), using the chunk-local index as an atom index; every other kernel in the file resolves d_ilist[iatom + chunk_offset]. Same reachability as above, since pre_ui short-circuits on !chem_flag. The two ComputeBi overloads that guard on iatom_shift also passed iatom to compute_bi; the two are equal wherever those overloads run today, so that one is a latent inconsistency rather than a live defect. j is also masked with NEIGHMASK at four sites that were missing it. --- src/KOKKOS/pair_snap_kokkos.h | 5 +++ src/KOKKOS/pair_snap_kokkos_impl.h | 45 +++++++++++++++---- src/KOKKOS/sna_kokkos.h | 4 +- src/KOKKOS/sna_kokkos_impl.h | 70 +++++++++++++++--------------- 4 files changed, 79 insertions(+), 45 deletions(-) diff --git a/src/KOKKOS/pair_snap_kokkos.h b/src/KOKKOS/pair_snap_kokkos.h index 2bee391d0cc..8c872cf8459 100644 --- a/src/KOKKOS/pair_snap_kokkos.h +++ b/src/KOKKOS/pair_snap_kokkos.h @@ -364,6 +364,11 @@ class PairSNAPKokkos : public PairSNAP { template KOKKOS_INLINE_FUNCTION void operator() (TagPairSNAPComputeBi, const int& iatom) const; + // central atom elements of the `yi_batch` atoms ComputeBi processes together +// NOLINTNEXTLINE + KOKKOS_INLINE_FUNCTION + Kokkos::Array get_ielem_batch(const int&) const; + // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION void operator() (TagPairSNAPComputeBetaLinear, const int& iatom_mod, const int& idxb, const int& iatom_div) const; diff --git a/src/KOKKOS/pair_snap_kokkos_impl.h b/src/KOKKOS/pair_snap_kokkos_impl.h index 4608311d1f0..332b7d360c0 100644 --- a/src/KOKKOS/pair_snap_kokkos_impl.h +++ b/src/KOKKOS/pair_snap_kokkos_impl.h @@ -552,6 +552,7 @@ void PairSNAPKokkos::operator( Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,num_neighs), [&] (const int jj, int& count) { T_INT j = d_neighbors(i,jj); + j &= NEIGHMASK; const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; @@ -579,6 +580,7 @@ void PairSNAPKokkos::operator( if (jtype >= 0) { if (final) { T_INT j = d_neighbors(i,jj); + j &= NEIGHMASK; const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; @@ -632,6 +634,7 @@ void PairSNAPKokkos::operator( [&] (const int jj, int& count) { Kokkos::single(Kokkos::PerThread(team), [&] () { T_INT j = d_neighbors(i,jj); + j &= NEIGHMASK; const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; @@ -651,6 +654,7 @@ void PairSNAPKokkos::operator( [&] (const int jj, int& offset, bool final) { //for (int jj = 0; jj < num_neighs; jj++) { T_INT j = d_neighbors(i,jj); + j &= NEIGHMASK; const double dx = static_cast(x(j,0)) - xtmp; const double dy = static_cast(x(j,1)) - ytmp; const double dz = static_cast(x(j,2)) - ztmp; @@ -712,8 +716,9 @@ void PairSNAPKokkos::operator( const int iatom = iatom_mod + iatom_div * vector_length; if (iatom >= chunk_size) return; - int itype = type(iatom); - int ielem = d_map[itype]; + const int i = d_ilist[iatom + chunk_offset]; + const int itype = type[i]; + const int ielem = d_map[itype]; snaKK.pre_ui(iatom, j, ielem); } @@ -724,8 +729,9 @@ KOKKOS_INLINE_FUNCTION void PairSNAPKokkos::operator() (TagPairSNAPPreUi, const int& iatom, const int& j) const { if (iatom >= chunk_size) return; - int itype = type(iatom); - int ielem = d_map[itype]; + const int i = d_ilist[iatom + chunk_offset]; + const int itype = type[i]; + const int ielem = d_map[itype]; snaKK.pre_ui(iatom, j, ielem); } @@ -736,7 +742,8 @@ KOKKOS_INLINE_FUNCTION void PairSNAPKokkos::operator() (TagPairSNAPPreUi, const int& iatom) const { if (iatom >= chunk_size) return; - const int itype = type(iatom); + const int i = d_ilist[iatom + chunk_offset]; + const int itype = type[i]; const int ielem = d_map[itype]; for (int j = 0; j <= twojmax; j++) @@ -925,6 +932,27 @@ void PairSNAPKokkos::operator( snaKK.template compute_zi(iatom_shift, jjz); } +/* ---------------------------------------------------------------------- + Look up the element of the central atom for each of the `yi_batch` atoms + that one ComputeBi thread handles. The bzero shift in `evaluate_bi` needs it. +------------------------------------------------------------------------- */ + +template +// NOLINTNEXTLINE +KOKKOS_INLINE_FUNCTION +auto PairSNAPKokkos::get_ielem_batch(const int& iatom) const -> Kokkos::Array +{ + Kokkos::Array ielem; + for (int n = 0; n < yi_batch; n++) { + // the trailing entries of a batch can reach past the end of a short final + // chunk; they only feed padded rows of blist, so clamping the lookup is safe + const int iatom_batch = iatom + n * vector_length; + const int i = d_ilist[(iatom_batch < chunk_size ? iatom_batch : chunk_size - 1) + chunk_offset]; + ielem[n] = d_map[type[i]]; + } + return ielem; +} + /* ---------------------------------------------------------------------- Compute the energy triple products and store in the "blist" View. CPU and GPU. @@ -937,7 +965,7 @@ void PairSNAPKokkos::operator( const int iatom = iatom_mod + yi_batch * iatom_div * vector_length; if (iatom >= chunk_size) return; if (jjb >= snaKK.idxb_max) return; - snaKK.template compute_bi(iatom, jjb); + snaKK.template compute_bi(iatom, jjb, get_ielem_batch(iatom)); } template @@ -951,7 +979,7 @@ void PairSNAPKokkos::operator( iatom_shift = iatom_mod + yi_batch * iatom_div * vector_length; } if (iatom_shift >= chunk_size) return; - snaKK.template compute_bi(iatom, jjb); + snaKK.template compute_bi(iatom_shift, jjb, get_ielem_batch(iatom_shift)); } template @@ -965,8 +993,9 @@ void PairSNAPKokkos::operator( iatom_shift = iatom_mod + yi_batch * iatom_div * vector_length; } if (iatom_shift >= chunk_size) return; + const Kokkos::Array ielem = get_ielem_batch(iatom_shift); for (int jjb = 0; jjb < snaKK.idxb_max; jjb++) - snaKK.template compute_bi(iatom, jjb); + snaKK.template compute_bi(iatom_shift, jjb, ielem); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/sna_kokkos.h b/src/KOKKOS/sna_kokkos.h index 669a314284c..d44b7892c09 100644 --- a/src/KOKKOS/sna_kokkos.h +++ b/src/KOKKOS/sna_kokkos.h @@ -297,7 +297,7 @@ class SNAKokkos { void compute_yi_with_zlist(const int&, const int&) const; // ForceSNAP // NOLINTNEXTLINE template KOKKOS_INLINE_FUNCTION - void compute_bi(const int&, const int&) const; // ForceSNAP + void compute_bi(const int&, const int&, const Kokkos::Array&) const; // ForceSNAP // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION void compute_beta_linear(const int&, const int&, const int&) const; @@ -338,7 +338,7 @@ class SNAKokkos { // NOLINTNEXTLINE template KOKKOS_FORCEINLINE_FUNCTION auto evaluate_bi(const int&, const int&, const int&, const int&, - const int&, const int&, const int&) const; + const int&, const int&, const int&, const Kokkos::Array&) const; // plugged into compute_yi, compute_yi_with_zlist; returns real_type // NOLINTNEXTLINE template KOKKOS_FORCEINLINE_FUNCTION diff --git a/src/KOKKOS/sna_kokkos_impl.h b/src/KOKKOS/sna_kokkos_impl.h index 912be807281..3aef976ca1c 100644 --- a/src/KOKKOS/sna_kokkos_impl.h +++ b/src/KOKKOS/sna_kokkos_impl.h @@ -18,6 +18,7 @@ ------------------------------------------------------------------------- */ #include "sna_kokkos.h" +#include "math_const.h" #include "memory_kokkos.h" #include #include @@ -26,9 +27,6 @@ namespace LAMMPS_NS { -static const double MY_PI = 3.14159265358979323846; // pi -static const double MY_PI2 = 1.57079632679489661923; // pi/2 - template template inline @@ -362,7 +360,7 @@ void SNAKokkos::compute_cayley const real_type rcut = rcutij(iatom, jnbor); const real_type sinner = sinnerij(iatom, jnbor); const real_type dinner = dinnerij(iatom, jnbor); - const real_type rscale0 = rfac0 * static_cast(MY_PI) / (rcut - rmin0); + const real_type rscale0 = rfac0 * static_cast(MathConst::MY_PI) / (rcut - rmin0); const real_type theta0 = (r - rmin0) * rscale0; const real_type sn = Kokkos::sin(theta0); const real_type cs = Kokkos::cos(theta0); @@ -763,7 +761,7 @@ void SNAKokkos::compute_ui_cpu const real_type rsq = x * x + y * y + z * z; const real_type r = Kokkos::sqrt(rsq); - const real_type theta0 = (r - rmin0) * rfac0 * static_cast(MY_PI) / (rcutij(iatom,jnbor) - rmin0); + const real_type theta0 = (r - rmin0) * rfac0 * static_cast(MathConst::MY_PI) / (rcutij(iatom,jnbor) - rmin0); // theta0 = (r - rmin0) * rscale0; const real_type z0 = r / Kokkos::tan(theta0); @@ -1006,7 +1004,7 @@ auto SNAKokkos::evaluate_zi(co template // NOLINTNEXTLINE template KOKKOS_INLINE_FUNCTION -void SNAKokkos::compute_bi(const int& iatom, const int& jjb) const +void SNAKokkos::compute_bi(const int& iatom, const int& jjb, const Kokkos::Array& ielem) const { // for j1 = 0,...,twojmax // for j2 = 0,twojmax @@ -1029,7 +1027,7 @@ void SNAKokkos::compute_bi(con for (int elem1 = 0; elem1 < nelements; elem1++) { for (int elem2 = 0; elem2 < nelements; elem2++) { for (int elem3 = 0; elem3 < nelements; elem3++) { - Kokkos::Array bval = evaluate_bi(j, jjz, jju, iatom, elem1, elem2, elem3); + Kokkos::Array bval = evaluate_bi(j, jjz, jju, iatom, elem1, elem2, elem3, ielem); register_loop([&] (int n) -> void { blist(iatom + n * vector_length, itriple, jjb) = bval[n]; }); @@ -1038,7 +1036,7 @@ void SNAKokkos::compute_bi(con } // end loop over elem2 } // end loop over elem1 } else { - Kokkos::Array bval = evaluate_bi(j, jjz, jju, iatom, 0, 0, 0); + Kokkos::Array bval = evaluate_bi(j, jjz, jju, iatom, 0, 0, 0, ielem); register_loop([&] (int n) -> void { blist(iatom + n * vector_length, 0, jjb) = bval[n]; }); @@ -1053,7 +1051,7 @@ void SNAKokkos::compute_bi(con template // NOLINTNEXTLINE template KOKKOS_INLINE_FUNCTION -auto SNAKokkos::evaluate_bi(const int& j, const int& jjz, const int& jju, const int& iatom, const int& elem1, const int& elem2, const int& elem3) const +auto SNAKokkos::evaluate_bi(const int& j, const int& jjz, const int& jju, const int& iatom, const int& elem1, const int& elem2, const int& elem3, const Kokkos::Array& ielem) const { // this computes the: // b(j1,j2,j) = 0 @@ -1116,7 +1114,9 @@ auto SNAKokkos::evaluate_bi(co bval[n] *= static_cast(2.0); if (bzero_flag) { if (!wselfall_flag) { - if (elem1 == elem2 && elem1 == elem3) { + // SNA::compute_bi() shifts only the triple built from the element of the + // central atom, so all three indices must match it, not just each other + if (!chem_flag || ((elem1 == ielem[n]) && (elem2 == ielem[n]) && (elem3 == ielem[n]))) { bval[n] -= static_cast(bzero[j]); } } else { @@ -1689,7 +1689,7 @@ void SNAKokkos::compute_duidrj const real_type z = rij(iatom,jnbor,2); const real_type rsq = x * x + y * y + z * z; const real_type r = Kokkos::sqrt(rsq); - const real_type rscale0 = rfac0 * static_cast(MY_PI) / (rcutij(iatom,jnbor) - rmin0); + const real_type rscale0 = rfac0 * static_cast(MathConst::MY_PI) / (rcutij(iatom,jnbor) - rmin0); const real_type theta0 = (r - rmin0) * rscale0; const real_type sn = Kokkos::sin(theta0); const real_type cs = Kokkos::cos(theta0); @@ -2227,7 +2227,7 @@ real_type SNAKokkos::compute_s if (r <= rmin0) sfac_outer = one; else if (r > rcut) return zero; else { - real_type rcutfac = static_cast(MY_PI) / (rcut - rmin0); + real_type rcutfac = static_cast(MathConst::MY_PI) / (rcut - rmin0); sfac_outer = onehalf * (Kokkos::cos((r - rmin0) * rcutfac) + one); } } else sfac_outer = zero; // switch_flag is always 0 or 1 @@ -2237,9 +2237,9 @@ real_type SNAKokkos::compute_s if (r >= sinner + dinner) return sfac_outer; else if (r > sinner - dinner) { - real_type rcutfac = static_cast(MY_PI2) / dinner; + real_type rcutfac = static_cast(MathConst::MY_PI2) / dinner; return sfac_outer * - onehalf * (one - Kokkos::cos(static_cast(MY_PI2) + (r - sinner) * rcutfac)); + onehalf * (one - Kokkos::cos(static_cast(MathConst::MY_PI2) + (r - sinner) * rcutfac)); } else return zero; } return zero; // dummy return @@ -2261,8 +2261,8 @@ real_type SNAKokkos::compute_d if (r <= rmin0) dsfac_outer = zero; else if (r > rcut) return zero; else { - real_type rcutfac = static_cast(MY_PI) / (rcut - rmin0); - dsfac_outer = -onehalf * sin((r - rmin0) * rcutfac) * rcutfac; + real_type rcutfac = static_cast(MathConst::MY_PI) / (rcut - rmin0); + dsfac_outer = -onehalf * Kokkos::sin((r - rmin0) * rcutfac) * rcutfac; } } else dsfac_outer = zero; // switch_flag is always 0 or 1 @@ -2279,16 +2279,16 @@ real_type SNAKokkos::compute_d if (r <= rmin0) sfac_outer = one; else if (r > rcut) sfac_outer = zero; else { - real_type rcutfac = static_cast(MY_PI) / (rcut - rmin0); - sfac_outer = onehalf * (cos((r - rmin0) * rcutfac) + one); + real_type rcutfac = static_cast(MathConst::MY_PI) / (rcut - rmin0); + sfac_outer = onehalf * (Kokkos::cos((r - rmin0) * rcutfac) + one); } } else sfac_outer = zero; // switch_flag is always 0 or 1 // calculate sfac_inner - real_type rcutfac = static_cast(MY_PI2) / dinner; - sfac_inner = onehalf * (one - cos(static_cast(MY_PI2) + (r - sinner) * rcutfac)); - dsfac_inner = onehalf * rcutfac * sin(static_cast(MY_PI2) + (r - sinner) * rcutfac); + real_type rcutfac = static_cast(MathConst::MY_PI2) / dinner; + sfac_inner = onehalf * (one - Kokkos::cos(static_cast(MathConst::MY_PI2) + (r - sinner) * rcutfac)); + dsfac_inner = onehalf * rcutfac * Kokkos::sin(static_cast(MathConst::MY_PI2) + (r - sinner) * rcutfac); return dsfac_outer * sfac_inner + sfac_outer * dsfac_inner; } else return zero; @@ -2311,7 +2311,7 @@ void SNAKokkos::compute_s_dsfa if (r <= rmin0) { sfac_outer = one; dsfac_outer = zero; } else if (r > rcut) { sfac = zero; dsfac = zero; return; } else { - const real_type rcutfac = static_cast(MY_PI) / (rcut - rmin0); + const real_type rcutfac = static_cast(MathConst::MY_PI) / (rcut - rmin0); const real_type theta0 = (r - rmin0) * rcutfac; const real_type sn = Kokkos::sin(theta0); const real_type cs = Kokkos::cos(theta0); @@ -2324,9 +2324,9 @@ void SNAKokkos::compute_s_dsfa else if (switch_inner_flag == 1) { if (r >= sinner + dinner) { sfac = sfac_outer; dsfac = dsfac_outer; return; } else if (r > sinner - dinner) { - real_type rcutfac = static_cast(MY_PI2) / dinner; - sfac_inner = onehalf * (one - Kokkos::cos(static_cast(MY_PI2) + (r - sinner) * rcutfac)); - dsfac_inner = onehalf * rcutfac * Kokkos::sin(static_cast(MY_PI2) + (r - sinner) * rcutfac); + real_type rcutfac = static_cast(MathConst::MY_PI2) / dinner; + sfac_inner = onehalf * (one - Kokkos::cos(static_cast(MathConst::MY_PI2) + (r - sinner) * rcutfac)); + dsfac_inner = onehalf * rcutfac * Kokkos::sin(static_cast(MathConst::MY_PI2) + (r - sinner) * rcutfac); sfac = sfac_outer * sfac_inner; dsfac = dsfac_outer * sfac_inner + sfac_outer * dsfac_inner; return; @@ -2357,16 +2357,16 @@ double SNAKokkos::memory_usage bytes += MemKK::memory_usage(ylist_re); bytes += MemKK::memory_usage(ylist_im); - if constexpr (!host_flag) { - bytes += MemKK::memory_usage(a_gpu); - bytes += MemKK::memory_usage(b_gpu); - bytes += MemKK::memory_usage(da_gpu); - bytes += MemKK::memory_usage(db_gpu); - bytes += MemKK::memory_usage(sfac_gpu); - } else { - bytes += MemKK::memory_usage(ulist_cpu); - bytes += MemKK::memory_usage(dulist_cpu); - } + // grow_rij() allocates both sets of arrays, sizing the unused one to a single + // element, so both are counted here unconditionally + + bytes += MemKK::memory_usage(a_gpu); + bytes += MemKK::memory_usage(b_gpu); + bytes += MemKK::memory_usage(da_gpu); + bytes += MemKK::memory_usage(db_gpu); + bytes += MemKK::memory_usage(sfac_gpu); + bytes += MemKK::memory_usage(ulist_cpu); + bytes += MemKK::memory_usage(dulist_cpu); bytes += MemKK::memory_usage(dedr); From 899cbef4b2625fd65362ae7b6023f58833bd44bf Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:59:40 +0000 Subject: [PATCH 097/120] KOKKOS: remaining pair style and accessor fixes pair brownian/kk built its RNG pool in the constructor, before settings() had parsed the seed, so every seed produced the same stream. Moved to init_style(). It also now rejects a full neighbour list, which is the default on a GPU: a full list visits each pair twice and draws independent random numbers each time, so the stochastic force stops being equal and opposite. eatom is allocated and zeroed, since ev_init is called with alloc == 0. pair nm/cut/coul/long/kk had no tabulated Coulomb path; ncoultablebits was left at 0, which would then leak into write_restart_settings. The full tabulated path is ported. pair exp6/rx/kk marked k_cutsq modified only in allocate(), so a cutoff changed between runs never reached the device; an init_one() override marks it. pair table/rx/kk and ylz/kk were missing datamask entries (F_MASK, UCG_MASK, UCGNEW_MASK and BONUS_MASK respectively). pair mliap/kk sized a per-atom virial view from maxeatom. The remaining files carry single-site corrections of the same kind found by comparing each style against its CPU base. --- src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp | 85 +++++++++---- src/KOKKOS/min_cg_kokkos.cpp | 22 ++-- src/KOKKOS/modify_kokkos.h | 1 - src/KOKKOS/pair_bondval_kokkos.cpp | 13 -- src/KOKKOS/pair_bondval_kokkos.h | 1 - src/KOKKOS/pair_bondval_vec_kokkos.cpp | 14 -- src/KOKKOS/pair_bondval_vec_kokkos.h | 1 - src/KOKKOS/pair_brownian_kokkos.cpp | 29 ++++- src/KOKKOS/pair_dpd_tstat_kokkos.cpp | 3 + src/KOKKOS/pair_exp6_rx_kokkos.cpp | 17 +++ src/KOKKOS/pair_exp6_rx_kokkos.h | 1 + .../pair_lj_switch3_coulgauss_long_kokkos.cpp | 75 +++++++---- .../pair_lj_switch3_coulgauss_long_kokkos.h | 6 + src/KOKKOS/pair_mliap_kokkos.cpp | 4 +- ...pair_mm3_switch3_coulgauss_long_kokkos.cpp | 75 +++++++---- .../pair_mm3_switch3_coulgauss_long_kokkos.h | 6 + src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 29 ++++- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 1 + src/KOKKOS/pair_nm_cut_coul_long_kokkos.cpp | 120 ++++++++++++++---- src/KOKKOS/pair_nm_cut_coul_long_kokkos.h | 46 +++++-- src/KOKKOS/pair_pace_extrapolation_kokkos.cpp | 7 +- src/KOKKOS/pair_table_kokkos.cpp | 8 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 22 ++-- src/KOKKOS/pair_tip4p_kokkos.h | 33 ++++- src/KOKKOS/pair_ylz_kokkos.cpp | 2 +- 25 files changed, 439 insertions(+), 182 deletions(-) diff --git a/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp b/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp index 73f44921fc1..976c1b778c3 100644 --- a/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp +++ b/src/KOKKOS/atom_vec_ellipsoid_kokkos.cpp @@ -62,6 +62,12 @@ void AtomVecEllipsoidKokkos::init() { AtomVecEllipsoid::init(); + // the KOKKOS bonus layout is hard-wired to shape[3]+quat[4] and grow() does + // not allocate the per-atom radius the superellipsoid sub-style adds + + if (atom->superellipsoid_flag) + error->all(FLERR,"Atom style ellipsoid/kk does not (yet) support the superellipsoid option"); + set_atom_masks(); } @@ -184,7 +190,10 @@ void AtomVecEllipsoidKokkos::sort_kokkos(Kokkos::BinSort &So Sorter.sort(LMPDeviceType(), d_rmass); Sorter.sort(LMPDeviceType(), d_angmom); Sorter.sort(LMPDeviceType(), d_ellipsoid); - Sorter.sort(LMPDeviceType(), d_bonus); + + // the bonus array is compacted and indexed through ellipsoid[i], not by atom + // index, so the per-atom bin permutation must not be applied to it. Bonus + // styles therefore use the legacy (host) sort, see AtomKokkos::sort(). atomKK->modified(Device, ALL_MASK & ~F_MASK & ~TORQUE_MASK); } @@ -207,14 +216,17 @@ struct AtomVecEllipsoidKokkos_PackCommBonus { const typename DAT::tdual_double_2d_lr &buf, const typename DEllipsoidBonusAT::tdual_bonus_1d &bonus, const typename DAT::tdual_int_1d &list, - const int &offset): + const int &offset, + const int &vel_flag): _bonus(bonus.view()), _ellipsoid(atomKK->k_ellipsoid.view()), _list(list.view()), _offset(offset) { - const int size_forward = atomKK->avecKK->size_forward; - const size_t maxsend = (buf.view().extent(0)*buf.view().extent(1))/size_forward; - const size_t elements = size_forward; + // must use the same row stride as AtomVecKokkos_PackComm(Vel), which packs + // the rest of the same buffer, or the bonus data lands in the wrong rows + const size_t elements = atomKK->avecKK->size_forward + + (vel_flag ? atomKK->avecKK->size_velocity : 0); + const size_t maxsend = (buf.view().extent(0)*buf.view().extent(1))/elements; buffer_view(_buf,buf,maxsend,elements); } @@ -241,11 +253,11 @@ void AtomVecEllipsoidKokkos::pack_comm_bonus_kokkos(const int &n, const DAT::tdu if (lmp->kokkos->forward_comm_on_host) { atomKK->sync(HostKK,datamask_bonus); - struct AtomVecEllipsoidKokkos_PackCommBonus f(atomKK,buf,k_bonus,list,offset); + struct AtomVecEllipsoidKokkos_PackCommBonus f(atomKK,buf,k_bonus,list,offset,vel_flag); Kokkos::parallel_for(n,f); } else { atomKK->sync(Device,datamask_bonus); - struct AtomVecEllipsoidKokkos_PackCommBonus f(atomKK,buf,k_bonus,list,offset); + struct AtomVecEllipsoidKokkos_PackCommBonus f(atomKK,buf,k_bonus,list,offset,vel_flag); Kokkos::parallel_for(n,f); } } @@ -268,14 +280,17 @@ struct AtomVecEllipsoidKokkos_UnpackCommBonus { const typename DAT::tdual_double_2d_lr &buf, const typename DEllipsoidBonusAT::tdual_bonus_1d &bonus, const int& first, - const int& offset): + const int& offset, + const int& vel_flag): _bonus(bonus.view()), _ellipsoid(atomKK->k_ellipsoid.view()), _first(first), _offset(offset) { - const int size_forward = atomKK->avecKK->size_forward; - const size_t maxsend = (buf.view().extent(0)*buf.view().extent(1))/size_forward; - const size_t elements = size_forward; + // must use the same row stride as AtomVecKokkos_UnpackComm(Vel), which + // unpacks the rest of the same buffer + const size_t elements = atomKK->avecKK->size_forward + + (vel_flag ? atomKK->avecKK->size_velocity : 0); + const size_t maxsend = (buf.view().extent(0)*buf.view().extent(1))/elements; buffer_view(_buf,buf,maxsend,elements); } @@ -302,13 +317,13 @@ void AtomVecEllipsoidKokkos::unpack_comm_bonus_kokkos(const int &n, const int &f if (lmp->kokkos->forward_comm_on_host) { atomKK->sync(HostKK,datamask_bonus); struct AtomVecEllipsoidKokkos_UnpackCommBonus f( - atomKK,buf,k_bonus,first,offset); + atomKK,buf,k_bonus,first,offset,vel_flag); Kokkos::parallel_for(n,f); atomKK->modified(HostKK,datamask_bonus); } else { atomKK->sync(Device,datamask_bonus); struct AtomVecEllipsoidKokkos_UnpackCommBonus f( - atomKK,buf,k_bonus,first,offset); + atomKK,buf,k_bonus,first,offset,vel_flag); Kokkos::parallel_for(n,f); atomKK->modified(Device,datamask_bonus); } @@ -454,7 +469,7 @@ struct AtomVecEllipsoidKokkos_PackBorderBonus { typedef DeviceType device_type; typedef ArrayTypes AT; - typename AT::t_double_2d_lr _buf; + typename AT::t_double_2d_lr_um _buf; const typename AT::t_int_1d_const _list; const typename AtomVecEllipsoidKokkosBonusArray::t_bonus_1d_randomread _bonus; const typename AT::t_int_1d_randomread _ellipsoid; @@ -465,11 +480,20 @@ struct AtomVecEllipsoidKokkos_PackBorderBonus { const typename AT::t_double_2d_lr &buf, const typename AtomVecEllipsoidKokkosBonusArray::t_bonus_1d &bonus, const typename AT::t_int_1d_const &list, - const int &offset): - _buf(buf),_list(list), + const int &offset, + const int &vel_flag): + _list(list), _bonus(bonus), _ellipsoid(atomKK->k_ellipsoid.view()), - _offset(offset) {}; + _offset(offset) + { + // must use the same row stride as AtomVecKokkos_PackBorder(Vel), which packs + // the rest of the same buffer; the raw view's extent(1) can be narrower + const size_t elements = atomKK->avecKK->size_border + + (vel_flag ? atomKK->avecKK->size_velocity : 0); + const int maxsend = (buf.extent(0)*buf.extent(1))/elements; + _buf = typename AT::t_double_2d_lr_um(buf.data(),maxsend,elements); + }; KOKKOS_INLINE_FUNCTION void operator() (const int& i) const { @@ -504,11 +528,11 @@ void AtomVecEllipsoidKokkos::pack_border_bonus_kokkos(int n, DAT::tdual_int_1d k if (space == HostKK) { AtomVecEllipsoidKokkos_PackBorderBonus f( - atomKK,buf.view_host(),k_bonus.view_host(),k_sendlist.view_host(),offset); + atomKK,buf.view_host(),k_bonus.view_host(),k_sendlist.view_host(),offset,vel_flag); Kokkos::parallel_for(n,f); } else { AtomVecEllipsoidKokkos_PackBorderBonus f( - atomKK,buf.view_device(),k_bonus.view_device(),k_sendlist.view_device(),offset); + atomKK,buf.view_device(),k_bonus.view_device(),k_sendlist.view_device(),offset,vel_flag); Kokkos::parallel_for(n,f); } } @@ -520,7 +544,7 @@ struct AtomVecEllipsoidKokkos_UnpackBorderBonus { typedef DeviceType device_type; typedef ArrayTypes AT; - typename AT::t_double_2d_lr_const _buf; + typename AT::t_double_2d_lr_const_um _buf; typename AtomVecEllipsoidKokkosBonusArray::t_bonus_1d _bonus; typename AT::t_int_1d _ellipsoid; const int _first; @@ -535,14 +559,23 @@ struct AtomVecEllipsoidKokkos_UnpackBorderBonus { const int& first, const int& offset, const int &nlocal_bonus, - const typename AT::t_int_scalar &nghost_bonus): - _buf(buf), + const typename AT::t_int_scalar &nghost_bonus, + const int &vel_flag): _bonus(bonus), _ellipsoid(atomKK->k_ellipsoid.view()), _first(first), _offset(offset), _nlocal_bonus(nlocal_bonus), - _nghost_bonus(nghost_bonus) {}; + _nghost_bonus(nghost_bonus) + { + // must use the same row stride as AtomVecKokkos_UnpackBorder(Vel), which + // unpacks the rest of the same buffer; the receive buffer is allocated with + // extent(1) = size_border even when ghost velocities widen the packing + const size_t elements = atomKK->avecKK->size_border + + (vel_flag ? atomKK->avecKK->size_velocity : 0); + const int maxsend = (buf.extent(0)*buf.extent(1))/elements; + _buf = typename AT::t_double_2d_lr_const_um(buf.data(),maxsend,elements); + }; KOKKOS_INLINE_FUNCTION void operator() (const int& i) const { @@ -584,7 +617,7 @@ void AtomVecEllipsoidKokkos::unpack_border_bonus_kokkos(const int &n, const int k_nghost_bonus.view_host()() = nghost_bonus; struct AtomVecEllipsoidKokkos_UnpackBorderBonus f( atomKK,buf.view_host(),k_bonus.view_host(),first,offset, - this->nlocal_bonus,k_nghost_bonus.view_host()); + this->nlocal_bonus,k_nghost_bonus.view_host(),vel_flag); Kokkos::parallel_for(n,f); } else { k_nghost_bonus.view_host()() = nghost_bonus; @@ -592,7 +625,7 @@ void AtomVecEllipsoidKokkos::unpack_border_bonus_kokkos(const int &n, const int k_nghost_bonus.sync_device(); struct AtomVecEllipsoidKokkos_UnpackBorderBonus f( atomKK,buf.view_device(),k_bonus.view_device(),first,offset, - this->nlocal_bonus, k_nghost_bonus.view_device()); + this->nlocal_bonus, k_nghost_bonus.view_device(),vel_flag); Kokkos::parallel_for(n,f); k_nghost_bonus.modify_device(); k_nghost_bonus.sync_host(); @@ -723,7 +756,7 @@ struct AtomVecEllipsoidKokkos_BackfillEllipsoid { void operator() (const int &mysend) const { const int i = _sendlist(mysend); - // if atom J has bonus data, reset J’s bonus.ilocal to loc I + // if atom J has bonus data, reset J's bonus.ilocal to loc I int j = _copylist(mysend); if (j > -1) { diff --git a/src/KOKKOS/min_cg_kokkos.cpp b/src/KOKKOS/min_cg_kokkos.cpp index 69fb29c5b7e..35f9be631ae 100644 --- a/src/KOKKOS/min_cg_kokkos.cpp +++ b/src/KOKKOS/min_cg_kokkos.cpp @@ -116,6 +116,12 @@ int MinCGKokkos::iterate(int maxiter) // force tolerance criterion + // a force style without a KOKKOS variant leaves the device copy stale, + // and energy_force() only pushes it back for newton on or a min_post_force + // fix, so the force array has to be claimed here before it is read + + atomKK->sync(Device,F_MASK); + s_KK_double2 sdot; { // local variables for lambda capture @@ -125,20 +131,20 @@ int MinCGKokkos::iterate(int maxiter) if constexpr (F_LAYOUTRIGHT) { auto l_fvec = fvec; Kokkos::parallel_reduce(nvec, LAMMPS_LAMBDA(const int& i, s_KK_double2& sdot) { - sdot.d0 += static_cast(l_fvec[i]*l_fvec[i]); - sdot.d1 += static_cast(l_fvec[i])*l_g[i]; + sdot.d0 += static_cast(l_fvec[i])*static_cast(l_fvec[i]); + sdot.d1 += static_cast(l_fvec[i])*static_cast(l_g[i]); },sdot); } else { auto l_f = atomKK->k_f.view_device(); Kokkos::parallel_reduce(atom->nlocal, LAMMPS_LAMBDA(const int& i, s_KK_double2& sdot) { - sdot.d0 += static_cast(l_f(i,0)*l_f(i,0)); - sdot.d0 += static_cast(l_f(i,1)*l_f(i,1)); - sdot.d0 += static_cast(l_f(i,2)*l_f(i,2)); + sdot.d0 += static_cast(l_f(i,0))*static_cast(l_f(i,0)); + sdot.d0 += static_cast(l_f(i,1))*static_cast(l_f(i,1)); + sdot.d0 += static_cast(l_f(i,2))*static_cast(l_f(i,2)); const int j = i*3; - sdot.d1 += static_cast(l_f(i,0))*l_g[j]; - sdot.d1 += static_cast(l_f(i,1))*l_g[j+1]; - sdot.d1 += static_cast(l_f(i,2))*l_g[j+2]; + sdot.d1 += static_cast(l_f(i,0))*static_cast(l_g[j]); + sdot.d1 += static_cast(l_f(i,1))*static_cast(l_g[j+1]); + sdot.d1 += static_cast(l_f(i,2))*static_cast(l_g[j+2]); },sdot); } } diff --git a/src/KOKKOS/modify_kokkos.h b/src/KOKKOS/modify_kokkos.h index 527518219c1..7d0bebf2a83 100644 --- a/src/KOKKOS/modify_kokkos.h +++ b/src/KOKKOS/modify_kokkos.h @@ -31,7 +31,6 @@ class ModifyKokkos : public Modify { void setup_pre_reverse(int, int) override; void initial_integrate(int) override; void post_integrate() override; - void pre_decide(); void pre_exchange() override; void pre_neighbor() override; void post_neighbor() override; diff --git a/src/KOKKOS/pair_bondval_kokkos.cpp b/src/KOKKOS/pair_bondval_kokkos.cpp index 7fb1a363519..7051622a9da 100644 --- a/src/KOKKOS/pair_bondval_kokkos.cpp +++ b/src/KOKKOS/pair_bondval_kokkos.cpp @@ -332,19 +332,6 @@ void PairBondValKokkos::allocate() } -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -template -void PairBondValKokkos::settings(int narg, char **arg) -{ - if (narg > 3) error->all(FLERR,"Illegal pair_style command"); - - PairBondVal::settings(2,arg); -} - - /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_bondval_kokkos.h b/src/KOKKOS/pair_bondval_kokkos.h index 050cd8c3042..702a4f92687 100644 --- a/src/KOKKOS/pair_bondval_kokkos.h +++ b/src/KOKKOS/pair_bondval_kokkos.h @@ -59,7 +59,6 @@ class PairBondValKokkos : public PairBondVal, public KokkosBase { ~PairBondValKokkos() override; void compute(int, int) override; void allocate() override; - void settings(int, char **) override; void init_style() override; double init_one(int, int) override; diff --git a/src/KOKKOS/pair_bondval_vec_kokkos.cpp b/src/KOKKOS/pair_bondval_vec_kokkos.cpp index 03694480862..95ed4c02f49 100644 --- a/src/KOKKOS/pair_bondval_vec_kokkos.cpp +++ b/src/KOKKOS/pair_bondval_vec_kokkos.cpp @@ -330,18 +330,6 @@ void PairBondValVecKokkos::allocate() params = k_params.template view(); } -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -template -void PairBondValVecKokkos::settings(int narg, char **arg) -{ - if (narg > 3) error->all(FLERR,"Illegal pair_style command"); - - PairBondValVec::settings(2,arg); -} - /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ @@ -598,11 +586,9 @@ void PairBondValVecKokkos::operator()(TagPairBondValVecKernelB(2.0)*s0x_kk*s; d_Di(i,1) = (params(itype,itype).bvvsparam)*power_global_kk*static_cast(2.0)*s0y_kk*s; d_Di(i,2) = (params(itype,itype).bvvsparam)*power_global_kk*static_cast(2.0)*s0z_kk*s; - //printf("i: %d, d_Di(i,0): %f, d_Di(i,1): %f, d_Di(i,2): %f\n", i, d_Di(i,0), d_Di(i,1), d_Di(i,2)); if (EFLAG) { KK_FLOAT phi = (params(itype,itype).bvvsparam)*ss; - //printf("i: %d, phi: %f", i, phi); if (eflag_global) ev.evdwl += static_cast(phi); if (eflag_atom) d_eatom[i] += static_cast(phi); } diff --git a/src/KOKKOS/pair_bondval_vec_kokkos.h b/src/KOKKOS/pair_bondval_vec_kokkos.h index d5eba32251e..90deb4e017f 100644 --- a/src/KOKKOS/pair_bondval_vec_kokkos.h +++ b/src/KOKKOS/pair_bondval_vec_kokkos.h @@ -61,7 +61,6 @@ class PairBondValVecKokkos : public PairBondValVec, public KokkosBase { ~PairBondValVecKokkos() override; void compute(int, int) override; void allocate() override; - void settings(int, char **) override; void init_style() override; double init_one(int, int) override; diff --git a/src/KOKKOS/pair_brownian_kokkos.cpp b/src/KOKKOS/pair_brownian_kokkos.cpp index 07c435c2f9a..71db6cf7071 100644 --- a/src/KOKKOS/pair_brownian_kokkos.cpp +++ b/src/KOKKOS/pair_brownian_kokkos.cpp @@ -46,8 +46,7 @@ enum { EDGE, CONSTANT, VARIABLE }; /* ---------------------------------------------------------------------- */ template -PairBrownianKokkos::PairBrownianKokkos(LAMMPS *lmp) : PairBrownian(lmp), - rand_pool(seed + comm->me) +PairBrownianKokkos::PairBrownianKokkos(LAMMPS *lmp) : PairBrownian(lmp) { respa_enable = 0; @@ -91,14 +90,29 @@ void PairBrownianKokkos::init_style() error->all(FLERR,"Cannot use Kokkos pair style with rRESPA inner/middle"); } + // the random number seed is only known after settings() has run, so the + // pool cannot be created in the constructor + + typedef Kokkos::Experimental::UniqueToken< + DeviceType, Kokkos::Experimental::UniqueTokenScope::Global> unique_token_type; + unique_token_type unique_token; + rand_pool = decltype(rand_pool)(seed + comm->me,unique_token.size()); + // adjust neighbor list request for KOKKOS neighflag = lmp->kokkos->neighflag; + + // a full neighbor list would visit each pair twice and draw independent + // random numbers each time, so the stochastic pair force would no longer + // be equal and opposite + + if (neighflag == FULL) + error->all(FLERR,"Must use half neighbor list style with pair style brownian/kk"); + 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(); } /* ---------------------------------------------------------------------- */ @@ -160,6 +174,15 @@ void PairBrownianKokkos::compute(int eflag_in, int vflag_in) prethermostat *= static_cast(sqrt(force->vxmu2f / force->ftm2v / force->mvv2e)); // reallocate per-atom arrays if necessary + // this style has no per-atom energy, but eatom must exist and be zeroed + // because ev_init() above was called with alloc == 0 + + if (eflag_atom) { + maxeatom = atom->nmax; + memory->destroy(eatom); + memory->create(eatom,maxeatom,"pair:eatom"); + memset(&eatom[0], 0, maxeatom * sizeof(double)); + } if (vflag_atom) { memoryKK->destroy_kokkos(k_vatom,vatom); diff --git a/src/KOKKOS/pair_dpd_tstat_kokkos.cpp b/src/KOKKOS/pair_dpd_tstat_kokkos.cpp index 9c92724cae8..6c736ebb846 100644 --- a/src/KOKKOS/pair_dpd_tstat_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_tstat_kokkos.cpp @@ -122,6 +122,9 @@ void PairDPDTstatKokkos::compute(int eflagin, int vflagin) } k_params.modify_host(); + // this style has no per-atom energy, but eatom must exist and be zeroed + // because ev_init() above was called with alloc == 0 + if (eflag_atom) { maxeatom = atom->nmax; memory->destroy(eatom); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 027fcd0a101..840c8e8a4c6 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -1687,6 +1687,23 @@ void PairExp6rxKokkos::coeff(int narg, char **arg) d_params = k_params.template view(); } +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairExp6rxKokkos::init_one(int i, int j) +{ + double cutone = PairExp6rx::init_one(i,j); + + // Pair::init() writes cutsq[i][j] on the host after each init_one() call, + // so the host side of the shared k_cutsq view must be flagged as modified + + k_cutsq.modify_host(); + + return cutone; +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 3e38f8c8825..233ea8ba2e2 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -92,6 +92,7 @@ class PairExp6rxKokkos : public PairExp6rx { void compute(int, int) override; void coeff(int, char **) override; void init_style() override; + double init_one(int, int) override; // NOLINTNEXTLINE KOKKOS_INLINE_FUNCTION diff --git a/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.cpp b/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.cpp index 975eecbfe81..e8d691a7adb 100644 --- a/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.cpp @@ -94,6 +94,7 @@ void PairLJSwitch3CoulGaussLongKokkos::compute(int eflag_in, int vfl atomKK->sync(execution_space,datamask_read); k_cutsq.template sync(); k_cut_ljsq.template sync(); + k_cut_coulsq.template sync(); k_params.template sync(); if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); else atomKK->modified(execution_space,F_MASK); @@ -116,6 +117,7 @@ void PairLJSwitch3CoulGaussLongKokkos::compute(int eflag_in, int vfl qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; g_ewald_kk = static_cast(g_ewald); + cut_coulsq_kk = static_cast(cut_coulsq); truncw_kk = static_cast(truncw); truncwi_kk = static_cast(truncwi); @@ -207,18 +209,25 @@ compute_fcoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT r2inv = static_cast(1.0) / rsq; const KK_FLOAT rinv = static_cast(1.0) / r; - const KK_FLOAT grij = g_ewald_kk * r; - const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); - const KK_FLOAT t = static_cast(1.0) / - (static_cast(1.0) + static_cast(EWALD_P)*grij); - const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ - t * (static_cast(A3)+t*(static_cast(A4)+ - t * static_cast(A5))))) * expm2; - const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; // Ewald Coulomb force - KK_FLOAT forcecoul = prefactor * (erfc1 + static_cast(EWALD_F)*grij*expm2); - if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + // this function is called out to the LJ cutoff for the sake of the Gaussian + // correction below, so the Ewald part needs its own Coulomb cutoff test + + KK_FLOAT forcecoul = static_cast(0.0); + if (rsq < cut_coulsq_kk) { + const KK_FLOAT grij = g_ewald_kk * r; + const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); + const KK_FLOAT t = static_cast(1.0) / + (static_cast(1.0) + static_cast(EWALD_P)*grij); + const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ + t * (static_cast(A3)+t*(static_cast(A4)+ + t * static_cast(A5))))) * expm2; + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; + + forcecoul = prefactor * (erfc1 + static_cast(EWALD_F)*grij*expm2); + if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + } // Gaussian correction (only within VdW cutoff) const KK_FLOAT cut_ljsq_val = STACKPARAMS ? m_params[itype][jtype].cut_ljsq : params(itype,jtype).cut_ljsq; @@ -283,17 +292,23 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, { const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT rinv = static_cast(1.0) / r; - const KK_FLOAT grij = g_ewald_kk * r; - const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); - const KK_FLOAT t = static_cast(1.0) / - (static_cast(1.0) + static_cast(EWALD_P)*grij); - const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ - t * (static_cast(A3)+t*(static_cast(A4)+ - t * static_cast(A5))))) * expm2; - const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; - - KK_FLOAT ecoul = prefactor * erfc1; - if (factor_coul < static_cast(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + + // as in compute_fcoul(), the Ewald part carries its own Coulomb cutoff test + + KK_FLOAT ecoul = static_cast(0.0); + if (rsq < cut_coulsq_kk) { + const KK_FLOAT grij = g_ewald_kk * r; + const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); + const KK_FLOAT t = static_cast(1.0) / + (static_cast(1.0) + static_cast(EWALD_P)*grij); + const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ + t * (static_cast(A3)+t*(static_cast(A4)+ + t * static_cast(A5))))) * expm2; + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; + + ecoul = prefactor * erfc1; + if (factor_coul < static_cast(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + } // Gaussian correction (only within VdW cutoff) const KK_FLOAT cut_ljsq_val = STACKPARAMS ? m_params[itype][jtype].cut_ljsq : params(itype,jtype).cut_ljsq; @@ -327,7 +342,8 @@ void PairLJSwitch3CoulGaussLongKokkos::allocate() memoryKK->create_kokkos(k_cut_ljsq,cut_ljsq,n+1,n+1,"pair:cut_ljsq"); d_cut_ljsq = k_cut_ljsq.template view(); - d_cut_coulsq = typename AT::t_kkfloat_2d("pair:cut_coulsq",n+1,n+1); + k_cut_coulsq = DAT::tdual_kkfloat_2d("pair:cut_coulsq",n+1,n+1); + d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView( "PairLJSwitch3CoulGaussLong::params",n+1,n+1); @@ -343,8 +359,6 @@ void PairLJSwitch3CoulGaussLongKokkos::init_style() { PairLJSwitch3CoulGaussLong::init_style(); - Kokkos::deep_copy(d_cut_coulsq,static_cast(cut_coulsq)); - if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) { int respa = 0; if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; @@ -371,26 +385,35 @@ double PairLJSwitch3CoulGaussLongKokkos::init_one(int i, int j) double cutone = PairLJSwitch3CoulGaussLong::init_one(i,j); double cut_ljsqm = cut_ljsq[i][j]; + // the Gaussian charge correction is evaluated in compute_fcoul() and + // compute_ecoul(), which pair_kokkos only calls within this bound, while + // the CPU style applies the correction out to the LJ cutoff + + double cut_coulsqm = MAX(cut_coulsq,cut_ljsqm); + k_params.view_host()(i,j).lj2 = static_cast(lj2[i][j]); k_params.view_host()(i,j).lj3 = static_cast(lj3[i][j]); k_params.view_host()(i,j).lj4 = static_cast(lj4[i][j]); k_params.view_host()(i,j).offset = static_cast(offset[i][j]); k_params.view_host()(i,j).cut_lj = static_cast(cut_lj[i][j]); k_params.view_host()(i,j).cut_ljsq = static_cast(cut_ljsqm); - k_params.view_host()(i,j).cut_coulsq = static_cast(cut_coulsq); + k_params.view_host()(i,j).cut_coulsq = static_cast(cut_coulsqm); k_params.view_host()(j,i) = k_params.view_host()(i,j); if (i(cutone*cutone); m_cut_ljsq[j][i] = m_cut_ljsq[i][j] = static_cast(cut_ljsqm); - m_cut_coulsq[j][i] = m_cut_coulsq[i][j] = static_cast(cut_coulsq); + m_cut_coulsq[j][i] = m_cut_coulsq[i][j] = static_cast(cut_coulsqm); } k_cutsq.view_host()(i,j) = k_cutsq.view_host()(j,i) = cutone*cutone; k_cutsq.modify_host(); k_cut_ljsq.view_host()(i,j) = k_cut_ljsq.view_host()(j,i) = cut_ljsqm; k_cut_ljsq.modify_host(); + k_cut_coulsq.view_host()(i,j) = k_cut_coulsq.view_host()(j,i) = + static_cast(cut_coulsqm); + k_cut_coulsq.modify_host(); k_params.modify_host(); return cutone; diff --git a/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.h b/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.h index bd8b7512dab..18cde5a9a9f 100644 --- a/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.h +++ b/src/KOKKOS/pair_lj_switch3_coulgauss_long_kokkos.h @@ -107,6 +107,11 @@ class PairLJSwitch3CoulGaussLongKokkos : public PairLJSwitch3CoulGaussLong { typename AT::t_kkfloat_2d d_cutsq; DAT::ttransform_kkfloat_2d k_cut_ljsq; typename AT::t_kkfloat_2d d_cut_ljsq; + // the Coulomb hooks of pair_kokkos are gated by this bound, which is + // widened to the LJ cutoff so the Gaussian charge correction reaches as + // far as it does in the CPU style; cut_coulsq_kk still cuts the Ewald part + + DAT::tdual_kkfloat_2d k_cut_coulsq; typename AT::t_kkfloat_2d d_cut_coulsq; int neighflag; @@ -116,6 +121,7 @@ class PairLJSwitch3CoulGaussLongKokkos : public PairLJSwitch3CoulGaussLong { KK_FLOAT special_lj[4]; KK_FLOAT qqrd2e; KK_FLOAT g_ewald_kk; + KK_FLOAT cut_coulsq_kk; KK_FLOAT truncw_kk; KK_FLOAT truncwi_kk; diff --git a/src/KOKKOS/pair_mliap_kokkos.cpp b/src/KOKKOS/pair_mliap_kokkos.cpp index cf8dc7d69a1..3937cf65a10 100644 --- a/src/KOKKOS/pair_mliap_kokkos.cpp +++ b/src/KOKKOS/pair_mliap_kokkos.cpp @@ -97,9 +97,9 @@ void PairMLIAPKokkos::compute(int eflag, int vflag) } if (vflag_atom) { - if ((int)k_vatom.view_host().extent(0) < maxeatom) { + if ((int)k_vatom.view_host().extent(0) < maxvatom) { memoryKK->destroy_kokkos(k_vatom,vatom); - memoryKK->create_kokkos(k_vatom,vatom,maxeatom,6,"pair:eatom"); + memoryKK->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); } else { Kokkos::deep_copy(k_vatom.template view(),0); k_vatom.modify(); diff --git a/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.cpp b/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.cpp index fc12e1fecc0..5946c105780 100644 --- a/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.cpp +++ b/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.cpp @@ -94,6 +94,7 @@ void PairMM3Switch3CoulGaussLongKokkos::compute(int eflag_in, int vf atomKK->sync(execution_space,datamask_read); k_cutsq.template sync(); k_cut_ljsq.template sync(); + k_cut_coulsq.template sync(); k_params.template sync(); if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); else atomKK->modified(execution_space,F_MASK); @@ -116,6 +117,7 @@ void PairMM3Switch3CoulGaussLongKokkos::compute(int eflag_in, int vf qqrd2e = static_cast(force->qqrd2e); newton_pair = force->newton_pair; g_ewald_kk = static_cast(g_ewald); + cut_coulsq_kk = static_cast(cut_coulsq); truncw_kk = static_cast(truncw); truncwi_kk = static_cast(truncwi); @@ -209,18 +211,25 @@ compute_fcoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT r2inv = static_cast(1.0) / rsq; const KK_FLOAT rinv = static_cast(1.0) / r; - const KK_FLOAT grij = g_ewald_kk * r; - const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); - const KK_FLOAT t = static_cast(1.0) / - (static_cast(1.0) + static_cast(EWALD_P)*grij); - const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ - t * (static_cast(A3)+t*(static_cast(A4)+ - t * static_cast(A5))))) * expm2; - const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; // Ewald Coulomb force - KK_FLOAT forcecoul = prefactor * (erfc1 + static_cast(EWALD_F)*grij*expm2); - if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + // this function is called out to the LJ cutoff for the sake of the Gaussian + // correction below, so the Ewald part needs its own Coulomb cutoff test + + KK_FLOAT forcecoul = static_cast(0.0); + if (rsq < cut_coulsq_kk) { + const KK_FLOAT grij = g_ewald_kk * r; + const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); + const KK_FLOAT t = static_cast(1.0) / + (static_cast(1.0) + static_cast(EWALD_P)*grij); + const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ + t * (static_cast(A3)+t*(static_cast(A4)+ + t * static_cast(A5))))) * expm2; + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; + + forcecoul = prefactor * (erfc1 + static_cast(EWALD_F)*grij*expm2); + if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + } // Gaussian correction (only within VdW cutoff) const KK_FLOAT cut_ljsq_val = STACKPARAMS ? m_params[itype][jtype].cut_ljsq : params(itype,jtype).cut_ljsq; @@ -287,17 +296,23 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, { const KK_FLOAT r = Kokkos::sqrt(rsq); const KK_FLOAT rinv = static_cast(1.0) / r; - const KK_FLOAT grij = g_ewald_kk * r; - const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); - const KK_FLOAT t = static_cast(1.0) / - (static_cast(1.0) + static_cast(EWALD_P)*grij); - const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ - t * (static_cast(A3)+t*(static_cast(A4)+ - t * static_cast(A5))))) * expm2; - const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; - - KK_FLOAT ecoul = prefactor * erfc1; - if (factor_coul < static_cast(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + + // as in compute_fcoul(), the Ewald part carries its own Coulomb cutoff test + + KK_FLOAT ecoul = static_cast(0.0); + if (rsq < cut_coulsq_kk) { + const KK_FLOAT grij = g_ewald_kk * r; + const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); + const KK_FLOAT t = static_cast(1.0) / + (static_cast(1.0) + static_cast(EWALD_P)*grij); + const KK_FLOAT erfc1 = t * (static_cast(A1)+t*(static_cast(A2)+ + t * (static_cast(A3)+t*(static_cast(A4)+ + t * static_cast(A5))))) * expm2; + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; + + ecoul = prefactor * erfc1; + if (factor_coul < static_cast(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + } // Gaussian correction (only within VdW cutoff) const KK_FLOAT cut_ljsq_val = STACKPARAMS ? m_params[itype][jtype].cut_ljsq : params(itype,jtype).cut_ljsq; @@ -331,7 +346,8 @@ void PairMM3Switch3CoulGaussLongKokkos::allocate() memoryKK->create_kokkos(k_cut_ljsq,cut_ljsq,n+1,n+1,"pair:cut_ljsq"); d_cut_ljsq = k_cut_ljsq.template view(); - d_cut_coulsq = typename AT::t_kkfloat_2d("pair:cut_coulsq",n+1,n+1); + k_cut_coulsq = DAT::tdual_kkfloat_2d("pair:cut_coulsq",n+1,n+1); + d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView( "PairMM3Switch3CoulGaussLong::params",n+1,n+1); @@ -347,8 +363,6 @@ void PairMM3Switch3CoulGaussLongKokkos::init_style() { PairMM3Switch3CoulGaussLong::init_style(); - Kokkos::deep_copy(d_cut_coulsq,static_cast(cut_coulsq)); - if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) { int respa = 0; if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; @@ -375,6 +389,12 @@ double PairMM3Switch3CoulGaussLongKokkos::init_one(int i, int j) double cutone = PairMM3Switch3CoulGaussLong::init_one(i,j); double cut_ljsqm = cut_ljsq[i][j]; + // the Gaussian charge correction is evaluated in compute_fcoul() and + // compute_ecoul(), which pair_kokkos only calls within this bound, while + // the CPU style applies the correction out to the LJ cutoff + + double cut_coulsqm = MAX(cut_coulsq,cut_ljsqm); + k_params.view_host()(i,j).lj1 = static_cast(lj1[i][j]); k_params.view_host()(i,j).lj2 = static_cast(lj2[i][j]); k_params.view_host()(i,j).lj3 = static_cast(lj3[i][j]); @@ -382,20 +402,23 @@ double PairMM3Switch3CoulGaussLongKokkos::init_one(int i, int j) k_params.view_host()(i,j).offset = static_cast(offset[i][j]); k_params.view_host()(i,j).cut_lj = static_cast(cut_lj[i][j]); k_params.view_host()(i,j).cut_ljsq = static_cast(cut_ljsqm); - k_params.view_host()(i,j).cut_coulsq = static_cast(cut_coulsq); + k_params.view_host()(i,j).cut_coulsq = static_cast(cut_coulsqm); k_params.view_host()(j,i) = k_params.view_host()(i,j); if (i(cutone*cutone); m_cut_ljsq[j][i] = m_cut_ljsq[i][j] = static_cast(cut_ljsqm); - m_cut_coulsq[j][i] = m_cut_coulsq[i][j] = static_cast(cut_coulsq); + m_cut_coulsq[j][i] = m_cut_coulsq[i][j] = static_cast(cut_coulsqm); } k_cutsq.view_host()(i,j) = k_cutsq.view_host()(j,i) = cutone*cutone; k_cutsq.modify_host(); k_cut_ljsq.view_host()(i,j) = k_cut_ljsq.view_host()(j,i) = cut_ljsqm; k_cut_ljsq.modify_host(); + k_cut_coulsq.view_host()(i,j) = k_cut_coulsq.view_host()(j,i) = + static_cast(cut_coulsqm); + k_cut_coulsq.modify_host(); k_params.modify_host(); return cutone; diff --git a/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.h b/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.h index 6aa6ad4703a..7fdcd3e781e 100644 --- a/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.h +++ b/src/KOKKOS/pair_mm3_switch3_coulgauss_long_kokkos.h @@ -107,6 +107,11 @@ class PairMM3Switch3CoulGaussLongKokkos : public PairMM3Switch3CoulGaussLong { typename AT::t_kkfloat_2d d_cutsq; DAT::ttransform_kkfloat_2d k_cut_ljsq; typename AT::t_kkfloat_2d d_cut_ljsq; + // the Coulomb hooks of pair_kokkos are gated by this bound, which is + // widened to the LJ cutoff so the Gaussian charge correction reaches as + // far as it does in the CPU style; cut_coulsq_kk still cuts the Ewald part + + DAT::tdual_kkfloat_2d k_cut_coulsq; typename AT::t_kkfloat_2d d_cut_coulsq; int neighflag; @@ -116,6 +121,7 @@ class PairMM3Switch3CoulGaussLongKokkos : public PairMM3Switch3CoulGaussLong { KK_FLOAT special_lj[4]; KK_FLOAT qqrd2e; KK_FLOAT g_ewald_kk; + KK_FLOAT cut_coulsq_kk; KK_FLOAT truncw_kk; KK_FLOAT truncwi_kk; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 8d38bcee7b1..f62295f2956 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -97,6 +97,11 @@ template void PairMultiLucyRXKokkos::coeff(int narg, char **arg) { PairMultiLucyRX::coeff(narg, arg); + // a pair_coeff after the first run adds a table on the host only, + // so force the device side tables to be rebuilt in the next compute() + + update_table = 1; + // rx_fix is initialized in PairMultiLucyRX::coeff(). rx_fixKK = dynamic_cast *>(rx_fix); if (!rx_fixKK) @@ -121,6 +126,23 @@ void PairMultiLucyRXKokkos::init_style() if (neighflag == FULL) request->enable_full(); } +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairMultiLucyRXKokkos::init_one(int i, int j) +{ + double cutone = PairMultiLucyRX::init_one(i,j); + + // Pair::init() refills the host side cutsq on every run setup, and the host + // view of k_cutsq aliases it, so the device copy has to be refreshed too + + k_cutsq.modify_host(); + + return cutone; +} + /* ---------------------------------------------------------------------- */ template @@ -437,9 +459,12 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute(1.0):static_cast(0.5))*static_cast(evdwl); + ev.evdwl += static_cast(evdwl); } template diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index 8ee9a57477f..330d5b491d5 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -63,6 +63,7 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX, public KokkosBase { void compute_style(int, int); void init_style() override; + double init_one(int, int) override; int pack_forward_comm_kokkos(int, DAT::tdual_int_1d, DAT::tdual_double_1d&, int, int *) override; void unpack_forward_comm_kokkos(int, int, DAT::tdual_double_1d&) override; diff --git a/src/KOKKOS/pair_nm_cut_coul_long_kokkos.cpp b/src/KOKKOS/pair_nm_cut_coul_long_kokkos.cpp index b9c8ab50a1e..e95c8fafbf7 100644 --- a/src/KOKKOS/pair_nm_cut_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_nm_cut_coul_long_kokkos.cpp @@ -121,8 +121,12 @@ void PairNMCutCoulLongKokkos::compute(int eflag_in, int vflag_in) copymode = 1; - ev = pair_compute,void> - (this,(NeighListKokkos*)list); + if (ncoultablebits) + ev = pair_compute,CoulLongTable<1>> + (this,(NeighListKokkos*)list); + else + ev = pair_compute,CoulLongTable<0>> + (this,(NeighListKokkos*)list); if (eflag) { eng_vdwl += static_cast(ev.evdwl); @@ -192,19 +196,34 @@ compute_fcoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, const int& /*itype*/, const int& /*jtype*/, const KK_FLOAT& factor_coul, const KK_FLOAT& qtmp) const { - const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT grij = g_ewald_kk * r; - const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); - const KK_FLOAT t = static_cast(1.0) / - (static_cast(1.0) + static_cast(EWALD_P)*grij); - const KK_FLOAT rinv = static_cast(1.0) / r; - const KK_FLOAT erfc = t * (static_cast(A1)+t*(static_cast(A2)+ - t * (static_cast(A3)+t*(static_cast(A4)+ - t * static_cast(A5))))) * expm2; - const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; - KK_FLOAT forcecoul = prefactor * (erfc + static_cast(EWALD_F)*grij*expm2); - if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; - return forcecoul * rinv * rinv; + if (Specialisation::DoTable && rsq > tabinnersq_kk) { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + const int itable = (rsq_lookup.i & ncoulmask) >> ncoulshiftbits; + const KK_FLOAT fraction = ((KK_FLOAT)rsq_lookup.f - d_rtable[itable]) * d_drtable[itable]; + const KK_FLOAT table = d_ftable[itable] + fraction*d_dftable[itable]; + KK_FLOAT forcecoul = qtmp*q(j) * table; + if (factor_coul < static_cast(1.0)) { + const KK_FLOAT table = d_ctable[itable] + fraction*d_dctable[itable]; + const KK_FLOAT prefactor = qtmp*q(j) * table; + forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + } + return forcecoul/rsq; + } else { + const KK_FLOAT r = Kokkos::sqrt(rsq); + const KK_FLOAT grij = g_ewald_kk * r; + const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); + const KK_FLOAT t = static_cast(1.0) / + (static_cast(1.0) + static_cast(EWALD_P)*grij); + const KK_FLOAT rinv = static_cast(1.0) / r; + const KK_FLOAT erfc = t * (static_cast(A1)+t*(static_cast(A2)+ + t * (static_cast(A3)+t*(static_cast(A4)+ + t * static_cast(A5))))) * expm2; + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) * rinv; + KK_FLOAT forcecoul = prefactor * (erfc + static_cast(EWALD_F)*grij*expm2); + if (factor_coul < static_cast(1.0)) forcecoul -= (static_cast(1.0)-factor_coul)*prefactor; + return forcecoul * rinv * rinv; + } } /* ---------------------------------------------------------------------- @@ -245,18 +264,33 @@ compute_ecoul(const KK_FLOAT& rsq, const int& /*i*/, const int& j, const int& /*itype*/, const int& /*jtype*/, const KK_FLOAT& factor_coul, const KK_FLOAT& qtmp) const { - const KK_FLOAT r = Kokkos::sqrt(rsq); - const KK_FLOAT grij = g_ewald_kk * r; - const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); - const KK_FLOAT t = static_cast(1.0) / - (static_cast(1.0) + static_cast(EWALD_P)*grij); - const KK_FLOAT erfc = t * (static_cast(A1)+t*(static_cast(A2)+ - t * (static_cast(A3)+t*(static_cast(A4)+ - t * static_cast(A5))))) * expm2; - const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) / r; - KK_FLOAT ecoul = prefactor * erfc; - if (factor_coul < static_cast(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; - return ecoul; + if (Specialisation::DoTable && rsq > tabinnersq_kk) { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + const int itable = (rsq_lookup.i & ncoulmask) >> ncoulshiftbits; + const KK_FLOAT fraction = ((KK_FLOAT)rsq_lookup.f - d_rtable[itable]) * d_drtable[itable]; + const KK_FLOAT table = d_etable[itable] + fraction*d_detable[itable]; + KK_FLOAT ecoul = qtmp*q(j) * table; + if (factor_coul < static_cast(1.0)) { + const KK_FLOAT table = d_ctable[itable] + fraction*d_dctable[itable]; + const KK_FLOAT prefactor = qtmp*q(j) * table; + ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + } + return ecoul; + } else { + const KK_FLOAT r = Kokkos::sqrt(rsq); + const KK_FLOAT grij = g_ewald_kk * r; + const KK_FLOAT expm2 = Kokkos::exp(-grij*grij); + const KK_FLOAT t = static_cast(1.0) / + (static_cast(1.0) + static_cast(EWALD_P)*grij); + const KK_FLOAT erfc = t * (static_cast(A1)+t*(static_cast(A2)+ + t * (static_cast(A3)+t*(static_cast(A4)+ + t * static_cast(A5))))) * expm2; + const KK_FLOAT prefactor = qqrd2e * qtmp * q(j) / r; + KK_FLOAT ecoul = prefactor * erfc; + if (factor_coul < static_cast(1.0)) ecoul -= (static_cast(1.0)-factor_coul)*prefactor; + return ecoul; + } } /* ---------------------------------------------------------------------- @@ -285,6 +319,38 @@ void PairNMCutCoulLongKokkos::allocate() params = k_params.template view(); } +/* ---------------------------------------------------------------------- + copy the tabulated Coulomb interpolation tables to the device +------------------------------------------------------------------------- */ + +template +void PairNMCutCoulLongKokkos::init_tables(double cut_coul, double *cut_respa) +{ + Pair::init_tables(cut_coul,cut_respa); + + typedef typename AT::t_kkfloat_1d table_type; + typedef HAT::t_kkfloat_1d host_table_type; + + int ntable = 1; + for (int i = 0; i < ncoultablebits; i++) ntable *= 2; + + tabinnersq_kk = static_cast(tabinnersq); + + const double *const h_src[8] = {rtable,drtable,ftable,dftable, + ctable,dctable,etable,detable}; + typename AT::t_kkfloat_1d_randomread *const d_dst[8] = + {&d_rtable,&d_drtable,&d_ftable,&d_dftable, + &d_ctable,&d_dctable,&d_etable,&d_detable}; + + for (int n = 0; n < 8; n++) { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + for (int i = 0; i < ntable; i++) h_table(i) = static_cast(h_src[n][i]); + Kokkos::deep_copy(d_table,h_table); + *d_dst[n] = d_table; + } +} + /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_nm_cut_coul_long_kokkos.h b/src/KOKKOS/pair_nm_cut_coul_long_kokkos.h index 959a1abfe10..07c7c9e9b46 100644 --- a/src/KOKKOS/pair_nm_cut_coul_long_kokkos.h +++ b/src/KOKKOS/pair_nm_cut_coul_long_kokkos.h @@ -42,6 +42,7 @@ class PairNMCutCoulLongKokkos : public PairNMCutCoulLong { void compute(int, int) override; void init_style() override; double init_one(int, int) override; + void init_tables(double cut_coul, double *cut_respa) override; struct params_nm_coul { // NOLINTNEXTLINE @@ -107,6 +108,10 @@ class PairNMCutCoulLongKokkos : public PairNMCutCoulLong { typename AT::t_kkfloat_2d d_cut_ljsq; typename AT::t_kkfloat_2d d_cut_coulsq; + typename AT::t_kkfloat_1d_randomread + d_rtable, d_drtable, d_ftable, d_dftable, + d_ctable, d_dctable, d_etable, d_detable; + int neighflag; int nlocal,nall,eflag,vflag; @@ -114,21 +119,36 @@ class PairNMCutCoulLongKokkos : public PairNMCutCoulLong { KK_FLOAT special_lj[4]; KK_FLOAT qqrd2e; KK_FLOAT g_ewald_kk; + KK_FLOAT tabinnersq_kk; 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(PairNMCutCoulLongKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_neighlist(PairNMCutCoulLongKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_neighlist(PairNMCutCoulLongKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_neighlist(PairNMCutCoulLongKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute(PairNMCutCoulLongKokkos*, + 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>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute>(PairNMCutCoulLongKokkos*, + NeighListKokkos*); + 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>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairNMCutCoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute>(PairNMCutCoulLongKokkos*, NeighListKokkos*); friend void pair_virial_fdotr_compute(PairNMCutCoulLongKokkos*); }; diff --git a/src/KOKKOS/pair_pace_extrapolation_kokkos.cpp b/src/KOKKOS/pair_pace_extrapolation_kokkos.cpp index 7e32b25eaf9..c1ac252b8b9 100644 --- a/src/KOKKOS/pair_pace_extrapolation_kokkos.cpp +++ b/src/KOKKOS/pair_pace_extrapolation_kokkos.cpp @@ -1426,7 +1426,12 @@ void PairPACEExtrapolationKokkos::operator() (TagPairPACEComputeDeri if (jj >= ncount) return; const int itype = type(i); - const KK_FLOAT scale = d_scale(itype,itype); + + // the pair force uses the off-diagonal scale factor, as the CPU style does; + // the diagonal element is reserved for the per-atom energy + + const int jtype = type(d_nearest(ii,jj)); + const KK_FLOAT scale = d_scale(itype,jtype); const int mu_j = d_mu(ii, jj); KK_FLOAT r_hat[3]; diff --git a/src/KOKKOS/pair_table_kokkos.cpp b/src/KOKKOS/pair_table_kokkos.cpp index 59e0f0b782c..b73ec579143 100644 --- a/src/KOKKOS/pair_table_kokkos.cpp +++ b/src/KOKKOS/pair_table_kokkos.cpp @@ -174,7 +174,7 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) } } - if (eflag) eng_vdwl += static_cast(ev.evdwl); + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); @@ -469,10 +469,12 @@ void PairTableKokkos::settings(int narg, char **arg) if (allocated) { memory->destroy(setflag); - d_table_const.tabindex = d_table->tabindex = typename AT::t_int_2d_lr(); + memoryKK->destroy_kokkos(d_table->tabindex,tabindex); + d_table_const.tabindex = d_table->tabindex; h_table->tabindex = HAT::t_int_2d_lr(); - d_table_const.cutsq = d_table->cutsq = typename AT::t_double_2d_lr(); + memoryKK->destroy_kokkos(d_table->cutsq,cutsq); + d_table_const.cutsq = d_table->cutsq; h_table->cutsq = HAT::t_double_2d_lr(); } allocated = 0; diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index cc907539066..f00a2481928 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -87,10 +87,8 @@ void getMixingWeights( if (nTotal < static_cast(MY_EPSILON) || nTotalOld < static_cast(MY_EPSILON)) Kokkos::abort("The number of molecules in CG particle is less than 10*DBL_EPSILON."); - assert(isite1 >= 0); - assert(isite1 < nspecies); - assert(isite2 >= 0); - assert(isite2 < nspecies); + assert(isOneFluid(isite1) || (isite1 >= 0 && isite1 < nspecies)); + assert(isOneFluid(isite2) || (isite2 >= 0 && isite2 < nspecies)); if (isOneFluid(isite1) == false) { const auto atom_site1_ind = species_ind_to_atom_prop_ind(isite1); const auto atom_site1_ind_old = species_ind_to_atom_prop_ind_old(isite1); @@ -422,7 +420,7 @@ compute_item( Kokkos::View const& mixWtSite2old, Kokkos::View const& mixWtSite1, Kokkos::View const& mixWtSite2, - Few const& special_lj, + Few const& special_lj, Few, MAX_TYPES_STACKPARAMS+1> const& m_cutsq, typename ArrayTypes::t_double_2d_lr const& d_cutsq, Kokkos::View const& mixWtSite2old, Kokkos::View const& mixWtSite1, Kokkos::View const& mixWtSite2, - Few special_lj, + Few special_lj, Few, MAX_TYPES_STACKPARAMS+1> m_cutsq, typename ArrayTypes::t_double_2d_lr d_cutsq, Kokkos::View::compute_style(int eflag_in, int vflag_in) atomKK->sync(execution_space,datamask_read); if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); - else atomKK->modified(execution_space,F_MASK); + else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); x = atomKK->k_x.view(); f = atomKK->k_f.view(); @@ -676,7 +674,7 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) auto uCG = atomKK->k_uCG.view(); auto uCGnew = atomKK->k_uCGnew.view(); auto nlocal = atom->nlocal; - Few special_lj_local; + Few special_lj_local; special_lj_local[0] = force->special_lj[0]; special_lj_local[1] = force->special_lj[1]; special_lj_local[2] = force->special_lj[2]; @@ -807,7 +805,7 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) } } - if (eflag) eng_vdwl += static_cast(ev.evdwl); + if (eflag_global) eng_vdwl += static_cast(ev.evdwl); if (vflag_global) { virial[0] += static_cast(ev.v[0]); virial[1] += static_cast(ev.v[1]); @@ -1038,10 +1036,12 @@ void PairTableRXKokkos::settings(int narg, char **arg) if (allocated) { memory->destroy(setflag); - d_table_const.tabindex = d_table->tabindex = typename ArrayTypes::t_int_2d_lr(); + memoryKK->destroy_kokkos(d_table->tabindex,tabindex); + d_table_const.tabindex = d_table->tabindex; h_table->tabindex = typename ArrayTypes::t_int_2d_lr(); - d_table_const.cutsq = d_table->cutsq = typename ArrayTypes::t_double_2d_lr(); + memoryKK->destroy_kokkos(d_table->cutsq,cutsq); + d_table_const.cutsq = d_table->cutsq; h_table->cutsq = typename ArrayTypes::t_double_2d_lr(); allocated = 0; } diff --git a/src/KOKKOS/pair_tip4p_kokkos.h b/src/KOKKOS/pair_tip4p_kokkos.h index bca63c65e25..814943368d6 100644 --- a/src/KOKKOS/pair_tip4p_kokkos.h +++ b/src/KOKKOS/pair_tip4p_kokkos.h @@ -75,6 +75,7 @@ class PairTIP4PKokkos : public PairCPUBase { // TIP4P tallies the virial explicitly (charge site is off-atom) this->no_virial_fdotr_compute = 1; k_h_missing = DAT::tdual_int_scalar("pair:tip4p_h_missing"); + k_h_badtype = DAT::tdual_int_scalar("pair:tip4p_h_badtype"); } ~PairTIP4PKokkos() override @@ -104,6 +105,17 @@ class PairTIP4PKokkos : public PairCPUBase { int iH1 = AtomKokkos::map_kokkos(tag(i)+1,map_style,k_map_array,k_map_hash); int iH2 = AtomKokkos::map_kokkos(tag(i)+2,map_style,k_map_array,k_map_hash); if (iH1 < 0 || iH2 < 0) { d_hneigh(i,0) = -1; return; } + + // the two atoms following the oxygen must really be the hydrogens, as the + // CPU find_M() checks. Mark the M site unusable so the compute kernels + // stop the run where they would for a missing H, and record the reason so + // finalize() can report it + + if (type(iH1) != m_typeH || type(iH2) != m_typeH) { + d_h_badtype() = 1; + d_hneigh(i,0) = -1; + return; + } iH1 = closest_image(i,iH1); iH2 = closest_image(i,iH2); d_hneigh(i,0) = iH1; @@ -435,12 +447,17 @@ class PairTIP4PKokkos : public PairCPUBase { d_hneigh = typename AT::t_int_1d_3("tip4p/kk:hneigh", this->atom->nmax); } - // reset the missing-hydrogen flag, checked in finalize() + // reset the missing-hydrogen flags, checked in finalize() k_h_missing.view_host()() = 0; k_h_missing.modify_host(); k_h_missing.template sync(); d_h_missing = k_h_missing.template view(); + k_h_badtype.view_host()() = 0; + k_h_badtype.modify_host(); + k_h_badtype.template sync(); + d_h_badtype = k_h_badtype.template view(); + if (this->eflag_atom) { this->memoryKK->destroy_kokkos(k_eatom, this->eatom); this->memoryKK->create_kokkos(k_eatom, this->eatom, this->maxeatom, "pair:eatom"); @@ -466,8 +483,14 @@ class PairTIP4PKokkos : public PairCPUBase { { k_h_missing.template modify(); k_h_missing.sync_host(); - if (k_h_missing.view_host()()) - this->error->one(FLERR,"TIP4P hydrogen is missing"); + k_h_badtype.template modify(); + k_h_badtype.sync_host(); + if (k_h_missing.view_host()()) { + if (k_h_badtype.view_host()()) + this->error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); + else + this->error->one(FLERR,"TIP4P hydrogen is missing"); + } if (this->eflag_global) this->eng_coul += static_cast(ev.ecoul); if (this->vflag_global) @@ -491,6 +514,10 @@ class PairTIP4PKokkos : public PairCPUBase { DAT::tdual_int_scalar k_h_missing; typename AT::t_int_scalar d_h_missing; + // set on device when the two atoms following an O are not both of type H + DAT::tdual_int_scalar k_h_badtype; + typename AT::t_int_scalar d_h_badtype; + typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; typename AT::t_int_1d_randomread d_numneigh; diff --git a/src/KOKKOS/pair_ylz_kokkos.cpp b/src/KOKKOS/pair_ylz_kokkos.cpp index fecf3f2f384..3b5e314780e 100644 --- a/src/KOKKOS/pair_ylz_kokkos.cpp +++ b/src/KOKKOS/pair_ylz_kokkos.cpp @@ -49,7 +49,7 @@ PairYLZKokkos::PairYLZKokkos(LAMMPS *lmp) : PairYLZ(lmp), avecKK(nul kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TORQUE_MASK | TYPE_MASK | ELLIPSOID_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | TORQUE_MASK | TYPE_MASK | ELLIPSOID_MASK | BONUS_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | TORQUE_MASK | ENERGY_MASK | VIRIAL_MASK; } From 773580327dc3113bb8aecbed5c7ae6addf28a1c0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:59:52 +0000 Subject: [PATCH 098/120] test: read KOKKOS_PREC in python-capabilities instead of assuming double test_accelerator_config asserted that the KOKKOS precision reported at runtime contains "double", so the test could not pass in a mixed or single precision build: AssertionError: 'double' not found in ['mixed'] The GPU block a few lines above already does this correctly, reading GPU_PREC from the cmake cache and asserting the matching value; the KOKKOS block had the value hardcoded. It now reads KOKKOS_PREC the same way, falling back to double when the entry is absent. Verified against double, mixed and single builds. --- unittest/python/python-capabilities.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/unittest/python/python-capabilities.py b/unittest/python/python-capabilities.py index e38a26b1afc..9169776c998 100644 --- a/unittest/python/python-capabilities.py +++ b/unittest/python/python-capabilities.py @@ -179,7 +179,10 @@ def test_accelerator_config(self): self.assertIn('openmp',settings['KOKKOS']['api']) if 'Kokkos_ENABLE_SERIAL' in self.cmake_cache and self.cmake_cache['Kokkos_ENABLE_SERIAL']: self.assertIn('serial',settings['KOKKOS']['api']) - self.assertIn('double',settings['KOKKOS']['precision']) + if 'KOKKOS_PREC' in self.cmake_cache: + self.assertIn(self.cmake_cache['KOKKOS_PREC'].lower(),settings['KOKKOS']['precision']) + else: + self.assertIn('double',settings['KOKKOS']['precision']) def test_gpu_device(self): From 72fdd8a7f18f9c955095e890a9ecbfb778dc096d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 12:59:52 +0000 Subject: [PATCH 099/120] doc: record the KOKKOS restrictions added by these fixes Three accelerated styles now refuse an option they previously accepted and handled incorrectly, so each needs a note where users will look for it: fix nve/sphere/kk has no DLM kernel, pair brownian/kk needs a half neighbour list, and pppm/kk cannot do kspace_modify slab auto. The kspace_modify page already listed the variants supporting slab auto and KOKKOS was not among them, but "the corresponding OpenMP/GPU/Intel variants" left that implicit; it is now stated. The kokkos variants of the nve/sphere dipole/dlm fixture are marked skip_tests, since the style now errors rather than silently running the plain orientation update. KiB is added to the spelling false-positives list; GiB was already there. --- doc/src/fix_nve_sphere.rst | 6 ++++++ doc/src/kspace_modify.rst | 4 +++- doc/src/pair_brownian.rst | 9 +++++++++ doc/utils/sphinx-config/false_positives.txt | 1 + .../tests/fix-timestep-nve_sphere_dipole_dlm.yaml | 2 +- 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/src/fix_nve_sphere.rst b/doc/src/fix_nve_sphere.rst index 9340e4af220..c0958963939 100644 --- a/doc/src/fix_nve_sphere.rst +++ b/doc/src/fix_nve_sphere.rst @@ -99,6 +99,12 @@ be point particles. Use of the *disc* keyword is only allowed for 2d simulations, as defined by the :doc:`dimension ` keyword. +.. versionchanged:: TBD + +The KOKKOS version of this fix does not support the *dipole/dlm* option of +the *update* keyword and will stop with an error if it is requested. Use the +non-accelerated version of the fix for the DLM integrator. + Related commands """""""""""""""" diff --git a/doc/src/kspace_modify.rst b/doc/src/kspace_modify.rst index 06384545bcb..d72e4f17ff3 100644 --- a/doc/src/kspace_modify.rst +++ b/doc/src/kspace_modify.rst @@ -452,7 +452,9 @@ parameter-selection guidance in the more general dielectric-confined setting, see :ref:`(Gao2025) `. The *auto* setting is currently supported by :doc:`kspace_style ` *ewald*, *pppm*, *pppm/cg*, *pppm/tip4p*, *pppm/stagger*, and the corresponding -OpenMP/GPU/Intel variants that reuse the same slab-correction setup. +OpenMP/GPU/Intel variants that reuse the same slab-correction setup. The +KOKKOS variants do not support it and will stop with an error if it is +requested; use an explicit volfactor with those. An alternative slab option can be invoked with the *nozforce* keyword in lieu of the volfactor. This turns off all kspace forces in the z diff --git a/doc/src/pair_brownian.rst b/doc/src/pair_brownian.rst index 03c781d667b..895eee84841 100644 --- a/doc/src/pair_brownian.rst +++ b/doc/src/pair_brownian.rst @@ -140,6 +140,15 @@ brownian. Only spherical particles are allowed for pair_style brownian/poly. The volume fraction correction is not supported by pair_style brownian/poly. +.. versionchanged:: TBD + +The KOKKOS versions of these styles require a half neighbor list and will +stop with an error if a full neighbor list is requested, as it is by default +on a GPU. A full list would visit each pair twice and draw independent +random numbers each time, so the stochastic part of the pair force would no +longer be equal and opposite. Use *package kokkos neigh half* with these +styles. + These pair styles are only compatible with the following wall fixes: :doc:`fix wall/lj93, fix wall/lj126, fix wall/lj1043, fix wall/colloid, fix wall/harmonic, fix wall/lepton, fix wall/morse, fix wall/table diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index fe63f4b1b54..04dfd2258a8 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2015,6 +2015,7 @@ Khersonskii Khrapak Khvostov Ki +KiB Kikkawa Kikugawa kim diff --git a/unittest/force-styles/tests/fix-timestep-nve_sphere_dipole_dlm.yaml b/unittest/force-styles/tests/fix-timestep-nve_sphere_dipole_dlm.yaml index 36c7bf1c4bb..d4cacb58eed 100644 --- a/unittest/force-styles/tests/fix-timestep-nve_sphere_dipole_dlm.yaml +++ b/unittest/force-styles/tests/fix-timestep-nve_sphere_dipole_dlm.yaml @@ -2,7 +2,7 @@ lammps_version: 27 Jun 2024 date_generated: Sun Aug 4 23:06:24 2024 epsilon: 1e-09 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: ! | atom full atom dipole From 5565107ddd3e8a9339710e2f7c570b037bf83164 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:46:17 +0000 Subject: [PATCH 100/120] KOKKOS: add math_special_kokkos.cpp to the CMake source list KOKKOS_PKG_SOURCES is an explicit list and math_special_kokkos.cpp was not in it, nor added by any package block, so CMake never compiled the file. The traditional make build copies and compiles every src/KOKKOS/*.cpp, so the two build systems disagreed about what the package contains. math_special_kokkos.h declares erfcx_y100(), which only that file defines, and its inline erfcx() calls it. Nothing calls erfcx() today, which is why the CMake build still linked; the first KOKKOS style to use it would have built under make and failed to link under CMake. Note that the header also declares "extern double factorial(const int n)", which is defined nowhere: src/math_special.cpp defines both erfcx_y100() and factorial(), but the KOKKOS adaptation kept only the former. That dangling declaration is left alone here -- it needs either the definition ported or the declaration removed, and nothing calls it either. --- cmake/Modules/Packages/KOKKOS.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/Modules/Packages/KOKKOS.cmake b/cmake/Modules/Packages/KOKKOS.cmake index aa657845ecc..e08b95912ab 100644 --- a/cmake/Modules/Packages/KOKKOS.cmake +++ b/cmake/Modules/Packages/KOKKOS.cmake @@ -192,6 +192,7 @@ set(KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/npair_kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/npair_halffull_kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/domain_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/math_special_kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/modify_kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/rand_pool_wrap_kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/tune_kokkos.cpp From 8a381fe71b07e71a756baac36f5f346ca3e46e61 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 14:41:03 +0000 Subject: [PATCH 101/120] Use fix property/atom/kk whenever the KOKKOS package is active fix property/atom keeps its per-atom data in arrays that AtomKokkos owns and grows as Kokkos views: AtomKokkos::add_custom() allocates dvector, ivector, darray and iarray with memoryKK->grow_kokkos(). The plain style then hands those pointers to memory->grow(), i.e. srealloc() on a Kokkos allocation: atom_style atomic/kk fix p all property/atom d_foo -> realloc(): invalid pointer Memory::srealloc / FixPropertyAtom::grow_arrays / Modify::add_fix This is normally hidden because the /kk suffix selects FixPropertyAtomKokkos, which overrides grow_arrays() and grows the views correctly. Reaching the base class -- with "suffix off" around the command, or by naming atom_style atomic/kk and not passing -sf kk -- is immediate heap corruption rather than a wrong answer. Overriding grow_arrays() cannot fix this: the object being constructed is a plain FixPropertyAtom, so the KOKKOS override is never reached. Instead promote the style at creation, in the same place and the same shape as the existing suffix handling, including the style-string rewrite. The promotion is deliberately limited to property/atom, the one style whose plain version is unsafe under KOKKOS; every other fix is still free to run non-accelerated. Verified: an input that put "suffix off" around the command aborted with "invalid pointer" on develop and now runs, giving results identical to the same input without KOKKOS. Normal -sf kk runs and non-KOKKOS runs are unchanged. The kokkosable guard in AtomKokkos::update_property_atom() is kept as a backstop; it should now be unreachable. Also drop the declaration of MathSpecialKokkos::factorial. The CPU src/math_special.cpp defines both erfcx_y100 and factorial, but the KOKKOS adaptation kept only erfcx_y100, so the header promised a symbol that exists nowhere and the first caller would have failed to link. --- src/KOKKOS/math_special_kokkos.h | 11 ----------- src/modify.cpp | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/KOKKOS/math_special_kokkos.h b/src/KOKKOS/math_special_kokkos.h index fad2f9ea19d..5c59288f2fa 100644 --- a/src/KOKKOS/math_special_kokkos.h +++ b/src/KOKKOS/math_special_kokkos.h @@ -22,17 +22,6 @@ namespace LAMMPS_NS::MathSpecialKokkos { - /*! Fast tabulated factorial function - * - * This function looks up pre-computed factorial values for arguments of n = 0 - * to a maximum of 167, which is the maximal value representable by a double - * precision floating point number. For other values of n a NaN value is returned. - * - * \param n argument (valid: 0 <= n <= 167) - * \return value of n! as double precision number or NaN */ - - extern double factorial(const int n); - /* optimizer friendly implementation of exp2(x). * * strategy: diff --git a/src/modify.cpp b/src/modify.cpp index 39413cedf7f..d09f4ab34da 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -907,6 +907,20 @@ Fix *Modify::add_fix(int narg, char **arg, int trysuffix) } } + // fix property/atom keeps its per-atom data in arrays that AtomKokkos owns and + // grows as Kokkos views. The plain style would hand those pointers to + // memory->grow(), i.e. srealloc() on a Kokkos allocation, which corrupts the + // heap. Use the KOKKOS version whenever the package is active, even where the + // suffix machinery above did not apply because suffixes are disabled. + + if ((fix[ifix] == nullptr) && lmp->kokkos && (strcmp(arg[2], "property/atom") == 0)) { + if (FixCreator fix_creator = fix_styles().find("property/atom/kk")) { + fix[ifix] = fix_creator(lmp, narg, arg); + delete[] fix[ifix]->style; + fix[ifix]->style = utils::strdup("property/atom/kk"); + } + } + if (fix[ifix] == nullptr) { if (FixCreator fix_creator = fix_styles().find(arg[2])) fix[ifix] = fix_creator(lmp, narg, arg); From 0f41f0874e96ad6a80355360731c7b34ef133194 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 19:29:05 +0000 Subject: [PATCH 102/120] unittest: skip KOKKOS cases that need unported styles, skip omp in born/coul/table The command and format tests are also run with the KOKKOS package active (LAMMPS_ACCELERATOR_ARGS="-k on t 1 -sf kk"). The KOKKOS package requires a Kokkos-enabled atom style and has no version of atom styles body, electron and oxdna, nor of the tally computes, so the tests that need those are skipped in that configuration instead of failing on the corresponding error. The omp variant of pair style born/coul/long does not implement the tabulated Coulomb interaction, so the new born/coul/table reference skips the omp test case. --- unittest/commands/test_compute_chunk.cpp | 5 +++++ unittest/commands/test_compute_global.cpp | 8 ++++++++ unittest/commands/test_groups.cpp | 5 +++++ unittest/commands/test_restart_settings.cpp | 5 +++++ unittest/commands/test_set_property.cpp | 5 +++++ .../force-styles/tests/mol-pair-born_coul_table.yaml | 2 +- unittest/formats/test_atom_styles.cpp | 10 ++++++++++ 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/unittest/commands/test_compute_chunk.cpp b/unittest/commands/test_compute_chunk.cpp index d32eac8e220..134de9543e8 100644 --- a/unittest/commands/test_compute_chunk.cpp +++ b/unittest/commands/test_compute_chunk.cpp @@ -522,6 +522,11 @@ TEST_F(ComputeInertiaChunkTest, Body) { if (!lammps_config_has_package("BODY")) GTEST_SKIP(); + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style body + if (lmp->kokkos && !info->has_style("atom", "body/kk")) + GTEST_SKIP() << "atom style body has no KOKKOS version"; + // single body/nparticle at the origin with a known diagonal inertia // tensor (2,3,4); a single chunk must return it unchanged diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 741e0ebc708..ddf20ad51c8 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -81,6 +81,9 @@ TEST_F(ComputeGlobalTest, Energy) if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); int has_tally = lammps_config_has_package("TALLY"); + // the tally computes are not supported by the KOKKOS package + if (lmp->kokkos) has_tally = 0; + BEGIN_HIDE_OUTPUT(); command("pair_style lj/cut/coul/cut 10.0"); command("pair_coeff * * 0.01 3.0"); @@ -499,6 +502,11 @@ TEST_F(ComputeInertiaTest, Body) { if (!lammps_config_has_package("BODY")) GTEST_SKIP(); + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style body + if (lmp->kokkos && !info->has_style("atom", "body/kk")) + GTEST_SKIP() << "atom style body has no KOKKOS version"; + // single body/nparticle at the origin with a known diagonal inertia // tensor (2,3,4); compute inertia must return it unchanged (the orbital // term is zero at the COM). Exercises the body-particle branch, which diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index 5c70a1080fd..ed7ffd9c9fe 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -684,6 +684,11 @@ TEST_F(GroupTest, InertiaBody) { if (!lammps_config_has_package("BODY")) GTEST_SKIP(); + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style body + if (lmp->kokkos && !info->has_style("atom", "body/kk")) + GTEST_SKIP() << "atom style body has no KOKKOS version"; + // single body/nparticle at the origin with a known diagonal inertia // tensor (2,3,4); Group::inertia must return it unchanged diff --git a/unittest/commands/test_restart_settings.cpp b/unittest/commands/test_restart_settings.cpp index 87a22ddeddf..cddcec4b274 100644 --- a/unittest/commands/test_restart_settings.cpp +++ b/unittest/commands/test_restart_settings.cpp @@ -153,6 +153,11 @@ TEST_F(RestartSettingsTest, eff_cut_settings) { if (!Info::has_package("EFF")) GTEST_SKIP(); + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style electron + if (lmp->kokkos && !info->has_style("atom", "electron/kk")) + GTEST_SKIP() << "atom style electron has no KOKKOS version"; + BEGIN_HIDE_OUTPUT(); command("units electron"); command("atom_style electron"); diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index 05398665976..c66fc0effe2 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -529,6 +529,11 @@ TEST_F(SetTest, SpinPackage) TEST_F(SetTest, EffPackage) { if (!Info::has_package("EFF")) GTEST_SKIP(); + + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style electron + if (lmp->kokkos && !info->has_style("atom", "electron/kk")) + GTEST_SKIP() << "atom style electron has no KOKKOS version"; atomic_system("electron"); ASSERT_EQ(atom->natoms, 8); diff --git a/unittest/force-styles/tests/mol-pair-born_coul_table.yaml b/unittest/force-styles/tests/mol-pair-born_coul_table.yaml index 3f42716205b..b236ad8118a 100644 --- a/unittest/force-styles/tests/mol-pair-born_coul_table.yaml +++ b/unittest/force-styles/tests/mol-pair-born_coul_table.yaml @@ -3,7 +3,7 @@ lammps_version: 2 Sep 2026 tags: date_generated: Fri Sep 4 18:15:19 2026 epsilon: 5e-12 -skip_tests: gpu +skip_tests: gpu omp prerequisites: | atom full pair born/coul/long diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index 3ceb12a22ba..6bdeaa53edd 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -2358,6 +2358,11 @@ TEST_F(AtomStyleTest, body_nparticle) { if (!Info::has_package("BODY")) GTEST_SKIP(); + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style body + if (lmp->kokkos && !info->has_style("atom", "body/kk")) + GTEST_SKIP() << "atom style body has no KOKKOS version"; + BEGIN_HIDE_OUTPUT(); command("atom_style body nparticle 2 4"); END_HIDE_OUTPUT(); @@ -5119,6 +5124,11 @@ TEST_F(AtomStyleTest, oxdna) if (!Info::has_package("ASPHERE")) GTEST_SKIP(); if (!Info::has_package("CG-DNA")) GTEST_SKIP(); + // the KOKKOS package requires a Kokkos-enabled atom style, and there is + // no accelerated version of atom style oxdna + if (lmp->kokkos && !info->has_style("atom", "oxdna/kk")) + GTEST_SKIP() << "atom style oxdna has no KOKKOS version"; + BEGIN_HIDE_OUTPUT(); command("atom_style hybrid bond ellipsoid oxdna"); END_HIDE_OUTPUT(); From 4baea44624216a9253be45637447eac0969c3902 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 19:32:50 +0000 Subject: [PATCH 103/120] doc: use the spelling 'back end' in the KOKKOS_DEBUG_RNG description The spelling check of the manual flags 'backend', which the rest of the manual writes as two words. --- doc/src/Build_extras.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/Build_extras.rst b/doc/src/Build_extras.rst index e1627f8d074..3f7b39f31f4 100644 --- a/doc/src/Build_extras.rst +++ b/doc/src/Build_extras.rst @@ -983,7 +983,7 @@ that need random numbers (for example :doc:`fix langevin ` or :doc:`fix brownian `) use the same random number generator as the corresponding plain styles instead of the parallel generator of the Kokkos library. A run on a single MPI process with the -Serial backend then follows the same trajectory as a run without the +Serial back end then follows the same trajectory as a run without the KOKKOS package, which makes it possible to compare the two directly and thus to validate the KOKKOS versions of those styles. This is a validation and debugging aid only: the substitute generator is slower From 82ceb245c57c366396795e08fbdb2fb686cc2f6d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 19:48:27 +0000 Subject: [PATCH 104/120] OPENMP: reduce per-atom energy and virial into the style that owns the thread data ThrOMP::reduce_thr() reduced the per-thread per-atom energy and virial of a bonded style into force->bond, force->angle, force->dihedral or force->improper, i.e. into the hybrid style when the style is a sub-style of a hybrid, while the sub-style had set up the per-thread arrays in its own eatom and vatom. The hybrid then added only the first thread's part of each sub-style's arrays, so the per-atom virial of a hybrid bonded style was wrong with more than one thread. Reduce into the style that was passed in, as the pair case already does. bond style quartic/omp tallied the pair correction of a broken bond through ev_tally_thr() with the pair style, whose per-thread per-atom arrays are not set up by a bond style, which crashes with a per-atom virial. Tally directly into the pair style under a critical section, as the plain style does. Both were found by the new per-atom virial consistency test. --- src/OPENMP/bond_quartic_omp.cpp | 12 ++++++++++-- src/OPENMP/thr_omp.cpp | 14 ++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/OPENMP/bond_quartic_omp.cpp b/src/OPENMP/bond_quartic_omp.cpp index 64ba2aaf779..d235feafc19 100644 --- a/src/OPENMP/bond_quartic_omp.cpp +++ b/src/OPENMP/bond_quartic_omp.cpp @@ -194,8 +194,16 @@ void BondQuarticOMP::eval(int nfrom, int nto, ThrData * const thr) f[i2][2] -= delz*fpair; } - if (EVFLAG) ev_tally_thr(force->pair,i1,i2,nlocal,NEWTON_BOND, - evdwl,0.0,fpair,delx,dely,delz,thr); + // the per-thread accumulators of this style were set up for the bond + // style only, so the pair style has no per-thread per-atom arrays here. + // tally directly into the pair style instead, serialized across threads + + if (EVFLAG) { +#if defined(_OPENMP) +#pragma omp critical +#endif + force->pair->ev_tally(i1,i2,nlocal,NEWTON_BOND,evdwl,0.0,fpair,delx,dely,delz); + } } } } diff --git a/src/OPENMP/thr_omp.cpp b/src/OPENMP/thr_omp.cpp index c45f2944329..f5a0fb96bd0 100644 --- a/src/OPENMP/thr_omp.cpp +++ b/src/OPENMP/thr_omp.cpp @@ -249,7 +249,9 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag, case THR_BOND: if (evflag) { - Bond * const bond = lmp->force->bond; + // reduce into the style that set up the per-thread arrays: for a hybrid + // style this is the sub-style, not lmp->force->bond + auto *const bond = (Bond *) style; #if defined(_OPENMP) #pragma omp critical #endif @@ -281,7 +283,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag, case THR_ANGLE: if (evflag) { - Angle * const angle = lmp->force->angle; + auto *const angle = (Angle *) style; #if defined(_OPENMP) #pragma omp critical #endif @@ -315,7 +317,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag, case THR_ANGLE|THR_CHARMM: // special case for angle styles with a 1-3 pairwise term if (evflag) { - Angle * const angle = lmp->force->angle; + auto *const angle = (Angle *) style; Pair * const pair = lmp->force->pair; #if defined(_OPENMP) #pragma omp critical @@ -365,7 +367,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag, case THR_DIHEDRAL: if (evflag) { - Dihedral * const dihedral = lmp->force->dihedral; + auto *const dihedral = (Dihedral *) style; #if defined(_OPENMP) #pragma omp critical #endif @@ -399,7 +401,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag, case THR_DIHEDRAL|THR_CHARMM: // special case for CHARMM dihedrals if (evflag) { - Dihedral * const dihedral = lmp->force->dihedral; + auto *const dihedral = (Dihedral *) style; Pair * const pair = lmp->force->pair; #if defined(_OPENMP) #pragma omp critical @@ -449,7 +451,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag, case THR_IMPROPER: if (evflag) { - Improper *improper = lmp->force->improper; + auto *const improper = (Improper *) style; #if defined(_OPENMP) #pragma omp critical #endif From 3658bace100a83a618bc4261a3401c3e1971e9bf Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:51:00 -0600 Subject: [PATCH 105/120] KOKKOS: clear the stale team scratch request on the ghost neighbor build NPairKokkos::build() constructs NPairKokkosBuildFunctorGhost with a team scratch request of atoms_per_bin*5*sizeof(double)*factor bytes, but the team policy path for GHOST has been commented out since 2d3bbd2e72, so the functor is always launched through a flat RangePolicy that never uses team scratch. The request stayed behind. That is not inert. Kokkos deduces the CUDA/HIP block size for a RangePolicy with cuda_get_opt_block_size(), which adds FunctorTeamShmemSize::value(f, block_size) -- i.e. our sharedsize -- to the dynamic shared memory of every candidate block size. The value does not scale with block size, so once it exceeds the per-block shared memory limit (48 KB by default, i.e. atoms_per_bin > ~1228 with factor == 1) cuda_deduce_block_size() rejects every candidate and returns 0. The kernel is then launched with dim3 block(1,0,1), which fails as an illegal memory access inside Kokkos. Below that threshold the phantom request still suppresses occupancy and shrinks the block size for every ghost neighbor list build on a GPU. Zero the request before the flat launch, matching what the disabled team policy path did on its own fall-back branch. Diagnosed and fixed by Trung Nguyen; reported by Rushik Desai with pair style reaxff/kk on CUDA at https://matsci.org/t/66975 --- src/KOKKOS/npair_kokkos.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index 85c194ad04a..ee4b1009dba 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -287,6 +287,11 @@ void NPairKokkos::build(NeighList *list_) // } else // Kokkos::parallel_for(nall, f); //#else + // the flat kernel uses no team scratch, but Kokkos still queries + // team_shmem_size() when deducing the CUDA/HIP block size for a + // RangePolicy. A stale request larger than the shared memory limit + // makes that deduction return a block size of zero. + f.sharedsize = 0; Kokkos::parallel_for(nall, f); //#endif } else { From 453774cb892aaf09c675c1ec7d1474a8efacf91e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:51:00 -0600 Subject: [PATCH 106/120] KOKKOS: bound the stencil bin lookup in the ghost neighbor team kernel build_ItemGhostGPU() reads c_bincount[jbin] and c_bins(jbin, MY_II) for every stencil entry without checking that jbin is a bin at all. For owned atoms that is safe, because the padding around the owned region guarantees that ibin + stencil[k] stays inside the bin array. Ghost atoms break the guarantee: they sit in the outermost bins, so the stencil reaches past the end of the array in either direction. jbin then indexes outside the extent of both views -- mbins entries for c_bincount -- and the build dies with an illegal memory access. The flat kernel does not have the problem: build_ItemGhost() applies the same 3d out-of-bounds test and skips the bin before reading it. The team kernel instead evaluates the test into a per-thread 'active' flag that only masks the accumulation further down, because a team can span more than one bin (BINS_PER_TEAM == factor) and every thread has to reach the barriers in the stencil loop. That leaves the load itself unguarded. Mask the load the same way: an out-of-range bin reports a count of zero, so the inner loop over its atoms is empty. The 3d test is still needed and still runs -- it rejects the bins that stay within [0,mbins) but wrap into a different row or plane. Also zero-initialize binxyz, which is read for owned atoms even though coord2bin() only fills it for ghosts. This is the "known bug" behind 2d3bbd2e72, which took the team policy out of the ghost build in 2023. The path is still disabled by that commit; this only fixes the kernel it calls. --- src/KOKKOS/npair_kokkos.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index ee4b1009dba..6ea79e5445b 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -1053,7 +1053,7 @@ void NeighborKokkosExecute::build_ItemGhostGPU(typename Kokkos::Team // no molecular test when i = ghost atom int ghost = (i >= nlocal && i < nall); - int binxyz[3]; + int binxyz[3] = {0,0,0}; if (ghost) coord2bin(xtmp, ytmp, ztmp, binxyz); const int xbin = binxyz[0]; @@ -1070,9 +1070,18 @@ void NeighborKokkosExecute::build_ItemGhostGPU(typename Kokkos::Team zbin2 < 0 || zbin2 >= mbinz) active = 0; } + // ghost atoms live in the outermost bins, so unlike the owned-atom + // stencil the offset can leave the bin array altogether. build_ItemGhost() + // skips such a bin before it is touched; here the threads of a team can + // be working on different bins and all of them have to reach the barriers + // below, so mask the load rather than skipping the stencil entry. An + // empty bin contributes nothing, and the 3d test above still rejects the + // bins that stay in range but wrap into a different row or plane. + const int jbin = ibin + stencil[k]; - bincount_current = c_bincount[jbin]; - int j = MY_II < bincount_current ? c_bins(jbin, MY_II) : -1; + const bool jbin_valid = (jbin >= 0 && jbin < mbins); + bincount_current = jbin_valid ? c_bincount[jbin] : 0; + int j = (jbin_valid && MY_II < bincount_current) ? c_bins(jbin, MY_II) : -1; if (j >= 0) { other_x[MY_II] = x(j, 0); From 63660d3567b63a5d070f33b59dc770cdc377ca43 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:51:01 -0600 Subject: [PATCH 107/120] KOKKOS: re-enable the team policy for the ghost neighbor list build NOT VALIDATED ON A GPU -- drop this commit if it does not hold up. 2d3bbd2e72 took this path out in 2023 over a bug that the previous commit fixes: the stencil loop read c_bincount[]/c_bins() for bins outside the bin array, which only ghost atoms can reach. With the lookup bounded, restore the launch and keep the flat kernel as the fall-back it always was. Two things that had to change on the way back in: - The flat fall-back now zeroes the scratch request, which the branch that the team policy fell through to already did. Since 2d3bbd2e72 every ghost build went through the flat kernel, so this is what a GPU does today for any atoms_per_bin large enough to push team_size past team_size_max. - The team kernel writes d_numneigh()/d_ilist() only for atoms it finds in the bins, whereas the flat kernel walks 0..nall. NBinKokkos leaves the atoms outside an include group out of the bins, so with 'neigh_modify include' the team kernel would leave their list entries untouched. Take the flat kernel whenever an include group is set. Two rough edges are left alone because the owned-atom kernels have them too, and neither is reachable with the launch configuration used here: the early returns ahead of the team barriers can diverge within the last team, and bincount_current is stale on the second and later iterations of the TEAMS_PER_BIN loop (team_size >= atoms_per_bin makes that loop run once). --- src/KOKKOS/npair_kokkos.cpp | 42 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index 6ea79e5445b..53708deac0f 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -271,29 +271,29 @@ void NPairKokkos::build(NeighList *list_) NPairKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(double) * factor); -// temporarily disable team policy for ghost due to known bug - -//#ifdef LMP_KOKKOS_GPU -// if (ExecutionSpaceFromDevice::space == Device) { -// int team_size = atoms_per_bin*factor; -// int team_size_max = Kokkos::TeamPolicy(team_size,Kokkos::AUTO).team_size_max(f,Kokkos::ParallelForTag()); -// if (team_size <= team_size_max) { -// Kokkos::TeamPolicy config((mbins+factor-1)/factor,team_size); -// Kokkos::parallel_for(config, f); -// } else { // fall back to flat method -// f.sharedsize = 0; -// Kokkos::parallel_for(nall, f); -// } -// } else -// Kokkos::parallel_for(nall, f); -//#else - // the flat kernel uses no team scratch, but Kokkos still queries - // team_shmem_size() when deducing the CUDA/HIP block size for a - // RangePolicy. A stale request larger than the shared memory limit - // makes that deduction return a block size of zero. + // the team kernel builds a list only for the atoms it finds in the bins, + // while the flat kernel walks 0..nall. Those differ when an include group + // keeps atoms out of the bins, so use the flat kernel in that case. + +#ifdef LMP_KOKKOS_GPU + if (ExecutionSpaceFromDevice::space == Device && !includegroup) { + int team_size = atoms_per_bin*factor; + int team_size_max = Kokkos::TeamPolicy(team_size,Kokkos::AUTO).team_size_max(f,Kokkos::ParallelForTag()); + if (team_size <= team_size_max) { + Kokkos::TeamPolicy config((mbins+factor-1)/factor,team_size); + Kokkos::parallel_for(config, f); + } else { // fall back to flat method + f.sharedsize = 0; + Kokkos::parallel_for(nall, f); + } + } else { + f.sharedsize = 0; + Kokkos::parallel_for(nall, f); + } +#else f.sharedsize = 0; Kokkos::parallel_for(nall, f); -//#endif +#endif } else { if (SIZE) { NPairKokkosBuildFunctorSize f(data,atoms_per_bin * 7 * sizeof(double) * factor); From 6111169ddfebf5c695116a9899407981ebfcb69a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:51:01 -0600 Subject: [PATCH 108/120] Hand the host writes of atom creation over to KOKKOS lammps_create_atoms() and the create_atoms command build atoms through AtomVec::create_atom() and then write tag, v and image through the plain per-atom pointers. Neither tells KOKKOS about it, so the dual views still name whatever space was current before as the owner of that data. Between two runs that is the device: AtomVec*Kokkos::grow() claims the device for ALL_MASK, and VerletKokkos::run() leaves auto_sync back on when it returns. The next atomKK->sync(Device, ...) therefore takes the auto_sync path in AtomKokkos::sync(), whose first step is a sync(Host) -- which copies the stale device arrays over the tags that were just written on the host instead of leaving them alone. AtomKokkos::map_set_device() then sorts by those tags and stores d_map_array(tag_i) = i for each one, so a tag outside [0, map_tag_max] writes past the end of the map and the build dies with an illegal memory access, reported at the deep_copy that follows the kernel. Atom carries the hooks for this: sync_host_arrays()/modified_host_arrays() are no-ops without KOKKOS and forward to AtomKokkos::sync(Host, ...) / modified(Host, ...) with it. The set command already brackets its per-atom writes that way (Set::invoke_actions()). Do the same around atom creation, claiming the host once the IDs are assigned and the per-atom fix, compute and variable data is initialized. Reported at https://matsci.org/t/59054 against a Kokkos/CUDA build driven through the library interface, where a run of lammps_create_atoms() plus "run 0" crashed in map_set_device() after a few iterations and only ran when "atom_modify map" was dropped, which is what takes map_set() -- the one consumer of the tags on the device -- out of the loop. --- src/create_atoms.cpp | 11 +++++++++++ src/library.cpp | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp index ed4191a93e2..6974e97829f 100644 --- a/src/create_atoms.cpp +++ b/src/create_atoms.cpp @@ -19,6 +19,7 @@ #include "create_atoms.h" #include "atom.h" +#include "atom_masks.h" #include "atom_vec.h" #include "comm.h" #include "domain.h" @@ -512,6 +513,14 @@ void CreateAtoms::command(int narg, char **arg) atom->nghost = 0; atom->avec->clear_bonus(); + // the add() methods below create atoms and write their per-atom data through + // the plain pointers, so bring the host side up to date first and hand the + // writes over after the IDs are assigned; without the KOKKOS package these + // do nothing. a create_atoms between two runs finds the device holding the + // newer copy of the per-atom arrays + + atom->sync_host_arrays(ALL_MASK); + // add atoms/molecules with appropriate add() method bigint natoms_previous = atom->natoms; @@ -543,6 +552,8 @@ void CreateAtoms::command(int narg, char **arg) if (atom->tag_enable) atom->tag_extend(); atom->tag_check(); + atom->modified_host_arrays(ALL_MASK); + // if global map exists, reset it // invoke map_init() b/c atom count has grown diff --git a/src/library.cpp b/src/library.cpp index 3c7cab54a38..d1675b3f56c 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -21,6 +21,7 @@ #include "accelerator_kokkos.h" #include "atom.h" +#include "atom_masks.h" #include "atom_vec.h" #include "comm.h" #include "command.h" @@ -6213,6 +6214,15 @@ int lammps_create_atoms(void *handle, int n, const tagint *id, const int *type, Atom *atom = lmp->atom; Domain *domain = lmp->domain; + + // the loop below creates atoms and writes their per-atom data through the + // plain pointers, so bring the host side up to date first and hand the + // writes over afterwards; without the KOKKOS package these do nothing. + // both are needed here: this function is typically called between runs, + // when the device holds the newer copy of the per-atom arrays + + atom->sync_host_arrays(ALL_MASK); + int nlocal = atom->nlocal; int nlocal_prev = nlocal; @@ -6263,6 +6273,8 @@ int lammps_create_atoms(void *handle, int n, const tagint *id, const int *type, atom->data_fix_compute_variable(nlocal_prev,nlocal); + atom->modified_host_arrays(ALL_MASK); + // if global map exists, reset it // invoke map_init() b/c atom count has grown From bec1dd4fbbde5eaa29d1e8961cae39cf122ea5c1 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 13:53:29 -0600 Subject: [PATCH 109/120] KOKKOS: sync the per-atom dual views before the device exchange unpack Three fixes run a device kernel over their per-atom dual views in unpack_exchange_kokkos() and call modify() afterwards without syncing to the device first: wall/gran/kk (k_history_one), neigh/history/kk (k_npartner, k_partner, k_valuepartner) and wall/flow/kk (k_current_segment). fix spring/self/kk shows the intended shape: sync the buffer, the index view and the per-atom views, then run the kernel, then claim the device. The kernel writes only the rows of the atoms that arrived, so the rest are whatever the device happens to hold, and the claim at the end is made while the host copy may still be the newer one, which Kokkos rejects: Kokkos::DualView::modify_device ERROR: Concurrent modification of host and device views wall/gran/kk hits that on every device exchange. CommKokkos::exchange_device() unpacks the atoms first, which grows the per-atom arrays and so calls every fix's grow_arrays(); the wall/gran one syncs to the host and claims it, deliberately, so that the resize keeps the legacy history_one pointer valid. Only then does the nextra_grow loop reach unpack_exchange_kokkos(). For the other two, grow_arrays() claims the device, so the abort needs a host claim from copy_arrays() or the host unpack_exchange() to be outstanding instead, but the stale rows are the same either way. Also override set_arrays() in wall/gran/kk. FixWallGranOld::set_arrays() zeroes a new particle's contact history through the plain host pointer, and the fix sets create_attribute, so Atom::data_fix_compute_variable() calls it for every atom that create_atoms, read_data or the library interface adds -- without telling the dual view, leaving the device rows uninitialized. Found while investigating https://matsci.org/t/67158 and https://matsci.org/t/66764, which report both symptoms from granular runs with a wall, the second one naming NEIGH_HISTORY/KK/DEVICE in its backtrace. Neither has a reproducer attached, so whether this is those reporters' bug is unconfirmed. --- src/KOKKOS/fix_neigh_history_kokkos.cpp | 12 ++++++++++++ src/KOKKOS/fix_wall_flow_kokkos.cpp | 11 +++++++++++ src/KOKKOS/fix_wall_gran_kokkos.cpp | 22 ++++++++++++++++++++++ src/KOKKOS/fix_wall_gran_kokkos.h | 1 + 4 files changed, 46 insertions(+) diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index ea9cf5324da..99978df6981 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -482,6 +482,9 @@ void FixNeighHistoryKokkos::unpack_exchange_kokkos( int nrecv1, int nextrarecv1, ExecutionSpace /*space*/) { + k_buf.template sync(); + k_indices.template sync(); + d_buf = typename AT::t_double_1d_um( k_buf.template view().data(), k_buf.extent(0)*k_buf.extent(1)); @@ -490,6 +493,15 @@ void FixNeighHistoryKokkos::unpack_exchange_kokkos( this->nrecv1 = nrecv1; this->nextrarecv1 = nextrarecv1; + // the kernel below writes only the rows of the atoms that arrived, so the + // rest have to be current on the device first. syncing here also retires + // any outstanding host claim, which the modify() at the end + // would otherwise hit as a concurrent modification + + k_npartner.template sync(); + k_partner.template sync(); + k_valuepartner.template sync(); + d_npartner = k_npartner.template view(); d_partner = k_partner.template view(); d_valuepartner = k_valuepartner.template view(); diff --git a/src/KOKKOS/fix_wall_flow_kokkos.cpp b/src/KOKKOS/fix_wall_flow_kokkos.cpp index 2dcbff3a87c..ce9374a31aa 100644 --- a/src/KOKKOS/fix_wall_flow_kokkos.cpp +++ b/src/KOKKOS/fix_wall_flow_kokkos.cpp @@ -282,10 +282,21 @@ void FixWallFlowKokkos::unpack_exchange_kokkos(DAT::tdual_double_2d_ int /*nrecv1*/, int /*nextrarecv1*/, ExecutionSpace /*space*/) { + k_buf.template sync(); + k_indices.template sync(); + d_buf = typename AT::t_double_1d_um(k_buf.template view().data(), k_buf.extent(0) * k_buf.extent(1)); d_indices = k_indices.view(); + // the kernel below writes only the rows of the atoms that arrived, so the + // rest have to be current on the device first. syncing here also retires + // any outstanding host claim, which the modify() at the end + // would otherwise hit as a concurrent modification + + k_current_segment.template sync(); + d_current_segment = k_current_segment.template view(); + copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy(0, nrecv), *this); diff --git a/src/KOKKOS/fix_wall_gran_kokkos.cpp b/src/KOKKOS/fix_wall_gran_kokkos.cpp index 1508af0b6f2..312c2d27026 100644 --- a/src/KOKKOS/fix_wall_gran_kokkos.cpp +++ b/src/KOKKOS/fix_wall_gran_kokkos.cpp @@ -322,6 +322,18 @@ void FixWallGranKokkos::copy_arrays(int i, int j, int delflag) } } +/* ---------------------------------------------------------------------- */ + +template +void FixWallGranKokkos::set_arrays(int i) +{ + if (use_history) { + k_history_one.sync_host(); + FixWallGranOld::set_arrays(i); + k_history_one.modify_host(); + } +} + /* ---------------------------------------------------------------------- sort local atom-based arrays ------------------------------------------------------------------------- */ @@ -433,11 +445,21 @@ void FixWallGranKokkos::unpack_exchange_kokkos( int /*nrecv1*/, int /*nextrarecv1*/, ExecutionSpace /*space*/) { + k_buf.template sync(); + k_indices.template sync(); + d_buf = typename AT::t_double_1d_um( k_buf.template view().data(), k_buf.extent(0)*k_buf.extent(1)); d_indices = k_indices.view(); + // the kernel below writes only the rows of the atoms that arrived, so the + // rest have to be current on the device first. syncing here also retires + // any outstanding host claim, which the modify() at the end + // would otherwise hit as a concurrent modification + + k_history_one.template sync(); + d_history_one = k_history_one.template view(); copymode = 1; diff --git a/src/KOKKOS/fix_wall_gran_kokkos.h b/src/KOKKOS/fix_wall_gran_kokkos.h index bc7da57e54c..5b769d31393 100644 --- a/src/KOKKOS/fix_wall_gran_kokkos.h +++ b/src/KOKKOS/fix_wall_gran_kokkos.h @@ -47,6 +47,7 @@ class FixWallGranKokkos : public FixWallGranOld, public KokkosBase { void post_force(int) override; void grow_arrays(int) override; void copy_arrays(int, int, int) override; + void set_arrays(int) override; void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; From a16f0b9e1fd5504f3c23e90fcf9669d725cf8a7b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 19:58:22 +0000 Subject: [PATCH 110/120] unittest: run the stochastic references single-threaded on the KOKKOS OpenMP backend The host random number generator selected by -D KOKKOS_DEBUG_RNG=on reproduces the random number stream of the plain styles only from a single thread. The kokkos_omp and kokkos_omp_full test cases of the force style drivers run with four threads, so the references that depend on that stream (marked by a kokkos_omp_devicerng skip entry) could never match. Run those references with one thread instead, so the KOKKOS versions of the stochastic styles are validated on a build with the OpenMP backend as well. --- unittest/force-styles/test_angle_style.cpp | 15 +++++++++++++-- unittest/force-styles/test_bond_style.cpp | 15 +++++++++++++-- unittest/force-styles/test_dihedral_style.cpp | 15 +++++++++++++-- unittest/force-styles/test_fix_timestep.cpp | 15 +++++++++++++-- unittest/force-styles/test_improper_style.cpp | 15 +++++++++++++-- unittest/force-styles/test_min_style.cpp | 15 +++++++++++++-- unittest/force-styles/test_output_style.cpp | 15 +++++++++++++-- unittest/force-styles/test_pair_style.cpp | 15 +++++++++++++-- 8 files changed, 104 insertions(+), 16 deletions(-) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index 86dee71cc22..69fd3d1cf0a 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -585,6 +585,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // the "newton" argument must match the newton setting the command line // arguments select: with "-pk kokkos neigh full" the KOKKOS package rejects // "newton on", so the run re-reading the data file must use newton off as well @@ -919,7 +930,7 @@ TEST(AngleStyle, kokkos_omp) GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; run_kokkos_test(args); }; @@ -963,7 +974,7 @@ TEST(AngleStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 05435905f04..80e02447aff 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -585,6 +585,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // append the words of the LAMMPS_KOKKOS_ARGS environment variable to the // command line of the KOKKOS test cases. this lets the whole suite be re-run // with the "package kokkos" settings a GPU would choose -- @@ -901,7 +912,7 @@ TEST(BondStyle, kokkos_omp) GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; run_kokkos_test(args); }; @@ -945,7 +956,7 @@ TEST(BondStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 63727fc2a80..c3d9d527813 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -604,6 +604,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // append the words of the LAMMPS_KOKKOS_ARGS environment variable to the // command line of the KOKKOS test cases. this lets the whole suite be re-run // with the "package kokkos" settings a GPU would choose -- @@ -920,7 +931,7 @@ TEST(DihedralStyle, kokkos_omp) GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", - "-nocite", "-k", "on", "t", "4", + "-nocite", "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; run_kokkos_test(args); @@ -965,7 +976,7 @@ TEST(DihedralStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 21aa1b3b1a9..034fb60b8ee 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -970,6 +970,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // append the words of the LAMMPS_KOKKOS_ARGS environment variable to the // command line of the KOKKOS test cases. this lets the whole suite be re-run // with the "package kokkos" settings a GPU would choose -- @@ -1198,7 +1209,7 @@ TEST(FixTimestep, kokkos_omp) } LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; run_kokkos_test(args); }; @@ -1243,7 +1254,7 @@ TEST(FixTimestep, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index afe9f7c872f..ecdfa6c5a10 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -579,6 +579,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // append the words of the LAMMPS_KOKKOS_ARGS environment variable to the // command line of the KOKKOS test cases. this lets the whole suite be re-run // with the "package kokkos" settings a GPU would choose -- @@ -892,7 +903,7 @@ TEST(ImproperStyle, kokkos_omp) GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled"; LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", - "-nocite", "-k", "on", "t", "4", + "-nocite", "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; run_kokkos_test(args); @@ -937,7 +948,7 @@ TEST(ImproperStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_min_style.cpp b/unittest/force-styles/test_min_style.cpp index a7c0bb2cdf4..9d5ee04fe2e 100644 --- a/unittest/force-styles/test_min_style.cpp +++ b/unittest/force-styles/test_min_style.cpp @@ -313,6 +313,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // the KOKKOS minimizers descend along a different (but equally valid) path // than their plain counterparts, so the tolerances have to be relaxed the // same way as for the other KOKKOS force style tests @@ -354,7 +365,7 @@ TEST(MinStyle, kokkos_omp) } LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; append_kokkos_env_args(args); run_min_test(args, kokkos_epsilon()); @@ -400,7 +411,7 @@ TEST(MinStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"MinStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_output_style.cpp b/unittest/force-styles/test_output_style.cpp index 57541fd8175..a69cc2902d3 100644 --- a/unittest/force-styles/test_output_style.cpp +++ b/unittest/force-styles/test_output_style.cpp @@ -387,6 +387,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // the KOKKOS package accumulates in a different order and - depending on how it // was compiled - with reduced precision, so the tolerance has to be relaxed static double kokkos_epsilon() @@ -431,7 +442,7 @@ TEST(OutputStyle, kokkos_omp) } LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; append_kokkos_env_args(args); run_output_test(args, kokkos_epsilon(), true); @@ -477,7 +488,7 @@ TEST(OutputStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"OutputStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 52c726368a2..21b2d536116 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -754,6 +754,17 @@ static std::string kokkos_precision() return "double"; } +// the references of the stochastic styles can only be reproduced when the +// KOKKOS styles draw their random numbers from the host generator (see the +// KOKKOS_DEBUG_RNG build option) and from a single stream, i.e. with a single +// thread. those references carry a "kokkos_omp_devicerng" skip entry, so the +// OpenMP backend cases run them with one thread instead of four +static std::string kokkos_omp_nthreads() +{ + if (test_config.skip_tests.count("kokkos_omp_devicerng")) return "1"; + return "4"; +} + // the "newton" argument must match the newton setting the command line // arguments select: with "-pk kokkos neigh full" the KOKKOS package rejects // "newton on", so the restarted run has to be set up with newton off as well @@ -1214,7 +1225,7 @@ TEST(PairStyle, kokkos_omp) } LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk"}; // some styles cannot run with more than one thread in the test (dpd uses // multiple pRNGs, snap and pace due to their implementation); these are @@ -1264,7 +1275,7 @@ TEST(PairStyle, kokkos_omp_full) // index style variable defined with -var on the command line takes // precedence over the "variable ... index" definition inside the template LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", + "-k", "on", "t", kokkos_omp_nthreads(), "-sf", "kk", "-pk", "kokkos", "neigh", "full", "newton", "off", "-var", "newton_pair", "off", "-var", "newton_bond", "off"}; From 6b8d840b57db51ae6b2496b05a7146505da0e52d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 8 Sep 2026 16:04:46 -0400 Subject: [PATCH 111/120] hack to try and make the lammps-gui binary find the LAMMPS shared lib in the build folder --- cmake/Modules/Tools.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index a29f15337e7..13f4d4bee66 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -55,6 +55,17 @@ if(BUILD_LAMMPS_GUI) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") list(JOIN CMAKE_OSX_ARCHITECTURES , MACOSX_ARCHS) endif() + # hack to encode the LAMMPS build folder into the binary's rpath + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(LAMMPS_GUI_RPATH "@loader_path") + elseif(NOT WIN32) + set(LAMMPS_GUI_RPATH "\$ORIGIN") + endif() + if(LAMMPS_INSTALL_RPATH) + list(APPEND LAMMPS_GUI_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) + endif() + list(JOIN LAMMPS_GUI_RPATH , LAMMPS_GUI_RPATH) + # When building LAMMPS-GUI with LAMMPS we don't support plugin mode and don't include docs. ExternalProject_Add(lammps-gui_build GIT_REPOSITORY https://github.com/akohlmey/lammps-gui.git @@ -74,6 +85,7 @@ if(BUILD_LAMMPS_GUI) -D CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -D CMAKE_OSX_ARCHITECTURES=${MACOSX_ARCHS} -D CMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} + -D CMAKE_INSTALL_RPATH=${LAMMPS_GUI_RPATH} DEPENDS lammps BUILD_BYPRODUCTS /bin/lammps-gui ) From 96c6b118654b2592827273e261f0e13efe760571 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 20:07:10 +0000 Subject: [PATCH 112/120] fix wall/piston: initialize the temperature seed, seed the KOKKOS pool only with temp FixWallPiston left tseed uninitialized unless the temp keyword was given, and fix wall/piston/kk seeds its random pool from it in the constructor regardless. With the host random number generator (KOKKOS_DEBUG_RNG) that fed a garbage seed to RanMars, which rejects it; with the device pool it seeded the generator from uninitialized memory. Initialize the seed to zero and only set up and tear down the host generator wrapper when the temp keyword, and with it the generator, exists. --- src/KOKKOS/fix_wall_piston_kokkos.cpp | 6 ++++-- src/SHOCK/fix_wall_piston.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_wall_piston_kokkos.cpp b/src/KOKKOS/fix_wall_piston_kokkos.cpp index 134aef2a82e..b56d263084f 100644 --- a/src/KOKKOS/fix_wall_piston_kokkos.cpp +++ b/src/KOKKOS/fix_wall_piston_kokkos.cpp @@ -46,8 +46,10 @@ FixWallPistonKokkos::FixWallPistonKokkos(LAMMPS *lmp, int narg, char datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK | TYPE_MASK | RMASS_MASK; datamask_modify = X_MASK | V_MASK | F_MASK; + // the random number generator only exists with the temp keyword + #ifdef LMP_KOKKOS_DEBUG_RNG - rand_pool.init(randomt,tseed + comm->me); + if (tempflag) rand_pool.init(randomt,tseed + comm->me); #endif } @@ -59,7 +61,7 @@ FixWallPistonKokkos::~FixWallPistonKokkos() if (copymode) return; #ifdef LMP_KOKKOS_DEBUG_RNG - rand_pool.destroy(); + if (tempflag) rand_pool.destroy(); #endif } diff --git a/src/SHOCK/fix_wall_piston.cpp b/src/SHOCK/fix_wall_piston.cpp index 112e55e8545..fcb3412ba82 100644 --- a/src/SHOCK/fix_wall_piston.cpp +++ b/src/SHOCK/fix_wall_piston.cpp @@ -42,6 +42,7 @@ FixWallPiston::FixWallPiston(LAMMPS *lmp, int narg, char **arg) : if (narg < 4) utils::missing_cmd_args(FLERR,"fix wall/piston", error); tempflag = 0; + tseed = 0; scaleflag = 1; roughflag = 0; roughdist = 0.0; From 22d3173c79e2eb98bd461c1a85cf5ebefb20f8e9 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Sep 2026 20:26:32 +0000 Subject: [PATCH 113/120] unittest: skip the KOKKOS cases of the tally compute and sph references The tally computes are rejected by Pair::init() when the KOKKOS package is active, and atom style sph has no KOKKOS version, so the kokkos_omp and kokkos_serial cases of these output style references cannot run. --- unittest/force-styles/tests/compute-heat_flux_tally.yaml | 2 +- unittest/force-styles/tests/compute-pe_mol_tally.yaml | 2 +- unittest/force-styles/tests/compute-pe_tally.yaml | 2 +- unittest/force-styles/tests/compute-property_atom_sph.yaml | 2 +- unittest/force-styles/tests/compute-stress_tally.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unittest/force-styles/tests/compute-heat_flux_tally.yaml b/unittest/force-styles/tests/compute-heat_flux_tally.yaml index 5a94a70bb9a..bfc50d8dbd8 100644 --- a/unittest/force-styles/tests/compute-heat_flux_tally.yaml +++ b/unittest/force-styles/tests/compute-heat_flux_tally.yaml @@ -4,7 +4,7 @@ tags: date_generated: Thu Jul 9 16:34:29 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full compute heat/flux/tally diff --git a/unittest/force-styles/tests/compute-pe_mol_tally.yaml b/unittest/force-styles/tests/compute-pe_mol_tally.yaml index aa2d8e3999d..0c8caa25b90 100644 --- a/unittest/force-styles/tests/compute-pe_mol_tally.yaml +++ b/unittest/force-styles/tests/compute-pe_mol_tally.yaml @@ -4,7 +4,7 @@ tags: date_generated: Thu Jul 9 16:34:27 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full compute pe/mol/tally diff --git a/unittest/force-styles/tests/compute-pe_tally.yaml b/unittest/force-styles/tests/compute-pe_tally.yaml index 165f29729dc..08933ca3ddd 100644 --- a/unittest/force-styles/tests/compute-pe_tally.yaml +++ b/unittest/force-styles/tests/compute-pe_tally.yaml @@ -4,7 +4,7 @@ tags: date_generated: Thu Jul 9 16:34:26 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full compute pe/tally diff --git a/unittest/force-styles/tests/compute-property_atom_sph.yaml b/unittest/force-styles/tests/compute-property_atom_sph.yaml index 38ac50cf265..e70028850ce 100644 --- a/unittest/force-styles/tests/compute-property_atom_sph.yaml +++ b/unittest/force-styles/tests/compute-property_atom_sph.yaml @@ -4,7 +4,7 @@ tags: date_generated: Sun Aug 23 12:37:04 2026 epsilon: 1e-08 timestep: 5e-04 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom sph compute property/atom diff --git a/unittest/force-styles/tests/compute-stress_tally.yaml b/unittest/force-styles/tests/compute-stress_tally.yaml index c0da935a08f..9519ee5eebb 100644 --- a/unittest/force-styles/tests/compute-stress_tally.yaml +++ b/unittest/force-styles/tests/compute-stress_tally.yaml @@ -4,7 +4,7 @@ tags: date_generated: Thu Jul 9 16:34:28 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full compute stress/tally From b7ac38e2a4ba9d56d272f320edd17a34575cc958 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 9 Sep 2026 01:00:00 +0000 Subject: [PATCH 114/120] fix baoab: form the noise amplitude without cancellation, skip force/tally with KOKKOS The O-step noise amplitude of fix baoab uses 1 - c1^2 with c1 = exp(-gamma*dt). For small gamma*dt that difference loses precision: a one ulp change of exp() from one libm to another becomes a relative change of order ulp/(gamma*dt) in every random kick, which is why the fix-timestep-baoab_zero reference passed on Linux/glibc but failed on macOS and Windows. Form 1 - exp(-2*gamma*dt) with expm1() instead, in the plain style and in the KOKKOS variant, which reuses the value. The two baoab references were regenerated for this (relative changes of up to 2e-13 for baoab and 2e-12 for baoab_zero on glibc), and the zero variant, whose smallest velocity component is a factor of 300 below the velocity scale, now uses a tolerance of 1e-12. The compute-force_tally reference gains the same KOKKOS skip as the other tally computes, which Pair::init() rejects with the KOKKOS package. --- src/EXTRA-FIX/fix_baoab.cpp | 9 ++- src/EXTRA-FIX/fix_baoab.h | 1 + src/KOKKOS/fix_baoab_kokkos.cpp | 2 +- .../tests/compute-force_tally.yaml | 2 +- .../tests/fix-timestep-baoab.yaml | 68 ++++++++--------- .../tests/fix-timestep-baoab_zero.yaml | 76 +++++++++---------- 6 files changed, 81 insertions(+), 77 deletions(-) diff --git a/src/EXTRA-FIX/fix_baoab.cpp b/src/EXTRA-FIX/fix_baoab.cpp index 14bc0097b6b..143de2070a0 100644 --- a/src/EXTRA-FIX/fix_baoab.cpp +++ b/src/EXTRA-FIX/fix_baoab.cpp @@ -133,6 +133,12 @@ void FixBAOAB::recompute_dt_coeffs() dtf = 0.5 * dt * force->ftm2v; // half-kick: F/m -> dv dtby2 = 0.5 * dt; // half-drift: v -> dx c1 = exp(-gamma * dt); // O-step decay (full dt) + + // 1 - c1^2 = 1 - exp(-2*gamma*dt) suffers from cancellation for small + // gamma*dt (a one ulp difference in exp() from one libm to another shows + // up as a relative difference of order ulp/(gamma*dt) in the noise + // amplitude); expm1() forms it without that loss of precision. + one_minus_c1sq = -std::expm1(-2.0 * gamma * dt); } /* ---------------------------------------------------------------------- */ @@ -180,9 +186,6 @@ void FixBAOAB::initial_integrate(int /*vflag*/) // so v^2 ~ kT / (mvv2e * m), hence noise scale = sqrt(kT / (mvv2e * m)) double kT = force->boltz * t_target / force->mvv2e; - // O-step coefficients that are mass-independent - double one_minus_c1sq = 1.0 - c1 * c1; - // For energy tally: accumulate KE change during O step energy_onestep = 0.0; diff --git a/src/EXTRA-FIX/fix_baoab.h b/src/EXTRA-FIX/fix_baoab.h index 8dbf3b7e9ca..882e59658ad 100644 --- a/src/EXTRA-FIX/fix_baoab.h +++ b/src/EXTRA-FIX/fix_baoab.h @@ -48,6 +48,7 @@ class FixBAOAB : public Fix { double dtf; // 0.5*dt*ftm2v (force->velocity kick) double dtby2; // 0.5*dt (half-step drift) double c1; // exp(-gamma*dt) for O step + double one_minus_c1sq; // 1 - c1^2, formed without cancellation // Energy accounting double energy; // cumulative thermostat energy diff --git a/src/KOKKOS/fix_baoab_kokkos.cpp b/src/KOKKOS/fix_baoab_kokkos.cpp index 219a298e1f8..0581c447490 100644 --- a/src/KOKKOS/fix_baoab_kokkos.cpp +++ b/src/KOKKOS/fix_baoab_kokkos.cpp @@ -103,7 +103,7 @@ void FixBAOABKokkos::initial_integrate(int /*vflag*/) l_dtby2 = static_cast(dtby2); l_c1 = static_cast(c1); l_kT = static_cast(kT); - l_one_minus_c1sq = static_cast(1.0 - c1*c1); + l_one_minus_c1sq = static_cast(one_minus_c1sq); l_mvv2e = static_cast(force->mvv2e); const int rmass_flag = (atomKK->rmass) ? 1 : 0; diff --git a/unittest/force-styles/tests/compute-force_tally.yaml b/unittest/force-styles/tests/compute-force_tally.yaml index c77199a8780..09ccb75779f 100644 --- a/unittest/force-styles/tests/compute-force_tally.yaml +++ b/unittest/force-styles/tests/compute-force_tally.yaml @@ -4,7 +4,7 @@ tags: date_generated: Thu Jul 9 16:34:28 2026 epsilon: 1e-08 timestep: 0.25 -skip_tests: +skip_tests: kokkos_omp kokkos_serial kokkos_gpu prerequisites: | atom full compute force/tally diff --git a/unittest/force-styles/tests/fix-timestep-baoab.yaml b/unittest/force-styles/tests/fix-timestep-baoab.yaml index a4ec72038ea..62ef66a2c53 100644 --- a/unittest/force-styles/tests/fix-timestep-baoab.yaml +++ b/unittest/force-styles/tests/fix-timestep-baoab.yaml @@ -1,7 +1,7 @@ --- -lammps_version: 4 Jul 2026 +lammps_version: 2 Sep 2026 tags: no_respa no_restart -date_generated: Fri Jul 10 18:23:09 2026 +date_generated: Wed Sep 9 00:58:56 2026 epsilon: 1e-13 skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | @@ -13,15 +13,15 @@ post_commands: | input_file: in.fourmol input_coeffs: coeffs.fourmol natoms: 29 -global_scalar: 3.664877636075576 +global_scalar: 3.66487763607563 run_pos: |2 1 -2.7067507143691355e-01 2.4910580768574300e+00 -1.6631050376577533e-01 2 3.1152799841835715e-01 2.9613675727312270e+00 -8.5346547950480645e-01 3 -7.0413876628554428e-01 1.2304969508698880e+00 -6.2750409217653003e-01 4 -1.5811175437564533e+00 1.4816588063613170e+00 -1.2532028295810731e+00 - 5 -9.0815952672731581e-01 9.2721690802654755e-01 3.9823529868989327e-01 + 5 -9.0815952672731581e-01 9.2721690802654755e-01 3.9823529868989332e-01 6 2.4921296853059641e-01 2.8345043050314966e-01 -1.2315206807841570e+00 - 7 3.4191267808772707e-01 -2.2916968108084280e-02 -2.5291322218611092e+00 + 7 3.4191267808772707e-01 -2.2916968108084277e-02 -2.5291322218611092e+00 8 1.1735264709244912e+00 -4.8882924911844700e-01 -6.3770292847806975e-01 9 1.3796171883370409e+00 -2.5175146135035870e-01 2.8371227828850698e-01 10 2.0511923252022850e+00 -1.4598280863156896e+00 -9.8305060327887195e-01 @@ -45,33 +45,33 @@ run_pos: |2 28 -2.7473937657551240e+00 -4.0197651566756409e+00 1.5838675023152931e+00 29 -1.3132267304809122e+00 -3.5967795074193862e+00 2.2734909574012834e+00 run_vel: |2 - 1 7.9399065388223253e-03 1.6531396704975415e-02 5.1269062624833793e-03 - 2 7.2427904338974803e-03 5.1067110173538101e-03 -1.2656232116416504e-04 - 3 -8.6679865024174331e-03 -1.3021618085860562e-02 -4.0396986904126207e-03 - 4 -3.2384154460983888e-03 -8.5997583988723977e-03 1.4344217478502006e-04 - 5 -1.1323772923719840e-02 -9.3757662053162438e-03 -3.7377464177891047e-03 - 6 -3.8730464220717728e-02 4.6978399683187469e-02 3.6576885964478813e-02 - 7 1.2904330923861871e-03 -1.0062264193717488e-02 -5.0952949783776867e-02 - 8 7.5613019768830799e-03 -3.2642517187285924e-03 3.4475573576465982e-02 - 9 9.2603550312237901e-04 4.6641185730215912e-03 1.4637575818793934e-02 - 10 2.9812398718965228e-02 -2.9019554608477757e-02 -1.5048466638201327e-02 - 11 -5.5052071532369256e-03 -3.2618867386116951e-03 -3.3057113269925496e-03 - 12 1.8020832808338808e-03 -7.0830377984021007e-04 -3.0292676892394862e-03 - 13 3.4076025486203306e-03 6.0849953971147510e-03 -2.3939542443458827e-03 - 14 2.2558002210795046e-03 -6.1349270585104561e-03 -1.6577101684239082e-03 - 15 -2.8077496698201217e-03 -5.1642923603242644e-03 5.0865499123589107e-03 - 16 1.8516425491062617e-02 -1.3616126464292522e-02 -4.5142394026034371e-02 - 17 -1.2764304499001483e-02 9.5378027922474237e-03 3.6448723975950323e-02 - 18 -8.0586311061791097e-04 -7.2418017120987749e-04 -1.5767099261385573e-03 - 19 5.8077475881775130e-04 -2.8148382973097580e-03 6.4606782830329956e-03 - 20 4.1877767247630125e-03 3.6281596605146544e-03 2.7333996849199941e-03 - 21 -8.7776861000622437e-04 -8.8069958739756150e-05 -9.6526028935571526e-05 - 22 -8.1627691852073775e-03 -5.0909905763817948e-03 4.7569140452230024e-05 - 23 5.1612483859322681e-03 -2.0148452435599208e-03 3.0009099167834035e-03 - 24 1.3085212729330755e-04 -7.4631608703425102e-04 2.2748391047174742e-04 - 25 8.2628353782606529e-04 -4.8824907076967369e-03 -1.5456182538864036e-03 - 26 2.3028600877504006e-03 1.1966380674180411e-03 4.1344983323392702e-03 - 27 1.1243343826718409e-03 -1.4731218556795285e-03 1.1699868197163194e-03 - 28 -5.8952383128557844e-03 8.1666000663859850e-04 -9.9038089085807623e-04 - 29 4.5067181216534977e-05 3.0055726486582757e-03 2.8509966494852570e-03 + 1 7.9399065388223271e-03 1.6531396704975415e-02 5.1269062624833758e-03 + 2 7.2427904338974612e-03 5.1067110173538084e-03 -1.2656232116417800e-04 + 3 -8.6679865024174279e-03 -1.3021618085860555e-02 -4.0396986904126207e-03 + 4 -3.2384154460983940e-03 -8.5997583988723768e-03 1.4344217478500743e-04 + 5 -1.1323772923719836e-02 -9.3757662053162508e-03 -3.7377464177890951e-03 + 6 -3.8730464220717742e-02 4.6978399683187476e-02 3.6576885964478806e-02 + 7 1.2904330923861832e-03 -1.0062264193717486e-02 -5.0952949783776867e-02 + 8 7.5613019768830869e-03 -3.2642517187285963e-03 3.4475573576465988e-02 + 9 9.2603550312238508e-04 4.6641185730215799e-03 1.4637575818793935e-02 + 10 2.9812398718965218e-02 -2.9019554608477761e-02 -1.5048466638201327e-02 + 11 -5.5052071532369169e-03 -3.2618867386116994e-03 -3.3057113269925383e-03 + 12 1.8020832808338864e-03 -7.0830377984020529e-04 -3.0292676892394866e-03 + 13 3.4076025486203224e-03 6.0849953971147475e-03 -2.3939542443458658e-03 + 14 2.2558002210795181e-03 -6.1349270585104526e-03 -1.6577101684239323e-03 + 15 -2.8077496698201091e-03 -5.1642923603242713e-03 5.0865499123589212e-03 + 16 1.8516425491062614e-02 -1.3616126464292517e-02 -4.5142394026034385e-02 + 17 -1.2764304499001480e-02 9.5378027922474237e-03 3.6448723975950323e-02 + 18 -8.0586311061791075e-04 -7.2418017120987857e-04 -1.5767099261385557e-03 + 19 5.8077475881775857e-04 -2.8148382973097537e-03 6.4606782830330025e-03 + 20 4.1877767247630046e-03 3.6281596605146553e-03 2.7333996849199988e-03 + 21 -8.7776861000623109e-04 -8.8069958739758427e-05 -9.6526028935563340e-05 + 22 -8.1627691852073636e-03 -5.0909905763817861e-03 4.7569140452233114e-05 + 23 5.1612483859322785e-03 -2.0148452435599139e-03 3.0009099167833970e-03 + 24 1.3085212729330929e-04 -7.4631608703425406e-04 2.2748391047174656e-04 + 25 8.2628353782605683e-04 -4.8824907076967308e-03 -1.5456182538863958e-03 + 26 2.3028600877503989e-03 1.1966380674180589e-03 4.1344983323392710e-03 + 27 1.1243343826718339e-03 -1.4731218556795237e-03 1.1699868197163096e-03 + 28 -5.8952383128557870e-03 8.1666000663860392e-04 -9.9038089085808491e-04 + 29 4.5067181216542241e-05 3.0055726486582779e-03 2.8509966494852665e-03 ... diff --git a/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml b/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml index 22815197eda..0f8a1aabb08 100644 --- a/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml +++ b/unittest/force-styles/tests/fix-timestep-baoab_zero.yaml @@ -1,8 +1,8 @@ --- lammps_version: 2 Sep 2026 tags: no_respa no_restart -date_generated: Fri Sep 4 18:13:44 2026 -epsilon: 1e-13 +date_generated: Wed Sep 9 00:58:57 2026 +epsilon: 1e-12 skip_tests: kokkos_gpu_devicerng kokkos_omp_devicerng kokkos_serial_devicerng prerequisites: | atom full @@ -13,24 +13,24 @@ post_commands: | input_file: in.fourmol input_coeffs: coeffs.fourmol natoms: 29 -global_scalar: 3.6606108848920593 +global_scalar: 3.6606108848921 run_pos: |2 1 -2.7065544220190391e-01 2.4911779835474488e+00 -1.6630178090272518e-01 2 3.1154762765336685e-01 2.9614874794212449e+00 -8.5345675664175580e-01 3 -7.0411913705053442e-01 1.2306168575599066e+00 -6.2749536931347982e-01 4 -1.5810979145214437e+00 1.4817787130513353e+00 -1.2531941067180228e+00 - 5 -9.0813989749230650e-01 9.2733681471656615e-01 3.9824402155294347e-01 + 5 -9.0813989749230639e-01 9.2733681471656615e-01 3.9824402155294347e-01 6 2.4923259776560597e-01 2.8357033719316821e-01 -1.2315119579211076e+00 - 7 3.4193230732273677e-01 -2.2797061418065614e-02 -2.5291234989980591e+00 + 7 3.4193230732273672e-01 -2.2797061418065610e-02 -2.5291234989980591e+00 8 1.1735461001595002e+00 -4.8870934242842856e-01 -6.3769420561501922e-01 - 9 1.3796368175720506e+00 -2.5163155466034015e-01 2.8372100115155724e-01 - 10 2.0512119544372944e+00 -1.4597081796256712e+00 -9.8304188041582130e-01 + 9 1.3796368175720506e+00 -2.5163155466034021e-01 2.8372100115155724e-01 + 10 2.0512119544372944e+00 -1.4597081796256715e+00 -9.8304188041582130e-01 11 1.7875223460235372e+00 -1.9921845604438904e+00 -1.8903443497496268e+00 12 3.0054437039770825e+00 -4.9069919886744923e-01 -1.6230628479382263e+00 - 13 4.0529102819981135e+00 -8.9092089612028269e-01 -1.6410002725417654e+00 + 13 4.0529102819981135e+00 -8.9092089612028280e-01 -1.6410002725417654e+00 14 2.6058383843415562e+00 -4.1772313378282200e-01 -2.6618514969951499e+00 15 2.9681750895611816e+00 5.5545681271484615e-01 -1.2351544003038268e+00 - 16 2.6742512015348341e+00 -2.4129907577800975e+00 -2.2996058488555324e-02 + 16 2.6742512015348341e+00 -2.4129907577800975e+00 -2.2996058488555318e-02 17 2.2151741055502736e+00 -2.0898342586976626e+00 1.1954825227154366e+00 18 2.1369461782623187e+00 3.0159409086854065e+00 -3.5182858172867579e+00 19 1.5351313107554068e+00 2.6251451580743863e+00 -4.2365877214351615e+00 @@ -45,33 +45,33 @@ run_pos: |2 28 -2.7473741365201145e+00 -4.0196452499856239e+00 1.5838762251783427e+00 29 -1.3132071012459021e+00 -3.5966596007293687e+00 2.2734996802643330e+00 run_vel: |2 - 1 7.8829824947026037e-03 1.6618157210244445e-02 5.1537759308672706e-03 - 2 7.1858663897778263e-03 5.1934715226229569e-03 -9.9692652780288422e-05 - 3 -8.7249105465370992e-03 -1.2934857580591333e-02 -4.0128290220286696e-03 - 4 -3.2953394902180549e-03 -8.5129978936032899e-03 1.7031184316892309e-04 - 5 -1.1380696967839497e-02 -9.2890057000471222e-03 -3.7108767494052073e-03 - 6 -3.8787388264837394e-02 4.7065160188456585e-02 3.6603755632862764e-02 - 7 1.2335090482665093e-03 -9.9755036884483662e-03 -5.0926080115392972e-02 - 8 7.5043779327633392e-03 -3.1774912134594283e-03 3.4502443244849884e-02 - 9 8.6911145900270118e-04 4.7508790782907354e-03 1.4664445487177878e-02 - 10 2.9755474674845607e-02 -2.8932794103208648e-02 -1.5021596969817447e-02 - 11 -5.5621311973566186e-03 -3.1751262333425856e-03 -3.2788416586086375e-03 - 12 1.7451592367141713e-03 -6.2154327457110273e-04 -3.0023980208555459e-03 - 13 3.3506785045005916e-03 6.1717559023839030e-03 -2.3670845759619858e-03 - 14 2.1988761769598459e-03 -6.0481665532413527e-03 -1.6308405000400471e-03 - 15 -2.8646737139397687e-03 -5.0775318550551453e-03 5.1134195807428342e-03 - 16 1.8459501446942982e-02 -1.3529365959023449e-02 -4.5115524357650635e-02 - 17 -1.2821228543121196e-02 9.6245632975165783e-03 3.6475593644334371e-02 - 18 -8.6278715473761211e-04 -6.3741966594076625e-04 -1.5498402577546753e-03 - 19 5.2385071469808410e-04 -2.7280777920406386e-03 6.4875479514169970e-03 - 20 4.1308526806433880e-03 3.7149201657838216e-03 2.7602693533039335e-03 - 21 -9.3469265412593342e-04 -1.3094534706537315e-06 -6.9656360551624186e-05 - 22 -8.2196932293271303e-03 -5.0042300711126957e-03 7.4438808836049103e-05 - 23 5.1043243418127616e-03 -1.9280847382906988e-03 3.0277795851672653e-03 - 24 7.3928083173641925e-05 -6.5955558176511019e-04 2.5435357885566503e-04 - 25 7.6935949370634344e-04 -4.7957302024276187e-03 -1.5187485855025185e-03 - 26 2.2459360436306868e-03 1.2833985726870920e-03 4.1613680007231875e-03 - 27 1.0674103385521442e-03 -1.3863613504104372e-03 1.1968564881002337e-03 - 28 -5.9521623569754514e-03 9.0342051190774877e-04 -9.6351122247416595e-04 - 29 -1.1856862903108020e-05 3.0923331539274936e-03 2.8778663178691630e-03 + 1 7.8829824947026072e-03 1.6618157210244441e-02 5.1537759308672671e-03 + 2 7.1858663897778081e-03 5.1934715226229534e-03 -9.9692652780302001e-05 + 3 -8.7249105465370940e-03 -1.2934857580591326e-02 -4.0128290220286713e-03 + 4 -3.2953394902180623e-03 -8.5129978936032673e-03 1.7031184316891338e-04 + 5 -1.1380696967839497e-02 -9.2890057000471309e-03 -3.7108767494051925e-03 + 6 -3.8787388264837394e-02 4.7065160188456578e-02 3.6603755632862764e-02 + 7 1.2335090482665052e-03 -9.9755036884483644e-03 -5.0926080115392972e-02 + 8 7.5043779327633861e-03 -3.1774912134594699e-03 3.4502443244849870e-02 + 9 8.6911145900270834e-04 4.7508790782907215e-03 1.4664445487177878e-02 + 10 2.9755474674845551e-02 -2.8932794103208596e-02 -1.5021596969817436e-02 + 11 -5.5621311973566108e-03 -3.1751262333425978e-03 -3.2788416586086288e-03 + 12 1.7451592367141778e-03 -6.2154327457110512e-04 -3.0023980208555437e-03 + 13 3.3506785045005795e-03 6.1717559023839012e-03 -2.3670845759619680e-03 + 14 2.1988761769598589e-03 -6.0481665532413518e-03 -1.6308405000400705e-03 + 15 -2.8646737139397574e-03 -5.0775318550551540e-03 5.1134195807428463e-03 + 16 1.8459501446942989e-02 -1.3529365959023449e-02 -4.5115524357650656e-02 + 17 -1.2821228543121196e-02 9.6245632975165835e-03 3.6475593644334378e-02 + 18 -8.6278715473761124e-04 -6.3741966594076820e-04 -1.5498402577546740e-03 + 19 5.2385071469809223e-04 -2.7280777920406351e-03 6.4875479514170048e-03 + 20 4.1308526806433802e-03 3.7149201657838212e-03 2.7602693533039383e-03 + 21 -9.3469265412593938e-04 -1.3094534706569231e-06 -6.9656360551616326e-05 + 22 -8.2196932293271182e-03 -5.0042300711126888e-03 7.4438808836052302e-05 + 23 5.1043243418127712e-03 -1.9280847382906923e-03 3.0277795851672588e-03 + 24 7.3928083173644039e-05 -6.5955558176511409e-04 2.5435357885566395e-04 + 25 7.6935949370633607e-04 -4.7957302024276153e-03 -1.5187485855025116e-03 + 26 2.2459360436306859e-03 1.2833985726871094e-03 4.1613680007231901e-03 + 27 1.0674103385521375e-03 -1.3863613504104333e-03 1.1968564881002230e-03 + 28 -5.9521623569754548e-03 9.0342051190775365e-04 -9.6351122247417505e-04 + 29 -1.1856862903100160e-05 3.0923331539274945e-03 2.8778663178691726e-03 ... From 6cd545001780aa36bf2f9b12900575e90073b857 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 9 Sep 2026 02:30:57 +0000 Subject: [PATCH 115/120] compute pe/atom, stress/atom, centroid/stress/atom: zero ghost entries before a TIP4P reverse communication The three per-atom computes reverse communicate their ghost entries not only with newton on but also when the kspace style carries the tip4pflag (kspace_style zero, pppm/tip4p, pppm/disp/tip4p). With newton off, however, only the entries of the owned atoms were cleared, so the ghost part of the array held whatever the memory contained before and was added to the owned atoms by the reverse communication. With freshly mapped memory the garbage is zero, so the defect stayed silent; when the allocation reuses memory of an earlier run the sum is wrong. valgrind reports the uninitialized values on a plain CPU run of the kspace-zero reference with newton off, and the KOKKOS full neighbor list case of that reference (which requires newton off) failed at random with a per-atom energy sum of several hundred while the pair style, with pair_modify compute no, had computed nothing. Clear the ghost entries whenever the reverse communication runs. --- src/compute_centroid_stress_atom.cpp | 6 ++++-- src/compute_pe_atom.cpp | 6 ++++-- src/compute_stress_atom.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/compute_centroid_stress_atom.cpp b/src/compute_centroid_stress_atom.cpp index 60a9c2a36b1..b00752e5fe1 100644 --- a/src/compute_centroid_stress_atom.cpp +++ b/src/compute_centroid_stress_atom.cpp @@ -225,8 +225,10 @@ void ComputeCentroidStressAtom::compute_peratom() // npair includes ghosts if either newton flag is set // b/c some bonds/dihedrals call pair::ev_tally with pairwise info // nbond includes ghosts if newton_bond is set - // ntotal includes ghosts if either newton flag is set // KSpace includes ghosts if tip4pflag is set + // ntotal includes ghosts if either newton flag is set or if the ghost + // values are reverse communicated below (tip4pflag), since the entries + // of atoms that are not tallied by any style must be zero for that int nlocal = atom->nlocal; int npair = nlocal; @@ -235,8 +237,8 @@ void ComputeCentroidStressAtom::compute_peratom() int nkspace = nlocal; if (force->newton) npair += atom->nghost; if (force->newton_bond) nbond += atom->nghost; - if (force->newton) ntotal += atom->nghost; if (force->kspace && force->kspace->tip4pflag) nkspace += atom->nghost; + if (force->newton || (force->kspace && force->kspace->tip4pflag)) ntotal += atom->nghost; // clear local stress array diff --git a/src/compute_pe_atom.cpp b/src/compute_pe_atom.cpp index 05f35ca9a61..e6ab459567c 100644 --- a/src/compute_pe_atom.cpp +++ b/src/compute_pe_atom.cpp @@ -109,8 +109,10 @@ void ComputePEAtom::compute_peratom() // npair includes ghosts if either newton flag is set // b/c some bonds/dihedrals call pair::ev_tally with pairwise info // nbond includes ghosts if newton_bond is set - // ntotal includes ghosts if either newton flag is set // KSpace includes ghosts if tip4pflag is set + // ntotal includes ghosts if either newton flag is set or if the ghost + // values are reverse communicated below (tip4pflag), since the entries + // of atoms that are not tallied by any style must be zero for that int nlocal = atom->nlocal; int npair = nlocal; @@ -119,8 +121,8 @@ void ComputePEAtom::compute_peratom() int nkspace = nlocal; if (force->newton) npair += atom->nghost; if (force->newton_bond) nbond += atom->nghost; - if (force->newton) ntotal += atom->nghost; if (force->kspace && force->kspace->tip4pflag) nkspace += atom->nghost; + if (force->newton || (force->kspace && force->kspace->tip4pflag)) ntotal += atom->nghost; // clear local energy array diff --git a/src/compute_stress_atom.cpp b/src/compute_stress_atom.cpp index 6f0f90b1966..43ebbd31c7c 100644 --- a/src/compute_stress_atom.cpp +++ b/src/compute_stress_atom.cpp @@ -157,8 +157,10 @@ void ComputeStressAtom::compute_peratom() // npair includes ghosts if either newton flag is set // b/c some bonds/dihedrals call pair::ev_tally with pairwise info // nbond includes ghosts if newton_bond is set - // ntotal includes ghosts if either newton flag is set // KSpace includes ghosts if tip4pflag is set + // ntotal includes ghosts if either newton flag is set or if the ghost + // values are reverse communicated below (tip4pflag), since the entries + // of atoms that are not tallied by any style must be zero for that int nlocal = atom->nlocal; int npair = nlocal; @@ -167,8 +169,8 @@ void ComputeStressAtom::compute_peratom() int nkspace = nlocal; if (force->newton) npair += atom->nghost; if (force->newton_bond) nbond += atom->nghost; - if (force->newton) ntotal += atom->nghost; if (force->kspace && force->kspace->tip4pflag) nkspace += atom->nghost; + if (force->newton || (force->kspace && force->kspace->tip4pflag)) ntotal += atom->nghost; // clear local stress array From 65f29f92bbe737f87f8efca7865f51a74f22f90b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 9 Sep 2026 10:27:47 -0400 Subject: [PATCH 116/120] flag slow tests as slow --- unittest/force-styles/tests/kspace-ewald_disp_arith.yaml | 2 +- unittest/force-styles/tests/kspace-ewald_disp_mixgeom.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unittest/force-styles/tests/kspace-ewald_disp_arith.yaml b/unittest/force-styles/tests/kspace-ewald_disp_arith.yaml index 55ec8ba5c7c..f1a8b58510c 100644 --- a/unittest/force-styles/tests/kspace-ewald_disp_arith.yaml +++ b/unittest/force-styles/tests/kspace-ewald_disp_arith.yaml @@ -1,6 +1,6 @@ --- lammps_version: 30 Mar 2026 -tags: +tags: slow date_generated: Wed Jun 10 22:46:10 2026 epsilon: 5e-12 skip_tests: extract gpu single diff --git a/unittest/force-styles/tests/kspace-ewald_disp_mixgeom.yaml b/unittest/force-styles/tests/kspace-ewald_disp_mixgeom.yaml index 81e5c4cc41b..7881030e310 100644 --- a/unittest/force-styles/tests/kspace-ewald_disp_mixgeom.yaml +++ b/unittest/force-styles/tests/kspace-ewald_disp_mixgeom.yaml @@ -1,6 +1,6 @@ --- lammps_version: 30 Mar 2026 -tags: +tags: slow date_generated: Tue Jun 30 16:11:28 2026 epsilon: 5e-12 skip_tests: extract gpu single From 9df17fb8e34a09d5df972d4de3a2695f51d99037 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 9 Sep 2026 10:30:14 -0400 Subject: [PATCH 117/120] update unittest YAML file tags --- unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml | 2 +- .../force-styles/tests/fix-timestep-wall_region_harmonic.yaml | 2 +- .../force-styles/tests/fix-timestep-wall_region_lj1043.yaml | 2 +- unittest/force-styles/tests/fix-timestep-wall_region_lj126.yaml | 2 +- unittest/force-styles/tests/fix-timestep-wall_region_lj93.yaml | 2 +- unittest/force-styles/tests/fix-timestep-wall_region_morse.yaml | 2 +- .../force-styles/tests/fix-timestep-wall_region_sphere.yaml | 2 +- unittest/force-styles/tests/kspace-ewald_conp_charge.yaml | 2 +- unittest/force-styles/tests/kspace-pppm_conp_charge.yaml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml b/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml index ef32e8b76db..4c91262df88 100644 --- a/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml +++ b/unittest/force-styles/tests/atomic-pair-lj_expand_sphere.yaml @@ -1,6 +1,6 @@ --- lammps_version: 2 Sep 2026 -tags: unstable generated +tags: unstable date_generated: Sat Sep 5 03:36:37 2026 epsilon: 7.5e-13 skip_tests: single diff --git a/unittest/force-styles/tests/fix-timestep-wall_region_harmonic.yaml b/unittest/force-styles/tests/fix-timestep-wall_region_harmonic.yaml index 066c5476869..ac4536a06f7 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_region_harmonic.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_region_harmonic.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Tue Sep 1 17:10:43 2026 epsilon: 1e-13 skip_tests: kokkos_gpu diff --git a/unittest/force-styles/tests/fix-timestep-wall_region_lj1043.yaml b/unittest/force-styles/tests/fix-timestep-wall_region_lj1043.yaml index e2665b9d28a..827f7f67dda 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_region_lj1043.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_region_lj1043.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Tue Sep 1 17:10:43 2026 epsilon: 1e-13 skip_tests: kokkos_gpu diff --git a/unittest/force-styles/tests/fix-timestep-wall_region_lj126.yaml b/unittest/force-styles/tests/fix-timestep-wall_region_lj126.yaml index de6fed482fd..a0b7c6d1d64 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_region_lj126.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_region_lj126.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Tue Sep 1 17:10:43 2026 epsilon: 1e-13 skip_tests: kokkos_gpu diff --git a/unittest/force-styles/tests/fix-timestep-wall_region_lj93.yaml b/unittest/force-styles/tests/fix-timestep-wall_region_lj93.yaml index b43557776c3..69db2869ba5 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_region_lj93.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_region_lj93.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Tue Sep 1 17:10:43 2026 epsilon: 1e-13 skip_tests: kokkos_gpu diff --git a/unittest/force-styles/tests/fix-timestep-wall_region_morse.yaml b/unittest/force-styles/tests/fix-timestep-wall_region_morse.yaml index a753ea815ef..fda827098cc 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_region_morse.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_region_morse.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Tue Sep 1 17:10:43 2026 epsilon: 1e-13 skip_tests: kokkos_gpu diff --git a/unittest/force-styles/tests/fix-timestep-wall_region_sphere.yaml b/unittest/force-styles/tests/fix-timestep-wall_region_sphere.yaml index 36c06abd80f..03a8a575664 100644 --- a/unittest/force-styles/tests/fix-timestep-wall_region_sphere.yaml +++ b/unittest/force-styles/tests/fix-timestep-wall_region_sphere.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Tue Sep 1 17:10:43 2026 epsilon: 1e-13 skip_tests: kokkos_gpu diff --git a/unittest/force-styles/tests/kspace-ewald_conp_charge.yaml b/unittest/force-styles/tests/kspace-ewald_conp_charge.yaml index 89404fac6b5..80770361dda 100644 --- a/unittest/force-styles/tests/kspace-ewald_conp_charge.yaml +++ b/unittest/force-styles/tests/kspace-ewald_conp_charge.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Sun Aug 30 15:50:29 2026 epsilon: 2e-12 skip_tests: single diff --git a/unittest/force-styles/tests/kspace-pppm_conp_charge.yaml b/unittest/force-styles/tests/kspace-pppm_conp_charge.yaml index 454d8f8d8ce..9cf486ef93c 100644 --- a/unittest/force-styles/tests/kspace-pppm_conp_charge.yaml +++ b/unittest/force-styles/tests/kspace-pppm_conp_charge.yaml @@ -1,6 +1,6 @@ --- lammps_version: 4 Jul 2026 -tags: generated +tags: date_generated: Sun Aug 30 15:50:29 2026 epsilon: 5e-12 skip_tests: single From 82d8474b1313c4e018512379a3388f64329e3494 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 9 Sep 2026 05:14:02 -0400 Subject: [PATCH 118/120] remove some dead code --- src/KOKKOS/comm_tiled_kokkos.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/KOKKOS/comm_tiled_kokkos.cpp b/src/KOKKOS/comm_tiled_kokkos.cpp index 92a79f74a8c..3c0397f0ab2 100644 --- a/src/KOKKOS/comm_tiled_kokkos.cpp +++ b/src/KOKKOS/comm_tiled_kokkos.cpp @@ -485,13 +485,10 @@ void CommTiledKokkos::forward_comm_device(Pair *pair, int size) // copy data to self if sendself is set // wait on all procs except self and unpack received data - double* buf_send_pair; double* buf_recv_pair; if (lmp->kokkos->gpu_aware_flag) { - buf_send_pair = k_buf_send_pair.view().data(); buf_recv_pair = k_buf_recv_pair.view().data(); } else { - buf_send_pair = k_buf_send_pair.view_host().data(); buf_recv_pair = k_buf_recv_pair.view_host().data(); } @@ -521,7 +518,7 @@ void CommTiledKokkos::forward_comm_device(Pair *pair, int size) } DeviceType().fence(); // take the pointer after the pack, which may have resized the buffer - buf_send_pair = lmp->kokkos->gpu_aware_flag ? k_buf_send_pair.view().data() + double *buf_send_pair = lmp->kokkos->gpu_aware_flag ? k_buf_send_pair.view().data() : k_buf_send_pair.view_host().data(); MPI_Send(buf_send_pair,n,MPI_DOUBLE,sendproc[iswap][i],0,world); } From 53e25bd43b76f234bdfb011c49d60e97c8fe813a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 9 Sep 2026 11:02:24 -0400 Subject: [PATCH 119/120] skip failing/crashing tests (for now) --- unittest/force-styles/tests/atomic-pair-kim_lj.yaml | 1 + unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml | 2 +- unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml | 2 +- unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/unittest/force-styles/tests/atomic-pair-kim_lj.yaml b/unittest/force-styles/tests/atomic-pair-kim_lj.yaml index 54750043480..64d3bd686df 100644 --- a/unittest/force-styles/tests/atomic-pair-kim_lj.yaml +++ b/unittest/force-styles/tests/atomic-pair-kim_lj.yaml @@ -1,6 +1,7 @@ --- lammps_version: 10 Feb 2021 date_generated: Fri Feb 26 23:09:03 2021 +skip_tests: vatom_only epsilon: 1e-12 prerequisites: ! | pair kim diff --git a/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml b/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml index 08bb0aa6bdf..d05ca0eddee 100644 --- a/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml +++ b/unittest/force-styles/tests/manybody-pair-hybrid_sw_lj_tri.yaml @@ -3,7 +3,7 @@ lammps_version: 2 Sep 2026 tags: date_generated: Fri Sep 4 18:24:31 2026 epsilon: 1e-10 -skip_tests: +skip_tests: gpu prerequisites: | pair sw pair lj/cut diff --git a/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml b/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml index 5e5088dd772..38bb5aa3fc7 100644 --- a/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml +++ b/unittest/force-styles/tests/mol-pair-dpd_ext_t0.yaml @@ -3,7 +3,7 @@ lammps_version: 2 Sep 2026 tags: single_thread date_generated: Fri Sep 4 12:52:23 2026 epsilon: 5e-14 -skip_tests: +skip_tests: gpu prerequisites: | atom full pair dpd/ext diff --git a/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml b/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml index 416740a22e5..36d46ec0c40 100644 --- a/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml +++ b/unittest/force-styles/tests/mol-pair-dpd_ext_tstat_t0.yaml @@ -3,7 +3,7 @@ lammps_version: 2 Sep 2026 tags: single_thread date_generated: Fri Sep 4 12:52:28 2026 epsilon: 5e-14 -skip_tests: +skip_tests: gpu prerequisites: | atom full pair dpd/ext/tstat From 71974e2db41243d13b772825b59e176bbf27eb4c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 9 Sep 2026 15:11:46 +0000 Subject: [PATCH 120/120] test: cover the self energy of the DSF and Wolf styles as hybrid sub-styles The KOKKOS DSF and Wolf styles tally a self energy once per atom in their own neighbor list. Six of them summed it on the host over all local atoms instead (lj/cut/coul/dsf also used the position in the list as an atom index and never added it to the per-atom energy). For a plain pair style the two are the same, so every existing reference passed; as a hybrid sub-style, whose list holds only the atoms of the type pairs assigned to it, the global Coulomb energy came out too negative by the self energy of every atom the sub-style does not see. With born/coul/wolf/kk on the four molecules of in.fourmol the error was a factor of 2.5. Add a hybrid reference with coul/dsf (self energy in the pairwise kernel), lj/cut/coul/dsf and born/coul/wolf (separate self energy kernel) and lj/cut, so all three code paths run with a neighbor list that is a strict subset of the local atoms. Against the previous KOKKOS code it fails the initial and final Coulomb energy, the forces, and the check that the sum of the per-atom energies equals the global energy. --- .../tests/mol-pair-hybrid_dsf_wolf.yaml | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 unittest/force-styles/tests/mol-pair-hybrid_dsf_wolf.yaml diff --git a/unittest/force-styles/tests/mol-pair-hybrid_dsf_wolf.yaml b/unittest/force-styles/tests/mol-pair-hybrid_dsf_wolf.yaml new file mode 100644 index 00000000000..e4af6923ebe --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-hybrid_dsf_wolf.yaml @@ -0,0 +1,104 @@ +--- +lammps_version: 2 Sep 2026 +tags: +date_generated: Wed Sep 9 15:07:47 2026 +epsilon: 5e-14 +skip_tests: +prerequisites: | + atom full + pair coul/dsf + pair lj/cut/coul/dsf + pair born/coul/wolf + pair lj/cut +pre_commands: "" +post_commands: "" +input_file: in.fourmol +pair_style: hybrid coul/dsf 0.25 8.0 lj/cut/coul/dsf 0.25 8.0 born/coul/wolf 0.25 + 8.0 lj/cut 8.0 +pair_coeff: | + 1 1 coul/dsf + 1 2 lj/cut/coul/dsf 0.02 2.5 + 1 3 lj/cut 0.02 2.85 8 + 1 4 born/coul/wolf 1.0 0.3 2.5 1.0 1.0 + 1 5 none + 2 2 coul/dsf + 2 3 lj/cut/coul/dsf 0.01 2.1 + 2 4 born/coul/wolf 0.8 0.35 2.6 1.2 0.9 + 2 5 lj/cut 0.00866025 2.05 8 + 3 3 lj/cut 0.02 3.2 8 + 3 4 born/coul/wolf 1.1 0.28 2.4 0.9 1.1 + 3 5 lj/cut/coul/dsf 0.0173205 3.15 + 4 4 born/coul/wolf 1.0 0.3 2.5 1.0 1.0 + 4 5 born/coul/wolf 0.9 0.32 2.55 1.05 0.95 + 5 5 lj/cut 0.02 3.1 8 +extract: "" +natoms: 29 +init_vdwl: 1300.4425793543792 +init_coul: -602.6817469668349 +init_stress: |2- + 4.6391168947921578e+03 4.2807937179632618e+03 6.4989688225475111e+03 -1.1408422420090428e+03 1.7782241133867046e+03 3.8240466057084694e+02 +init_forces: |2 + 1 -2.0350315843729565e+01 2.6940299672437891e+02 3.3328555689273810e+02 + 2 1.5787158871648421e+02 1.2873430890373908e+02 -1.8952713606375247e+02 + 3 1.3741231289068619e+03 -1.9057654274233019e+02 -1.0997472879372369e+03 + 4 -1.1627937314825174e+03 3.2627975976283204e+02 -8.2446474942921782e+02 + 5 -3.4961120037910530e+02 -5.3493164875981006e+02 1.7789020555732159e+03 + 6 -7.7840630421241849e+02 6.3653568946862367e+02 -5.2593399124326413e+02 + 7 -9.2862989789647568e+00 -1.0771010092890525e+00 -2.6867511677078497e+01 + 8 1.3862702468003934e+02 -1.0097532475705670e+02 3.8942000697637030e+02 + 9 7.7561146363741130e+01 8.7506780802416941e+01 3.5355663693728400e+02 + 10 9.0879367185873491e+02 2.5322476956198133e+02 1.2365702088896348e+03 + 11 -3.5329007535345369e+02 -8.7386623643622931e+02 -1.4308673804153564e+03 + 12 -6.6386039302522363e+02 -8.8657460678549091e+02 8.7730050990446193e+02 + 13 1.2085356473447823e+03 -4.7701323196077783e+02 -2.2682612581590234e+01 + 14 -4.9886310880216678e+02 1.0270291793693542e+02 -1.3055437833797071e+03 + 15 -3.1590408460966696e+01 1.2627907146846048e+03 4.4904303157690259e+02 + 16 8.3396243633566822e+00 -6.5900558698783973e+00 -1.6357131709510455e+01 + 17 -7.2655127861444813e+00 4.5969119193824364e+00 1.9725443758582678e+01 + 18 -5.7225355926386612e-01 -6.7667653099862279e-01 1.4793565259222504e+01 + 19 -1.0192307692411406e+01 -8.6517691580086726e+00 -8.9520831894336386e+00 + 20 1.0495874671654922e+01 1.0032291199731555e+01 -4.7561609268858769e+00 + 21 -7.0236532188901151e+01 -8.2825122759857337e+01 2.2468252456076917e+02 + 22 -1.1177539353768938e+02 -2.8253002960393907e+01 -1.7196708417709814e+02 + 23 1.8408169872593348e+02 1.0937411528581619e+02 -5.5258381233618515e+01 + 24 3.9218093118870570e+01 -2.0903175275563891e+02 1.1769351003945279e+02 + 25 -1.5312529641752619e+02 2.1842952747794904e+01 -1.2777985107596994e+02 + 26 1.1518544116575353e+02 1.8987706435612156e+02 1.4433177090762708e+01 + 27 4.9147912918445854e+01 -2.2906608577842638e+02 9.2013577590092083e+01 + 28 -1.8411755406801919e+02 7.6360212141211036e+01 -1.2385406730185446e+02 + 29 1.3335583395384313e+02 1.5084767276861638e+02 3.3139407292085110e+01 +run_vdwl: 1164.827420726581 +run_coul: -602.6992927723952 +run_stress: |2- + 4.2618340654085077e+03 3.9253996462066357e+03 5.6011718020217904e+03 -1.0687814410736546e+03 1.5873362977914055e+03 3.3811821056002526e+02 +run_forces: |2 + 1 -1.7468967393652672e+01 2.6957611192375299e+02 3.2624716225491790e+02 + 2 1.5254610964806082e+02 1.2441852592995316e+02 -1.8284694619690819e+02 + 3 1.1407044060460717e+03 -2.4550945120703966e+02 -8.6910197606210613e+02 + 4 -9.9235456861518151e+02 2.7672986234657236e+02 -6.9913948489901145e+02 + 5 -2.8415470616254674e+02 -4.2632254517657037e+02 1.4232738094242659e+03 + 6 -7.4377967868471637e+02 6.0876972004506365e+02 -5.0180848581238604e+02 + 7 -9.2622695600182414e+00 -1.1261944021812385e+00 -2.6830619824815116e+01 + 8 1.0473767167228279e+02 -7.0997052189993980e+01 3.7512384549305045e+02 + 9 7.5037752518367000e+01 8.4709144886702859e+01 3.4236637949888541e+02 + 10 8.4303927637247932e+02 7.9986380157453993e+01 9.5489009715477619e+02 + 11 -2.8576120538602180e+02 -6.9981727706114702e+02 -1.1478488015660696e+03 + 12 -5.9238475335324472e+02 -7.7348101605727322e+02 7.3920277173107092e+02 + 13 1.0541997736548556e+03 -4.1068740864395988e+02 -2.1877513285060374e+01 + 14 -4.2000382498366298e+02 8.8017856677407892e+01 -1.1083551201856726e+03 + 15 -2.7625029911558752e+01 1.0979005674162834e+03 3.8917036638157720e+02 + 16 8.3169962726827329e+00 -6.5702500514577435e+00 -1.6432712517442891e+01 + 17 -7.2543722760853298e+00 4.5718555520797421e+00 1.9782086337794002e+01 + 18 -4.9478632382083604e-01 -5.8805712502895835e-01 1.4741528002501035e+01 + 19 -1.0192583989944112e+01 -8.6634052009648439e+00 -8.9538527673806616e+00 + 20 1.0417360748480279e+01 9.9590047419762033e+00 -4.7032633422432255e+00 + 21 -6.9130238020976151e+01 -8.0923404502548365e+01 2.2039273051717902e+02 + 22 -1.1000746760170074e+02 -2.7987186275217368e+01 -1.6875640526972279e+02 + 23 1.8120975015559875e+02 1.0720223965903141e+02 -5.4180047820048401e+01 + 24 4.0759643625672354e+01 -2.0737042327518606e+02 1.1803690818611976e+02 + 25 -1.5368858428392298e+02 2.1678653713264843e+01 -1.2832932750662985e+02 + 26 1.1420624520883428e+02 1.8838306381374355e+02 1.4641152571935605e+01 + 27 4.8143279304439886e+01 -2.2486350665800694e+02 8.9745671404120671e+01 + 28 -1.8056891064179857e+02 7.4829400890290700e+01 -1.2124335854057000e+02 + 29 1.3081368196102653e+02 1.4817479007299940e+02 3.2793406637873623e+01 +...