diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 58b001be24..c7dd945f5f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -30,12 +30,12 @@ jobs: fetch-depth: 2 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/${{ matrix.language }}.yml @@ -55,4 +55,4 @@ jobs: cmake --build . --parallel 2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/compile-msvc.yml b/.github/workflows/compile-msvc.yml index 5c6ceeefb4..1a0f1ea62f 100644 --- a/.github/workflows/compile-msvc.yml +++ b/.github/workflows/compile-msvc.yml @@ -24,7 +24,7 @@ jobs: fetch-depth: 2 - name: Select Python version - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 28e02bbee7..f7e9b314bd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -971,33 +971,53 @@ if(PKG_KOKKOS) endif() endif() if(PKG_KSPACE) - message(STATUS "<<< FFT settings >>> --- Primary FFT lib: ${FFT}") - if(FFT_SINGLE) - message(STATUS "Using single precision FFTs") - else() - message(STATUS "Using double precision FFTs") - endif() - if(FFT_FFTW_THREADS OR FFT_MKL_THREADS) - message(STATUS "Using threaded FFTs") - else() - message(STATUS "Using non-threaded FFTs") - endif() - if(PKG_KOKKOS) - if(Kokkos_ENABLE_CUDA) - if(FFT STREQUAL "KISS") - message(STATUS "Kokkos FFT: KISS") - else() - message(STATUS "Kokkos FFT: cuFFT") - endif() - elseif(Kokkos_ENABLE_HIP) - if(FFT STREQUAL "KISS") - message(STATUS "Kokkos FFT: KISS") - else() - message(STATUS "Kokkos FFT: hipFFT") - endif() + if (LMP_HEFFTE) + message(STATUS "<<< FFT settings >>> +-- Primary FFT lib: heFFTe") + if (HEFFTE_BACKEND) + message(STATUS "heFFTe backend: ${HEFFTE_BACKEND}") else() - message(STATUS "Kokkos FFT: ${FFT}") + message(STATUS "heFFTe backend: stock (builtin FFT implementation, tested for corrected but not optimized for production)") + endif() + if(FFT_SINGLE) + message(STATUS "Using single precision FFTs") + else() + message(STATUS "Using double precision FFTs") + endif() + else() + message(STATUS "<<< FFT settings >>> +-- Primary FFT lib: ${FFT}") + if(FFT_SINGLE) + message(STATUS "Using single precision FFTs") + else() + message(STATUS "Using double precision FFTs") + endif() + if(FFT_FFTW_THREADS OR FFT_MKL_THREADS) + message(STATUS "Using threaded FFTs") + else() + message(STATUS "Using non-threaded FFTs") + endif() + if (FFT_HEFFTE) + message(STATUS "Using distributed algorithms from heFTTe") + else() + message(STATUS "Using builtin distributed algorithms") + endif() + if(PKG_KOKKOS) + if(Kokkos_ENABLE_CUDA) + if(FFT STREQUAL "KISS") + message(STATUS "Kokkos FFT: KISS") + else() + message(STATUS "Kokkos FFT: cuFFT") + endif() + elseif(Kokkos_ENABLE_HIP) + if(FFT STREQUAL "KISS") + message(STATUS "Kokkos FFT: KISS") + else() + message(STATUS "Kokkos FFT: hipFFT") + endif() + else() + message(STATUS "Kokkos FFT: ${FFT}") + endif() endif() endif() endif() diff --git a/cmake/Modules/Packages/GPU.cmake b/cmake/Modules/Packages/GPU.cmake index 47be8b8538..4c3288df84 100644 --- a/cmake/Modules/Packages/GPU.cmake +++ b/cmake/Modules/Packages/GPU.cmake @@ -151,10 +151,10 @@ if(GPU_API STREQUAL "CUDA") endif() cuda_compile_fatbin(GPU_GEN_OBJS ${GPU_LIB_CU} OPTIONS ${CUDA_REQUEST_PIC} - -DUNIX -O3 --use_fast_math -Wno-deprecated-gpu-targets -DNV_KERNEL -DUCL_CUDADR ${GPU_CUDA_GENCODE} -D_${GPU_PREC_SETTING} -DLAMMPS_${LAMMPS_SIZES}) + -DUNIX -O3 --use_fast_math -Wno-deprecated-gpu-targets -allow-unsupported-compiler -DNV_KERNEL -DUCL_CUDADR ${GPU_CUDA_GENCODE} -D_${GPU_PREC_SETTING} -DLAMMPS_${LAMMPS_SIZES}) cuda_compile(GPU_OBJS ${GPU_LIB_CUDPP_CU} OPTIONS ${CUDA_REQUEST_PIC} - -DUNIX -O3 --use_fast_math -Wno-deprecated-gpu-targets -DUCL_CUDADR ${GPU_CUDA_GENCODE} -D_${GPU_PREC_SETTING} -DLAMMPS_${LAMMPS_SIZES}) + -DUNIX -O3 --use_fast_math -Wno-deprecated-gpu-targets -allow-unsupported-compiler -DUCL_CUDADR ${GPU_CUDA_GENCODE} -D_${GPU_PREC_SETTING} -DLAMMPS_${LAMMPS_SIZES}) foreach(CU_OBJ ${GPU_GEN_OBJS}) get_filename_component(CU_NAME ${CU_OBJ} NAME_WE) diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index de7e7e5b20..9c9c879cd4 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -46,6 +46,42 @@ else() target_compile_definitions(lammps PRIVATE -DFFT_KISS) endif() +option(FFT_USE_HEFFTE "Use heFFTe as the distributed FFT engine, overrides the FFT option." OFF) +if(FFT_USE_HEFFTE) + # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte + set(FFT_HEFFTE_BACKEND_VALUES FFTW MKL) + set(FFT_HEFFTE_BACKEND "" CACHE STRING "Select heFFTe backend, e.g., FFTW or MKL") + set_property(CACHE FFT_HEFFTE_BACKEND PROPERTY STRINGS ${FFT_HEFFTE_BACKEND_VALUES}) + + if(FFT_HEFFTE_BACKEND STREQUAL "FFTW") # respect the backend choice, FFTW or MKL + set(HEFFTE_COMPONENTS "FFTW") + set(Heffte_ENABLE_FFTW "ON" CACHE BOOL "Enables FFTW backend for heFFTe") + elseif(FFT_HEFFTE_BACKEND STREQUAL "MKL") + set(HEFFTE_COMPONENTS "MKL") + set(Heffte_ENABLE_MKL "ON" CACHE BOOL "Enables MKL backend for heFFTe") + else() + message(WARNING "FFT_HEFFTE_BACKEND not selected, defaulting to the builtin 'stock' backend, which is intended for testing and is not optimized for production runs") + endif() + + find_package(Heffte 2.4.0 QUIET COMPONENTS ${HEFFTE_COMPONENTS}) + if (NOT Heffte_FOUND) # download and build + include(FetchContent) + FetchContent_Declare(HEFFTE_PROJECT # using v2.4.0 + URL "https://github.com/icl-utk-edu/heffte/archive/refs/tags/v2.4.0.tar.gz" + URL_HASH SHA256=02310fb4f9688df02f7181667e61c3adb7e38baf79611d80919d47452ff7881d + ) + FetchContent_Populate(HEFFTE_PROJECT) + add_subdirectory(${heffte_project_SOURCE_DIR} ${heffte_project_BINARY_DIR}) + set_target_properties(lmp PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + set_target_properties(lammps PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + add_library(Heffte::Heffte INTERFACE IMPORTED GLOBAL) + target_link_libraries(Heffte::Heffte INTERFACE Heffte) + endif() + + target_compile_definitions(lammps PRIVATE -DFFT_HEFFTE "-DFFT_HEFFTE_${FFT_HEFFTE_BACKEND}") + target_link_libraries(lammps PRIVATE Heffte::Heffte) +endif() + set(FFT_PACK "array" CACHE STRING "Optimization for FFT") set(FFT_PACK_VALUES array pointer memcpy) set_property(CACHE FFT_PACK PROPERTY STRINGS ${FFT_PACK_VALUES}) diff --git a/cmake/presets/gpu-cuda.cmake b/cmake/presets/gpu-cuda.cmake new file mode 100644 index 0000000000..2ac6bd9ea6 --- /dev/null +++ b/cmake/presets/gpu-cuda.cmake @@ -0,0 +1,11 @@ +# preset that enables GPU and selects CUDA API + +set(PKG_GPU ON CACHE BOOL "Build GPU package" FORCE) +set(GPU_API "cuda" CACHE STRING "APU used by GPU package" FORCE) +set(GPU_PREC "mixed" CACHE STRING "" FORCE) + +set(CUDA_NVCC_FLAGS "-allow-unsupported-compiler" CACHE STRING "" FORCE) +set(CUDA_NVCC_FLAGS_DEBUG "-allow-unsupported-compiler" CACHE STRING "" FORCE) +set(CUDA_NVCC_FLAGS_MINSIZEREL "-allow-unsupported-compiler" CACHE STRING "" FORCE) +set(CUDA_NVCC_FLAGS_RELWITHDEBINFO "-allow-unsupported-compiler" CACHE STRING "" FORCE) +set(CUDA_NVCC_FLAGS_RELEASE "-allow-unsupported-compiler" CACHE STRING "" FORCE) diff --git a/cmake/presets/oneapi.cmake b/cmake/presets/oneapi.cmake index 2aacf1a1f5..393d1d9b68 100644 --- a/cmake/presets/oneapi.cmake +++ b/cmake/presets/oneapi.cmake @@ -18,11 +18,11 @@ set(MPI_CXX_COMPILER "mpicxx" CACHE STRING "" FORCE) unset(HAVE_OMP_H_INCLUDE CACHE) set(OpenMP_C "icx" CACHE STRING "" FORCE) -set(OpenMP_C_FLAGS "-qopenmp -qopenmp-simd" CACHE STRING "" FORCE) +set(OpenMP_C_FLAGS "-qopenmp;-qopenmp-simd" CACHE STRING "" FORCE) set(OpenMP_C_LIB_NAMES "omp" CACHE STRING "" FORCE) set(OpenMP_CXX "icpx" CACHE STRING "" FORCE) -set(OpenMP_CXX_FLAGS "-qopenmp -qopenmp-simd" CACHE STRING "" FORCE) +set(OpenMP_CXX_FLAGS "-qopenmp;-qopenmp-simd" CACHE STRING "" FORCE) set(OpenMP_CXX_LIB_NAMES "omp" CACHE STRING "" FORCE) -set(OpenMP_Fortran_FLAGS "-qopenmp -qopenmp-simd" CACHE STRING "" FORCE) +set(OpenMP_Fortran_FLAGS "-qopenmp;-qopenmp-simd" CACHE STRING "" FORCE) set(OpenMP_omp_LIBRARY "libiomp5.so" CACHE PATH "" FORCE) diff --git a/doc/github-development-workflow.md b/doc/github-development-workflow.md index fccd75d29a..e16ae82764 100644 --- a/doc/github-development-workflow.md +++ b/doc/github-development-workflow.md @@ -36,10 +36,10 @@ requests. MUST be submitted as a pull request to GitHub. All changes to the "develop" branch must be made exclusively through merging pull requests. The "release" and "stable" branches, respectively, are only to be -updated upon feature or stable releases based on the associated -tags. Updates to the stable release in between stable releases +updated upon "feature releases" or "stable releases" based on the +associated tags. Updates to the stable release in between stable releases (for example, back-ported bug fixes) are first merged into the "maintenance" -branch and then into the "stable" branch as update releases. +branch and then into the "stable" branch as "stable update releases". Pull requests may also be submitted to (long-running) feature branches created by LAMMPS developers inside the LAMMPS project, if needed. Those @@ -131,7 +131,7 @@ testing -- that the code in the branch "develop" does not get easily broken. These tests are run after every update to a pull request. More extensive and time-consuming tests (including regression testing) are performed after code is merged to the "develop" branch. There are feature -releases of LAMMPS made about every 4-6 weeks at a point, when the LAMMPS +releases of LAMMPS made about every 4-8 weeks at a point, when the LAMMPS developers feel, that a sufficient number of changes have been included and all post-merge testing has been successful. These feature releases are marked with a `patch_` tag and the "release" branch diff --git a/doc/graphviz/Makefile b/doc/graphviz/Makefile index a3e0c94c63..00b651e888 100644 --- a/doc/graphviz/Makefile +++ b/doc/graphviz/Makefile @@ -16,8 +16,11 @@ clean: rm -f $(IMGSVG) $(IMGPDF) $(IMGPNG) *~ ifeq ($(HAS_DOT),YES) -$(IMGDIR)/%.png: %.dot +$(IMGDIR)/lammps-classes.png : lammps-classes.dot dot -Tpng -Kneato -o $@ $< + +$(IMGDIR)/%.png: %.dot + dot -Tpng -Kdot -o $@ $< endif ifeq ($(HAS_DOT),NO) diff --git a/doc/graphviz/lammps-releases.dot b/doc/graphviz/lammps-releases.dot new file mode 100644 index 0000000000..f641cac029 --- /dev/null +++ b/doc/graphviz/lammps-releases.dot @@ -0,0 +1,34 @@ +// LAMMPS branches and releases +digraph releases { + rankdir="LR"; + github [shape="box" label="Pull Requests\non GitHub" height=0.75]; + github -> develop [label="Merge commits"]; + { + rank = "same"; + work [shape="none" label="Development branches:"] + develop [label="'develop' branch" height=0.75]; + maintenance [label="'maintenance' branch" height=0.75]; + }; + { + rank = "same"; + upload [shape="none" label="Release branches:"] + release [label="'release' branch" height=0.75]; + stable [label="'stable' branch" height=0.75]; + }; + develop -> release [label="Feature release\n(every 4-8 weeks)"]; + release -> stable [label="Stable release\n(once per year)"]; + stable -> maintenance [label="Reset on stable release" style="setlinewidth(2)"]; + develop -> maintenance [label="Backports of bugfixes" style="dashed"]; + maintenance -> stable [label="Updates to stable release"]; + { + rank = "same"; + tag [shape="none" label="Applied tags:"]; + patchtag [shape="box" label="patch_"]; + stabletag [shape="box" label="stable_"]; + updatetag [shape="box" label="stable__update"]; + }; + release -> patchtag [label="feature release" style="dotted"]; + stable -> stabletag [label="stable release" style="dotted"]; + stable -> updatetag [label="update release" style="dotted"]; +} + diff --git a/doc/src/Bibliography.rst b/doc/src/Bibliography.rst index e9ea8b0925..4ed8e73dfe 100644 --- a/doc/src/Bibliography.rst +++ b/doc/src/Bibliography.rst @@ -562,6 +562,9 @@ Bibliography **(Kumar)** Kumar and Skinner, J. Phys. Chem. B, 112, 8311 (2008) +**(Lafourcade)** + Lafourcade, Maillet, Denoual, Duval, Allera, Goryaeva, and Marinica, `Comp. Mat. Science, 230, 112534 (2023) `_ + **(Lamoureux and Roux)** G.\ Lamoureux, B. Roux, J. Chem. Phys 119, 3025 (2003) diff --git a/doc/src/Build_development.rst b/doc/src/Build_development.rst index c75c7a6a41..c674b2c258 100644 --- a/doc/src/Build_development.rst +++ b/doc/src/Build_development.rst @@ -255,16 +255,18 @@ A test run is then a a collection multiple individual test runs each with many comparisons to reference results based on template input files, individual command settings, relative error margins, and reference data stored in a YAML format file with ``.yaml`` -suffix. Currently the programs ``test_pair_style``, ``test_bond_style``, and -``test_angle_style`` are implemented. They will compare forces, energies and -(global) stress for all atoms after a ``run 0`` calculation and after a -few steps of MD with :doc:`fix nve `, each in multiple variants -with different settings and also for multiple accelerated styles. If a -prerequisite style or package is missing, the individual tests are -skipped. All tests will be executed on a single MPI process, so using -the CMake option ``-D BUILD_MPI=off`` can significantly speed up testing, -since this will skip the MPI initialization for each test run. -Below is an example command and output: +suffix. Currently the programs ``test_pair_style``, ``test_bond_style``, +``test_angle_style``, ``test_dihedral_style``, and +``test_improper_style`` are implemented. They will compare forces, +energies and (global) stress for all atoms after a ``run 0`` calculation +and after a few steps of MD with :doc:`fix nve `, each in +multiple variants with different settings and also for multiple +accelerated styles. If a prerequisite style or package is missing, the +individual tests are skipped. All force style tests will be executed on +a single MPI process, so using the CMake option ``-D BUILD_MPI=off`` can +significantly speed up testing, since this will skip the MPI +initialization for each test run. Below is an example command and +output: .. code-block:: console @@ -416,15 +418,16 @@ When compiling LAMMPS with enabled tests, most test executables will need to be linked against the LAMMPS library. Since this can be a very large library with many C++ objects when many packages are enabled, link times can become very long on machines that use the GNU BFD linker (e.g. -Linux systems). Alternatives like the ``lld`` linker of the LLVM project -or the ``gold`` linker available with GNU binutils can speed up this step -substantially. CMake will by default test if any of the two can be -enabled and use it when ``ENABLE_TESTING`` is active. It can also be -selected manually through the ``CMAKE_CUSTOM_LINKER`` CMake variable. -Allowed values are ``lld``, ``gold``, ``bfd``, or ``default``. The -``default`` option will use the system default linker otherwise, the -linker is chosen explicitly. This option is only available for the -GNU or Clang C++ compiler. +Linux systems). Alternatives like the ``mold`` linker, the ``lld`` +linker of the LLVM project, or the ``gold`` linker available with GNU +binutils can speed up this step substantially (in this order). CMake +will by default test if any of the three can be enabled and use it when +``ENABLE_TESTING`` is active. It can also be selected manually through +the ``CMAKE_CUSTOM_LINKER`` CMake variable. Allowed values are +``mold``, ``lld``, ``gold``, ``bfd``, or ``default``. The ``default`` +option will use the system default linker otherwise, the linker is +chosen explicitly. This option is only available for the GNU or Clang +C++ compilers. Tests for other components and utility functions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -518,6 +521,8 @@ The following options are available. make fix-errordocs # remove error docs in header files make check-permissions # search for files with permissions issues make fix-permissions # correct permissions issues in files + make check-docs # search for several issues in the manual + make check-version # list files with pending release version tags make check # run all check targets from above These should help to make source and documentation files conforming diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index 7576cae3eb..7fb7539506 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -44,6 +44,14 @@ require use of an FFT library to compute 1d FFTs. The KISS FFT library is included with LAMMPS, but other libraries can be faster. LAMMPS can use them if they are available on your system. +.. versionadded:: TBD + +Alternatively, LAMMPS can use the `heFFTe +`_ library for the MPI +communication algorithms, which comes with many optimizations for +special cases, e.g. leveraging available 2D and 3D FFTs in the back end +libraries and better pipelining for packing and communication. + .. tabs:: .. tab:: CMake build @@ -53,6 +61,7 @@ LAMMPS can use them if they are available on your system. -D FFT=value # FFTW3 or MKL or KISS, default is FFTW3 if found, else KISS -D FFT_SINGLE=value # yes or no (default), no = double precision -D FFT_PACK=value # array (default) or pointer or memcpy + -D FFT_USE_HEFFTE=value # yes or no (default), yes links to heFFTe .. note:: @@ -76,6 +85,16 @@ LAMMPS can use them if they are available on your system. -D MKL_INCLUDE_DIR=path # ditto for Intel MKL library -D FFT_MKL_THREADS=on # enable using threaded FFTs with MKL libraries -D MKL_LIBRARY=path # path to MKL libraries + -D FFT_HEFFTE_BACKEND=value # FFTW or MKL or empty/undefined for the stock heFFTe back end + -D Heffte_ROOT=path # path to an existing heFFTe installation + + .. note:: + + heFFTe comes with a builtin (= stock) back end for FFTs, i.e. a + default internal FFT implementation; however, this stock back + end is intended for testing purposes only and is not optimized + for production runs. + .. tab:: Traditional make @@ -111,6 +130,24 @@ LAMMPS can use them if they are available on your system. files in its default search path. You must specify ``FFT_LIB`` with the appropriate FFT libraries to include in the link. + Traditional make can also link to heFFTe using an existing installation + + .. code-block:: make + + include /share/heffte/HeffteMakefile.in + FFT_INC = -DFFT_HEFFTE -DFFT_HEFFTE_FFTW $(heffte_include) + FFT_PATH = + FFT_LIB = $(heffte_link) $(heffte_libs) + + The heFFTe install path will contain `HeffteMakefile.in`. + which will define the `heffte_` include variables needed to link to heFFTe from + an external project using traditional make. + The `-DFFT_HEFFTE` is required to switch to using heFFTe, while the optional `-DFFT_HEFFTE_FFTW` + selects the desired heFFTe back end, e.g., `-DFFT_HEFFTE_FFTW` or `-DFFT_HEFFTE_MKL`, + omitting the variable will default to the `stock` back end. + The heFFTe `stock` back end is intended to be used for testing and debugging, + but is not performance optimized for large scale production runs. + The `KISS FFT library `_ is included in the LAMMPS distribution. It is portable across all platforms. Depending on the size of the FFTs and the number of @@ -170,6 +207,16 @@ Depending on the machine, the size of the FFT grid, the number of processors used, one option may be slightly faster. The default is ARRAY mode. +When using ``-DFFT_HEFFTE`` CMake will first look for an existing +install with hints provided by ``-DHeffte_ROOT``, as recommended by the +CMake standard and note that the name is case sensitive. If CMake cannot +find a heFFTe installation with the correct back end (e.g., FFTW or +MKL), it will attempt to download and build the library automatically. +In this case, LAMMPS CMake will also accept all heFFTe specific +variables listed in the `heFFTe documentation +`_ +and those variables will be passed into the heFFTe build. + ---------- .. _size: @@ -463,8 +510,8 @@ Exception handling when using LAMMPS as a library LAMMPS errors do not kill the calling code, but throw an exception. In the C-library interface, the call stack is unwound and control returns -to the caller, e.g. to Python or a code that is coupled to LAMMPS and -the error status can be queried. When using C++ directly, the calling +to the caller, e.g. to Python or a code that is coupled to LAMMPS. The +error status can then be queried. When using C++ directly, the calling code has to be set up to *catch* exceptions thrown from within LAMMPS. .. note:: diff --git a/doc/src/Commands_compute.rst b/doc/src/Commands_compute.rst index 07f5100ea4..0352ad5374 100644 --- a/doc/src/Commands_compute.rst +++ b/doc/src/Commands_compute.rst @@ -100,6 +100,7 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`nbond/atom ` * :doc:`omega/chunk ` * :doc:`orientorder/atom (k) ` + * :doc:`pace ` * :doc:`pair ` * :doc:`pair/local ` * :doc:`pe ` @@ -117,11 +118,13 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`ptm/atom ` * :doc:`rattlers/atom ` * :doc:`rdf ` + * :doc:`reaxff/atom (k) ` * :doc:`reduce ` * :doc:`reduce/chunk ` * :doc:`reduce/region ` * :doc:`rigid/local ` * :doc:`saed ` + * :doc:`slcsa/atom ` * :doc:`slice ` * :doc:`smd/contact/radius ` * :doc:`smd/damage ` diff --git a/doc/src/Commands_fix.rst b/doc/src/Commands_fix.rst index 3283561c41..e89e302673 100644 --- a/doc/src/Commands_fix.rst +++ b/doc/src/Commands_fix.rst @@ -239,10 +239,10 @@ OPT. * :doc:`store/force ` * :doc:`store/state ` * :doc:`tdpd/source ` - * :doc:`temp/berendsen ` + * :doc:`temp/berendsen (k) ` * :doc:`temp/csld ` * :doc:`temp/csvr ` - * :doc:`temp/rescale ` + * :doc:`temp/rescale (k) ` * :doc:`temp/rescale/eff ` * :doc:`tfmc ` * :doc:`tgnpt/drude ` diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 828f0b10d9..e7761e7bee 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -87,7 +87,7 @@ OPT. * :doc:`coul/long/soft (o) ` * :doc:`coul/msm (o) ` * :doc:`coul/slater/cut ` - * :doc:`coul/slater/long ` + * :doc:`coul/slater/long (g) ` * :doc:`coul/shield ` * :doc:`coul/streitz ` * :doc:`coul/tt ` @@ -110,7 +110,7 @@ OPT. * :doc:`eam/he ` * :doc:`edip (o) ` * :doc:`edip/multi ` - * :doc:`edpd ` + * :doc:`edpd (g) ` * :doc:`eff/cut ` * :doc:`eim (o) ` * :doc:`exp6/rx (k) ` @@ -158,14 +158,14 @@ OPT. * :doc:`lj/cut (gikot) ` * :doc:`lj/cut/coul/cut (gko) ` * :doc:`lj/cut/coul/cut/dielectric (o) ` - * :doc:`lj/cut/coul/cut/soft (o) ` + * :doc:`lj/cut/coul/cut/soft (go) ` * :doc:`lj/cut/coul/debye (gko) ` * :doc:`lj/cut/coul/debye/dielectric (o) ` * :doc:`lj/cut/coul/dsf (gko) ` * :doc:`lj/cut/coul/long (gikot) ` * :doc:`lj/cut/coul/long/cs ` * :doc:`lj/cut/coul/long/dielectric (o) ` - * :doc:`lj/cut/coul/long/soft (o) ` + * :doc:`lj/cut/coul/long/soft (go) ` * :doc:`lj/cut/coul/msm (go) ` * :doc:`lj/cut/coul/msm/dielectric ` * :doc:`lj/cut/coul/wolf (o) ` @@ -202,7 +202,7 @@ OPT. * :doc:`lubricate/poly (o) ` * :doc:`lubricateU ` * :doc:`lubricateU/poly ` - * :doc:`mdpd ` + * :doc:`mdpd (g) ` * :doc:`mdpd/rhosum ` * :doc:`meam (k) ` * :doc:`meam/ms (k) ` @@ -268,11 +268,11 @@ OPT. * :doc:`smtbq ` * :doc:`snap (ik) ` * :doc:`soft (go) ` - * :doc:`sph/heatconduction ` + * :doc:`sph/heatconduction (g) ` * :doc:`sph/idealgas ` - * :doc:`sph/lj ` + * :doc:`sph/lj (g) ` * :doc:`sph/rhosum ` - * :doc:`sph/taitwater ` + * :doc:`sph/taitwater (g) ` * :doc:`sph/taitwater/morris ` * :doc:`spin/dipole/cut ` * :doc:`spin/dipole/long ` diff --git a/doc/src/Developer_platform.rst b/doc/src/Developer_platform.rst index cdc4bb6770..9b05299146 100644 --- a/doc/src/Developer_platform.rst +++ b/doc/src/Developer_platform.rst @@ -70,6 +70,9 @@ File and path functions and global constants .. doxygenfunction:: is_console :project: progguide +.. doxygenfunction:: disk_free + :project: progguide + .. doxygenfunction:: path_is_directory :project: progguide diff --git a/doc/src/Developer_unittest.rst b/doc/src/Developer_unittest.rst index 67c5ce365a..b48c3b4e17 100644 --- a/doc/src/Developer_unittest.rst +++ b/doc/src/Developer_unittest.rst @@ -121,7 +121,7 @@ will be suppressed and only a summary printed, but adding the '-V' option will then produce output from the tests above like the following: -.. code-block:: +.. code-block:: console [...] 1: [ RUN ] Tokenizer.empty_string @@ -274,9 +274,7 @@ Tests for using the Fortran module are in the ``unittest/fortran`` folder. Since they are also using the GoogleTest library, they require to also implement test wrappers in C++ that will call fortran functions which provide a C function interface through ISO_C_BINDINGS that will in -turn call the functions in the LAMMPS Fortran module. This part of the -unit tests is incomplete since the Fortran module it is based on is -incomplete as well. +turn call the functions in the LAMMPS Fortran module. Tests for the C++-style library interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -397,10 +395,10 @@ compare with the reference and also start from the data file. A final check will use multi-cutoff r-RESPA (if supported by the pair style) at a 1:1 split and compare to the Verlet results. These sets of tests are run with multiple test fixtures for accelerated styles (OPT, OPENMP, -INTEL) and for the latter two with 4 OpenMP threads enabled. For -these tests the relative error (epsilon) is lowered by a common factor -due to the additional numerical noise, but the tests are still comparing -to the same reference data. +INTEL, KOKKOS (OpenMP only)) and for the latter three with 4 OpenMP +threads enabled. For these tests the relative error (epsilon) is lowered +by a common factor due to the additional numerical noise, but the tests +are still comparing to the same reference data. Additional tests will check whether all listed extract keywords are supported and have the correct dimensionality and the final set of tests @@ -434,17 +432,19 @@ The ``test_pair_style`` tester is used with 4 categories of test inputs: pair style is defined, but the computation of the pair style contributions is disabled. -The ``test_bond_style`` and ``test_angle_style`` are set up in a similar -fashion and share support functions with the pair style tester. The final -group of tests in this section is for fix styles that add/manipulate forces -and velocities, e.g. for time integration, thermostats and more. +The ``test_bond_style``, ``test_angle_style``, ``test_dihedral_style``, and +``test_improper_style`` tester programs are set up in a similar fashion and +share support functions with the pair style tester. The final group of +tests in this section is for fix styles that add/manipulate forces and +velocities, e.g. for time integration, thermostats and more. -Adding a new test is easiest done by copying and modifying an existing test -for a style that is similar to one to be tested. The file name should follow -the naming conventions described above and after copying the file, the first -step is to replace the style names where needed. The coefficient values -do not have to be meaningful, just in a reasonable range for the given system. -It does not matter if some forces are large, for as long as they do not diverge. +Adding a new test is easiest done by copying and modifying an existing YAML +file for a style that is similar to one to be tested. The file name should +follow the naming conventions described above and after copying the file, +the first step is to replace the style names where needed. The coefficient +values do not have to be meaningful, just in a reasonable range for the +given system. It does not matter if some forces are large, for as long as +they do not diverge. The template input files define a large number of index variables at the top that can be modified inside the YAML file to control the behavior. For example, @@ -472,7 +472,7 @@ Note that this disables computing the kspace contribution, but still will run the setup. The "gewald" parameter should be set explicitly to speed up the run. For styles with long-range electrostatics, typically two tests are added one using the (slower) analytic approximation of the erfc() function and the other using -the tabulated coulomb, to test both code paths. The reference results in the YAML +the tabulated coulomb, to test both code paths. The reference results in the YAML files then should be compared manually, if they agree well enough within the limits of those two approximations. @@ -526,3 +526,102 @@ The ``unittest/tools`` folder contains tests for programs in the shell, which are implemented as a python scripts using the ``unittest`` Python module and launching the tool commands through the ``subprocess`` Python module. + + +Troubleshooting failed unit tests +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The are by default no unit tests for newly added features (e.g. pair, fix, +or compute styles) unless your pull request also includes tests for the +added features. If you are modifying some features, you may see failures +for existing tests, if your modifications have some unexpected side effects +or your changes render the existing text invalid. If you are adding an +accelerated version of an existing style, then only tests for INTEL, +KOKKOS (with OpenMP only), OPENMP, and OPT will be run automatically. +Tests for the GPU package are time consuming and thus are only run +*after* a merge, or when a special label, ``gpu_unit_tests`` is added +to the pull request. After the test has started, it is often best to +remove the label since every PR activity will re-trigger the test (that +is a limitation of triggering a test with a label). Support for unit +tests with using KOKKOS with GPU acceleration is currently not supported. + +When you see a failed build on GitHub, click on ``Details`` to be taken +to the corresponding LAMMPS Jenkins CI web page. Click on the "Exit" +symbol near the ``Logout`` button on the top right of that page to go to +the "classic view". In the classic view, there is a list of the +individual runs that make up this test run (they are shown but cannot be +inspected in the default view). You can click on any of those. +Clicking on ``Test Result`` will display the list of failed tests. Click +on the "Status" column to sort the tests based on their Failed or Passed +status. Then click on the failed test to expand its output. + +For example, the following output snippet shows the failed unit test + +.. code-block:: console + + [ RUN ] PairStyle.gpu + /home/builder/workspace/dev/pull_requests/ubuntu_gpu/unit_tests/cmake_gpu_opencl_mixed_smallbig_clang_static/unittest/force-styles/test_main.cpp:63: Failure + Expected: (err) <= (epsilon) + Actual: 0.00018957912910606503 vs 0.0001 + Google Test trace: + /home/builder/workspace/dev/pull_requests/ubuntu_gpu/unit_tests/cmake_gpu_opencl_mixed_smallbig_clang_static/unittest/force-styles/test_main.cpp:56: EXPECT_FORCES: init_forces (newton off) + /home/builder/workspace/dev/pull_requests/ubuntu_gpu/unit_tests/cmake_gpu_opencl_mixed_smallbig_clang_static/unittest/force-styles/test_main.cpp:64: Failure + Expected: (err) <= (epsilon) + Actual: 0.00022892713393549854 vs 0.0001 + +The failed assertions provide line numbers in the test source +(e.g. ``test_main.cpp:56``), from which one can understand what +specific assertion failed. + +Note that the force style engine runs one of a small number of systems +in a rather off-equilibrium configuration with a few atoms for a few +steps, writes data and restart files, uses :doc:`the clear command +` to reset LAMMPS, and then runs from those files with different +settings (e.g. newton on/off) and integrators (e.g. verlet vs. respa). +Beyond potential issues/bugs in the source code, the mismatch between +the expected and actual values could be that force arrays are not +properly cleared between multiple run commands or that class members are +not correctly initialized or written to or read from a data or restart +file. + +While the epsilon (relative precision) for a single, `IEEE 754 compliant +`_, double precision floating +point operation is at about 2.2e-16, the achievable precision for the +tests is lower due to most numbers being sums over intermediate results +and the non-associativity of floating point math leading to larger +errors. In some cases specific properties of the tested style. As a +rule of thumb, the test epsilon can often be in the range 5.0e-14 to +1.0e-13. But for "noisy" force kernels, e.g. those a larger amount of +arithmetic operations involving `exp()`, `log()` or `sin()` functions, +and also due to the effect of compiler optimization or differences +between compilers or platforms, epsilon may need to be further relaxed, +sometimes epsilon can be relaxed to 1.0e-12. If interpolation or lookup +tables are used, epsilon may need to be set to 1.0e-10 or even higher. +For tests of accelerated styles, the per-test epsilon is multiplied +by empirical factors that take into account the differences in the order +of floating point operations or that some or most intermediate operations +may be done using approximations or with single precision floating point +math. + +To rerun the failed unit test individually, change to the ``build`` directory +and run the test with verbose output. For example, + +.. code-block:: bash + + env TEST_ARGS=-v ctest -R ^MolPairStyle:lj_cut_coul_long -V + +``ctest`` with the ``-V`` flag also shows the exact command line +of the test. One can then use ``gdb --args`` to further debug and +catch exceptions with the test command, for example, + +.. code-block:: bash + + gdb --args /path/to/lammps/build/test_pair_style /path/to/lammps/unittest/force-styles/tests/mol-pair-lj_cut_coul_long.yaml + + +It is recommended to configure the build with ``-D +BUILD_SHARED_LIBS=on`` and use a custom linker to shorten the build time +during recompilation. Installing `ccache` in your development +environment helps speed up recompilation by caching previous +compilations and detecting when the same compilation is being done +again. Please see :doc:`Build_development` for further details. diff --git a/doc/src/Howto_github.rst b/doc/src/Howto_github.rst index cbe1264d52..b81716c09d 100644 --- a/doc/src/Howto_github.rst +++ b/doc/src/Howto_github.rst @@ -480,11 +480,11 @@ Some recent changes to the workflow are not captured in this tutorial. For example, in addition to the *develop* branch, to which all new features should be submitted, there is also a *release*, a *stable*, and a *maintenance* branch; the *release* branch is updated from the -*develop* as part of a feature release, and *stable* (together with -*release*) are updated from *develop* when a stable release is made. In -between stable releases, selected bug fixes and infrastructure updates -are back-ported from the *develop* branch to the *maintenance* branch -and occasionally merged to *stable* as an update release. +*develop* branch as part of a "feature release", and *stable* (together +with *release*) are updated from *develop* when a "stable release" is +made. In between stable releases, selected bug fixes and infrastructure +updates are back-ported from the *develop* branch to the *maintenance* +branch and occasionally merged to *stable* as an update release. Furthermore, the naming of the release tags now follow the pattern "patch_" to simplify comparisons between releases. diff --git a/doc/src/Howto_tip4p.rst b/doc/src/Howto_tip4p.rst index 4d9b514e0d..bc6e91b6b0 100644 --- a/doc/src/Howto_tip4p.rst +++ b/doc/src/Howto_tip4p.rst @@ -193,11 +193,14 @@ file changed): write_data tip4p-implicit.data nocoeff Below is the code for a LAMMPS input file using the explicit method and -a TIP4P molecule file. Because of using :doc:`fix rigid/nvt/small +a TIP4P molecule file. Because of using :doc:`fix rigid/small ` no bonds need to be defined and thus no extra storage needs -to be reserved for them, but we need to switch to atom style full or use -:doc:`fix property/atom mol ` so that fix -rigid/nvt/small can identify rigid bodies by their molecule ID: +to be reserved for them, but we need to either switch to atom style full +or use :doc:`fix property/atom mol ` so that fix +rigid/small can identify rigid bodies by their molecule ID. Also a +:doc:`neigh_modify exclude ` command is added to exclude +computing intramolecular non-bonded interactions, since those are +removed by the rigid fix anyway: .. code-block:: LAMMPS @@ -216,17 +219,17 @@ rigid/nvt/small can identify rigid bodies by their molecule ID: pair_coeff 2 2 0.0 1.0 pair_coeff 3 3 0.0 1.0 - fix mol all property/atom mol + fix mol all property/atom mol ghost yes molecule water tip4p.mol create_atoms 0 random 33 34564 NULL mol water 25367 overlap 1.33 + neigh_modify exclude molecule/intra all timestep 0.5 - fix integrate all rigid/nvt/small molecule temp 300.0 300.0 100.0 - velocity all create 300.0 5463576 + fix integrate all rigid/small molecule langevin 300.0 300.0 100.0 2345634 thermo_style custom step temp press etotal density pe ke - thermo 1000 - run 20000 + thermo 2000 + run 40000 write_data tip4p-explicit.data nocoeff .. _tip4p_molecule: diff --git a/doc/src/Howto_tip5p.rst b/doc/src/Howto_tip5p.rst index 10674a04b6..4bb9754875 100644 --- a/doc/src/Howto_tip5p.rst +++ b/doc/src/Howto_tip5p.rst @@ -81,11 +81,13 @@ long-range Coulombic solver (e.g. Ewald or PPPM in LAMMPS). Below is the code for a LAMMPS input file for setting up a simulation of TIP5P water with a molecule file. Because of using :doc:`fix -rigid/nvt/small ` no bonds need to be defined and thus no -extra storage needs to be reserved for them, but we need to switch to +rigid/small ` no bonds need to be defined and thus no extra +storage needs to be reserved for them, but we need to either switch to atom style full or use :doc:`fix property/atom mol ` -so that fix rigid/nvt/small can identify rigid bodies by their molecule -ID: +so that fix rigid/small can identify rigid bodies by their molecule ID. +Also a :doc:`neigh_modify exclude ` command is added to +exclude computing intramolecular non-bonded interactions, since those +are removed by the rigid fix anyway: .. code-block:: LAMMPS @@ -107,11 +109,11 @@ ID: fix mol all property/atom mol molecule water tip5p.mol create_atoms 0 random 33 34564 NULL mol water 25367 overlap 1.33 + neigh_modify exclude molecule/intra all timestep 0.5 - fix integrate all rigid/nvt/small molecule temp 300.0 300.0 100.0 + fix integrate all rigid/small molecule langevin 300.0 300.0 50.0 235664 reset_timestep 0 - velocity all create 300.0 5463576 thermo_style custom step temp press etotal density pe ke thermo 1000 diff --git a/doc/src/Install_git.rst b/doc/src/Install_git.rst index b6d3ced0a5..45e364a226 100644 --- a/doc/src/Install_git.rst +++ b/doc/src/Install_git.rst @@ -28,16 +28,16 @@ provides `limited support for subversion clients `_. You can follow the LAMMPS development on 4 different git branches: -* **release** : this branch is updated with every patch or feature release; - updates are always "fast-forward" merges from *develop* -* **develop** : this branch follows the ongoing development and - is updated with every merge commit of a pull request -* **stable** : this branch is updated from the *release* branch with - every stable release version and also has selected bug fixes with every - update release when the *maintenance* branch is merged into it -* **maintenance** : this branch collects back-ported bug fixes from the - *develop* branch to the *stable* branch. It is used to update *stable* - for update releases and it synchronized with *stable* at each stable release. +* **develop** : this branch follows the ongoing development and is + updated with every merge commit of a pull request +* **release** : this branch is updated with every "feature release"; + updates are always "fast-forward" merges from *develop* +* **maintenance** : this branch collects back-ported bug fixes from the + *develop* branch to the *stable* branch. It is used to update the + *stable* branch for "stable update releases". +* **stable** : this branch is updated from the *release* branch with + every "stable release" version and also has selected bug fixes with + every "update release" when the *maintenance* branch is merged into it To access the git repositories on your box, use the clone command to create a local copy of the LAMMPS repository with a command like: diff --git a/doc/src/JPG/lammps-classes.png b/doc/src/JPG/lammps-classes.png index 71b5af9ccc..d7ed506ab3 100644 Binary files a/doc/src/JPG/lammps-classes.png and b/doc/src/JPG/lammps-classes.png differ diff --git a/doc/src/JPG/lammps-invoke-python.png b/doc/src/JPG/lammps-invoke-python.png index d1e25f52ea..890963a577 100644 Binary files a/doc/src/JPG/lammps-invoke-python.png and b/doc/src/JPG/lammps-invoke-python.png differ diff --git a/doc/src/JPG/lammps-releases.png b/doc/src/JPG/lammps-releases.png new file mode 100644 index 0000000000..d5c317088f Binary files /dev/null and b/doc/src/JPG/lammps-releases.png differ diff --git a/doc/src/JPG/pylammps-invoke-lammps.png b/doc/src/JPG/pylammps-invoke-lammps.png index 39296ee272..f5d4dd66a0 100644 Binary files a/doc/src/JPG/pylammps-invoke-lammps.png and b/doc/src/JPG/pylammps-invoke-lammps.png differ diff --git a/doc/src/JPG/python-invoke-lammps.png b/doc/src/JPG/python-invoke-lammps.png index 0c456028db..6e44b8d56e 100644 Binary files a/doc/src/JPG/python-invoke-lammps.png and b/doc/src/JPG/python-invoke-lammps.png differ diff --git a/doc/src/Manual_version.rst b/doc/src/Manual_version.rst index 8fb28fef84..1bfaffaf6d 100644 --- a/doc/src/Manual_version.rst +++ b/doc/src/Manual_version.rst @@ -3,45 +3,25 @@ What does a LAMMPS version mean The LAMMPS "version" is the date when it was released, such as 1 May 2014. LAMMPS is updated continuously, and we aim to keep it working -correctly and reliably at all times. You can follow its development -in a public `git repository on GitHub `_. - -Modifications of the LAMMPS source code (like bug fixes, code refactors, -updates to existing features, or addition of new features) are organized -into pull requests. Pull requests will be merged into the *develop* -branch of the git repository after they pass automated testing and code -review by the LAMMPS developers. When a sufficient number of changes -have accumulated *and* the *develop* branch version passes an extended -set of automated tests, we release it as a *feature release*, which are -currently made every 4 to 8 weeks. The *release* branch of the git -repository is updated with every such release. A summary of the most -important changes of the patch releases are on `this website page -`_. More detailed release notes are -`available on GitHub `_. - -Once or twice a year, we have a "stabilization period" where we apply -only bug fixes and small, non-intrusive changes to the *develop* -branch. At the same time, the code is subjected to more detailed and -thorough manual testing than the default automated testing. Also, -several variants of static code analysis are run to improve the overall -code quality, consistency, and compliance with programming standards, -best practices and style conventions. - -The release after such a stabilization period is called a *stable* -version and both, the *release* and the *stable* branches are updated -with it. Between stable releases, we collect back-ported bug fixes and -updates from the *develop* branch in the *maintenance* branch. From the -*maintenance* branch we make occasional update releases and update the -*stable* branch accordingly. +correctly and reliably at all times. Also, several variants of static +code analysis are run regularly to maintain or improve the overall code +quality, consistency, and compliance with programming standards, best +practices and style conventions. You can follow its development in a +public `git repository on GitHub `_. Each version of LAMMPS contains all the documented *features* up to and including its version date. For recently added features, we add markers to the documentation at which specific LAMMPS version a feature or keyword was added or significantly changed. -The version date is printed to the screen and log file every time you run -LAMMPS. It is also in the file src/version.h and in the LAMMPS -directory name created when you unpack a tarball. And it is on the +Identifying the Version +^^^^^^^^^^^^^^^^^^^^^^^ + +The version date is printed to the screen and log file every time you +run LAMMPS. There also is an indication, if a LAMMPS binary was +compiled from version with modifications **after** a release. +It is also visible in the file src/version.h and in the LAMMPS directory +name created when you unpack a downloaded tarball. And it is on the first page of the :doc:`manual `. * If you browse the HTML pages of the online version of the LAMMPS @@ -53,3 +33,56 @@ first page of the :doc:`manual `. * If you browse the HTML pages included in your downloaded tarball, they describe the version you have, which may be older than the online version. + +LAMMPS releases, branches, and tags +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: JPG/lammps-releases.png + :figclass: align-center + + Relations between releases, main branches, and tags in the LAMMPS git repository + +Development +""""""""""" + +Modifications of the LAMMPS source code (like bug fixes, code +refactoring, updates to existing features, or addition of new features) +are organized into pull requests. Pull requests will be merged into the +*develop* branch of the git repository after they pass automated testing +and code review by the LAMMPS developers. + +Feature Releases +"""""""""""""""" + +When a sufficient number of new features and updates have accumulated +*and* the LAMMPS version on the *develop* branch passes an extended set +of automated tests, we release it as a *feature release*, which are +currently made every 4 to 8 weeks. The *release* branch of the git +repository is updated with every such *feature release* and a tag in the +format ``patch_1May2014`` is added. A summary of the most important +changes of these releases for the current year are posted on `this +website page `_. More detailed release +notes are `available on GitHub +`_. + +Stable Releases +""""""""""""""" + +About once a year, we release a *stable release* version of LAMMPS. +This is done after a "stabilization period" where we apply only bug +fixes and small, non-intrusive changes to the *develop* branch but no +new features. At the same time, the code is subjected to more detailed +and thorough manual testing than the default automated testing. +After such a *stable release*, both the *release* and the *stable* +branches are updated and two tags are applied, a ``patch_1May2014`` format +and a ``stable_1May2014`` format tag. + +Stable Release Updates +"""""""""""""""""""""" + +Between *stable releases*, we collect bug fixes and updates back-ported +from the *develop* branch in a branch called *maintenance*. From the +*maintenance* branch we make occasional *stable update releases* and +update the *stable* branch accordingly. The first update to the +``stable_1May2014`` release would be tagged as +``stable_1May2014_update1``. These updates contain no new features. diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index 12aa8eeb52..a3d65d9d65 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -2226,7 +2226,7 @@ and third order tensor from finite differences. **Install:** -The PHONON package requires that also the :ref:`KSPACE ` +The fix phonon command also requires that the :ref:`KSPACE ` package is installed. diff --git a/doc/src/Python_error.rst b/doc/src/Python_error.rst index 6aec8df391..bdf69df5b4 100644 --- a/doc/src/Python_error.rst +++ b/doc/src/Python_error.rst @@ -1,11 +1,11 @@ Handling LAMMPS errors ********************** -The shared library is compiled with :ref:`C++ exception support -` to provide a better error handling experience. C++ -exceptions allow capturing errors on the C++ side and rethrowing them on -the Python side. This way LAMMPS errors can be handled through the -Python exception handling mechanism. +LAMMPS and the LAMMPS library are compiled with :ref:`C++ exception support +` to provide a better error handling experience. LAMMPS errors +trigger throwing a C++ exception. These exceptions allow capturing errors on +the C++ side and rethrowing them on the Python side. This way LAMMPS errors +can be handled through the Python exception handling mechanism. .. code-block:: python diff --git a/doc/src/Run_output.rst b/doc/src/Run_output.rst index b1458f056d..2025bf5321 100644 --- a/doc/src/Run_output.rst +++ b/doc/src/Run_output.rst @@ -49,14 +49,17 @@ simulation. An example set of statistics is shown here: ---------- The first section provides a global loop timing summary. The *loop time* -is the total wall-clock time for the simulation to run. The -*Performance* line is provided for convenience to help predict how long -it will take to run a desired physical simulation and to have numbers -useful for performance comparison between different simulation settings -or system sizes. The *CPU use* line provides the CPU utilization per -MPI task; it should be close to 100% times the number of OpenMP threads -(or 1 of not using OpenMP). Lower numbers correspond to delays due to -file I/O or insufficient thread utilization. +is the total wall-clock time for the MD steps of the simulation run, +excluding the time for initialization and setup (i.e. the parts that may +be skipped with :doc:`run N pre no `). The *Performance* line is +provided for convenience to help predict how long it will take to run a +desired physical simulation and to have numbers useful for performance +comparison between different simulation settings or system sizes. The +*CPU use* line provides the CPU utilization per MPI task; it should be +close to 100% times the number of OpenMP threads (or 1 if not using +OpenMP). Lower numbers correspond to delays due to file I/O or +insufficient thread utilization from parts of the code that have not +been multi-threaded. ---------- diff --git a/doc/src/compute.rst b/doc/src/compute.rst index a99d7d7c9c..7b620deed7 100644 --- a/doc/src/compute.rst +++ b/doc/src/compute.rst @@ -264,6 +264,7 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`nbond/atom ` - calculates number of bonds per atom * :doc:`omega/chunk ` - angular velocity for each chunk * :doc:`orientorder/atom ` - Steinhardt bond orientational order parameters Ql +* :doc:`pace ` - atomic cluster expansion descriptors and related quantities * :doc:`pair ` - values computed by a pair style * :doc:`pair/local ` - distance/energy/force of each pairwise interaction * :doc:`pe ` - potential energy @@ -281,11 +282,13 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`ptm/atom ` - determines the local lattice structure based on the Polyhedral Template Matching method * :doc:`rattlers/atom ` - identify under-coordinated rattler atoms * :doc:`rdf ` - radial distribution function :math:`g(r)` histogram of group of atoms +* :doc:`reaxff/atom ` - extract ReaxFF bond information * :doc:`reduce ` - combine per-atom quantities into a single global value * :doc:`reduce/chunk ` - reduce per-atom quantities within each chunk * :doc:`reduce/region ` - same as compute reduce, within a region * :doc:`rigid/local ` - extract rigid body attributes * :doc:`saed ` - electron diffraction intensity on a mesh of reciprocal lattice nodes +* :doc:`slcsa/atom ` - perform Supervised Learning Crystal Structure Analysis (SL-CSA) * :doc:`slice ` - extract values from global vector or array * :doc:`smd/contact/radius ` - contact radius for Smooth Mach Dynamics * :doc:`smd/damage ` - damage status of SPH particles in Smooth Mach Dynamics diff --git a/doc/src/compute_pace.rst b/doc/src/compute_pace.rst new file mode 100644 index 0000000000..c510319dfc --- /dev/null +++ b/doc/src/compute_pace.rst @@ -0,0 +1,253 @@ +.. index:: compute pace + +compute pace command +======================== + +Syntax +"""""" + +.. code-block:: LAMMPS + + compute ID group-ID pace ace_potential_filename ... keyword values ... + +* ID, group-ID are documented in :doc:`compute ` command +* pace = style name of this compute command +* ace_potential_filename = file name (in the .yace or .ace format from :doc:`pace pair_style `) including ACE hyper-parameters, bonds, and generalized coupling coefficients +* keyword = *bikflag* or *dgradflag* + + .. parsed-literal:: + + *bikflag* value = *0* or *1* + *0* = descriptors are summed over atoms of each type + *1* = descriptors are listed separately for each atom + *dgradflag* value = *0* or *1* + *0* = descriptor gradients are summed over atoms of each type + *1* = descriptor gradients are listed separately for each atom pair + +Examples +"""""""" + +.. code-block:: LAMMPS + + compute pace all pace coupling_coefficients.yace + compute pace all pace coupling_coefficients.yace 0 1 + compute pace all pace coupling_coefficients.yace 1 1 + +Description +""""""""""" + +.. versionadded:: TBD + +This compute calculates a set of quantities related to the atomic +cluster expansion (ACE) descriptors of the atoms in a group. ACE +descriptors are highly general atomic descriptors, encoding the radial +and angular distribution of neighbor atoms, up to arbitrary bond order +(rank). The detailed mathematical definition is given in the paper by +:ref:`(Drautz) `. These descriptors are used in the +:doc:`pace pair_style `. Quantities obtained from `compute +pace` are related to those used in :doc:`pace pair_style ` to +evaluate atomic energies, forces, and stresses for linear ACE models. + +For example, the energy for a linear ACE model is calculated as: +:math:`E=\sum_i^{N\_atoms} \sum_{\boldsymbol{\nu}} c_{\boldsymbol{\nu}} +B_{i,\boldsymbol{\boldsymbol{\nu}}}`. The ACE descriptors for atom `i` +:math:`B_{i,\boldsymbol{\nu}}`, and :math:`c_{\nu}` are linear model +parameters. The detailed definition and indexing convention for ACE +descriptors is given in :ref:`(Drautz) `. In short, body +order :math:`N`, angular character, radial character, and chemical +elements in the *N-body* descriptor are encoded by :math:`\nu`. In the +:doc:`pace pair_style `, the linear model parameters and the +ACE descriptors are combined for efficient evaluation of energies and +forces. The details and benefits of this efficient implementation are +given in :ref:`(Lysogorskiy) `, but the combined +descriptors and linear model parameters for the purposes of `compute +pace` may be expressed in terms of the ACE descriptors mentioned above. + +:math:`c_{\boldsymbol{\nu}} B_{i,\boldsymbol{\nu}}= \sum_{\boldsymbol{\nu}' \in \boldsymbol{\nu} } \big[ c_{\boldsymbol{\nu}} C(\boldsymbol{\nu}') \big] A_{i,\boldsymbol{\nu}'}` + +where the bracketed terms on the right-hand side are the combined functions +with linear model parameters typically provided in the `.yace` potential +file for `pace pair_style`. When these bracketed terms are multiplied by the +products of the atomic base from :ref:`(Drautz) `, +:math:`A_{i,\boldsymbol{\nu'}}`, the ACE descriptors are recovered but they +are also scaled by linear model parameters. The generalized coupling coefficients, +written in short-hand here as :math:`C(\boldsymbol{\nu}')`, are the generalized +Clebsch-Gordan or generalized Wigner symbols. It may be desirable to reverse the +combination of these descriptors and the linear model parameters so that the +ACE descriptors themselves may be used. The ACE descriptors and their gradients +are often used when training ACE models, performing custom data analysis, +generalizing ACE model forms, and other tasks that involve direct computation of +descriptors. The key utility of `compute pace` is that it can compute the ACE +descriptors and gradients so that these tasks can be performed during a LAMMPS +simulation or so that LAMMPS can be used as a driver for tasks like ACE model +parameterization. To see how this command can be used within a Python workflow +to train ACE potentials, see the examples in +`FitSNAP `_. Examples on using outputs from +this compute to construct general ACE potential forms are demonstrated in +:ref:`(Goff) `. The various keywords and inputs to `compute pace` +determine what ACE descriptors and related quantities are returned in a compute +array. + +The coefficient file, `.yace`, ultimately defines the number of ACE +descriptors to be computed, their maximum body-order, the degree of angular +character they have, the degree of radial character they have, the chemical +character (which element-element interactions are encoded by descriptors), +and other hyper-parameters defined in :ref:`(Drautz) `. These may +be modeled after the potential files in :doc:`pace pair_style `, +and have the same format. Details on how to generate the coefficient files +to train ACE models may be found in `FitSNAP `_. + +The keyword *bikflag* determines whether or not to list the descriptors of +each atom separately, or sum them together and list in a single row. If +*bikflag* is set to *0* then a single descriptor row is used, which contains +the per-atom ACE descriptors :math:`B_{i,\boldsymbol{\nu}}` summed over all +atoms *i* to produce :math:`B_{\boldsymbol{\nu}}`. If *bikflag* is set to +*1* this is replaced by a separate per-atom ACE descriptor row for each atom. +In this case, the entries in the final column for these rows are set to zero. + +The keyword *dgradflag* determines whether to sum atom gradients or list +them separately. If *dgradflag* is set to 0, the ACE +descriptor gradients w.r.t. atom *j* are summed over all atoms *i'* +of, which may be useful when training linear ACE models on atomic forces. +If *dgradflag* is set to 1, gradients are listed separately for each pair of atoms. +Each row corresponds +to a single term :math:`\frac{\partial {B_{i,\boldsymbol{\nu}}}}{\partial {r}^a_j}` +where :math:`{r}^a_j` is the *a-th* position coordinate of the atom with global +index *j*. This also changes the number of columns to be equal to the number of +ACE descriptors, with 3 additional columns representing the indices :math:`i`, +:math:`j`, and :math:`a`, as explained more in the Output info section below. +The option *dgradflag=1* requires that *bikflag=1*. + +.. note:: + + It is noted here that in contrast to :doc:`pace pair_style `, + the *.yace* file for `compute pace` typically should not contain linear + parameters for an ACE potential. If :math:`c_{\nu}` are included, + the value of the descriptor will not be returned in the `compute` array, + but instead, the energy contribution from that descriptor will be returned. + Do not do this unless it is the desired behavior. + *In short, you should not plug in a '.yace' for a pace potential into this + compute to evaluate descriptors.* + +.. note:: + + *Generalized Clebsch-Gordan or Generalized Wigner symbols (with appropriate + factors) must be used to evaluate ACE descriptors with this compute.* There + are multiple ways to define the generalized coupling coefficients. Because + of this, this compute will not revert your potential file to a coupling + coefficient file. Instead this compute allows the user to supply coupling + coefficients that follow any convention. + +.. note:: + + Using *dgradflag* = 1 produces a global array with :math:`N + 3N^2 + 1` rows + which becomes expensive for systems with more than 1000 atoms. + +.. note:: + + If you have a bonded system, then the settings of :doc:`special_bonds + ` command can remove pairwise interactions between + atoms in the same bond, angle, or dihedral. This is the default + setting for the :doc:`special_bonds ` command, and + means those pairwise interactions do not appear in the neighbor list. + Because this fix uses the neighbor list, it also means those pairs + will not be included in the calculation. One way to get around this, + is to write a dump file, and use the :doc:`rerun ` command to + compute the ACE descriptors for snapshots in the dump file. + The rerun script can use a :doc:`special_bonds ` + command that includes all pairs in the neighbor list. + +---------- + +Output info +""""""""""" + +Compute *pace* evaluates a global array. The columns are arranged into +*ntypes* blocks, listed in order of atom type *I*\ . Each block contains +one column for each ACE descriptor, the same as for compute +*sna/atom*\ in :doc:`compute snap `. A final column contains the corresponding energy, force +component on an atom, or virial stress component. The rows of the array +appear in the following order: + +* 1 row: *pace* average descriptor values for all atoms of type *I* +* 3\*\ *n* force rows: quantities, with derivatives w.r.t. x, y, and z coordinate of atom *i* appearing in consecutive rows. The atoms are sorted based on atom ID and run up to the total number of atoms, *n*. +* 6 rows: *virial* quantities summed for all atoms of type *I* + +For example, if :math:`\# \; B_{i, \boldsymbol{\nu}}` =30 and ntypes=1, the number of columns in the +The number of columns in the global array generated by *pace* are 31, and +931, respectively, while the number of rows is 1+3\*\ *n*\ +6, where *n* +is the total number of atoms. + +If the *bik* keyword is set to 1, the structure of the pace array is expanded. +The first :math:`N` rows of the pace array +correspond to :math:`\# \; B_{i,\boldsymbol{\nu}}` instead of a single row summed over atoms :math:`i`. +In this case, the entries in the final column for these rows +are set to zero. Also, each row contains only non-zero entries for the +columns corresponding to the type of that atom. This is not true in the case +of *dgradflag* keyword = 1 (see below). + +If the *dgradflag* keyword is set to 1, this changes the structure of the +global array completely. +Here the per-atom quantities are replaced with rows corresponding to +descriptor gradient components on single atoms: + +.. math:: + + \frac{\partial {B_{i,\boldsymbol{\nu}} }}{\partial {r}^a_j} + +where :math:`{r}^a_j` is the *a-th* position coordinate of the atom with global +index *j*. The rows are +organized in chunks, where each chunk corresponds to an atom with global index +:math:`j`. The rows in an atom :math:`j` chunk correspond to +atoms with global index :math:`i`. The total number of rows for +these descriptor gradients is therefore :math:`3N^2`. +The number of columns is equal to the number of ACE descriptors, +plus 3 additional left-most columns representing the global atom indices +:math:`i`, :math:`j`, +and Cartesian direction :math:`a` (0, 1, 2, for x, y, z). +The first 3 columns of the first :math:`N` rows belong to the reference +potential force components. The remaining K columns contain the +:math:`B_{i,\boldsymbol{\nu}}` per-atom descriptors corresponding to the non-zero entries +obtained when *bikflag* = 1. +The first column of the last row, after the first +:math:`N + 3N^2` rows, contains the reference potential +energy. The virial components are not used with this option. The total number of +rows is therefore :math:`N + 3N^2 + 1` and the number of columns is :math:`K + 3`. + +These values can be accessed by any command that uses global values +from a compute as input. See the :doc:`Howto output ` doc +page for an overview of LAMMPS output options. + +Restrictions +"""""""""""" + +These computes are part of the ML-PACE package. They are only enabled +if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +Related commands +"""""""""""""""" + +:doc:`pair_style pace ` +:doc:`pair_style snap ` +:doc:`compute snap ` + +Default +""""""" + +The optional keyword defaults are *bikflag* = 0, +*dgradflag* = 0 + +---------- + +.. _Drautz19: + +**(Drautz)** Drautz, Phys Rev B, 99, 014104 (2019). + +.. _Lysogorskiy21: + +**(Lysogorskiy)** Lysogorskiy, van der Oord, Bochkarev, Menon, Rinaldi, Hammerschmidt, Mrovec, Thompson, Csanyi, Ortner, Drautz, npj Comp Mat, 7, 97 (2021). + +.. _Goff23: + +**(Goff)** Goff, Zhang, Negre, Rohskopf, Niklasson, Journal of Chemical Theory and Computation 19, no. 13 (2023). diff --git a/doc/src/compute_rattlers_atom.rst b/doc/src/compute_rattlers_atom.rst index a69d091466..cf4e888657 100644 --- a/doc/src/compute_rattlers_atom.rst +++ b/doc/src/compute_rattlers_atom.rst @@ -1,7 +1,7 @@ .. index:: compute rattlers/atom compute rattlers/atom command -======================== +============================= Syntax """""" @@ -35,7 +35,7 @@ Description .. versionadded:: TBD Define a compute that identifies rattlers in a system. Rattlers are often -identified in granular or glassy packings as undercoordinated atoms that +identified in granular or glassy packings as under-coordinated atoms that do not have the required number of contacts to constrain their translational degrees of freedom. Such atoms are not considered rigid and can often freely rattle around in the system. This compute identifies rattlers which can be diff --git a/doc/src/compute_reaxff_atom.rst b/doc/src/compute_reaxff_atom.rst new file mode 100644 index 0000000000..997ad02e9f --- /dev/null +++ b/doc/src/compute_reaxff_atom.rst @@ -0,0 +1,97 @@ +.. index:: compute reaxff/atom +.. index:: compute reaxff/atom/kk + +compute reaxff/atom command +=========================== + +Accelerator Variants: *reaxff/atom/kk* + +Syntax +"""""" + +.. code-block:: LAMMPS + + compute ID group-ID reaxff/atom attribute args ... keyword value ... + +* ID, group-ID are documented in :doc:`compute ` command +* reaxff/atom = name of this compute command +* attribute = *pair* + + .. parsed-literal:: + + *pair* args = nsub + nsub = *n*-instance of a sub-style, if a pair style is used multiple times in a hybrid style + +* keyword = *bonds* + + .. parsed-literal:: + + *bonds* value = *no* or *yes* + *no* = ignore list of local bonds + *yes* = include list of local bonds + +Examples +"""""""" + +.. code-block:: LAMMPS + + compute 1 all reaxff/atom bonds yes + +Description +""""""""""" + +.. versionadded:: TBD + +Define a computation that extracts bond information computed by the ReaxFF +potential specified by :doc:`pair_style reaxff `. + +By default, it produces per-atom data that includes the following columns: + +* abo = atom bond order (sum of all bonds) +* nlp = number of lone pairs +* nb = number of bonds + +Bonds will only be included if its atoms are in the group. + +In addition, if ``bonds`` is set to ``yes``, the compute will also produce a +local array of all bonds on the current processor whose atoms are in the group. +The columns of each entry of this local array are: + +* id_i = atom i id of bond +* id_j = atom j id of bond +* bo = bond order of bond + +Output info +""""""""""" + +This compute calculates a per-atom array and local array depending on the +number of keywords. The number of rows in the local array is the number of +bonds as described above. Both per-atom and local array have 3 columns. + +The arrays can be accessed by any command that uses local and per-atom values +from a compute as input. See the :doc:`Howto output ` page for +an overview of LAMMPS output options. + +---------- + +.. include:: accel_styles.rst + +---------- + +Restrictions +"""""""""""" + +The compute reaxff/atom command requires that the :doc:`pair_style reaxff +` is invoked. This fix is part of the REAXFF package. It is only +enabled if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +Related commands +"""""""""""""""" + +:doc:`pair_style reaxff ` + +Default +""""""" + +The option defaults are *bonds* = *no*. diff --git a/doc/src/compute_saed.rst b/doc/src/compute_saed.rst index 9ec455d03b..3079afb7ce 100644 --- a/doc/src/compute_saed.rst +++ b/doc/src/compute_saed.rst @@ -68,7 +68,7 @@ reciprocal lattice nodes. The mesh spacing is defined either (a) by the entire simulation domain or (b) manually using selected values as shown in the 2D diagram below. -.. image:: img/saed_mesh.jpg +.. image:: img/saed_mesh.png :scale: 75% :align: center diff --git a/doc/src/compute_slcsa_atom.rst b/doc/src/compute_slcsa_atom.rst new file mode 100644 index 0000000000..6b2708c4d9 --- /dev/null +++ b/doc/src/compute_slcsa_atom.rst @@ -0,0 +1,162 @@ +.. index:: compute slcsa/atom + +compute slcsa/atom command +============================ + +Syntax +"""""" + +.. code-block:: LAMMPS + + compute ID group-ID slcsa/atom twojmax nclasses db_mean_descriptor_file lda_file lr_decision_file lr_bias_file maha_file value + +* ID, group-ID are documented in :doc:`compute ` command +* slcsa/atom = style name of this compute command +* twojmax = band limit for bispectrum components (non-negative integer) +* nclasses = number of crystal structures used in the database for the classifier SL-CSA +* db_mean_descriptor_file = file name of file containing the database mean descriptor +* lda_file = file name of file containing the linear discriminant analysis matrix for dimension reduction +* lr_decision_file = file name of file containing the scaling matrix for logistic regression classification +* lr_bias_file = file name of file containing the bias vector for logistic regression classification +* maha_file = file name of file containing for each crystal structure: the Mahalanobis distance threshold for sanity check purposes, the average reduced descriptor and the inverse of the corresponding covariance matrix +* c_ID[*] = compute ID of previously required *compute sna/atom* command + +Examples +"""""""" + +.. code-block:: LAMMPS + + compute b1 all sna/atom 9.0 0.99363 8 0.5 1.0 rmin0 0.0 nnn 24 wmode 1 delta 0.3 + compute b2 all slcsa/atom 8 4 mean_descriptors.dat lda_scalings.dat lr_decision.dat lr_bias.dat maha_thresholds.dat c_b1[*] + +Description +""""""""""" + +.. versionadded:: TBD + +Define a computation that performs the Supervised Learning Crystal +Structure Analysis (SL-CSA) from :ref:`(Lafourcade) ` +for each atom in the group. The SL-CSA tool takes as an input a per-atom +descriptor (bispectrum) that is computed through the *compute sna/atom* +command and then proceeds to a dimension reduction step followed by a +logistic regression in order to assign a probable crystal structure to +each atom in the group. The SL-CSA tool is pre-trained on a database +containing :math:`C` distinct crystal structures from which a crystal +structure classifier is derived and a tutorial to build such a tool is +available at `SL-CSA `_. + +The first step of the SL-CSA tool consists in performing a dimension +reduction of the per-atom descriptor :math:`\mathbf{B}^i \in +\mathbb{R}^{D}` through the Linear Discriminant Analysis (LDA) method, +leading to a new projected descriptor +:math:`\mathbf{x}^i=\mathrm{P}_\mathrm{LDA}(\mathbf{B}^i):\mathbb{R}^D +\rightarrow \mathbb{R}^{d=C-1}`: + +.. math:: + + \mathbf{x}^i = \mathbf{C}^T_\mathrm{LDA} \cdot (\mathbf{B}^i - \mu^\mathbf{B}_\mathrm{db}) + +where :math:`\mathbf{C}^T_\mathrm{LDA} \in \mathbb{R}^{D \times d}` is +the reduction coefficients matrix of the LDA model read in file +*lda_file*, :math:`\mathbf{B}^i \in \mathbb{R}^{D}` is the bispectrum of +atom :math:`i` and :math:`\mu^\mathbf{B}_\mathrm{db} \in \mathbb{R}^{D}` +is the average descriptor of the entire database. The latter is computed +from the average descriptors of each crystal structure read from the +file *mean_descriptors_file*. + +The new projected descriptor with dimension :math:`d=C-1` allows for a +good separation of different crystal structures fingerprints in the +latent space. + +Once the dimension reduction step is performed by means of LDA, the new +descriptor :math:`\mathbf{x}^i \in \mathbb{R}^{d=C-1}` is taken as an +input for performing a multinomial logistic regression (LR) which +provides a score vector +:math:`\mathbf{s}^i=\mathrm{P}_\mathrm{LR}(\mathbf{x}^i):\mathbb{R}^d +\rightarrow \mathbb{R}^C` defined as: + +.. math:: + + \mathbf{s}^i = \mathbf{b}_\mathrm{LR} + \mathbf{D}_\mathrm{LR} \cdot {\mathbf{x}^i}^T + +with :math:`\mathbf{b}_\mathrm{LR} \in \mathbb{R}^C` and +:math:`\mathbf{D}_\mathrm{LR} \in \mathbb{R}^{C \times d}` the bias +vector and decision matrix of the LR model after training both read in +files *lr_fil1* and *lr_file2* respectively. + +Finally, a probability vector +:math:`\mathbf{p}^i=\mathrm{P}_\mathrm{LR}(\mathbf{x}^i):\mathbb{R}^d +\rightarrow \mathbb{R}^C` is defined as: + +.. math:: + + \mathbf{p}^i = \frac{\mathrm{exp}(\mathbf{s}^i)}{\sum\limits_{j} \mathrm{exp}(s^i_j) } + +from which the crystal structure assigned to each atom with descriptor +:math:`\mathbf{B}^i` and projected descriptor :math:`\mathbf{x}^i` is +computed as the *argmax* of the probability vector +:math:`\mathbf{p}^i`. Since the logistic regression step systematically +attributes a crystal structure to each atom, a sanity check is needed to +avoid misclassification. To this end, a per-atom Mahalanobis distance to +each crystal structure *CS* present in the database is computed: + +.. math:: + + d_\mathrm{Mahalanobis}^{i \rightarrow \mathrm{CS}} = \sqrt{(\mathbf{x}^i - \mathbf{\mu}^\mathbf{x}_\mathrm{CS})^\mathrm{T} \cdot \mathbf{\Sigma}^{-1}_\mathrm{CS} \cdot (\mathbf{x}^i - \mathbf{\mu}^\mathbf{x}_\mathrm{CS}) } + +where :math:`\mathbf{\mu}^\mathbf{x}_\mathrm{CS} \in \mathbb{R}^{d}` is +the average projected descriptor of crystal structure *CS* in the +database and where :math:`\mathbf{\Sigma}_\mathrm{CS} \in \mathbb{R}^{d +\times d}` is the corresponding covariance matrix. Finally, if the +Mahalanobis distance to crystal structure *CS* for atom *i* is greater +than the pre-determined threshold, no crystal structure is assigned to +atom *i*. The Mahalanobis distance thresholds are read in file +*maha_file* while the covariance matrices are read in file +*covmat_file*. + +The `SL-CSA `_ framework provides +an automatic computation of the different matrices and thresholds +required for a proper classification and writes down all the required +files for calling the *compute slcsa/atom* command. + +The *compute slcsa/atom* command requires that the :doc:`compute +sna/atom ` command is called before as it takes the +resulting per-atom bispectrum as an input. In addition, it is crucial +that the value *twojmax* is set to the same value of the value *twojmax* +used in the *compute sna/atom* command, as well as that the value +*nclasses* is set to the number of crystal structures used in the +database to train the SL-CSA tool. + +Output info +""""""""""" + +By default, this compute computes the Mahalanobis distances to the +different crystal structures present in the database in addition to +assigning a crystal structure for each atom as a per-atom vector, which +can be accessed by any command that uses per-atom values from a compute +as input. See the :doc:`Howto output ` page for an +overview of LAMMPS output options. + +Restrictions +"""""""""""" + +This compute is part of the EXTRA-COMPUTE package. It is only enabled +if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +Related commands +"""""""""""""""" + +:doc:`compute sna/atom ` + +Default +""""""" + +none + +---------- + +.. _Lafourcade2023_1: + +**(Lafourcade)** Lafourcade, Maillet, Denoual, Duval, Allera, Goryaeva, and Marinica, +`Comp. Mat. Science, 230, 112534 (2023) `_ diff --git a/doc/src/compute_sna_atom.rst b/doc/src/compute_sna_atom.rst index 8d06868f3d..179c362dc6 100644 --- a/doc/src/compute_sna_atom.rst +++ b/doc/src/compute_sna_atom.rst @@ -45,7 +45,7 @@ Syntax * w_1, w_2,... = list of neighbor weights, one for each type * nx, ny, nz = number of grid points in x, y, and z directions (positive integer) * zero or more keyword/value pairs may be appended -* keyword = *rmin0* or *switchflag* or *bzeroflag* or *quadraticflag* or *chem* or *bnormflag* or *wselfallflag* or *bikflag* or *switchinnerflag* or *sinner* or *dinner* or *dgradflag* +* keyword = *rmin0* or *switchflag* or *bzeroflag* or *quadraticflag* or *chem* or *bnormflag* or *wselfallflag* or *bikflag* or *switchinnerflag* or *sinner* or *dinner* or *dgradflag* or *nnn* or *wmode* or *delta* .. parsed-literal:: @@ -82,6 +82,16 @@ Syntax *0* = descriptor gradients are summed over atoms of each type *1* = descriptor gradients are listed separately for each atom pair +* additional keyword = *nnn* or *wmode* or *delta* + + .. parsed-literal:: + + *nnn* value = number of considered nearest neighbors to compute the bispectrum over a target specific number of neighbors (only implemented for compute sna/atom) + *wmode* value = weight function for finding optimal cutoff to match the target number of neighbors (required if nnn used, only implemented for compute sna/atom) + *0* = heavyside weight function + *1* = hyperbolic tangent weight function + *delta* value = transition interval centered at cutoff distance for hyperbolic tangent weight function (ignored if wmode=0, required if wmode=1, only implemented for compute sna/atom) + Examples """""""" @@ -94,6 +104,7 @@ Examples compute snap all snap 1.0 0.99363 6 3.81 3.83 1.0 0.93 chem 2 0 1 compute snap all snap 1.0 0.99363 6 3.81 3.83 1.0 0.93 switchinnerflag 1 sinner 1.35 1.6 dinner 0.25 0.3 compute bgrid all sna/grid/local 200 200 200 1.4 0.95 6 2.0 1.0 + compute bnnn all sna/atom 9.0 0.99363 8 0.5 1.0 rmin0 0.0 nnn 24 wmode 1 delta 0.2 Description """"""""""" @@ -433,6 +444,25 @@ requires that *bikflag=1*. The rerun script can use a :doc:`special_bonds ` command that includes all pairs in the neighbor list. +The keyword *nnn* allows for the calculation of the bispectrum over a +specific target number of neighbors. This option is only implemented for +the compute *sna/atom*\ . An optimal cutoff radius for defining the +neighborhood of the central atom is calculated by means of a dichotomy +algorithm. This iterative process allows to assign weights to +neighboring atoms in order to match the total sum of weights with the +target number of neighbors. Depending on the radial weight function +used in that process, the cutoff radius can fluctuate a lot in the +presence of thermal noise. Therefore, in addition to the *nnn* keyword, +the keyword *wmode* allows to choose whether a Heaviside (*wmode* = 0) +function or a Hyperbolic tangent function (*wmode* = 1) should be used. +If the Heaviside function is used, the cutoff radius exactly matches the +distance between the central atom an its *nnn*'th neighbor. However, in +the case of the hyperbolic tangent function, the dichotomy algorithm +allows to span the weights over a distance *delta* in order to reduce +fluctuations in the resulting local atomic environment fingerprint. The +detailed formalism is given in the paper by Lafourcade et +al. :ref:`(Lafourcade) `. + ---------- Output info @@ -585,6 +615,7 @@ Related commands """""""""""""""" :doc:`pair_style snap ` +:doc:`compute slcsa/atom ` Default """"""" @@ -592,6 +623,7 @@ Default The optional keyword defaults are *rmin0* = 0, *switchflag* = 1, *bzeroflag* = 1, *quadraticflag* = 0, *bnormflag* = 0, *wselfallflag* = 0, *switchinnerflag* = 0, +*nnn* = -1, *wmode* = 0, *delta* = 1.e-3 ---------- @@ -623,3 +655,8 @@ of Angular Momentum, World Scientific, Singapore (1987). .. _Ellis2021: **(Ellis)** Ellis, Fiedler, Popoola, Modine, Stephens, Thompson, Cangi, Rajamanickam, Phys Rev B, 104, 035120, (2021) + +.. _Lafourcade2023_2: + +**(Lafourcade)** Lafourcade, Maillet, Denoual, Duval, Allera, Goryaeva, and Marinica, +`Comp. Mat. Science, 230, 112534 (2023) `_ diff --git a/doc/src/compute_stress_atom.rst b/doc/src/compute_stress_atom.rst index 8a45171dfe..ffd0d2ffb4 100644 --- a/doc/src/compute_stress_atom.rst +++ b/doc/src/compute_stress_atom.rst @@ -127,11 +127,11 @@ result in more consistent heat flux values for angle, dihedrals, improper and constraint force contributions when computed via :doc:`compute heat/flux `. -If no extra keywords are listed, the kinetic contribution all of the -virial contribution terms are included in the per-atom stress tensor. -If any extra keywords are listed, only those terms are summed to -compute the tensor. The *virial* keyword means include all terms -except the kinetic energy *ke*\ . +If no extra keywords are listed, the kinetic contribution *and* all +of the virial contribution terms are included in the per-atom stress +tensor. If any extra keywords are listed, only those terms are +summed to compute the tensor. The *virial* keyword means include all +terms except the kinetic energy *ke*\ . Note that the stress for each atom is due to its interaction with all other atoms in the simulation, not just with other atoms in the group. diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index 21c2963545..74d4c618e7 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -18,7 +18,7 @@ Syntax * style = *stress/mop* or *stress/mop/profile* * dir = *x* or *y* or *z* is the direction normal to the plane * args = argument specific to the compute style -* keywords = *kin* or *conf* or *total* or *pair* or *bond* or *angle* (one or more can be specified) +* keywords = *kin* or *conf* or *total* or *pair* or *bond* or *angle* or *dihedral* (one or more can be specified) .. parsed-literal:: @@ -68,15 +68,13 @@ Verlet algorithm. .. versionadded:: 15Jun2023 - contributions from bond and angle potentials + contributions from bond, angle and dihedral potentials -Between one and six keywords can be used to indicate which contributions +Between one and seven keywords can be used to indicate which contributions to the stress must be computed: total stress (total), kinetic stress (kin), configurational stress (conf), stress due to bond stretching -(bond), stress due to angle bending (angle) and/or due to pairwise -non-bonded interactions (pair). The angle keyword is currently -available only for the *stress/mop* command and **not** the -*stress/mop/profile* command. +(bond), stress due to angle bending (angle), stress due to dihedral terms (dihedral) +and/or due to pairwise non-bonded interactions (pair). NOTE 1: The configurational stress is computed considering all pairs of atoms where at least one atom belongs to group group-ID. @@ -134,14 +132,9 @@ size does not change in time, and axis-aligned planes. The method only works with two-body pair interactions, because it requires the class method ``Pair::single()`` to be implemented, which is not possible for manybody potentials. In particular, compute -*stress/mop/profile* does not work with more than two-body pair +*stress/mop/profile* and *stress/mop* do not work with more than two-body pair interactions, long range (kspace) interactions and -angle/dihedral/improper intramolecular interactions. Similarly, compute -*stress/mop* does not work with more than two-body pair interactions, -long range (kspace) interactions and dihedral/improper intramolecular -interactions but works with all bond interactions with the class method -single() implemented and all angle interactions with the class method -born_matrix() implemented. +improper intramolecular interactions. Related commands """""""""""""""" diff --git a/doc/src/fix_adapt.rst b/doc/src/fix_adapt.rst index 9cfbef7a11..f857a6333c 100644 --- a/doc/src/fix_adapt.rst +++ b/doc/src/fix_adapt.rst @@ -221,7 +221,7 @@ formulas for the meaning of these parameters: +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`table ` | table_cutoff | type pairs | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ -| :doc:`ufm ` | epsilon,sigma | type pairs | +| :doc:`ufm ` | epsilon,sigma,scale | type pairs | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`wf/cut ` | epsilon,sigma,nu,mu | type pairs | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ diff --git a/doc/src/fix_adapt_fep.rst b/doc/src/fix_adapt_fep.rst index 1b2298cd96..474fc799de 100644 --- a/doc/src/fix_adapt_fep.rst +++ b/doc/src/fix_adapt_fep.rst @@ -123,19 +123,29 @@ styles and their energy formulas for the meaning of these parameters: +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`born ` | a,b,c | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`born/gauss ` | biga0,biga1,r0 | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`buck, buck/coul/cut, buck/coul/long, buck/coul/msm ` | a,c | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`buck/mdf ` | a,c | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ -| :doc:`coul/cut ` | scale | type pairs | +| :doc:`coul/cut, coul/cut/global ` | scale | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`coul/cut/soft ` | lambda | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`coul/debye ` | scale | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`coul/long, coul/msm ` | scale | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`coul/long/soft ` | scale, lambda | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ -| :doc:`eam ` | scale | type pairs | +| :doc:`coul/slater/long ` | scale | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`coul/streitz ` | scale | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`eam, eam/alloy, eam/fs ` | scale | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`harmonic/cut ` | k | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`gauss ` | a | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ @@ -163,6 +173,8 @@ styles and their energy formulas for the meaning of these parameters: +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`lj/sf/dipole/sf ` | epsilon,sigma,scale | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`meam ` | scale | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`mie/cut ` | epsilon,sigma,gamR,gamA | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`morse, morse/smooth/linear ` | d0,r0,alpha | type pairs | @@ -173,12 +185,16 @@ styles and their energy formulas for the meaning of these parameters: +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`nm/cut/coul/cut, nm/cut/coul/long ` | e0,r0,nn,mm | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`pace, pace/extrapolation ` | scale | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`snap ` | scale | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`soft ` | a | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ | :doc:`ufm ` | epsilon,sigma,scale | type pairs | +------------------------------------------------------------------------------+-------------------------+------------+ +| :doc:`wf/cut ` | epsilon,sigma,nu,mu | type pairs | ++------------------------------------------------------------------------------+-------------------------+------------+ .. note:: diff --git a/doc/src/fix_halt.rst b/doc/src/fix_halt.rst index 4231c77cc5..25331804aa 100644 --- a/doc/src/fix_halt.rst +++ b/doc/src/fix_halt.rst @@ -183,4 +183,4 @@ Related commands Default """"""" -The option defaults are error = hard, message = yes, and path = ".". +The option defaults are error = soft, message = yes, and path = ".". diff --git a/doc/src/fix_nh_uef.rst b/doc/src/fix_nh_uef.rst index a515375746..60d47994f0 100644 --- a/doc/src/fix_nh_uef.rst +++ b/doc/src/fix_nh_uef.rst @@ -23,7 +23,7 @@ Syntax .. parsed-literal:: keyword = *erate* or *ext* or *strain* or *temp* or *iso* or *x* or *y* or *z* or *tchain* or *pchain* or *tloop* or *ploop* or *mtk* - *erate* values = e_x e_y = engineering strain rates (required) + *erate* values = e_x e_y = true strain rates (required) *ext* value = *x* or *y* or *z* or *xy* or *yz* or *xz* = external dimensions sets the external dimensions used to calculate the scalar pressure *strain* values = e_x e_y = initial strain @@ -62,7 +62,7 @@ performed using the :doc:`fix deform `, :doc:`fix nvt/sllod `, and :doc:`compute temp/deform ` commands. -The applied flow field is set by the *eps* keyword. The values +The applied flow field is set by the *erate* keyword. The values *edot_x* and *edot_y* correspond to the strain rates in the xx and yy directions. It is implicitly assumed that the flow field is traceless, and therefore the strain rate in the zz direction is eqal diff --git a/doc/src/fix_phonon.rst b/doc/src/fix_phonon.rst index e99d2b6891..6c336dc091 100644 --- a/doc/src/fix_phonon.rst +++ b/doc/src/fix_phonon.rst @@ -181,10 +181,10 @@ This fix assumes a crystalline system with periodical lattice. The temperature of the system should not exceed the melting temperature to keep the system in its solid state. -This fix is part of the PHONON package. It is only enabled if -LAMMPS was built with that package. See the :doc:`Build package ` page for more info. - -This fix requires LAMMPS be built with an FFT library. See the :doc:`Build settings ` page for details. +This fix is part of the PHONON package. It is only enabled if LAMMPS +was built with that package. This fix also requires LAMMPS to be built +with 3d-FFT support which is included in the KSPACE package. See the +:doc:`Build package ` page for more info. Related commands """""""""""""""" diff --git a/doc/src/fix_temp_berendsen.rst b/doc/src/fix_temp_berendsen.rst index 67e496e6c5..541f3191d5 100644 --- a/doc/src/fix_temp_berendsen.rst +++ b/doc/src/fix_temp_berendsen.rst @@ -1,8 +1,11 @@ .. index:: fix temp/berendsen +.. index:: fix temp/berendsen/kk fix temp/berendsen command ========================== +Accelerator Variants: *temp/berendsen/kk* + Syntax """""" @@ -118,6 +121,10 @@ remaining thermal degrees of freedom, and the bias is added back in. ---------- +.. include:: accel_styles.rst + +---------- + Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/doc/src/fix_temp_rescale.rst b/doc/src/fix_temp_rescale.rst index bfdcaa90f8..2dd2178346 100644 --- a/doc/src/fix_temp_rescale.rst +++ b/doc/src/fix_temp_rescale.rst @@ -1,8 +1,11 @@ .. index:: fix temp/rescale +.. index:: fix temp/rescale/kk fix temp/rescale command ======================== +Accelerator Variants: *temp/rescale/kk* + Syntax """""" @@ -125,6 +128,10 @@ remaining thermal degrees of freedom, and the bias is added back in. ---------- +.. include:: accel_styles.rst + +---------- + Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/doc/src/img/saed_mesh.jpg b/doc/src/img/saed_mesh.jpg deleted file mode 100644 index 7b0bf4117f..0000000000 Binary files a/doc/src/img/saed_mesh.jpg and /dev/null differ diff --git a/doc/src/img/saed_mesh.png b/doc/src/img/saed_mesh.png new file mode 100644 index 0000000000..bd558ce072 Binary files /dev/null and b/doc/src/img/saed_mesh.png differ diff --git a/doc/src/molecule.rst b/doc/src/molecule.rst index 1de905886c..b930a9fc65 100644 --- a/doc/src/molecule.rst +++ b/doc/src/molecule.rst @@ -164,8 +164,8 @@ defining a *body* particle, which requires setting the number of * Nd *dihedrals* = # of dihedrals Nd in molecule, default = 0 * Ni *impropers* = # of impropers Ni in molecule, default = 0 * Nf *fragments* = # of fragments Nf in molecule, default = 0 -* Ninteger Ndouble *body* = # of integer and floating-point values in body -particle, default = 0 +* Ninteger Ndouble *body* = # of integer and floating-point values + in body particle, default = 0 * Mtotal *mass* = total mass of molecule * Xc Yc Zc *com* = coordinates of center-of-mass of molecule * Ixx Iyy Izz Ixy Ixz Iyz *inertia* = 6 components of inertia tensor of molecule diff --git a/doc/src/package.rst b/doc/src/package.rst index 63a7f095ad..212a06258c 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -344,12 +344,10 @@ specify additional flags for the runtime build. ---------- -The *intel* style invokes settings associated with the use of the -INTEL package. All of its settings, except the *omp* and *mode* -keywords, are ignored if LAMMPS was not built with Xeon Phi -co-processor support. All of its settings, including the *omp* and -*mode* keyword are applicable if LAMMPS was built with co-processor -support. +The *intel* style invokes settings associated with the use of the INTEL +package. The keywords *balance*, *ghost*, *tpc*, and *tptask* are +**only** applicable if LAMMPS was built with Xeon Phi co-processor +support and are otherwise ignored. The *Nphi* argument sets the number of co-processors per node. This can be set to any value, including 0, if LAMMPS was not @@ -474,13 +472,13 @@ If the *neigh/thread* keyword is set to *off*, then the KOKKOS package threads only over atoms. However, for small systems, this may not expose enough parallelism to keep a GPU busy. When this keyword is set to *on*, the KOKKOS package threads over both atoms and neighbors of atoms. When -using *neigh/thread* *on*, a full neighbor list must also be used. Using -*neigh/thread* *on* may be slower for large systems, so this this option -is turned on by default only when there are 16K atoms or less owned by -an MPI rank and when using a full neighbor list. Not all KOKKOS-enabled -potentials support this keyword yet, and only thread over atoms. Many -simple pairwise potentials such as Lennard-Jones do support threading -over both atoms and neighbors. +using *neigh/thread* *on*, the :doc:`newton pair ` setting must +be "off". Using *neigh/thread* *on* may be slower for large systems, so +this this option is turned on by default only when running on one or +more GPUs and there are 16k atoms or less owned by an MPI rank. Not all +KOKKOS-enabled potentials support this keyword yet, and only thread over +atoms. Many simple pairwise potentials such as Lennard-Jones do support +threading over both atoms and neighbors. If the *neigh/transpose* keyword is set to *off*, then the KOKKOS package will use the same memory layout for building the neighbor list on @@ -732,7 +730,7 @@ comm = device, sort = device, neigh/transpose = off, gpu/aware = on. When LAMMPS can safely detect that GPU-aware MPI is not available, the default value of gpu/aware becomes "off". For CPUs or Xeon Phis, the option defaults are neigh = half, neigh/qeq = half, newton = on, binsize = 0.0, comm = no, and sort -= no. The option neigh/thread = on when there are 16K atoms or less on an MPI += no. For GPUs, option neigh/thread = on when there are 16k atoms or less on an MPI rank, otherwise it is "off". These settings are made automatically by the required "-k on" :doc:`command-line switch `. You can change them by using the package kokkos command in your input script or via the :doc:`-pk diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index 5cee40edda..b84202e69e 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -22,13 +22,24 @@ Examples .. code-block:: LAMMPS pair_style hybrid/overlay aip/water/2dm 16.0 1 - pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw + pair_coeff * * aip/water/2dm CBNOH.aip.water.2dm C Ow Hw pair_style hybrid/overlay aip/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 - pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O - pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H - pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H - pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw + pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O + pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H + pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H + pair_coeff * * aip/water/2dm CBNOH.aip.water.2dm C Ow Hw + + pair_style hybrid/overlay aip/water/2dm 16.0 lj/cut/tip4p/long 3 4 1 1 0.1546 10 8.5 coul/shield 16.0 1 + pair_coeff 1*2 1*2 none + pair_coeff 3 3 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O + pair_coeff 3 4 lj/cut/tip4p/long 0.0 0.0 # O-H + pair_coeff 4 4 lj/cut/tip4p/long 0.0 0.0 # H-H + pair_coeff * * aip/water/2dm CBNOH.aip.water.2dm B N Ow Hw + pair_coeff 1 3 coul/shield 1.333 + pair_coeff 1 4 coul/shield 1.333 + pair_coeff 2 3 coul/shield 1.333 + pair_coeff 2 4 coul/shield 1.333 Description """"""""""" @@ -37,7 +48,7 @@ Description The *aip/water/2dm* style computes the anisotropic interfacial potential (AIP) potential for interfaces of water with two-dimensional (2D) -materials as described in :ref:`(Feng) `. +materials as described in :ref:`(Feng1) ` and :ref:`(Feng2) `. .. math:: @@ -62,12 +73,12 @@ larger than :math:`r_c` :doc:`pair_style ilp_graphene_hbn .. note:: This pair style uses the atomic normal vector definition from - :ref:`(Feng) `), where the atomic normal vectors of the + :ref:`(Feng1) `), where the atomic normal vectors of the hydrogen atoms are assumed to lie along the corresponding oxygen-hydrogen bonds and the normal vector of the central oxygen atom is defined as their average. -The provided parameter file, ``COH.aip.water.2dm``, is intended for use +The provided parameter file, ``CBNOH.aip.water.2dm``, is intended for use with *metal* :doc:`units `, with energies in meV. Two additional parameters, *S*, and *rcut* are included in the parameter file. *S* is designed to facilitate scaling of energies; *rcut* is the cutoff for an @@ -77,7 +88,7 @@ the calculation of the normals for all atom pairs. .. note:: The parameters presented in the provided parameter file, - ``COH.aip.water.2dm``, are fitted with the taper function enabled by + ``CBNOH.aip.water.2dm``, are fitted with the taper function enabled by setting the cutoff equal to 16.0 Angstrom. Using a different cutoff or taper function setting should be carefully checked as they can lead to significant errors. These parameters provide a good @@ -134,7 +145,7 @@ if LAMMPS was built with that package. See the :doc:`Build package This pair style requires the newton setting to be *on* for pair interactions. -The ``COH.aip.water.2dm`` potential file provided with LAMMPS is +The ``CBNOH.aip.water.2dm`` potential file provided with LAMMPS is parameterized for *metal* units. You can use this pair style with any LAMMPS units, but you would need to create your own potential file with parameters in the appropriate units, if your simulation does not use @@ -162,6 +173,10 @@ tap_flag = 1 ---------- -.. _Feng: +.. _Feng1: -**(Feng)** Z. Feng and W. Ouyang et al., J. Phys. Chem. C. 127, 8704-8713 (2023). +**(Feng1)** Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C. 127(18), 8704-8713 (2023). + +.. _Feng2: + +**(Feng2)** Z. Feng, ..., and W. Ouyang, Langmuir 39(50), 18198-18207 (2023). diff --git a/doc/src/pair_coul_slater.rst b/doc/src/pair_coul_slater.rst index 443de4262b..bde14276db 100644 --- a/doc/src/pair_coul_slater.rst +++ b/doc/src/pair_coul_slater.rst @@ -1,6 +1,7 @@ .. index:: pair_style coul/slater .. index:: pair_style coul/slater/cut .. index:: pair_style coul/slater/long +.. index:: pair_style coul/slater/long/gpu pair_style coul/slater command ============================== @@ -11,6 +12,8 @@ pair_style coul/slater/cut command pair_style coul/slater/long command =================================== +Accelerator Variants: *coul/slater/long/gpu* + Syntax """""" diff --git a/doc/src/pair_fep_soft.rst b/doc/src/pair_fep_soft.rst index 400ad0cc4a..20e17ce0b4 100644 --- a/doc/src/pair_fep_soft.rst +++ b/doc/src/pair_fep_soft.rst @@ -1,8 +1,10 @@ .. index:: pair_style lj/cut/soft .. index:: pair_style lj/cut/soft/omp .. index:: pair_style lj/cut/coul/cut/soft +.. index:: pair_style lj/cut/coul/cut/soft/gpu .. index:: pair_style lj/cut/coul/cut/soft/omp .. index:: pair_style lj/cut/coul/long/soft +.. index:: pair_style lj/cut/coul/long/soft/gpu .. index:: pair_style lj/cut/coul/long/soft/omp .. index:: pair_style lj/cut/tip4p/long/soft .. index:: pair_style lj/cut/tip4p/long/soft/omp @@ -27,12 +29,12 @@ Accelerator Variants: *lj/cut/soft/omp* pair_style lj/cut/coul/cut/soft command ======================================= -Accelerator Variants: *lj/cut/coul/cut/soft/omp* +Accelerator Variants: *lj/cut/coul/cut/soft/gpu*, *lj/cut/coul/cut/soft/omp* pair_style lj/cut/coul/long/soft command ======================================== -Accelerator Variants: *lj/cut/coul/long/soft/omp* +Accelerator Variants: *lj/cut/coul/long/soft/gpu*, *lj/cut/coul/long/soft/omp* pair_style lj/cut/tip4p/long/soft command ========================================= diff --git a/doc/src/pair_ilp_tmd.rst b/doc/src/pair_ilp_tmd.rst index 70a4768389..575bafdc91 100644 --- a/doc/src/pair_ilp_tmd.rst +++ b/doc/src/pair_ilp_tmd.rst @@ -22,12 +22,12 @@ Examples .. code-block:: LAMMPS pair_style hybrid/overlay ilp/tmd 16.0 1 - pair_coeff * * ilp/tmd MoS2.ILP Mo S S + pair_coeff * * ilp/tmd TMD.ILP Mo S S pair_style hybrid/overlay sw/mod sw/mod ilp/tmd 16.0 pair_coeff * * sw/mod 1 tmd.sw.mod Mo S S NULL NULL NULL - pair_coeff * * sw/mod 2 tmd.sw.mod NULL NULL NULL Mo S S - pair_coeff * * ilp/tmd MoS2.ILP Mo S S Mo S S + pair_coeff * * sw/mod 2 tmd.sw.mod NULL NULL NULL W Se Se + pair_coeff * * ilp/tmd TMD.ILP Mo S S W Se Se Description """"""""""" @@ -36,7 +36,7 @@ Description The *ilp/tmd* style computes the registry-dependent interlayer potential (ILP) potential for transition metal dichalcogenides (TMD) -as described in :ref:`(Ouyang7) `. +as described in :ref:`(Ouyang7) ` and :ref:`(Jiang) `. .. math:: @@ -69,7 +69,7 @@ calculating the normals. each atom `i`, its six nearest neighboring atoms belonging to the same sub-layer are chosen to define the normal vector `{\bf n}_i`. -The parameter file (e.g. MoS2.ILP), is intended for use with *metal* +The parameter file (e.g. TMD.ILP), is intended for use with *metal* :doc:`units `, with energies in meV. Two additional parameters, *S*, and *rcut* are included in the parameter file. *S* is designed to facilitate scaling of energies. *rcut* is designed to build the neighbor @@ -77,7 +77,7 @@ list for calculating the normals for each atom pair. .. note:: - The parameters presented in the parameter file (e.g. MoS2.ILP), + The parameters presented in the parameter file (e.g. TMD.ILP), are fitted with taper function by setting the cutoff equal to 16.0 Angstrom. Using different cutoff or taper function should be careful. These parameters provide a good description in both short- and long-range @@ -133,10 +133,10 @@ if LAMMPS was built with that package. See the :doc:`Build package This pair style requires the newton setting to be *on* for pair interactions. -The MoS2.ILP potential file provided with LAMMPS (see the potentials +The TMD.ILP potential file provided with LAMMPS (see the potentials directory) are parameterized for *metal* units. You can use this potential with any LAMMPS units, but you would need to create your own -custom MoS2.ILP potential file with coefficients listed in the appropriate +custom TMD.ILP potential file with coefficients listed in the appropriate units, if your simulation does not use *metal* units. Related commands @@ -164,3 +164,7 @@ tap_flag = 1 .. _Ouyang7: **(Ouyang7)** W. Ouyang, et al., J. Chem. Theory Comput. 17, 7237 (2021). + +.. _Jiang: + +**(Jiang)** W. Jiang, et al., J. Phys. Chem. A, 127, 46, 9820-9830 (2023). diff --git a/doc/src/pair_mesodpd.rst b/doc/src/pair_mesodpd.rst index 5d244f3b1d..28a398754f 100644 --- a/doc/src/pair_mesodpd.rst +++ b/doc/src/pair_mesodpd.rst @@ -1,14 +1,20 @@ .. index:: pair_style edpd +.. index:: pair_style edpd/gpu .. index:: pair_style mdpd +.. index:: pair_style mdpd/gpu .. index:: pair_style mdpd/rhosum .. index:: pair_style tdpd pair_style edpd command ======================= +Accelerator Variants: *edpd/gpu* + pair_style mdpd command ======================= +Accelerator Variants: *mdpd/gpu* + pair_style mdpd/rhosum command ============================== diff --git a/doc/src/pair_reaxff.rst b/doc/src/pair_reaxff.rst index d28e15b0a2..03d53d1ff4 100644 --- a/doc/src/pair_reaxff.rst +++ b/doc/src/pair_reaxff.rst @@ -373,7 +373,8 @@ Related commands :doc:`pair_coeff `, :doc:`fix qeq/reaxff `, :doc:`fix acks2/reaxff `, :doc:`fix reaxff/bonds `, -:doc:`fix reaxff/species ` +:doc:`fix reaxff/species `, +:doc:`compute reaxff/atom ` Default """"""" diff --git a/doc/src/pair_sph_heatconduction.rst b/doc/src/pair_sph_heatconduction.rst index 4716ed54fb..e9004cb5a4 100644 --- a/doc/src/pair_sph_heatconduction.rst +++ b/doc/src/pair_sph_heatconduction.rst @@ -1,8 +1,11 @@ .. index:: pair_style sph/heatconduction +.. index:: pair_style sph/heatconduction/gpu pair_style sph/heatconduction command ===================================== +Accelerator Variants: *sph/heatconduction/gpu* + Syntax """""" diff --git a/doc/src/pair_sph_lj.rst b/doc/src/pair_sph_lj.rst index b5c02c41ff..5ac7ab9c6b 100644 --- a/doc/src/pair_sph_lj.rst +++ b/doc/src/pair_sph_lj.rst @@ -1,8 +1,11 @@ .. index:: pair_style sph/lj +.. index:: pair_style sph/lj/gpu pair_style sph/lj command ========================= +Accelerator Variants: *sph/lj/gpu* + Syntax """""" diff --git a/doc/src/pair_sph_taitwater.rst b/doc/src/pair_sph_taitwater.rst index 34eb65f005..79972660c4 100644 --- a/doc/src/pair_sph_taitwater.rst +++ b/doc/src/pair_sph_taitwater.rst @@ -1,8 +1,11 @@ .. index:: pair_style sph/taitwater +.. index:: pair_style sph/taitwater/gpu pair_style sph/taitwater command ================================ +Accelerator Variants: *sph/taitwater/gpu* + Syntax """""" diff --git a/doc/src/run_style.rst b/doc/src/run_style.rst index 0804ce5c82..d2e47c0884 100644 --- a/doc/src/run_style.rst +++ b/doc/src/run_style.rst @@ -329,7 +329,8 @@ Restrictions The *verlet/split* style can only be used if LAMMPS was built with the REPLICA package. Correspondingly the *respa/omp* style is available only if the OPENMP package was included. See the :doc:`Build package -` page for more info. +` page for more info. It is not compatible with +kspace styles from the INTEL package. Whenever using rRESPA, the user should experiment with trade-offs in speed and accuracy for their system, and verify that they are diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 63564fe2e3..51197d9d0f 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -80,6 +80,7 @@ Alessandro Alexey ali aliceblue +Allera Allinger allocatable allocator @@ -732,6 +733,7 @@ dem Dendrimer dendritic Denniston +Denoual dephase dephasing dequidt @@ -803,6 +805,7 @@ dispersionflag dissipative Dissipative distharm +distutils dl dlabel dlambda @@ -873,6 +876,7 @@ Dunweg Dupend Dupont dUs +Duval dV dvector dVx @@ -1312,6 +1316,7 @@ Gonzalez-Melchor googlemail googletest Gordan +Goryaeva Goudeau GPa GPL @@ -1398,12 +1403,14 @@ hcp hdnnp HDNNP Hearn +Heaviside heatconduction heatflow Hebbeker Hebenstreit Hecht Heenen +heFFTe Hendrik Henin Henkelman @@ -1862,6 +1869,7 @@ lbl LBtype lcbop ld +lda ldfftw ldg lebedeva @@ -1983,6 +1991,7 @@ lossy Lozovik lps lpsapi +lr lrt lsfftw lt @@ -2025,7 +2034,10 @@ magelec Maginn magneton magnetons +maha +Mahalanobis Mahoney +Maillet mainboard mainboards makefile @@ -2204,6 +2216,7 @@ mintcream Mintmire Miron mis +misclassification Mises Mishin Mishra @@ -2312,6 +2325,7 @@ multicomponent multicore multielectron multinode +multinomial multiphysics Multipole multiscale @@ -2403,6 +2417,7 @@ Nbtypes Nbytes nc Nc +nclasses nchunk Nchunk ncoeff @@ -2817,6 +2832,7 @@ pIm pimd Piola pIp +pipelining Pisarev Pishevar Pitera @@ -3369,6 +3385,7 @@ Skylake slateblue slategray slater +slcsa Slepoy Sliozberg sLL @@ -4049,6 +4066,7 @@ xy xyz xz xzhou +yace Yade yade yaff diff --git a/examples/COUPLE/simple/simple.cpp b/examples/COUPLE/simple/simple.cpp index c8727cc81f..f6365ac3de 100644 --- a/examples/COUPLE/simple/simple.cpp +++ b/examples/COUPLE/simple/simple.cpp @@ -67,7 +67,7 @@ int main(int narg, char **arg) FILE *fp; if (me == 0) { fp = fopen(arg[2],"r"); - if (fp == NULL) { + if (fp == nullptr) { printf("ERROR: Could not open LAMMPS input script\n"); MPI_Abort(MPI_COMM_WORLD,1); } @@ -78,14 +78,14 @@ int main(int narg, char **arg) // (could just send it to proc 0 of comm_lammps and let it Bcast) // all LAMMPS procs call input->one() on the line - LAMMPS *lmp = NULL; - if (lammps == 1) lmp = new LAMMPS(0,NULL,comm_lammps); + LAMMPS *lmp = nullptr; + if (lammps == 1) lmp = new LAMMPS(0,nullptr,comm_lammps); int n; char line[1024]; - while (1) { + while (true) { if (me == 0) { - if (fgets(line,1024,fp) == NULL) n = 0; + if (fgets(line,1024,fp) == nullptr) n = 0; else n = strlen(line) + 1; if (n == 0) fclose(fp); } @@ -101,8 +101,8 @@ int main(int narg, char **arg) // put coords back into LAMMPS // run a single step with changed coords - double *x = NULL; - double *v = NULL; + double *x = nullptr; + double *v = nullptr; if (lammps == 1) { lmp->input->one("run 10"); @@ -147,7 +147,7 @@ int main(int narg, char **arg) // create_atoms() to create new ones with old coords, vels // initial thermo should be same as step 20 - int *type = NULL; + int *type = nullptr; if (lammps == 1) { int natoms = static_cast (lmp->atom->natoms); @@ -155,7 +155,7 @@ int main(int narg, char **arg) for (int i = 0; i < natoms; i++) type[i] = 1; lmp->input->one("delete_atoms group all"); - lammps_create_atoms(lmp,natoms,NULL,type,x,v,NULL,0); + lammps_create_atoms(lmp,natoms,nullptr,type,x,v,nullptr,0); lmp->input->one("run 10"); } diff --git a/examples/PACKAGES/dpd-meso/mdpd/in.mdpd b/examples/PACKAGES/dpd-meso/mdpd/in.mdpd index b0740c8227..2c740f4127 100644 --- a/examples/PACKAGES/dpd-meso/mdpd/in.mdpd +++ b/examples/PACKAGES/dpd-meso/mdpd/in.mdpd @@ -16,6 +16,7 @@ neighbor 0.3 bin neigh_modify every 1 delay 0 check yes atom_style mdpd +comm_modify vel yes region mdpd block -25 25 -10 10 -10 10 units box create_box 1 mdpd diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/CBNOH.aip.water.2dm b/examples/PACKAGES/interlayer/aip_water_2dm/CBNOH.aip.water.2dm new file mode 120000 index 0000000000..60c9c3a8f4 --- /dev/null +++ b/examples/PACKAGES/interlayer/aip_water_2dm/CBNOH.aip.water.2dm @@ -0,0 +1 @@ +../../../../potentials/CBNOH.aip.water.2dm \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm b/examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm deleted file mode 120000 index fe5cccfcd2..0000000000 --- a/examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm +++ /dev/null @@ -1 +0,0 @@ -../../../../potentials/COH.aip.water.2dm \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/ilp_tmds/MoS2.ILP b/examples/PACKAGES/interlayer/ilp_tmds/MoS2.ILP deleted file mode 120000 index 75dd894eef..0000000000 --- a/examples/PACKAGES/interlayer/ilp_tmds/MoS2.ILP +++ /dev/null @@ -1 +0,0 @@ -../../../../potentials/MoS2.ILP \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/ilp_tmds/TMD.ILP b/examples/PACKAGES/interlayer/ilp_tmds/TMD.ILP new file mode 120000 index 0000000000..70f7ea18df --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_tmds/TMD.ILP @@ -0,0 +1 @@ +../../../../potentials/TMD.ILP \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/ilp_tmds/in.mos2 b/examples/PACKAGES/interlayer/ilp_tmds/in.mos2 index b77f2fe719..0db4ec12d5 100644 --- a/examples/PACKAGES/interlayer/ilp_tmds/in.mos2 +++ b/examples/PACKAGES/interlayer/ilp_tmds/in.mos2 @@ -12,7 +12,7 @@ mass 4 95.94 pair_style hybrid/overlay sw/mod sw/mod ilp/tmd 16.0 pair_coeff * * sw/mod 1 tmd.sw.mod Mo S S NULL NULL NULL pair_coeff * * sw/mod 2 tmd.sw.mod NULL NULL NULL Mo S S -pair_coeff * * ilp/tmd MoS2.ILP Mo S S Mo S S +pair_coeff * * ilp/tmd TMD.ILP Mo S S Mo S S # Calculate the pair potential compute 0 all pair ilp/tmd diff --git a/examples/PACKAGES/pace/README.md b/examples/PACKAGES/pace/README.md new file mode 100644 index 0000000000..66254b5241 --- /dev/null +++ b/examples/PACKAGES/pace/README.md @@ -0,0 +1,9 @@ +# This folder contains examples for pace in LAMMPS + + +## Compute pace usage +compute/latte_cell_0.data # lammps data file with C-H-O structure +compute/latte_cell_0.xyz # xyz file with C-H-O structure +compute/coupling_coefficients.yace # .yace file containing coupling coefficients (or ACE potential parameters) +compute/in.compute # input file for calling `compute pace` + diff --git a/examples/PACKAGES/pace/compute/coupling_coefficients.yace b/examples/PACKAGES/pace/compute/coupling_coefficients.yace new file mode 100644 index 0000000000..2953222216 --- /dev/null +++ b/examples/PACKAGES/pace/compute/coupling_coefficients.yace @@ -0,0 +1,294 @@ +elements: [H, N, O] +E0: [0.000000, 0.000000, 0.000000] +deltaSplineBins: 0.001000 +embeddings: + 0: {ndensity: 1, FS_parameters: [1.0, 1.0], npoti: FinnisSinclair, rho_core_cutoff: 100000, drho_core_cutoff: 250} + 1: {ndensity: 1, FS_parameters: [1.0, 1.0], npoti: FinnisSinclair, rho_core_cutoff: 100000, drho_core_cutoff: 250} + 2: {ndensity: 1, FS_parameters: [1.0, 1.0], npoti: FinnisSinclair, rho_core_cutoff: 100000, drho_core_cutoff: 250} +bonds: + [0, 0]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.0, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [0, 1]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.5, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [0, 2]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.7, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [1, 0]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.5, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [1, 1]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 4.4, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [1, 2]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.7, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [2, 0]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.7, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [2, 1]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.7, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} + [2, 2]: {nradmax: 2, lmax: 2, nradbasemax: 2, radbasename: ChebExpCos, radparameters: [3.3], radcoefficients: [[[1, 0], [1, 0], [1, 0]], [[0, 1], [0, 1], [0, 1]]], prehc: 0, lambdahc: 3.3, rcut: 5.5, dcut: 0.01, rcut_in: 0.1, dcut_in: 0.01, inner_cutoff_type: distance} +functions: + 0: + - {mu0: 0, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [0], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 0, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [0], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 0, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [1], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 0, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [1], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 0, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [2], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 0, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [2], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 0, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 2, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [2, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 0], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 1], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 1], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 2, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [2, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 0, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 0], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 0, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [2, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + 1: + - {mu0: 1, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [1], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 1, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [1], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 1, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [2], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 1, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [2], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 1, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [0], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 1, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [0], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 2, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 1], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 0], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 1], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [2, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 2, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [2, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 1, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 0], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 1, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [2, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + 2: + - {mu0: 2, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [0], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 2, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [1], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 2, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [0], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 2, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [1], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 2, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [2], ns: [1], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 2, rank: 1, ndensity: 1, num_ms_combs: 1, mus: [2], ns: [2], ls: [0], ms_combs: [0], ctildes: [1.0]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 1], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [2, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 1], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 0], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 1], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [0, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [1, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [1, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 1], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [2, 2], ns: [2, 2], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 0], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [1, 1], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [1, 2], ns: [2, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 3, mus: [1, 2], ns: [2, 1], ls: [1, 1], ms_combs: [-1, 1, 0, 0, 1, -1], ctildes: [0.5773502691896257, -0.5773502691896257, 0.5773502691896257]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [0, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 2, ndensity: 1, num_ms_combs: 5, mus: [2, 2], ns: [1, 2], ls: [2, 2], ms_combs: [-2, 2, -1, 1, 0, 0, 1, -1, 2, -2], ctildes: [0.4472135954999579, -0.4472135954999579, 0.447213595499958, -0.4472135954999579, 0.4472135954999579]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 0], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 2, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 1], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 0, 1], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [2, 2, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [2, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 2], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [0, 1, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 2], ns: [1, 1, 1], ls: [1, 2, 1], ms_combs: [-1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -2, 1, 1, -1, 0, 1, 0, -1], ctildes: [0.10540925533894599, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.21081851067789198, -0.18257418583505536, 0.25819888974716115, -0.18257418583505536, 0.10540925533894599]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 1, 1], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 2, 2], ns: [1, 1, 1], ls: [2, 1, 1], ms_combs: [-2, 1, 1, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 2, -1, -1], ctildes: [0.25819888974716115, -0.18257418583505536, -0.18257418583505536, 0.10540925533894599, 0.21081851067789198, 0.10540925533894599, -0.18257418583505536, -0.18257418583505536, 0.25819888974716115]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 9, mus: [1, 2, 2], ns: [1, 1, 1], ls: [1, 1, 2], ms_combs: [-1, -1, 2, -1, 0, 1, -1, 1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 0, 1, 0, -1, 1, 1, -2], ctildes: [0.19999999999999998, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.16329931618554522, -0.1414213562373095, 0.08164965809277261, -0.1414213562373095, 0.19999999999999998]} + - {mu0: 2, rank: 3, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1], ns: [1, 1, 1], ls: [2, 2, 2], ms_combs: [-2, 0, 2, -2, 1, 1, -2, 2, 0, -1, -1, 2, -1, 0, 1, -1, 1, 0, -1, 2, -1, 0, -2, 2, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 2, -2, 1, -2, 1, 1, -1, 0, 1, 0, -1, 1, 1, -2, 2, -2, 0, 2, -1, -1, 2, 0, -2], ctildes: [0.10690449676496976, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, 0.05345224838248488, -0.10690449676496976, 0.05345224838248488, 0.10690449676496976, -0.1309307341415954, 0.05345224838248488, 0.05345224838248488, -0.1309307341415954, 0.10690449676496976, -0.1309307341415954, 0.10690449676496976]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 0], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 0, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 0, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 1, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [0, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1, 1], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 1, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 1, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [1, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} + - {mu0: 2, rank: 4, ndensity: 1, num_ms_combs: 19, mus: [2, 2, 2, 2], ns: [1, 1, 1, 1], ls: [1, 1, 1, 1], ms_combs: [-1, -1, 1, 1, -1, 0, 0, 1, -1, 0, 1, 0, -1, 1, -1, 1, -1, 1, 0, 0, -1, 1, 1, -1, 0, -1, 0, 1, 0, -1, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 1, 0, -1, 1, -1, -1, 1, 1, -1, 0, 0, 1, -1, 1, -1, 1, 0, -1, 0, 1, 0, 0, -1, 1, 1, -1, -1], ctildes: [0.0, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, -0.3333333333333333, 0.3333333333333333, -0.3333333333333333, 0.0, 0.0, 0.3333333333333333, -0.3333333333333333, 0.3333333333333333, 0.0, 0.0, 0.0]} diff --git a/examples/PACKAGES/pace/compute/in.compute b/examples/PACKAGES/pace/compute/in.compute new file mode 100644 index 0000000000..a0ef25f606 --- /dev/null +++ b/examples/PACKAGES/pace/compute/in.compute @@ -0,0 +1,22 @@ +#info all out log +units metal +atom_style atomic +boundary p p p +atom_modify map hash +boundary p p p +read_data latte_cell_0.data +mass 1 1.00 +mass 2 14.00 +mass 3 15.999 + + # potential settings + +pair_style zero 5.7 +pair_coeff * * + +compute pace all pace coupling_coefficients.yace 1 0 + +thermo 1 +thermo_style custom step temp c_pace[1][183] + +run 0 diff --git a/examples/PACKAGES/pace/compute/latte_cell_0.data b/examples/PACKAGES/pace/compute/latte_cell_0.data new file mode 100644 index 0000000000..b18ec13a4d --- /dev/null +++ b/examples/PACKAGES/pace/compute/latte_cell_0.data @@ -0,0 +1,172 @@ +latte_cell_0.data (written by ASE) + +161 atoms +3 atom types +0.0 12 xlo xhi +0.0 12 ylo yhi +0.0 12 zlo zhi + + +Atoms + + 1 3 1.2688096799999999 2.0079938400000001 2.7446829899999998 + 2 1 1.5343068200000001 2.0638766500000001 3.7105626900000002 + 3 1 1.7848279600000001 2.6755003400000001 2.2268847200000002 + 4 1 1.56251195 1.1089126899999999 2.3978115199999999 + 5 1 11.61728216 5.71881094 2.4732045999999999 + 6 2 6.5501865600000002 4.7439566800000001 3.6526025500000001 + 7 1 6.4564895299999998 4.1571673000000002 2.6975267999999999 + 8 2 2.0835561 1.59406078 8.5498047600000007 + 9 1 1.1041162499999999 1.4971771599999999 8.1507879200000009 + 10 1 2.60115534 2.2945960400000001 7.95374187 + 11 1 1.9817723300000001 2.0194066400000001 9.5128239400000005 + 12 1 0.99333338000000004 3.6983907299999998 8.1903947899999991 + 13 3 4.9484070999999998 5.3645501400000004 9.16152503 + 14 1 9.0716170599999995 9.3748453999999999 4.2276462400000003 + 15 2 0.30864418999999998 7.7136657499999997 2.9274995599999998 + 16 1 0.47661671 10.1807211 3.71160091 + 17 1 1.07465334 7.8226921999999997 3.5771466900000002 + 18 1 0.38402249999999999 8.3770493300000002 2.1748437100000002 + 19 1 11.435413410000001 7.7903735999999997 3.4040245499999999 + 20 3 6.1570384599999999 10.25988474 3.50899568 + 21 1 5.5932224399999999 9.5632944700000007 3.1446559000000001 + 22 2 1.7785569000000001 7.6312579300000003 9.1488452299999992 + 23 1 2.5594048599999999 6.96832838 9.3069700199999996 + 24 1 2.12441551 8.4547986999999996 8.6428622900000001 + 25 1 1.04552782 7.1697722800000001 8.5894244999999998 + 26 1 0.34824445999999998 10.17844028 9.1629463799999993 + 27 3 5.9638830399999998 10.723709400000001 9.4568803900000002 + 28 1 6.5890835699999997 10.926486110000001 8.7981925800000003 + 29 2 7.1065890400000002 1.83029753 3.3452543600000002 + 30 1 6.9229304999999997 1.8465022099999999 4.3089037100000001 + 31 1 8.0780433600000006 1.9303052199999999 3.2089521400000001 + 32 1 5.6795373600000003 10.471831630000001 4.3244390499999996 + 33 1 6.82999417 0.95850113000000003 2.9815288199999999 + 34 2 11.383805349999999 4.6301225199999996 2.5393688399999998 + 35 1 0.37927047000000003 4.1943216300000001 2.59073807 + 36 3 5.2376410099999999 1.91523463 9.7240636400000007 + 37 1 4.7887202499999999 2.7036936499999999 9.5698142300000004 + 38 1 9.8129906699999996 9.2075140700000002 4.08265499 + 39 1 4.7980879500000002 1.1403494700000001 9.6739962800000008 + 40 1 5.4455845600000004 2.0102099999999998 10.620773509999999 + 41 3 0.90954338999999995 4.6240093199999999 8.3108110600000007 + 42 1 11.909735319999999 4.7483814000000004 8.2500624600000005 + 43 2 7.3223424499999998 7.5866457 3.0245226500000002 + 44 1 7.4470362200000002 8.3169646700000008 3.7148003300000001 + 45 1 6.9073805300000002 7.9385021 2.1723768699999999 + 46 1 5.5542868500000004 5.1176065800000003 3.7655251999999999 + 47 1 6.8124309500000004 6.7778811599999997 3.3973232499999999 + 48 2 0.29575823000000001 11.04303794 3.1016142499999999 + 49 1 0.86490721999999998 11.83879228 3.6389974500000002 + 50 3 6.85201686 8.0846369300000003 8.8762878799999996 + 51 1 7.3351430100000004 7.4263498700000001 9.3821674799999997 + 52 1 6.7919613300000004 7.7595477199999996 7.9716174799999999 + 53 1 3.8990487699999998 6.4283490399999996 8.8832409600000002 + 54 1 5.95997296 9.9329723199999993 9.4746654699999997 + 55 3 11.403658979999999 10.371960359999999 9.2766092199999992 + 56 1 10.983666360000001 9.5157199800000001 9.1478757300000009 + 57 3 1.5223279700000001 5.3327331100000004 0.57537605999999997 + 58 1 2.3815113999999999 5.7251991200000001 0.77945295999999997 + 59 1 0.92079957000000001 6.0931282299999996 0.62203253000000003 + 60 3 11.23490924 2.9153355200000002 6.7585064099999999 + 61 1 10.792340190000001 2.9755225099999998 5.9000018399999998 + 62 1 10.751242059999999 2.1896156000000002 7.1807401500000001 + 63 3 11.39027944 7.3462855600000001 6.7258299499999996 + 64 1 10.92025679 6.69831954 7.2776696599999999 + 65 1 11.12238028 7.0632020999999998 5.8394107799999997 + 66 3 8.4684319499999994 10.71736286 10.60018556 + 67 1 8.5672201599999998 11.420466080000001 11.25794033 + 68 1 9.0803109800000001 10.04804949 10.9406517 + 69 3 6.5851757299999996 9.9940623399999993 6.5574614899999997 + 70 1 7.0276325799999997 10.76096604 6.1723333699999996 + 71 1 5.7419327400000002 10.384583920000001 6.8228822999999998 + 72 3 1.7600546399999999 1.01771919 5.4926787700000004 + 73 1 1.9704209100000001 1.01748419 6.4429703700000003 + 74 1 1.42973007 0.11076352 5.3470644900000002 + 75 1 2.61130613 9.7034123700000006 10.450306830000001 + 76 3 3.05086908 10.48131334 10.085189310000001 + 77 1 3.0032693199999998 10.93357295 9.3652121000000008 + 78 3 6.4631532199999997 8.7652058299999993 11.967847969999999 + 79 1 6.4506808400000004 9.6596595300000008 11.588956019999999 + 80 1 5.6611629700000003 8.3535737700000006 11.638443329999999 + 81 3 1.1745999300000001 5.2420690800000003 5.1001449699999997 + 82 1 1.31932881 5.5236392399999996 6.0128966300000002 + 83 1 0.58053834999999998 4.4898134599999997 5.2325565000000003 + 84 3 6.7275549699999999 0.78840874999999999 7.3817280900000002 + 85 1 6.3887965600000003 1.54670982 6.8634520400000003 + 86 1 7.6791783999999996 0.94039024000000004 7.2649461000000004 + 87 3 8.5476657199999995 0.0064750299999999997 5.0450514100000001 + 88 1 8.8736290899999997 11.10484108 4.8601807900000003 + 89 1 8.0477597599999999 0.20198361000000001 4.2357399400000002 + 90 3 1.2895030000000001 8.4280097900000008 11.82038504 + 91 1 1.4766666399999999 8.1087866399999999 10.87290333 + 92 1 2.10220669 8.1947620200000006 0.29510553 + 93 3 9.6797907599999995 6.4207335499999996 4.3469150599999997 + 94 1 8.9271530099999996 6.72940235 3.7974122399999999 + 95 1 10.20024126 5.9167739199999998 3.66976111 + 96 3 3.57411616 6.7041021699999996 3.8825478499999999 + 97 1 2.8894899500000002 6.1560529800000001 4.2980848099999998 + 98 1 4.3613707699999997 6.4304732400000004 4.3804965400000002 + 99 3 4.7506556 11.441853350000001 1.12537088 + 100 1 4.0861192800000001 10.748523670000001 1.1923347099999999 + 101 1 5.5035301600000004 10.965688249999999 0.73651277000000004 + 102 3 9.5254526399999992 4.8994443900000002 8.3732284099999994 + 103 1 8.7885959800000002 4.3508043900000004 8.6632831400000008 + 104 1 9.6149067499999994 4.6084911499999999 7.4540068699999997 + 105 3 4.1970746700000001 1.34592128 3.67401439 + 106 1 4.9437011999999996 0.74406280999999996 3.514068 + 107 1 4.1905534900000001 1.7730376000000001 2.7963049400000002 + 108 3 1.88232618 11.95451227 0.60024434000000004 + 109 1 2.0464587299999999 11.02454723 0.38329541 + 110 1 1.1518493700000001 0.17494340999999999 11.99928285 + 111 3 3.7593842199999998 11.01685511 6.4562050800000002 + 112 1 3.2125414299999999 10.4553747 5.8894917099999997 + 113 1 3.4166026899999999 10.821557670000001 7.3296563900000002 + 114 3 9.7039841399999993 3.95001545 11.894743249999999 + 115 1 10.461666060000001 3.9163117999999999 11.285435229999999 + 116 1 10.09834695 4.4026997400000001 0.68193007999999999 + 117 3 8.5639596400000002 3.5169507499999999 5.6224104199999996 + 118 1 8.3966650299999994 2.6262214699999999 5.2638164300000003 + 119 1 7.9695371399999999 4.0825059799999996 5.0049407400000003 + 120 3 9.6736245000000007 0.48030482000000002 7.9257577799999996 + 121 1 9.6131980400000003 11.883419180000001 7.1680923999999999 + 122 1 9.9784050299999993 11.90238635 8.63894187 + 123 3 3.9424153099999999 6.9650296699999998 11.60258943 + 124 1 4.2767152700000004 6.8460048999999996 10.670225220000001 + 125 1 4.6570638500000001 6.5129461500000003 0.091159879999999999 + 126 3 3.0570173199999999 9.6631958499999993 3.6611250599999998 + 127 1 2.5400490100000002 9.5743355000000001 2.8444047600000002 + 128 1 2.9314874400000002 8.7809807200000005 4.0425234200000002 + 129 3 7.4549612700000001 5.8430850799999998 11.011384720000001 + 130 1 8.1675884100000005 5.4639182799999997 10.47644287 + 131 1 6.7135573700000002 5.8393818399999997 10.361099749999999 + 132 3 9.8029139300000008 7.9578901699999998 10.21404942 + 133 1 10.38910242 8.3400641400000008 10.87949429 + 134 1 9.0637612000000001 7.6392374099999998 10.756928869999999 + 135 3 4.4963435599999997 4.1067935799999997 11.73387805 + 136 1 4.5473727899999998 4.9577970899999997 11.19223377 + 137 1 5.3588818399999996 4.1756111699999998 0.20355936999999999 + 138 3 9.5923448100000002 7.3418014600000001 1.34856172 + 139 1 8.8715593300000002 7.4776837199999999 2.05040471 + 140 1 9.0443221699999992 7.2732200799999998 0.54011714 + 141 3 7.0350963100000001 3.22348773 0.7070824 + 142 1 7.1784470499999999 4.1340314300000003 1.0184109699999999 + 143 1 7.7787854400000001 2.7888888399999998 1.15838887 + 144 3 9.2124107800000008 0.48085899999999998 1.21751966 + 145 1 9.6620436499999993 11.657271079999999 1.45318397 + 146 1 9.9404883900000005 1.11619136 1.18684594 + 147 3 1.19704207 9.5859959200000002 6.6190888899999996 + 148 1 0.25606413 9.6737366500000004 6.8319340899999998 + 149 1 1.2690051899999999 8.6249354900000004 6.5480112500000001 + 150 3 0.78256133999999999 2.6040609300000002 11.453408359999999 + 151 1 0.61502181 3.5607405999999999 11.40300991 + 152 1 1.55655312 2.5457368800000002 10.866733030000001 + 153 3 5.8627936099999998 7.1217054800000001 5.89173203 + 154 1 6.3432410700000004 7.9400136699999999 6.0855840299999997 + 155 1 5.5077296699999998 6.8468306800000001 6.7436875799999996 + 156 3 10.887828150000001 9.9637482500000001 0.51092815999999996 + 157 1 11.78841776 10.322043069999999 0.44704989000000001 + 158 1 11.02688182 9.2051906700000004 1.0976661299999999 + 159 3 3.93073389 4.1645674499999998 5.7137877000000001 + 160 1 4.6884062999999996 3.5788913299999998 5.5644605800000004 + 161 1 4.2956948500000003 4.7644888099999996 6.3801669700000003 diff --git a/examples/PACKAGES/pace/compute/latte_cell_0.xyz b/examples/PACKAGES/pace/compute/latte_cell_0.xyz new file mode 100644 index 0000000000..afe0a27f35 --- /dev/null +++ b/examples/PACKAGES/pace/compute/latte_cell_0.xyz @@ -0,0 +1,163 @@ +161 +Lattice="12.0 0.0 0.0 0.0 12.0 0.0 0.0 0.0 12.0" Properties=species:S:1:pos:R:3 pbc="T T T" +O 1.26880968 2.00799384 2.74468299 +H 1.53430682 2.06387665 3.71056269 +H 1.78482796 2.67550034 2.22688472 +H 1.56251195 1.10891269 2.39781152 +H 11.61728216 5.71881094 2.47320460 +N 6.55018656 4.74395668 3.65260255 +H 6.45648953 4.15716730 2.69752680 +N 2.08355610 1.59406078 8.54980476 +H 1.10411625 1.49717716 8.15078792 +H 2.60115534 2.29459604 7.95374187 +H 1.98177233 2.01940664 9.51282394 +H 0.99333338 3.69839073 8.19039479 +O 4.94840710 5.36455014 9.16152503 +H 9.07161706 9.37484540 4.22764624 +N 0.30864419 7.71366575 2.92749956 +H 0.47661671 10.18072110 3.71160091 +H 1.07465334 7.82269220 3.57714669 +H 0.38402250 8.37704933 2.17484371 +H 11.43541341 7.79037360 3.40402455 +O 6.15703846 10.25988474 3.50899568 +H 5.59322244 9.56329447 3.14465590 +N 1.77855690 7.63125793 9.14884523 +H 2.55940486 6.96832838 9.30697002 +H 2.12441551 8.45479870 8.64286229 +H 1.04552782 7.16977228 8.58942450 +H 0.34824446 10.17844028 9.16294638 +O 5.96388304 10.72370940 9.45688039 +H 6.58908357 10.92648611 8.79819258 +N 7.10658904 1.83029753 3.34525436 +H 6.92293050 1.84650221 4.30890371 +H 8.07804336 1.93030522 3.20895214 +H 5.67953736 10.47183163 4.32443905 +H 6.82999417 0.95850113 2.98152882 +N 11.38380535 4.63012252 2.53936884 +H 0.37927047 4.19432163 2.59073807 +O 5.23764101 1.91523463 9.72406364 +H 4.78872025 2.70369365 9.56981423 +H 9.81299067 9.20751407 4.08265499 +H 4.79808795 1.14034947 9.67399628 +H 5.44558456 2.01021000 10.62077351 +O 0.90954339 4.62400932 8.31081106 +H 11.90973532 4.74838140 8.25006246 +N 7.32234245 7.58664570 3.02452265 +H 7.44703622 8.31696467 3.71480033 +H 6.90738053 7.93850210 2.17237687 +H 5.55428685 5.11760658 3.76552520 +H 6.81243095 6.77788116 3.39732325 +N 0.29575823 11.04303794 3.10161425 +H 0.86490722 11.83879228 3.63899745 +O 6.85201686 8.08463693 8.87628788 +H 7.33514301 7.42634987 9.38216748 +H 6.79196133 7.75954772 7.97161748 +H 3.89904877 6.42834904 8.88324096 +H 5.95997296 9.93297232 9.47466547 +O 11.40365898 10.37196036 9.27660922 +H 10.98366636 9.51571998 9.14787573 +O 1.52232797 5.33273311 0.57537606 +H 2.38151140 5.72519912 0.77945296 +H 0.92079957 6.09312823 0.62203253 +O 11.23490924 2.91533552 6.75850641 +H 10.79234019 2.97552251 5.90000184 +H 10.75124206 2.18961560 7.18074015 +O 11.39027944 7.34628556 6.72582995 +H 10.92025679 6.69831954 7.27766966 +H 11.12238028 7.06320210 5.83941078 +O 8.46843195 10.71736286 10.60018556 +H 8.56722016 11.42046608 11.25794033 +H 9.08031098 10.04804949 10.94065170 +O 6.58517573 9.99406234 6.55746149 +H 7.02763258 10.76096604 6.17233337 +H 5.74193274 10.38458392 6.82288230 +O 1.76005464 1.01771919 5.49267877 +H 1.97042091 1.01748419 6.44297037 +H 1.42973007 0.11076352 5.34706449 +H 2.61130613 9.70341237 10.45030683 +O 3.05086908 10.48131334 10.08518931 +H 3.00326932 10.93357295 9.36521210 +O 6.46315322 8.76520583 11.96784797 +H 6.45068084 9.65965953 11.58895602 +H 5.66116297 8.35357377 11.63844333 +O 1.17459993 5.24206908 5.10014497 +H 1.31932881 5.52363924 6.01289663 +H 0.58053835 4.48981346 5.23255650 +O 6.72755497 0.78840875 7.38172809 +H 6.38879656 1.54670982 6.86345204 +H 7.67917840 0.94039024 7.26494610 +O 8.54766572 0.00647503 5.04505141 +H 8.87362909 11.10484108 4.86018079 +H 8.04775976 0.20198361 4.23573994 +O 1.28950300 8.42800979 11.82038504 +H 1.47666664 8.10878664 10.87290333 +H 2.10220669 8.19476202 0.29510553 +O 9.67979076 6.42073355 4.34691506 +H 8.92715301 6.72940235 3.79741224 +H 10.20024126 5.91677392 3.66976111 +O 3.57411616 6.70410217 3.88254785 +H 2.88948995 6.15605298 4.29808481 +H 4.36137077 6.43047324 4.38049654 +O 4.75065560 11.44185335 1.12537088 +H 4.08611928 10.74852367 1.19233471 +H 5.50353016 10.96568825 0.73651277 +O 9.52545264 4.89944439 8.37322841 +H 8.78859598 4.35080439 8.66328314 +H 9.61490675 4.60849115 7.45400687 +O 4.19707467 1.34592128 3.67401439 +H 4.94370120 0.74406281 3.51406800 +H 4.19055349 1.77303760 2.79630494 +O 1.88232618 11.95451227 0.60024434 +H 2.04645873 11.02454723 0.38329541 +H 1.15184937 0.17494341 11.99928285 +O 3.75938422 11.01685511 6.45620508 +H 3.21254143 10.45537470 5.88949171 +H 3.41660269 10.82155767 7.32965639 +O 9.70398414 3.95001545 11.89474325 +H 10.46166606 3.91631180 11.28543523 +H 10.09834695 4.40269974 0.68193008 +O 8.56395964 3.51695075 5.62241042 +H 8.39666503 2.62622147 5.26381643 +H 7.96953714 4.08250598 5.00494074 +O 9.67362450 0.48030482 7.92575778 +H 9.61319804 11.88341918 7.16809240 +H 9.97840503 11.90238635 8.63894187 +O 3.94241531 6.96502967 11.60258943 +H 4.27671527 6.84600490 10.67022522 +H 4.65706385 6.51294615 0.09115988 +O 3.05701732 9.66319585 3.66112506 +H 2.54004901 9.57433550 2.84440476 +H 2.93148744 8.78098072 4.04252342 +O 7.45496127 5.84308508 11.01138472 +H 8.16758841 5.46391828 10.47644287 +H 6.71355737 5.83938184 10.36109975 +O 9.80291393 7.95789017 10.21404942 +H 10.38910242 8.34006414 10.87949429 +H 9.06376120 7.63923741 10.75692887 +O 4.49634356 4.10679358 11.73387805 +H 4.54737279 4.95779709 11.19223377 +H 5.35888184 4.17561117 0.20355937 +O 9.59234481 7.34180146 1.34856172 +H 8.87155933 7.47768372 2.05040471 +H 9.04432217 7.27322008 0.54011714 +O 7.03509631 3.22348773 0.70708240 +H 7.17844705 4.13403143 1.01841097 +H 7.77878544 2.78888884 1.15838887 +O 9.21241078 0.48085900 1.21751966 +H 9.66204365 11.65727108 1.45318397 +H 9.94048839 1.11619136 1.18684594 +O 1.19704207 9.58599592 6.61908889 +H 0.25606413 9.67373665 6.83193409 +H 1.26900519 8.62493549 6.54801125 +O 0.78256134 2.60406093 11.45340836 +H 0.61502181 3.56074060 11.40300991 +H 1.55655312 2.54573688 10.86673303 +O 5.86279361 7.12170548 5.89173203 +H 6.34324107 7.94001367 6.08558403 +H 5.50772967 6.84683068 6.74368758 +O 10.88782815 9.96374825 0.51092816 +H 11.78841776 10.32204307 0.44704989 +H 11.02688182 9.20519067 1.09766613 +O 3.93073389 4.16456745 5.71378770 +H 4.68840630 3.57889133 5.56446058 +H 4.29569485 4.76448881 6.38016697 diff --git a/examples/PACKAGES/pace/compute/log.5Dec23.compute.g++.1 b/examples/PACKAGES/pace/compute/log.5Dec23.compute.g++.1 new file mode 100644 index 0000000000..e5036cfe5b --- /dev/null +++ b/examples/PACKAGES/pace/compute/log.5Dec23.compute.g++.1 @@ -0,0 +1,81 @@ +LAMMPS (21 Nov 2023) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +#info all out log +units metal +atom_style atomic +boundary p p p +atom_modify map hash +boundary p p p +read_data latte_cell_0.data +Reading data file ... + orthogonal box = (0 0 0) to (12 12 12) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 161 atoms + read_data CPU = 0.001 seconds +mass 1 1.00 +mass 2 14.00 +mass 3 15.999 + + # potential settings + +pair_style zero 5.7 +pair_coeff * * + +compute pace all pace coupling_coefficients.yace 1 0 + +thermo 1 +thermo_style custom step temp c_pace[1][183] + +run 0 +WARNING: No fixes with time integration, atoms won't move (src/verlet.cpp:60) +Generated 0 of 3 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 7.7 + ghost atom cutoff = 7.7 + binsize = 3.85, bins = 4 4 4 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair zero, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute pace, occasional + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.993 | 6.993 | 6.993 Mbytes + Step Temp c_pace[1][183] + 0 0 8.6885642 +Loop time of 1.217e-06 on 1 procs for 0 steps with 161 atoms + +164.3% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0 | 0 | 0 | 0.0 | 0.00 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0 | 0 | 0 | 0.0 | 0.00 +Output | 0 | 0 | 0 | 0.0 | 0.00 +Modify | 0 | 0 | 0 | 0.0 | 0.00 +Other | | 1.217e-06 | | |100.00 + +Nlocal: 161 ave 161 max 161 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1754 ave 1754 max 1754 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 14230 ave 14230 max 14230 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 28460 ave 28460 max 28460 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 28460 +Ave neighs/atom = 176.77019 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pace/compute/log.5Dec23.compute.g++.4 b/examples/PACKAGES/pace/compute/log.5Dec23.compute.g++.4 new file mode 100644 index 0000000000..49ca6129b6 --- /dev/null +++ b/examples/PACKAGES/pace/compute/log.5Dec23.compute.g++.4 @@ -0,0 +1,81 @@ +LAMMPS (21 Nov 2023) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +#info all out log +units metal +atom_style atomic +boundary p p p +atom_modify map hash +boundary p p p +read_data latte_cell_0.data +Reading data file ... + orthogonal box = (0 0 0) to (12 12 12) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 161 atoms + read_data CPU = 0.001 seconds +mass 1 1.00 +mass 2 14.00 +mass 3 15.999 + + # potential settings + +pair_style zero 5.7 +pair_coeff * * + +compute pace all pace coupling_coefficients.yace 1 0 + +thermo 1 +thermo_style custom step temp c_pace[1][183] + +run 0 +WARNING: No fixes with time integration, atoms won't move (src/verlet.cpp:60) +Generated 0 of 3 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 7.7 + ghost atom cutoff = 7.7 + binsize = 3.85, bins = 4 4 4 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair zero, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute pace, occasional + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.97 | 6.97 | 6.971 Mbytes + Step Temp c_pace[1][183] + 0 0 8.6885642 +Loop time of 1.979e-06 on 4 procs for 0 steps with 161 atoms + +164.2% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0 | 0 | 0 | 0.0 | 0.00 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0 | 0 | 0 | 0.0 | 0.00 +Output | 0 | 0 | 0 | 0.0 | 0.00 +Modify | 0 | 0 | 0 | 0.0 | 0.00 +Other | | 1.979e-06 | | |100.00 + +Nlocal: 40.25 ave 44 max 35 min +Histogram: 1 0 0 0 1 0 0 0 1 1 +Nghost: 1134.5 ave 1159 max 1117 min +Histogram: 1 1 0 0 1 0 0 0 0 1 +Neighs: 3557.5 ave 4115 max 3189 min +Histogram: 2 0 0 0 0 1 0 0 0 1 +FullNghs: 7115 ave 7755 max 6158 min +Histogram: 1 0 0 0 1 0 0 0 0 2 + +Total # of neighbors = 28460 +Ave neighs/atom = 176.77019 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/sna_nnn_slcsa/Zr_mm.eam.fs b/examples/PACKAGES/sna_nnn_slcsa/Zr_mm.eam.fs new file mode 120000 index 0000000000..f8b779307d --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/Zr_mm.eam.fs @@ -0,0 +1 @@ +../../../potentials/Zr_mm.eam.fs \ No newline at end of file diff --git a/examples/PACKAGES/sna_nnn_slcsa/data.zr_cell b/examples/PACKAGES/sna_nnn_slcsa/data.zr_cell new file mode 100644 index 0000000000..d7c83fc716 --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/data.zr_cell @@ -0,0 +1,879 @@ + # Hcp Zr with box vectors H1=[2-1-10], H2=[-12-10], H3=[0001]. + + 864 atoms + 1 atom types + + 0.000000000000 19.374000000000 xlo xhi + 0.000000000000 33.556752345839 ylo yhi + 0.000000000000 30.846000000000 zlo zhi + +Masses + + 1 91.22400000 # Zr + +Atoms # atomic + + 1 1 0.000000000000 1.864264019213 2.570500000000 + 2 1 0.000000000000 0.000000000000 0.000000000000 + 3 1 1.614500000000 4.660660048033 2.570500000000 + 4 1 1.614500000000 2.796396028820 0.000000000000 + 5 1 3.229000000000 1.864264019213 2.570500000000 + 6 1 3.229000000000 0.000000000000 0.000000000000 + 7 1 4.843500000000 4.660660048033 2.570500000000 + 8 1 4.843500000000 2.796396028820 0.000000000000 + 9 1 6.458000000000 1.864264019213 2.570500000000 + 10 1 6.458000000000 0.000000000000 0.000000000000 + 11 1 8.072500000000 4.660660048033 2.570500000000 + 12 1 8.072500000000 2.796396028820 0.000000000000 + 13 1 9.687000000000 1.864264019213 2.570500000000 + 14 1 9.687000000000 0.000000000000 0.000000000000 + 15 1 11.301500000000 4.660660048033 2.570500000000 + 16 1 11.301500000000 2.796396028820 0.000000000000 + 17 1 12.916000000000 1.864264019213 2.570500000000 + 18 1 12.916000000000 0.000000000000 0.000000000000 + 19 1 14.530500000000 4.660660048033 2.570500000000 + 20 1 14.530500000000 2.796396028820 0.000000000000 + 21 1 16.145000000000 1.864264019213 2.570500000000 + 22 1 16.145000000000 0.000000000000 0.000000000000 + 23 1 17.759500000000 4.660660048033 2.570500000000 + 24 1 17.759500000000 2.796396028820 0.000000000000 + 25 1 0.000000000000 7.457056076853 2.570500000000 + 26 1 0.000000000000 5.592792057640 0.000000000000 + 27 1 1.614500000000 10.253452105673 2.570500000000 + 28 1 1.614500000000 8.389188086460 0.000000000000 + 29 1 3.229000000000 7.457056076853 2.570500000000 + 30 1 3.229000000000 5.592792057640 0.000000000000 + 31 1 4.843500000000 10.253452105673 2.570500000000 + 32 1 4.843500000000 8.389188086460 0.000000000000 + 33 1 6.458000000000 7.457056076853 2.570500000000 + 34 1 6.458000000000 5.592792057640 0.000000000000 + 35 1 8.072500000000 10.253452105673 2.570500000000 + 36 1 8.072500000000 8.389188086460 0.000000000000 + 37 1 9.687000000000 7.457056076853 2.570500000000 + 38 1 9.687000000000 5.592792057640 0.000000000000 + 39 1 11.301500000000 10.253452105673 2.570500000000 + 40 1 11.301500000000 8.389188086460 0.000000000000 + 41 1 12.916000000000 7.457056076853 2.570500000000 + 42 1 12.916000000000 5.592792057640 0.000000000000 + 43 1 14.530500000000 10.253452105673 2.570500000000 + 44 1 14.530500000000 8.389188086460 0.000000000000 + 45 1 16.145000000000 7.457056076853 2.570500000000 + 46 1 16.145000000000 5.592792057640 0.000000000000 + 47 1 17.759500000000 10.253452105673 2.570500000000 + 48 1 17.759500000000 8.389188086460 0.000000000000 + 49 1 0.000000000000 13.049848134493 2.570500000000 + 50 1 0.000000000000 11.185584115280 0.000000000000 + 51 1 1.614500000000 15.846244163313 2.570500000000 + 52 1 1.614500000000 13.981980144100 0.000000000000 + 53 1 3.229000000000 13.049848134493 2.570500000000 + 54 1 3.229000000000 11.185584115280 0.000000000000 + 55 1 4.843500000000 15.846244163313 2.570500000000 + 56 1 4.843500000000 13.981980144100 0.000000000000 + 57 1 6.458000000000 13.049848134493 2.570500000000 + 58 1 6.458000000000 11.185584115280 0.000000000000 + 59 1 8.072500000000 15.846244163313 2.570500000000 + 60 1 8.072500000000 13.981980144100 0.000000000000 + 61 1 9.687000000000 13.049848134493 2.570500000000 + 62 1 9.687000000000 11.185584115280 0.000000000000 + 63 1 11.301500000000 15.846244163313 2.570500000000 + 64 1 11.301500000000 13.981980144100 0.000000000000 + 65 1 12.916000000000 13.049848134493 2.570500000000 + 66 1 12.916000000000 11.185584115280 0.000000000000 + 67 1 14.530500000000 15.846244163313 2.570500000000 + 68 1 14.530500000000 13.981980144100 0.000000000000 + 69 1 16.145000000000 13.049848134493 2.570500000000 + 70 1 16.145000000000 11.185584115280 0.000000000000 + 71 1 17.759500000000 15.846244163313 2.570500000000 + 72 1 17.759500000000 13.981980144100 0.000000000000 + 73 1 0.000000000000 18.642640192133 2.570500000000 + 74 1 0.000000000000 16.778376172920 0.000000000000 + 75 1 1.614500000000 21.439036220953 2.570500000000 + 76 1 1.614500000000 19.574772201740 0.000000000000 + 77 1 3.229000000000 18.642640192133 2.570500000000 + 78 1 3.229000000000 16.778376172920 0.000000000000 + 79 1 4.843500000000 21.439036220953 2.570500000000 + 80 1 4.843500000000 19.574772201740 0.000000000000 + 81 1 6.458000000000 18.642640192133 2.570500000000 + 82 1 6.458000000000 16.778376172920 0.000000000000 + 83 1 8.072500000000 21.439036220953 2.570500000000 + 84 1 8.072500000000 19.574772201740 0.000000000000 + 85 1 9.687000000000 18.642640192133 2.570500000000 + 86 1 9.687000000000 16.778376172920 0.000000000000 + 87 1 11.301500000000 21.439036220953 2.570500000000 + 88 1 11.301500000000 19.574772201740 0.000000000000 + 89 1 12.916000000000 18.642640192133 2.570500000000 + 90 1 12.916000000000 16.778376172920 0.000000000000 + 91 1 14.530500000000 21.439036220953 2.570500000000 + 92 1 14.530500000000 19.574772201740 0.000000000000 + 93 1 16.145000000000 18.642640192133 2.570500000000 + 94 1 16.145000000000 16.778376172920 0.000000000000 + 95 1 17.759500000000 21.439036220953 2.570500000000 + 96 1 17.759500000000 19.574772201740 0.000000000000 + 97 1 0.000000000000 24.235432249773 2.570500000000 + 98 1 0.000000000000 22.371168230560 0.000000000000 + 99 1 1.614500000000 27.031828278593 2.570500000000 + 100 1 1.614500000000 25.167564259380 0.000000000000 + 101 1 3.229000000000 24.235432249773 2.570500000000 + 102 1 3.229000000000 22.371168230560 0.000000000000 + 103 1 4.843500000000 27.031828278593 2.570500000000 + 104 1 4.843500000000 25.167564259380 0.000000000000 + 105 1 6.458000000000 24.235432249773 2.570500000000 + 106 1 6.458000000000 22.371168230560 0.000000000000 + 107 1 8.072500000000 27.031828278593 2.570500000000 + 108 1 8.072500000000 25.167564259380 0.000000000000 + 109 1 9.687000000000 24.235432249773 2.570500000000 + 110 1 9.687000000000 22.371168230560 0.000000000000 + 111 1 11.301500000000 27.031828278593 2.570500000000 + 112 1 11.301500000000 25.167564259380 0.000000000000 + 113 1 12.916000000000 24.235432249773 2.570500000000 + 114 1 12.916000000000 22.371168230560 0.000000000000 + 115 1 14.530500000000 27.031828278593 2.570500000000 + 116 1 14.530500000000 25.167564259380 0.000000000000 + 117 1 16.145000000000 24.235432249773 2.570500000000 + 118 1 16.145000000000 22.371168230560 0.000000000000 + 119 1 17.759500000000 27.031828278593 2.570500000000 + 120 1 17.759500000000 25.167564259380 0.000000000000 + 121 1 0.000000000000 29.828224307413 2.570500000000 + 122 1 0.000000000000 27.963960288200 0.000000000000 + 123 1 1.614500000000 32.624620336233 2.570500000000 + 124 1 1.614500000000 30.760356317019 0.000000000000 + 125 1 3.229000000000 29.828224307413 2.570500000000 + 126 1 3.229000000000 27.963960288200 0.000000000000 + 127 1 4.843500000000 32.624620336233 2.570500000000 + 128 1 4.843500000000 30.760356317019 0.000000000000 + 129 1 6.458000000000 29.828224307413 2.570500000000 + 130 1 6.458000000000 27.963960288200 0.000000000000 + 131 1 8.072500000000 32.624620336233 2.570500000000 + 132 1 8.072500000000 30.760356317019 0.000000000000 + 133 1 9.687000000000 29.828224307413 2.570500000000 + 134 1 9.687000000000 27.963960288200 0.000000000000 + 135 1 11.301500000000 32.624620336233 2.570500000000 + 136 1 11.301500000000 30.760356317019 0.000000000000 + 137 1 12.916000000000 29.828224307413 2.570500000000 + 138 1 12.916000000000 27.963960288200 0.000000000000 + 139 1 14.530500000000 32.624620336233 2.570500000000 + 140 1 14.530500000000 30.760356317019 0.000000000000 + 141 1 16.145000000000 29.828224307413 2.570500000000 + 142 1 16.145000000000 27.963960288200 0.000000000000 + 143 1 17.759500000000 32.624620336233 2.570500000000 + 144 1 17.759500000000 30.760356317019 0.000000000000 + 145 1 0.000000000000 1.864264019213 7.711500000000 + 146 1 0.000000000000 0.000000000000 5.141000000000 + 147 1 1.614500000000 4.660660048033 7.711500000000 + 148 1 1.614500000000 2.796396028820 5.141000000000 + 149 1 3.229000000000 1.864264019213 7.711500000000 + 150 1 3.229000000000 0.000000000000 5.141000000000 + 151 1 4.843500000000 4.660660048033 7.711500000000 + 152 1 4.843500000000 2.796396028820 5.141000000000 + 153 1 6.458000000000 1.864264019213 7.711500000000 + 154 1 6.458000000000 0.000000000000 5.141000000000 + 155 1 8.072500000000 4.660660048033 7.711500000000 + 156 1 8.072500000000 2.796396028820 5.141000000000 + 157 1 9.687000000000 1.864264019213 7.711500000000 + 158 1 9.687000000000 0.000000000000 5.141000000000 + 159 1 11.301500000000 4.660660048033 7.711500000000 + 160 1 11.301500000000 2.796396028820 5.141000000000 + 161 1 12.916000000000 1.864264019213 7.711500000000 + 162 1 12.916000000000 0.000000000000 5.141000000000 + 163 1 14.530500000000 4.660660048033 7.711500000000 + 164 1 14.530500000000 2.796396028820 5.141000000000 + 165 1 16.145000000000 1.864264019213 7.711500000000 + 166 1 16.145000000000 0.000000000000 5.141000000000 + 167 1 17.759500000000 4.660660048033 7.711500000000 + 168 1 17.759500000000 2.796396028820 5.141000000000 + 169 1 0.000000000000 7.457056076853 7.711500000000 + 170 1 0.000000000000 5.592792057640 5.141000000000 + 171 1 1.614500000000 10.253452105673 7.711500000000 + 172 1 1.614500000000 8.389188086460 5.141000000000 + 173 1 3.229000000000 7.457056076853 7.711500000000 + 174 1 3.229000000000 5.592792057640 5.141000000000 + 175 1 4.843500000000 10.253452105673 7.711500000000 + 176 1 4.843500000000 8.389188086460 5.141000000000 + 177 1 6.458000000000 7.457056076853 7.711500000000 + 178 1 6.458000000000 5.592792057640 5.141000000000 + 179 1 8.072500000000 10.253452105673 7.711500000000 + 180 1 8.072500000000 8.389188086460 5.141000000000 + 181 1 9.687000000000 7.457056076853 7.711500000000 + 182 1 9.687000000000 5.592792057640 5.141000000000 + 183 1 11.301500000000 10.253452105673 7.711500000000 + 184 1 11.301500000000 8.389188086460 5.141000000000 + 185 1 12.916000000000 7.457056076853 7.711500000000 + 186 1 12.916000000000 5.592792057640 5.141000000000 + 187 1 14.530500000000 10.253452105673 7.711500000000 + 188 1 14.530500000000 8.389188086460 5.141000000000 + 189 1 16.145000000000 7.457056076853 7.711500000000 + 190 1 16.145000000000 5.592792057640 5.141000000000 + 191 1 17.759500000000 10.253452105673 7.711500000000 + 192 1 17.759500000000 8.389188086460 5.141000000000 + 193 1 0.000000000000 13.049848134493 7.711500000000 + 194 1 0.000000000000 11.185584115280 5.141000000000 + 195 1 1.614500000000 15.846244163313 7.711500000000 + 196 1 1.614500000000 13.981980144100 5.141000000000 + 197 1 3.229000000000 13.049848134493 7.711500000000 + 198 1 3.229000000000 11.185584115280 5.141000000000 + 199 1 4.843500000000 15.846244163313 7.711500000000 + 200 1 4.843500000000 13.981980144100 5.141000000000 + 201 1 6.458000000000 13.049848134493 7.711500000000 + 202 1 6.458000000000 11.185584115280 5.141000000000 + 203 1 8.072500000000 15.846244163313 7.711500000000 + 204 1 8.072500000000 13.981980144100 5.141000000000 + 205 1 9.687000000000 13.049848134493 7.711500000000 + 206 1 9.687000000000 11.185584115280 5.141000000000 + 207 1 11.301500000000 15.846244163313 7.711500000000 + 208 1 11.301500000000 13.981980144100 5.141000000000 + 209 1 12.916000000000 13.049848134493 7.711500000000 + 210 1 12.916000000000 11.185584115280 5.141000000000 + 211 1 14.530500000000 15.846244163313 7.711500000000 + 212 1 14.530500000000 13.981980144100 5.141000000000 + 213 1 16.145000000000 13.049848134493 7.711500000000 + 214 1 16.145000000000 11.185584115280 5.141000000000 + 215 1 17.759500000000 15.846244163313 7.711500000000 + 216 1 17.759500000000 13.981980144100 5.141000000000 + 217 1 0.000000000000 18.642640192133 7.711500000000 + 218 1 0.000000000000 16.778376172920 5.141000000000 + 219 1 1.614500000000 21.439036220953 7.711500000000 + 220 1 1.614500000000 19.574772201740 5.141000000000 + 221 1 3.229000000000 18.642640192133 7.711500000000 + 222 1 3.229000000000 16.778376172920 5.141000000000 + 223 1 4.843500000000 21.439036220953 7.711500000000 + 224 1 4.843500000000 19.574772201740 5.141000000000 + 225 1 6.458000000000 18.642640192133 7.711500000000 + 226 1 6.458000000000 16.778376172920 5.141000000000 + 227 1 8.072500000000 21.439036220953 7.711500000000 + 228 1 8.072500000000 19.574772201740 5.141000000000 + 229 1 9.687000000000 18.642640192133 7.711500000000 + 230 1 9.687000000000 16.778376172920 5.141000000000 + 231 1 11.301500000000 21.439036220953 7.711500000000 + 232 1 11.301500000000 19.574772201740 5.141000000000 + 233 1 12.916000000000 18.642640192133 7.711500000000 + 234 1 12.916000000000 16.778376172920 5.141000000000 + 235 1 14.530500000000 21.439036220953 7.711500000000 + 236 1 14.530500000000 19.574772201740 5.141000000000 + 237 1 16.145000000000 18.642640192133 7.711500000000 + 238 1 16.145000000000 16.778376172920 5.141000000000 + 239 1 17.759500000000 21.439036220953 7.711500000000 + 240 1 17.759500000000 19.574772201740 5.141000000000 + 241 1 0.000000000000 24.235432249773 7.711500000000 + 242 1 0.000000000000 22.371168230560 5.141000000000 + 243 1 1.614500000000 27.031828278593 7.711500000000 + 244 1 1.614500000000 25.167564259380 5.141000000000 + 245 1 3.229000000000 24.235432249773 7.711500000000 + 246 1 3.229000000000 22.371168230560 5.141000000000 + 247 1 4.843500000000 27.031828278593 7.711500000000 + 248 1 4.843500000000 25.167564259380 5.141000000000 + 249 1 6.458000000000 24.235432249773 7.711500000000 + 250 1 6.458000000000 22.371168230560 5.141000000000 + 251 1 8.072500000000 27.031828278593 7.711500000000 + 252 1 8.072500000000 25.167564259380 5.141000000000 + 253 1 9.687000000000 24.235432249773 7.711500000000 + 254 1 9.687000000000 22.371168230560 5.141000000000 + 255 1 11.301500000000 27.031828278593 7.711500000000 + 256 1 11.301500000000 25.167564259380 5.141000000000 + 257 1 12.916000000000 24.235432249773 7.711500000000 + 258 1 12.916000000000 22.371168230560 5.141000000000 + 259 1 14.530500000000 27.031828278593 7.711500000000 + 260 1 14.530500000000 25.167564259380 5.141000000000 + 261 1 16.145000000000 24.235432249773 7.711500000000 + 262 1 16.145000000000 22.371168230560 5.141000000000 + 263 1 17.759500000000 27.031828278593 7.711500000000 + 264 1 17.759500000000 25.167564259380 5.141000000000 + 265 1 0.000000000000 29.828224307413 7.711500000000 + 266 1 0.000000000000 27.963960288200 5.141000000000 + 267 1 1.614500000000 32.624620336233 7.711500000000 + 268 1 1.614500000000 30.760356317019 5.141000000000 + 269 1 3.229000000000 29.828224307413 7.711500000000 + 270 1 3.229000000000 27.963960288200 5.141000000000 + 271 1 4.843500000000 32.624620336233 7.711500000000 + 272 1 4.843500000000 30.760356317019 5.141000000000 + 273 1 6.458000000000 29.828224307413 7.711500000000 + 274 1 6.458000000000 27.963960288200 5.141000000000 + 275 1 8.072500000000 32.624620336233 7.711500000000 + 276 1 8.072500000000 30.760356317019 5.141000000000 + 277 1 9.687000000000 29.828224307413 7.711500000000 + 278 1 9.687000000000 27.963960288200 5.141000000000 + 279 1 11.301500000000 32.624620336233 7.711500000000 + 280 1 11.301500000000 30.760356317019 5.141000000000 + 281 1 12.916000000000 29.828224307413 7.711500000000 + 282 1 12.916000000000 27.963960288200 5.141000000000 + 283 1 14.530500000000 32.624620336233 7.711500000000 + 284 1 14.530500000000 30.760356317019 5.141000000000 + 285 1 16.145000000000 29.828224307413 7.711500000000 + 286 1 16.145000000000 27.963960288200 5.141000000000 + 287 1 17.759500000000 32.624620336233 7.711500000000 + 288 1 17.759500000000 30.760356317019 5.141000000000 + 289 1 0.000000000000 1.864264019213 12.852500000000 + 290 1 0.000000000000 0.000000000000 10.282000000000 + 291 1 1.614500000000 4.660660048033 12.852500000000 + 292 1 1.614500000000 2.796396028820 10.282000000000 + 293 1 3.229000000000 1.864264019213 12.852500000000 + 294 1 3.229000000000 0.000000000000 10.282000000000 + 295 1 4.843500000000 4.660660048033 12.852500000000 + 296 1 4.843500000000 2.796396028820 10.282000000000 + 297 1 6.458000000000 1.864264019213 12.852500000000 + 298 1 6.458000000000 0.000000000000 10.282000000000 + 299 1 8.072500000000 4.660660048033 12.852500000000 + 300 1 8.072500000000 2.796396028820 10.282000000000 + 301 1 9.687000000000 1.864264019213 12.852500000000 + 302 1 9.687000000000 0.000000000000 10.282000000000 + 303 1 11.301500000000 4.660660048033 12.852500000000 + 304 1 11.301500000000 2.796396028820 10.282000000000 + 305 1 12.916000000000 1.864264019213 12.852500000000 + 306 1 12.916000000000 0.000000000000 10.282000000000 + 307 1 14.530500000000 4.660660048033 12.852500000000 + 308 1 14.530500000000 2.796396028820 10.282000000000 + 309 1 16.145000000000 1.864264019213 12.852500000000 + 310 1 16.145000000000 0.000000000000 10.282000000000 + 311 1 17.759500000000 4.660660048033 12.852500000000 + 312 1 17.759500000000 2.796396028820 10.282000000000 + 313 1 0.000000000000 7.457056076853 12.852500000000 + 314 1 0.000000000000 5.592792057640 10.282000000000 + 315 1 1.614500000000 10.253452105673 12.852500000000 + 316 1 1.614500000000 8.389188086460 10.282000000000 + 317 1 3.229000000000 7.457056076853 12.852500000000 + 318 1 3.229000000000 5.592792057640 10.282000000000 + 319 1 4.843500000000 10.253452105673 12.852500000000 + 320 1 4.843500000000 8.389188086460 10.282000000000 + 321 1 6.458000000000 7.457056076853 12.852500000000 + 322 1 6.458000000000 5.592792057640 10.282000000000 + 323 1 8.072500000000 10.253452105673 12.852500000000 + 324 1 8.072500000000 8.389188086460 10.282000000000 + 325 1 9.687000000000 7.457056076853 12.852500000000 + 326 1 9.687000000000 5.592792057640 10.282000000000 + 327 1 11.301500000000 10.253452105673 12.852500000000 + 328 1 11.301500000000 8.389188086460 10.282000000000 + 329 1 12.916000000000 7.457056076853 12.852500000000 + 330 1 12.916000000000 5.592792057640 10.282000000000 + 331 1 14.530500000000 10.253452105673 12.852500000000 + 332 1 14.530500000000 8.389188086460 10.282000000000 + 333 1 16.145000000000 7.457056076853 12.852500000000 + 334 1 16.145000000000 5.592792057640 10.282000000000 + 335 1 17.759500000000 10.253452105673 12.852500000000 + 336 1 17.759500000000 8.389188086460 10.282000000000 + 337 1 0.000000000000 13.049848134493 12.852500000000 + 338 1 0.000000000000 11.185584115280 10.282000000000 + 339 1 1.614500000000 15.846244163313 12.852500000000 + 340 1 1.614500000000 13.981980144100 10.282000000000 + 341 1 3.229000000000 13.049848134493 12.852500000000 + 342 1 3.229000000000 11.185584115280 10.282000000000 + 343 1 4.843500000000 15.846244163313 12.852500000000 + 344 1 4.843500000000 13.981980144100 10.282000000000 + 345 1 6.458000000000 13.049848134493 12.852500000000 + 346 1 6.458000000000 11.185584115280 10.282000000000 + 347 1 8.072500000000 15.846244163313 12.852500000000 + 348 1 8.072500000000 13.981980144100 10.282000000000 + 349 1 9.687000000000 13.049848134493 12.852500000000 + 350 1 9.687000000000 11.185584115280 10.282000000000 + 351 1 11.301500000000 15.846244163313 12.852500000000 + 352 1 11.301500000000 13.981980144100 10.282000000000 + 353 1 12.916000000000 13.049848134493 12.852500000000 + 354 1 12.916000000000 11.185584115280 10.282000000000 + 355 1 14.530500000000 15.846244163313 12.852500000000 + 356 1 14.530500000000 13.981980144100 10.282000000000 + 357 1 16.145000000000 13.049848134493 12.852500000000 + 358 1 16.145000000000 11.185584115280 10.282000000000 + 359 1 17.759500000000 15.846244163313 12.852500000000 + 360 1 17.759500000000 13.981980144100 10.282000000000 + 361 1 0.000000000000 18.642640192133 12.852500000000 + 362 1 0.000000000000 16.778376172920 10.282000000000 + 363 1 1.614500000000 21.439036220953 12.852500000000 + 364 1 1.614500000000 19.574772201740 10.282000000000 + 365 1 3.229000000000 18.642640192133 12.852500000000 + 366 1 3.229000000000 16.778376172920 10.282000000000 + 367 1 4.843500000000 21.439036220953 12.852500000000 + 368 1 4.843500000000 19.574772201740 10.282000000000 + 369 1 6.458000000000 18.642640192133 12.852500000000 + 370 1 6.458000000000 16.778376172920 10.282000000000 + 371 1 8.072500000000 21.439036220953 12.852500000000 + 372 1 8.072500000000 19.574772201740 10.282000000000 + 373 1 9.687000000000 18.642640192133 12.852500000000 + 374 1 9.687000000000 16.778376172920 10.282000000000 + 375 1 11.301500000000 21.439036220953 12.852500000000 + 376 1 11.301500000000 19.574772201740 10.282000000000 + 377 1 12.916000000000 18.642640192133 12.852500000000 + 378 1 12.916000000000 16.778376172920 10.282000000000 + 379 1 14.530500000000 21.439036220953 12.852500000000 + 380 1 14.530500000000 19.574772201740 10.282000000000 + 381 1 16.145000000000 18.642640192133 12.852500000000 + 382 1 16.145000000000 16.778376172920 10.282000000000 + 383 1 17.759500000000 21.439036220953 12.852500000000 + 384 1 17.759500000000 19.574772201740 10.282000000000 + 385 1 0.000000000000 24.235432249773 12.852500000000 + 386 1 0.000000000000 22.371168230560 10.282000000000 + 387 1 1.614500000000 27.031828278593 12.852500000000 + 388 1 1.614500000000 25.167564259380 10.282000000000 + 389 1 3.229000000000 24.235432249773 12.852500000000 + 390 1 3.229000000000 22.371168230560 10.282000000000 + 391 1 4.843500000000 27.031828278593 12.852500000000 + 392 1 4.843500000000 25.167564259380 10.282000000000 + 393 1 6.458000000000 24.235432249773 12.852500000000 + 394 1 6.458000000000 22.371168230560 10.282000000000 + 395 1 8.072500000000 27.031828278593 12.852500000000 + 396 1 8.072500000000 25.167564259380 10.282000000000 + 397 1 9.687000000000 24.235432249773 12.852500000000 + 398 1 9.687000000000 22.371168230560 10.282000000000 + 399 1 11.301500000000 27.031828278593 12.852500000000 + 400 1 11.301500000000 25.167564259380 10.282000000000 + 401 1 12.916000000000 24.235432249773 12.852500000000 + 402 1 12.916000000000 22.371168230560 10.282000000000 + 403 1 14.530500000000 27.031828278593 12.852500000000 + 404 1 14.530500000000 25.167564259380 10.282000000000 + 405 1 16.145000000000 24.235432249773 12.852500000000 + 406 1 16.145000000000 22.371168230560 10.282000000000 + 407 1 17.759500000000 27.031828278593 12.852500000000 + 408 1 17.759500000000 25.167564259380 10.282000000000 + 409 1 0.000000000000 29.828224307413 12.852500000000 + 410 1 0.000000000000 27.963960288200 10.282000000000 + 411 1 1.614500000000 32.624620336233 12.852500000000 + 412 1 1.614500000000 30.760356317019 10.282000000000 + 413 1 3.229000000000 29.828224307413 12.852500000000 + 414 1 3.229000000000 27.963960288200 10.282000000000 + 415 1 4.843500000000 32.624620336233 12.852500000000 + 416 1 4.843500000000 30.760356317019 10.282000000000 + 417 1 6.458000000000 29.828224307413 12.852500000000 + 418 1 6.458000000000 27.963960288200 10.282000000000 + 419 1 8.072500000000 32.624620336233 12.852500000000 + 420 1 8.072500000000 30.760356317019 10.282000000000 + 421 1 9.687000000000 29.828224307413 12.852500000000 + 422 1 9.687000000000 27.963960288200 10.282000000000 + 423 1 11.301500000000 32.624620336233 12.852500000000 + 424 1 11.301500000000 30.760356317019 10.282000000000 + 425 1 12.916000000000 29.828224307413 12.852500000000 + 426 1 12.916000000000 27.963960288200 10.282000000000 + 427 1 14.530500000000 32.624620336233 12.852500000000 + 428 1 14.530500000000 30.760356317019 10.282000000000 + 429 1 16.145000000000 29.828224307413 12.852500000000 + 430 1 16.145000000000 27.963960288200 10.282000000000 + 431 1 17.759500000000 32.624620336233 12.852500000000 + 432 1 17.759500000000 30.760356317019 10.282000000000 + 433 1 0.000000000000 1.864264019213 17.993500000000 + 434 1 0.000000000000 0.000000000000 15.423000000000 + 435 1 1.614500000000 4.660660048033 17.993500000000 + 436 1 1.614500000000 2.796396028820 15.423000000000 + 437 1 3.229000000000 1.864264019213 17.993500000000 + 438 1 3.229000000000 0.000000000000 15.423000000000 + 439 1 4.843500000000 4.660660048033 17.993500000000 + 440 1 4.843500000000 2.796396028820 15.423000000000 + 441 1 6.458000000000 1.864264019213 17.993500000000 + 442 1 6.458000000000 0.000000000000 15.423000000000 + 443 1 8.072500000000 4.660660048033 17.993500000000 + 444 1 8.072500000000 2.796396028820 15.423000000000 + 445 1 9.687000000000 1.864264019213 17.993500000000 + 446 1 9.687000000000 0.000000000000 15.423000000000 + 447 1 11.301500000000 4.660660048033 17.993500000000 + 448 1 11.301500000000 2.796396028820 15.423000000000 + 449 1 12.916000000000 1.864264019213 17.993500000000 + 450 1 12.916000000000 0.000000000000 15.423000000000 + 451 1 14.530500000000 4.660660048033 17.993500000000 + 452 1 14.530500000000 2.796396028820 15.423000000000 + 453 1 16.145000000000 1.864264019213 17.993500000000 + 454 1 16.145000000000 0.000000000000 15.423000000000 + 455 1 17.759500000000 4.660660048033 17.993500000000 + 456 1 17.759500000000 2.796396028820 15.423000000000 + 457 1 0.000000000000 7.457056076853 17.993500000000 + 458 1 0.000000000000 5.592792057640 15.423000000000 + 459 1 1.614500000000 10.253452105673 17.993500000000 + 460 1 1.614500000000 8.389188086460 15.423000000000 + 461 1 3.229000000000 7.457056076853 17.993500000000 + 462 1 3.229000000000 5.592792057640 15.423000000000 + 463 1 4.843500000000 10.253452105673 17.993500000000 + 464 1 4.843500000000 8.389188086460 15.423000000000 + 465 1 6.458000000000 7.457056076853 17.993500000000 + 466 1 6.458000000000 5.592792057640 15.423000000000 + 467 1 8.072500000000 10.253452105673 17.993500000000 + 468 1 8.072500000000 8.389188086460 15.423000000000 + 469 1 9.687000000000 7.457056076853 17.993500000000 + 470 1 9.687000000000 5.592792057640 15.423000000000 + 471 1 11.301500000000 10.253452105673 17.993500000000 + 472 1 11.301500000000 8.389188086460 15.423000000000 + 473 1 12.916000000000 7.457056076853 17.993500000000 + 474 1 12.916000000000 5.592792057640 15.423000000000 + 475 1 14.530500000000 10.253452105673 17.993500000000 + 476 1 14.530500000000 8.389188086460 15.423000000000 + 477 1 16.145000000000 7.457056076853 17.993500000000 + 478 1 16.145000000000 5.592792057640 15.423000000000 + 479 1 17.759500000000 10.253452105673 17.993500000000 + 480 1 17.759500000000 8.389188086460 15.423000000000 + 481 1 0.000000000000 13.049848134493 17.993500000000 + 482 1 0.000000000000 11.185584115280 15.423000000000 + 483 1 1.614500000000 15.846244163313 17.993500000000 + 484 1 1.614500000000 13.981980144100 15.423000000000 + 485 1 3.229000000000 13.049848134493 17.993500000000 + 486 1 3.229000000000 11.185584115280 15.423000000000 + 487 1 4.843500000000 15.846244163313 17.993500000000 + 488 1 4.843500000000 13.981980144100 15.423000000000 + 489 1 6.458000000000 13.049848134493 17.993500000000 + 490 1 6.458000000000 11.185584115280 15.423000000000 + 491 1 8.072500000000 15.846244163313 17.993500000000 + 492 1 8.072500000000 13.981980144100 15.423000000000 + 493 1 9.687000000000 13.049848134493 17.993500000000 + 494 1 9.687000000000 11.185584115280 15.423000000000 + 495 1 11.301500000000 15.846244163313 17.993500000000 + 496 1 11.301500000000 13.981980144100 15.423000000000 + 497 1 12.916000000000 13.049848134493 17.993500000000 + 498 1 12.916000000000 11.185584115280 15.423000000000 + 499 1 14.530500000000 15.846244163313 17.993500000000 + 500 1 14.530500000000 13.981980144100 15.423000000000 + 501 1 16.145000000000 13.049848134493 17.993500000000 + 502 1 16.145000000000 11.185584115280 15.423000000000 + 503 1 17.759500000000 15.846244163313 17.993500000000 + 504 1 17.759500000000 13.981980144100 15.423000000000 + 505 1 0.000000000000 18.642640192133 17.993500000000 + 506 1 0.000000000000 16.778376172920 15.423000000000 + 507 1 1.614500000000 21.439036220953 17.993500000000 + 508 1 1.614500000000 19.574772201740 15.423000000000 + 509 1 3.229000000000 18.642640192133 17.993500000000 + 510 1 3.229000000000 16.778376172920 15.423000000000 + 511 1 4.843500000000 21.439036220953 17.993500000000 + 512 1 4.843500000000 19.574772201740 15.423000000000 + 513 1 6.458000000000 18.642640192133 17.993500000000 + 514 1 6.458000000000 16.778376172920 15.423000000000 + 515 1 8.072500000000 21.439036220953 17.993500000000 + 516 1 8.072500000000 19.574772201740 15.423000000000 + 517 1 9.687000000000 18.642640192133 17.993500000000 + 518 1 9.687000000000 16.778376172920 15.423000000000 + 519 1 11.301500000000 21.439036220953 17.993500000000 + 520 1 11.301500000000 19.574772201740 15.423000000000 + 521 1 12.916000000000 18.642640192133 17.993500000000 + 522 1 12.916000000000 16.778376172920 15.423000000000 + 523 1 14.530500000000 21.439036220953 17.993500000000 + 524 1 14.530500000000 19.574772201740 15.423000000000 + 525 1 16.145000000000 18.642640192133 17.993500000000 + 526 1 16.145000000000 16.778376172920 15.423000000000 + 527 1 17.759500000000 21.439036220953 17.993500000000 + 528 1 17.759500000000 19.574772201740 15.423000000000 + 529 1 0.000000000000 24.235432249773 17.993500000000 + 530 1 0.000000000000 22.371168230560 15.423000000000 + 531 1 1.614500000000 27.031828278593 17.993500000000 + 532 1 1.614500000000 25.167564259380 15.423000000000 + 533 1 3.229000000000 24.235432249773 17.993500000000 + 534 1 3.229000000000 22.371168230560 15.423000000000 + 535 1 4.843500000000 27.031828278593 17.993500000000 + 536 1 4.843500000000 25.167564259380 15.423000000000 + 537 1 6.458000000000 24.235432249773 17.993500000000 + 538 1 6.458000000000 22.371168230560 15.423000000000 + 539 1 8.072500000000 27.031828278593 17.993500000000 + 540 1 8.072500000000 25.167564259380 15.423000000000 + 541 1 9.687000000000 24.235432249773 17.993500000000 + 542 1 9.687000000000 22.371168230560 15.423000000000 + 543 1 11.301500000000 27.031828278593 17.993500000000 + 544 1 11.301500000000 25.167564259380 15.423000000000 + 545 1 12.916000000000 24.235432249773 17.993500000000 + 546 1 12.916000000000 22.371168230560 15.423000000000 + 547 1 14.530500000000 27.031828278593 17.993500000000 + 548 1 14.530500000000 25.167564259380 15.423000000000 + 549 1 16.145000000000 24.235432249773 17.993500000000 + 550 1 16.145000000000 22.371168230560 15.423000000000 + 551 1 17.759500000000 27.031828278593 17.993500000000 + 552 1 17.759500000000 25.167564259380 15.423000000000 + 553 1 0.000000000000 29.828224307413 17.993500000000 + 554 1 0.000000000000 27.963960288200 15.423000000000 + 555 1 1.614500000000 32.624620336233 17.993500000000 + 556 1 1.614500000000 30.760356317019 15.423000000000 + 557 1 3.229000000000 29.828224307413 17.993500000000 + 558 1 3.229000000000 27.963960288200 15.423000000000 + 559 1 4.843500000000 32.624620336233 17.993500000000 + 560 1 4.843500000000 30.760356317019 15.423000000000 + 561 1 6.458000000000 29.828224307413 17.993500000000 + 562 1 6.458000000000 27.963960288200 15.423000000000 + 563 1 8.072500000000 32.624620336233 17.993500000000 + 564 1 8.072500000000 30.760356317019 15.423000000000 + 565 1 9.687000000000 29.828224307413 17.993500000000 + 566 1 9.687000000000 27.963960288200 15.423000000000 + 567 1 11.301500000000 32.624620336233 17.993500000000 + 568 1 11.301500000000 30.760356317019 15.423000000000 + 569 1 12.916000000000 29.828224307413 17.993500000000 + 570 1 12.916000000000 27.963960288200 15.423000000000 + 571 1 14.530500000000 32.624620336233 17.993500000000 + 572 1 14.530500000000 30.760356317019 15.423000000000 + 573 1 16.145000000000 29.828224307413 17.993500000000 + 574 1 16.145000000000 27.963960288200 15.423000000000 + 575 1 17.759500000000 32.624620336233 17.993500000000 + 576 1 17.759500000000 30.760356317019 15.423000000000 + 577 1 0.000000000000 1.864264019213 23.134500000000 + 578 1 0.000000000000 0.000000000000 20.564000000000 + 579 1 1.614500000000 4.660660048033 23.134500000000 + 580 1 1.614500000000 2.796396028820 20.564000000000 + 581 1 3.229000000000 1.864264019213 23.134500000000 + 582 1 3.229000000000 0.000000000000 20.564000000000 + 583 1 4.843500000000 4.660660048033 23.134500000000 + 584 1 4.843500000000 2.796396028820 20.564000000000 + 585 1 6.458000000000 1.864264019213 23.134500000000 + 586 1 6.458000000000 0.000000000000 20.564000000000 + 587 1 8.072500000000 4.660660048033 23.134500000000 + 588 1 8.072500000000 2.796396028820 20.564000000000 + 589 1 9.687000000000 1.864264019213 23.134500000000 + 590 1 9.687000000000 0.000000000000 20.564000000000 + 591 1 11.301500000000 4.660660048033 23.134500000000 + 592 1 11.301500000000 2.796396028820 20.564000000000 + 593 1 12.916000000000 1.864264019213 23.134500000000 + 594 1 12.916000000000 0.000000000000 20.564000000000 + 595 1 14.530500000000 4.660660048033 23.134500000000 + 596 1 14.530500000000 2.796396028820 20.564000000000 + 597 1 16.145000000000 1.864264019213 23.134500000000 + 598 1 16.145000000000 0.000000000000 20.564000000000 + 599 1 17.759500000000 4.660660048033 23.134500000000 + 600 1 17.759500000000 2.796396028820 20.564000000000 + 601 1 0.000000000000 7.457056076853 23.134500000000 + 602 1 0.000000000000 5.592792057640 20.564000000000 + 603 1 1.614500000000 10.253452105673 23.134500000000 + 604 1 1.614500000000 8.389188086460 20.564000000000 + 605 1 3.229000000000 7.457056076853 23.134500000000 + 606 1 3.229000000000 5.592792057640 20.564000000000 + 607 1 4.843500000000 10.253452105673 23.134500000000 + 608 1 4.843500000000 8.389188086460 20.564000000000 + 609 1 6.458000000000 7.457056076853 23.134500000000 + 610 1 6.458000000000 5.592792057640 20.564000000000 + 611 1 8.072500000000 10.253452105673 23.134500000000 + 612 1 8.072500000000 8.389188086460 20.564000000000 + 613 1 9.687000000000 7.457056076853 23.134500000000 + 614 1 9.687000000000 5.592792057640 20.564000000000 + 615 1 11.301500000000 10.253452105673 23.134500000000 + 616 1 11.301500000000 8.389188086460 20.564000000000 + 617 1 12.916000000000 7.457056076853 23.134500000000 + 618 1 12.916000000000 5.592792057640 20.564000000000 + 619 1 14.530500000000 10.253452105673 23.134500000000 + 620 1 14.530500000000 8.389188086460 20.564000000000 + 621 1 16.145000000000 7.457056076853 23.134500000000 + 622 1 16.145000000000 5.592792057640 20.564000000000 + 623 1 17.759500000000 10.253452105673 23.134500000000 + 624 1 17.759500000000 8.389188086460 20.564000000000 + 625 1 0.000000000000 13.049848134493 23.134500000000 + 626 1 0.000000000000 11.185584115280 20.564000000000 + 627 1 1.614500000000 15.846244163313 23.134500000000 + 628 1 1.614500000000 13.981980144100 20.564000000000 + 629 1 3.229000000000 13.049848134493 23.134500000000 + 630 1 3.229000000000 11.185584115280 20.564000000000 + 631 1 4.843500000000 15.846244163313 23.134500000000 + 632 1 4.843500000000 13.981980144100 20.564000000000 + 633 1 6.458000000000 13.049848134493 23.134500000000 + 634 1 6.458000000000 11.185584115280 20.564000000000 + 635 1 8.072500000000 15.846244163313 23.134500000000 + 636 1 8.072500000000 13.981980144100 20.564000000000 + 637 1 9.687000000000 13.049848134493 23.134500000000 + 638 1 9.687000000000 11.185584115280 20.564000000000 + 639 1 11.301500000000 15.846244163313 23.134500000000 + 640 1 11.301500000000 13.981980144100 20.564000000000 + 641 1 12.916000000000 13.049848134493 23.134500000000 + 642 1 12.916000000000 11.185584115280 20.564000000000 + 643 1 14.530500000000 15.846244163313 23.134500000000 + 644 1 14.530500000000 13.981980144100 20.564000000000 + 645 1 16.145000000000 13.049848134493 23.134500000000 + 646 1 16.145000000000 11.185584115280 20.564000000000 + 647 1 17.759500000000 15.846244163313 23.134500000000 + 648 1 17.759500000000 13.981980144100 20.564000000000 + 649 1 0.000000000000 18.642640192133 23.134500000000 + 650 1 0.000000000000 16.778376172920 20.564000000000 + 651 1 1.614500000000 21.439036220953 23.134500000000 + 652 1 1.614500000000 19.574772201740 20.564000000000 + 653 1 3.229000000000 18.642640192133 23.134500000000 + 654 1 3.229000000000 16.778376172920 20.564000000000 + 655 1 4.843500000000 21.439036220953 23.134500000000 + 656 1 4.843500000000 19.574772201740 20.564000000000 + 657 1 6.458000000000 18.642640192133 23.134500000000 + 658 1 6.458000000000 16.778376172920 20.564000000000 + 659 1 8.072500000000 21.439036220953 23.134500000000 + 660 1 8.072500000000 19.574772201740 20.564000000000 + 661 1 9.687000000000 18.642640192133 23.134500000000 + 662 1 9.687000000000 16.778376172920 20.564000000000 + 663 1 11.301500000000 21.439036220953 23.134500000000 + 664 1 11.301500000000 19.574772201740 20.564000000000 + 665 1 12.916000000000 18.642640192133 23.134500000000 + 666 1 12.916000000000 16.778376172920 20.564000000000 + 667 1 14.530500000000 21.439036220953 23.134500000000 + 668 1 14.530500000000 19.574772201740 20.564000000000 + 669 1 16.145000000000 18.642640192133 23.134500000000 + 670 1 16.145000000000 16.778376172920 20.564000000000 + 671 1 17.759500000000 21.439036220953 23.134500000000 + 672 1 17.759500000000 19.574772201740 20.564000000000 + 673 1 0.000000000000 24.235432249773 23.134500000000 + 674 1 0.000000000000 22.371168230560 20.564000000000 + 675 1 1.614500000000 27.031828278593 23.134500000000 + 676 1 1.614500000000 25.167564259380 20.564000000000 + 677 1 3.229000000000 24.235432249773 23.134500000000 + 678 1 3.229000000000 22.371168230560 20.564000000000 + 679 1 4.843500000000 27.031828278593 23.134500000000 + 680 1 4.843500000000 25.167564259380 20.564000000000 + 681 1 6.458000000000 24.235432249773 23.134500000000 + 682 1 6.458000000000 22.371168230560 20.564000000000 + 683 1 8.072500000000 27.031828278593 23.134500000000 + 684 1 8.072500000000 25.167564259380 20.564000000000 + 685 1 9.687000000000 24.235432249773 23.134500000000 + 686 1 9.687000000000 22.371168230560 20.564000000000 + 687 1 11.301500000000 27.031828278593 23.134500000000 + 688 1 11.301500000000 25.167564259380 20.564000000000 + 689 1 12.916000000000 24.235432249773 23.134500000000 + 690 1 12.916000000000 22.371168230560 20.564000000000 + 691 1 14.530500000000 27.031828278593 23.134500000000 + 692 1 14.530500000000 25.167564259380 20.564000000000 + 693 1 16.145000000000 24.235432249773 23.134500000000 + 694 1 16.145000000000 22.371168230560 20.564000000000 + 695 1 17.759500000000 27.031828278593 23.134500000000 + 696 1 17.759500000000 25.167564259380 20.564000000000 + 697 1 0.000000000000 29.828224307413 23.134500000000 + 698 1 0.000000000000 27.963960288200 20.564000000000 + 699 1 1.614500000000 32.624620336233 23.134500000000 + 700 1 1.614500000000 30.760356317019 20.564000000000 + 701 1 3.229000000000 29.828224307413 23.134500000000 + 702 1 3.229000000000 27.963960288200 20.564000000000 + 703 1 4.843500000000 32.624620336233 23.134500000000 + 704 1 4.843500000000 30.760356317019 20.564000000000 + 705 1 6.458000000000 29.828224307413 23.134500000000 + 706 1 6.458000000000 27.963960288200 20.564000000000 + 707 1 8.072500000000 32.624620336233 23.134500000000 + 708 1 8.072500000000 30.760356317019 20.564000000000 + 709 1 9.687000000000 29.828224307413 23.134500000000 + 710 1 9.687000000000 27.963960288200 20.564000000000 + 711 1 11.301500000000 32.624620336233 23.134500000000 + 712 1 11.301500000000 30.760356317019 20.564000000000 + 713 1 12.916000000000 29.828224307413 23.134500000000 + 714 1 12.916000000000 27.963960288200 20.564000000000 + 715 1 14.530500000000 32.624620336233 23.134500000000 + 716 1 14.530500000000 30.760356317019 20.564000000000 + 717 1 16.145000000000 29.828224307413 23.134500000000 + 718 1 16.145000000000 27.963960288200 20.564000000000 + 719 1 17.759500000000 32.624620336233 23.134500000000 + 720 1 17.759500000000 30.760356317019 20.564000000000 + 721 1 0.000000000000 1.864264019213 28.275500000000 + 722 1 0.000000000000 0.000000000000 25.705000000000 + 723 1 1.614500000000 4.660660048033 28.275500000000 + 724 1 1.614500000000 2.796396028820 25.705000000000 + 725 1 3.229000000000 1.864264019213 28.275500000000 + 726 1 3.229000000000 0.000000000000 25.705000000000 + 727 1 4.843500000000 4.660660048033 28.275500000000 + 728 1 4.843500000000 2.796396028820 25.705000000000 + 729 1 6.458000000000 1.864264019213 28.275500000000 + 730 1 6.458000000000 0.000000000000 25.705000000000 + 731 1 8.072500000000 4.660660048033 28.275500000000 + 732 1 8.072500000000 2.796396028820 25.705000000000 + 733 1 9.687000000000 1.864264019213 28.275500000000 + 734 1 9.687000000000 0.000000000000 25.705000000000 + 735 1 11.301500000000 4.660660048033 28.275500000000 + 736 1 11.301500000000 2.796396028820 25.705000000000 + 737 1 12.916000000000 1.864264019213 28.275500000000 + 738 1 12.916000000000 0.000000000000 25.705000000000 + 739 1 14.530500000000 4.660660048033 28.275500000000 + 740 1 14.530500000000 2.796396028820 25.705000000000 + 741 1 16.145000000000 1.864264019213 28.275500000000 + 742 1 16.145000000000 0.000000000000 25.705000000000 + 743 1 17.759500000000 4.660660048033 28.275500000000 + 744 1 17.759500000000 2.796396028820 25.705000000000 + 745 1 0.000000000000 7.457056076853 28.275500000000 + 746 1 0.000000000000 5.592792057640 25.705000000000 + 747 1 1.614500000000 10.253452105673 28.275500000000 + 748 1 1.614500000000 8.389188086460 25.705000000000 + 749 1 3.229000000000 7.457056076853 28.275500000000 + 750 1 3.229000000000 5.592792057640 25.705000000000 + 751 1 4.843500000000 10.253452105673 28.275500000000 + 752 1 4.843500000000 8.389188086460 25.705000000000 + 753 1 6.458000000000 7.457056076853 28.275500000000 + 754 1 6.458000000000 5.592792057640 25.705000000000 + 755 1 8.072500000000 10.253452105673 28.275500000000 + 756 1 8.072500000000 8.389188086460 25.705000000000 + 757 1 9.687000000000 7.457056076853 28.275500000000 + 758 1 9.687000000000 5.592792057640 25.705000000000 + 759 1 11.301500000000 10.253452105673 28.275500000000 + 760 1 11.301500000000 8.389188086460 25.705000000000 + 761 1 12.916000000000 7.457056076853 28.275500000000 + 762 1 12.916000000000 5.592792057640 25.705000000000 + 763 1 14.530500000000 10.253452105673 28.275500000000 + 764 1 14.530500000000 8.389188086460 25.705000000000 + 765 1 16.145000000000 7.457056076853 28.275500000000 + 766 1 16.145000000000 5.592792057640 25.705000000000 + 767 1 17.759500000000 10.253452105673 28.275500000000 + 768 1 17.759500000000 8.389188086460 25.705000000000 + 769 1 0.000000000000 13.049848134493 28.275500000000 + 770 1 0.000000000000 11.185584115280 25.705000000000 + 771 1 1.614500000000 15.846244163313 28.275500000000 + 772 1 1.614500000000 13.981980144100 25.705000000000 + 773 1 3.229000000000 13.049848134493 28.275500000000 + 774 1 3.229000000000 11.185584115280 25.705000000000 + 775 1 4.843500000000 15.846244163313 28.275500000000 + 776 1 4.843500000000 13.981980144100 25.705000000000 + 777 1 6.458000000000 13.049848134493 28.275500000000 + 778 1 6.458000000000 11.185584115280 25.705000000000 + 779 1 8.072500000000 15.846244163313 28.275500000000 + 780 1 8.072500000000 13.981980144100 25.705000000000 + 781 1 9.687000000000 13.049848134493 28.275500000000 + 782 1 9.687000000000 11.185584115280 25.705000000000 + 783 1 11.301500000000 15.846244163313 28.275500000000 + 784 1 11.301500000000 13.981980144100 25.705000000000 + 785 1 12.916000000000 13.049848134493 28.275500000000 + 786 1 12.916000000000 11.185584115280 25.705000000000 + 787 1 14.530500000000 15.846244163313 28.275500000000 + 788 1 14.530500000000 13.981980144100 25.705000000000 + 789 1 16.145000000000 13.049848134493 28.275500000000 + 790 1 16.145000000000 11.185584115280 25.705000000000 + 791 1 17.759500000000 15.846244163313 28.275500000000 + 792 1 17.759500000000 13.981980144100 25.705000000000 + 793 1 0.000000000000 18.642640192133 28.275500000000 + 794 1 0.000000000000 16.778376172920 25.705000000000 + 795 1 1.614500000000 21.439036220953 28.275500000000 + 796 1 1.614500000000 19.574772201740 25.705000000000 + 797 1 3.229000000000 18.642640192133 28.275500000000 + 798 1 3.229000000000 16.778376172920 25.705000000000 + 799 1 4.843500000000 21.439036220953 28.275500000000 + 800 1 4.843500000000 19.574772201740 25.705000000000 + 801 1 6.458000000000 18.642640192133 28.275500000000 + 802 1 6.458000000000 16.778376172920 25.705000000000 + 803 1 8.072500000000 21.439036220953 28.275500000000 + 804 1 8.072500000000 19.574772201740 25.705000000000 + 805 1 9.687000000000 18.642640192133 28.275500000000 + 806 1 9.687000000000 16.778376172920 25.705000000000 + 807 1 11.301500000000 21.439036220953 28.275500000000 + 808 1 11.301500000000 19.574772201740 25.705000000000 + 809 1 12.916000000000 18.642640192133 28.275500000000 + 810 1 12.916000000000 16.778376172920 25.705000000000 + 811 1 14.530500000000 21.439036220953 28.275500000000 + 812 1 14.530500000000 19.574772201740 25.705000000000 + 813 1 16.145000000000 18.642640192133 28.275500000000 + 814 1 16.145000000000 16.778376172920 25.705000000000 + 815 1 17.759500000000 21.439036220953 28.275500000000 + 816 1 17.759500000000 19.574772201740 25.705000000000 + 817 1 0.000000000000 24.235432249773 28.275500000000 + 818 1 0.000000000000 22.371168230560 25.705000000000 + 819 1 1.614500000000 27.031828278593 28.275500000000 + 820 1 1.614500000000 25.167564259380 25.705000000000 + 821 1 3.229000000000 24.235432249773 28.275500000000 + 822 1 3.229000000000 22.371168230560 25.705000000000 + 823 1 4.843500000000 27.031828278593 28.275500000000 + 824 1 4.843500000000 25.167564259380 25.705000000000 + 825 1 6.458000000000 24.235432249773 28.275500000000 + 826 1 6.458000000000 22.371168230560 25.705000000000 + 827 1 8.072500000000 27.031828278593 28.275500000000 + 828 1 8.072500000000 25.167564259380 25.705000000000 + 829 1 9.687000000000 24.235432249773 28.275500000000 + 830 1 9.687000000000 22.371168230560 25.705000000000 + 831 1 11.301500000000 27.031828278593 28.275500000000 + 832 1 11.301500000000 25.167564259380 25.705000000000 + 833 1 12.916000000000 24.235432249773 28.275500000000 + 834 1 12.916000000000 22.371168230560 25.705000000000 + 835 1 14.530500000000 27.031828278593 28.275500000000 + 836 1 14.530500000000 25.167564259380 25.705000000000 + 837 1 16.145000000000 24.235432249773 28.275500000000 + 838 1 16.145000000000 22.371168230560 25.705000000000 + 839 1 17.759500000000 27.031828278593 28.275500000000 + 840 1 17.759500000000 25.167564259380 25.705000000000 + 841 1 0.000000000000 29.828224307413 28.275500000000 + 842 1 0.000000000000 27.963960288200 25.705000000000 + 843 1 1.614500000000 32.624620336233 28.275500000000 + 844 1 1.614500000000 30.760356317019 25.705000000000 + 845 1 3.229000000000 29.828224307413 28.275500000000 + 846 1 3.229000000000 27.963960288200 25.705000000000 + 847 1 4.843500000000 32.624620336233 28.275500000000 + 848 1 4.843500000000 30.760356317019 25.705000000000 + 849 1 6.458000000000 29.828224307413 28.275500000000 + 850 1 6.458000000000 27.963960288200 25.705000000000 + 851 1 8.072500000000 32.624620336233 28.275500000000 + 852 1 8.072500000000 30.760356317019 25.705000000000 + 853 1 9.687000000000 29.828224307413 28.275500000000 + 854 1 9.687000000000 27.963960288200 25.705000000000 + 855 1 11.301500000000 32.624620336233 28.275500000000 + 856 1 11.301500000000 30.760356317019 25.705000000000 + 857 1 12.916000000000 29.828224307413 28.275500000000 + 858 1 12.916000000000 27.963960288200 25.705000000000 + 859 1 14.530500000000 32.624620336233 28.275500000000 + 860 1 14.530500000000 30.760356317019 25.705000000000 + 861 1 16.145000000000 29.828224307413 28.275500000000 + 862 1 16.145000000000 27.963960288200 25.705000000000 + 863 1 17.759500000000 32.624620336233 28.275500000000 + 864 1 17.759500000000 30.760356317019 25.705000000000 diff --git a/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lda_scalings.dat b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lda_scalings.dat new file mode 100644 index 0000000000..68a78f8c40 --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lda_scalings.dat @@ -0,0 +1,55 @@ +0.65552758 -0.08218108 -0.23122826 +2.03065849 0.46494117 0.87297750 +-15.80180341 1.50484584 0.31669351 +0.06060238 -0.47589059 -0.41017499 +4.23928030 -2.27982958 4.87969884 +-1.09746642 -1.28258171 2.03459312 +5.48480653 -0.66345012 3.18471732 +-1.57479966 0.17478998 -0.17156696 +3.85779786 1.59890578 1.78936017 +-1.14469715 -2.15823271 2.14353632 +5.97160056 0.11573423 0.97653410 +4.44645807 -0.15365582 -0.08773622 +3.09452721 0.32439223 1.19779688 +-1.22585061 -0.32185613 0.03949731 +0.44816997 -1.11182687 0.26222208 +0.19532128 0.30397832 -0.57154050 +5.52432571 -0.76685448 0.32647935 +6.37957282 -0.96148815 1.53439397 +2.73798648 -0.69516327 1.73607004 +0.94755899 0.41154702 -0.14095753 +1.50733544 1.22254481 0.26284605 +0.98313431 -1.24195379 0.59009611 +-0.76518592 0.11605047 -0.00304658 +-0.68335076 0.48935564 -0.53834507 +1.86534260 -0.49032664 -0.06298849 +1.52931829 0.64853878 -0.56286214 +2.64217062 -1.37348638 0.22526281 +0.18023516 0.03439864 0.77624538 +2.02366558 0.35432524 0.76748492 +0.80982907 0.31806067 0.08774175 +1.57388194 -1.07822533 0.15886237 +0.41345498 0.38916338 -0.29917607 +-0.24819893 0.13763422 0.45471609 +-2.27933523 -0.01771636 -0.20567577 +1.52275665 0.35306670 0.21266257 +0.28547991 1.05230832 1.16641438 +0.97147437 -0.63973458 -0.37994470 +0.48124764 0.03483500 -0.01982056 +0.74502588 0.14367872 -0.24443596 +0.48813660 0.15632903 -0.88469078 +0.04886450 0.00882595 -0.47920447 +0.03103900 -0.15091487 -0.41193682 +-0.10106190 0.14911569 0.10727243 +-0.15552036 -0.49286545 -0.04644942 +0.27304084 0.35638954 1.13331445 +0.57788886 -0.50269555 0.09110942 +0.36780762 -0.08710371 -0.28478716 +1.01678932 -0.42099561 -0.07317253 +0.06561086 -0.27253002 -0.05366136 +0.22266923 0.19999531 -0.30017173 +-0.18666193 0.02576273 0.27752106 +-0.76718071 0.61299522 0.58296511 +0.60978530 0.04962900 -0.32796430 +-0.11572649 0.03034386 -0.83005753 +0.12675714 0.00004617 -0.37078106 diff --git a/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lr_bias.dat b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lr_bias.dat new file mode 100644 index 0000000000..467f1844d9 --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lr_bias.dat @@ -0,0 +1 @@ +-6.32012657 5.62127377 1.19871662 -0.49986382 diff --git a/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lr_decision.dat b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lr_decision.dat new file mode 100644 index 0000000000..e938d59d8b --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/lr_decision.dat @@ -0,0 +1,4 @@ +-0.42810669 1.25467216 0.93144383 +0.09624929 -0.80420088 0.48996738 +-0.09865949 0.39991755 -0.69233982 +0.43051689 -0.85038883 -0.72907140 diff --git a/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/mahalanobis_file.dat b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/mahalanobis_file.dat new file mode 100644 index 0000000000..299ef3c72f --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/mahalanobis_file.dat @@ -0,0 +1,20 @@ +5.0540 +-23.8329 4.6638 3.9805 +1.1377 0.1077 -0.0171 +0.1077 0.8846 -0.2577 +-0.0171 -0.2577 0.6783 +5.2340 +-21.2853 -6.1583 1.7948 +1.7124 0.0341 0.1966 +0.0341 0.6453 0.2880 +0.1966 0.2880 1.8991 +5.0360 +-23.1593 1.3059 -5.7549 +0.7496 -0.0806 -0.1101 +-0.0806 1.1178 0.1667 +-0.1101 0.1667 0.6711 +7.9940 +68.1971 0.1604 -0.0067 +0.9663 -0.1846 0.6622 +-0.1846 8.2371 0.9841 +0.6622 0.9841 5.9601 diff --git a/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/mean_descriptor.dat b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/mean_descriptor.dat new file mode 100644 index 0000000000..ae50ec809f --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/dir.slcsa/mean_descriptor.dat @@ -0,0 +1,55 @@ +137.71497059 +0.36342014 +-2.78949838 +1.75623090 +-4.86893969 +-2.31918628 +-3.01873942 +59.70217846 +-8.31239311 +-1.05113276 +-4.08948813 +11.70560234 +17.48710737 +42.43158755 +-6.27727395 +-1.46675636 +-3.40739849 +1.58674150 +13.02515977 +5.67885926 +6.45692906 +4.69273492 +21.59764216 +-7.68805780 +-4.37357550 +-5.79764719 +0.53149261 +-0.00723980 +-2.47811316 +-0.34939237 +-4.59425510 +-4.44056296 +107.64051985 +-9.32851480 +-6.62214151 +-5.69590145 +22.80361437 +9.47641390 +2.25214024 +-0.19403065 +3.05386205 +12.91756406 +135.15381317 +-9.93292065 +-3.73311129 +10.67039500 +9.60945072 +-0.03566872 +21.97944941 +6.70251772 +74.60284853 +-5.99090678 +0.21877973 +-1.19909174 +1.37424965 diff --git a/examples/PACKAGES/sna_nnn_slcsa/in.slcsa b/examples/PACKAGES/sna_nnn_slcsa/in.slcsa new file mode 100644 index 0000000000..31a8189da3 --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/in.slcsa @@ -0,0 +1,57 @@ +variable trequis equal 750.0 +variable prequis_low equal 0.0 +variable prequis_high equal 25.0e4 +variable equilSteps equal 200 +variable runSteps equal 2000 +variable freqdump equal 200 +variable pstime equal step*dt +variable sxx equal 1.e-4*pxx +variable syy equal 1.e-4*pyy +variable szz equal 1.e-4*pzz +variable sxy equal 1.e-4*pxy +variable sxz equal 1.e-4*pxz +variable syz equal 1.e-4*pyz +variable TK equal temp +variable PE equal pe +variable KE equal ke +variable V equal vol + +dimension 3 +boundary p p p +units metal +atom_style atomic +read_data data.zr_cell +replicate 1 5 5 + +change_box all triclinic + +pair_style hybrid/overlay zero 9.0 eam/fs +pair_coeff * * zero +pair_coeff * * eam/fs Zr_mm.eam.fs Zr + +timestep 0.002 + +thermo 50 +thermo_style custom step pe ke temp vol pxx pyy pzz pxy pyz pxz + +# fix extra all print 50 "${pstime} ${TK} ${PE} ${KE} ${V} ${sxx} ${syy} ${szz} ${sxy} ${sxz} ${syz}" file thermo_global_npt_low_temperature_Zr_hcp.dat + +velocity all create ${trequis} 42345 dist gaussian + +# 1st step : compute the bispectrum on 24 nearest neighbors +compute bnnn all sna/atom 9.0 0.99363 8 0.5 1.0 rmin0 0.0 nnn 24 wmode 1 delta 0.25 + +# 2nd step : perform dimension reduction + logistic regression +compute slcsa all slcsa/atom 8 4 dir.slcsa/mean_descriptor.dat dir.slcsa/lda_scalings.dat dir.slcsa/lr_decision.dat dir.slcsa/lr_bias.dat dir.slcsa/mahalanobis_file.dat c_bnnn[*] + +#dump d1 all custom ${freqdump} slcsa_demo.dump id x y z c_slcsa[*] + +# for testing only. in production use dump as shown above +compute max_slcsa all reduce max c_slcsa[*] +compute min_slcsa all reduce min c_slcsa[*] +thermo_style custom step pe ke temp c_max_slcsa[*] c_min_slcsa[*] + +#fix 1 all nvt temp ${trequis} ${trequis} 0.100 +fix 1 all npt temp ${trequis} ${trequis} 0.100 tri ${prequis_low} ${prequis_low} 1.0 + +run ${equilSteps} diff --git a/examples/PACKAGES/sna_nnn_slcsa/log.12Dec23.slcsa.g++.1 b/examples/PACKAGES/sna_nnn_slcsa/log.12Dec23.slcsa.g++.1 new file mode 100644 index 0000000000..58c2f40684 --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/log.12Dec23.slcsa.g++.1 @@ -0,0 +1,180 @@ +LAMMPS (21 Nov 2023) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +variable trequis equal 750.0 +variable prequis_low equal 0.0 +variable prequis_high equal 25.0e4 +variable equilSteps equal 200 +variable runSteps equal 2000 +variable freqdump equal 200 +variable pstime equal step*dt +variable sxx equal 1.e-4*pxx +variable syy equal 1.e-4*pyy +variable szz equal 1.e-4*pzz +variable sxy equal 1.e-4*pxy +variable sxz equal 1.e-4*pxz +variable syz equal 1.e-4*pyz +variable TK equal temp +variable PE equal pe +variable KE equal ke +variable V equal vol + +dimension 3 +boundary p p p +units metal +atom_style atomic +read_data data.zr_cell +Reading data file ... + orthogonal box = (0 0 0) to (19.374 33.556752 30.846) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 864 atoms + read_data CPU = 0.002 seconds +replicate 1 5 5 +Replication is creating a 1x5x5 = 25 times larger system... + orthogonal box = (0 0 0) to (19.374 167.78376 154.23) + 1 by 1 by 1 MPI processor grid + 21600 atoms + replicate CPU = 0.001 seconds + +change_box all triclinic +Changing box ... + triclinic box = (0 0 0) to (19.374 167.78376 154.23) with tilt (0 0 0) + +pair_style hybrid/overlay zero 9.0 eam/fs +pair_coeff * * zero +pair_coeff * * eam/fs Zr_mm.eam.fs Zr +Reading eam/fs potential file Zr_mm.eam.fs with DATE: 2007-06-11 + +timestep 0.002 + +thermo 50 +thermo_style custom step pe ke temp vol pxx pyy pzz pxy pyz pxz + +# fix extra all print 50 "${pstime} ${TK} ${PE} ${KE} ${V} ${sxx} ${syy} ${szz} ${sxy} ${sxz} ${syz}" file thermo_global_npt_low_temperature_Zr_hcp.dat + +velocity all create ${trequis} 42345 dist gaussian +velocity all create 750 42345 dist gaussian + +# 1st step : compute the bispectrum on 24 nearest neighbors +compute bnnn all sna/atom 9.0 0.99363 8 0.5 1.0 rmin0 0.0 nnn 24 wmode 1 delta 0.25 + +# 2nd step : perform dimension reduction + logistic regression +compute slcsa all slcsa/atom 8 4 dir.slcsa/mean_descriptor.dat dir.slcsa/lda_scalings.dat dir.slcsa/lr_decision.dat dir.slcsa/lr_bias.dat dir.slcsa/mahalanobis_file.dat c_bnnn[*] +Files used: + database mean descriptor: dir.slcsa/mean_descriptor.dat + lda scalings : dir.slcsa/lda_scalings.dat + lr decision : dir.slcsa/lr_decision.dat + lr bias : dir.slcsa/lr_bias.dat + maha stats : dir.slcsa/mahalanobis_file.dat +For class 0 maha threshold = 5.054 + mean B: + -23.8329 + 4.6638 + 3.9805 + icov: + 1.1377 0.1077 -0.0171 + 0.1077 0.8846 -0.2577 + -0.0171 -0.2577 0.6783 +For class 1 maha threshold = 5.234 + mean B: + -21.2853 + -6.1583 + 1.7948 + icov: + 1.7124 0.0341 0.1966 + 0.0341 0.6453 0.288 + 0.1966 0.288 1.8991 +For class 2 maha threshold = 5.036 + mean B: + -23.1593 + 1.3059 + -5.7549 + icov: + 0.7496 -0.0806 -0.1101 + -0.0806 1.1178 0.1667 + -0.1101 0.1667 0.6711 +For class 3 maha threshold = 7.994 + mean B: + 68.1971 + 0.1604 + -0.0067 + icov: + 0.9663 -0.1846 0.6622 + -0.1846 8.2371 0.9841 + 0.6622 0.9841 5.9601 + +#dump d1 all custom ${freqdump} slcsa_demo.dump id x y z c_slcsa[*] + +# for testing only. in production use dump as shown above +compute max_slcsa all reduce max c_slcsa[*] +compute min_slcsa all reduce min c_slcsa[*] +thermo_style custom step pe ke temp c_max_slcsa[*] c_min_slcsa[*] + +#fix 1 all nvt temp ${trequis} ${trequis} 0.100 +fix 1 all npt temp ${trequis} ${trequis} 0.100 tri ${prequis_low} ${prequis_low} 1.0 +fix 1 all npt temp 750 ${trequis} 0.100 tri ${prequis_low} ${prequis_low} 1.0 +fix 1 all npt temp 750 750 0.100 tri ${prequis_low} ${prequis_low} 1.0 +fix 1 all npt temp 750 750 0.100 tri 0 ${prequis_low} 1.0 +fix 1 all npt temp 750 750 0.100 tri 0 0 1.0 + +run ${equilSteps} +run 200 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 11 + ghost atom cutoff = 11 + binsize = 5.5, bins = 4 31 29 + 3 neighbor lists, perpetual/occasional/extra = 2 1 0 + (1) pair zero, perpetual + attributes: half, newton on + pair build: half/bin/newton/tri + stencil: half/bin/3d/tri + bin: standard + (2) pair eam/fs, perpetual, trim from (1) + attributes: half, newton on, cut 9.6 + pair build: trim + stencil: none + bin: none + (3) compute sna/atom, occasional + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 31.9 | 31.9 | 31.9 Mbytes + Step PotEng KinEng Temp c_max_slcsa[1] c_max_slcsa[2] c_max_slcsa[3] c_max_slcsa[4] c_max_slcsa[5] c_min_slcsa[1] c_min_slcsa[2] c_min_slcsa[3] c_min_slcsa[4] c_min_slcsa[5] + 0 -143297.23 2093.9174 750 7.6195146 15.787294 1.2169942 111.01919 2 7.6195146 15.787294 1.2169942 111.01919 2 + 50 -142154.08 1007.7164 360.9442 8.8091564 19.23244 4.2093382 113.87959 2 5.0327148 9.6817454 0.02610585 106.71863 2 + 100 -142365.33 1406.6559 503.83647 8.6272189 17.908949 2.9294666 113.75167 2 6.2058895 11.913521 0.033775944 108.66893 2 + 150 -142188.18 1432.0075 512.91691 8.6441961 18.176321 2.9277374 114.27958 2 5.5899425 10.521867 0.014919473 108.14526 2 + 200 -142000.4 1481.7247 530.72462 8.5895692 18.65646 3.1725758 114.55015 2 5.5955774 10.776385 0.061469343 108.35384 2 +Loop time of 36.3759 on 1 procs for 200 steps with 21600 atoms + +Performance: 0.950 ns/day, 25.261 hours/ns, 5.498 timesteps/s, 118.760 katom-step/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 9.0837 | 9.0837 | 9.0837 | 0.0 | 24.97 +Neigh | 0.52896 | 0.52896 | 0.52896 | 0.0 | 1.45 +Comm | 0.045416 | 0.045416 | 0.045416 | 0.0 | 0.12 +Output | 26.548 | 26.548 | 26.548 | 0.0 | 72.98 +Modify | 0.1493 | 0.1493 | 0.1493 | 0.0 | 0.41 +Other | | 0.02088 | | | 0.06 + +Nlocal: 21600 ave 21600 max 21600 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 36674 ave 36674 max 36674 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 2.61729e+06 ave 2.61729e+06 max 2.61729e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 5.24007e+06 ave 5.24007e+06 max 5.24007e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 5240069 +Ave neighs/atom = 242.59579 +Neighbor list builds = 4 +Dangerous builds = 0 +Total wall time: 0:00:43 diff --git a/examples/PACKAGES/sna_nnn_slcsa/log.12Dec23.slcsa.g++.4 b/examples/PACKAGES/sna_nnn_slcsa/log.12Dec23.slcsa.g++.4 new file mode 100644 index 0000000000..6436eabe2b --- /dev/null +++ b/examples/PACKAGES/sna_nnn_slcsa/log.12Dec23.slcsa.g++.4 @@ -0,0 +1,180 @@ +LAMMPS (21 Nov 2023) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +variable trequis equal 750.0 +variable prequis_low equal 0.0 +variable prequis_high equal 25.0e4 +variable equilSteps equal 200 +variable runSteps equal 2000 +variable freqdump equal 200 +variable pstime equal step*dt +variable sxx equal 1.e-4*pxx +variable syy equal 1.e-4*pyy +variable szz equal 1.e-4*pzz +variable sxy equal 1.e-4*pxy +variable sxz equal 1.e-4*pxz +variable syz equal 1.e-4*pyz +variable TK equal temp +variable PE equal pe +variable KE equal ke +variable V equal vol + +dimension 3 +boundary p p p +units metal +atom_style atomic +read_data data.zr_cell +Reading data file ... + orthogonal box = (0 0 0) to (19.374 33.556752 30.846) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 864 atoms + read_data CPU = 0.002 seconds +replicate 1 5 5 +Replication is creating a 1x5x5 = 25 times larger system... + orthogonal box = (0 0 0) to (19.374 167.78376 154.23) + 1 by 2 by 2 MPI processor grid + 21600 atoms + replicate CPU = 0.001 seconds + +change_box all triclinic +Changing box ... + triclinic box = (0 0 0) to (19.374 167.78376 154.23) with tilt (0 0 0) + +pair_style hybrid/overlay zero 9.0 eam/fs +pair_coeff * * zero +pair_coeff * * eam/fs Zr_mm.eam.fs Zr +Reading eam/fs potential file Zr_mm.eam.fs with DATE: 2007-06-11 + +timestep 0.002 + +thermo 50 +thermo_style custom step pe ke temp vol pxx pyy pzz pxy pyz pxz + +# fix extra all print 50 "${pstime} ${TK} ${PE} ${KE} ${V} ${sxx} ${syy} ${szz} ${sxy} ${sxz} ${syz}" file thermo_global_npt_low_temperature_Zr_hcp.dat + +velocity all create ${trequis} 42345 dist gaussian +velocity all create 750 42345 dist gaussian + +# 1st step : compute the bispectrum on 24 nearest neighbors +compute bnnn all sna/atom 9.0 0.99363 8 0.5 1.0 rmin0 0.0 nnn 24 wmode 1 delta 0.25 + +# 2nd step : perform dimension reduction + logistic regression +compute slcsa all slcsa/atom 8 4 dir.slcsa/mean_descriptor.dat dir.slcsa/lda_scalings.dat dir.slcsa/lr_decision.dat dir.slcsa/lr_bias.dat dir.slcsa/mahalanobis_file.dat c_bnnn[*] +Files used: + database mean descriptor: dir.slcsa/mean_descriptor.dat + lda scalings : dir.slcsa/lda_scalings.dat + lr decision : dir.slcsa/lr_decision.dat + lr bias : dir.slcsa/lr_bias.dat + maha stats : dir.slcsa/mahalanobis_file.dat +For class 0 maha threshold = 5.054 + mean B: + -23.8329 + 4.6638 + 3.9805 + icov: + 1.1377 0.1077 -0.0171 + 0.1077 0.8846 -0.2577 + -0.0171 -0.2577 0.6783 +For class 1 maha threshold = 5.234 + mean B: + -21.2853 + -6.1583 + 1.7948 + icov: + 1.7124 0.0341 0.1966 + 0.0341 0.6453 0.288 + 0.1966 0.288 1.8991 +For class 2 maha threshold = 5.036 + mean B: + -23.1593 + 1.3059 + -5.7549 + icov: + 0.7496 -0.0806 -0.1101 + -0.0806 1.1178 0.1667 + -0.1101 0.1667 0.6711 +For class 3 maha threshold = 7.994 + mean B: + 68.1971 + 0.1604 + -0.0067 + icov: + 0.9663 -0.1846 0.6622 + -0.1846 8.2371 0.9841 + 0.6622 0.9841 5.9601 + +#dump d1 all custom ${freqdump} slcsa_demo.dump id x y z c_slcsa[*] + +# for testing only. in production use dump as shown above +compute max_slcsa all reduce max c_slcsa[*] +compute min_slcsa all reduce min c_slcsa[*] +thermo_style custom step pe ke temp c_max_slcsa[*] c_min_slcsa[*] + +#fix 1 all nvt temp ${trequis} ${trequis} 0.100 +fix 1 all npt temp ${trequis} ${trequis} 0.100 tri ${prequis_low} ${prequis_low} 1.0 +fix 1 all npt temp 750 ${trequis} 0.100 tri ${prequis_low} ${prequis_low} 1.0 +fix 1 all npt temp 750 750 0.100 tri ${prequis_low} ${prequis_low} 1.0 +fix 1 all npt temp 750 750 0.100 tri 0 ${prequis_low} 1.0 +fix 1 all npt temp 750 750 0.100 tri 0 0 1.0 + +run ${equilSteps} +run 200 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 11 + ghost atom cutoff = 11 + binsize = 5.5, bins = 4 31 29 + 3 neighbor lists, perpetual/occasional/extra = 2 1 0 + (1) pair zero, perpetual + attributes: half, newton on + pair build: half/bin/newton/tri + stencil: half/bin/3d/tri + bin: standard + (2) pair eam/fs, perpetual, trim from (1) + attributes: half, newton on, cut 9.6 + pair build: trim + stencil: none + bin: none + (3) compute sna/atom, occasional + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 11.26 | 11.45 | 11.64 Mbytes + Step PotEng KinEng Temp c_max_slcsa[1] c_max_slcsa[2] c_max_slcsa[3] c_max_slcsa[4] c_max_slcsa[5] c_min_slcsa[1] c_min_slcsa[2] c_min_slcsa[3] c_min_slcsa[4] c_min_slcsa[5] + 0 -143297.23 2093.9174 750 7.6195146 15.787294 1.2169942 111.01919 2 7.6195146 15.787294 1.2169942 111.01919 2 + 50 -142154.08 1007.7164 360.9442 8.8091564 19.23244 4.2093382 113.87959 2 5.0327148 9.6817454 0.02610585 106.71863 2 + 100 -142365.33 1406.6559 503.83647 8.6272189 17.908949 2.9294666 113.75167 2 6.2058895 11.913521 0.033775944 108.66893 2 + 150 -142188.18 1432.0075 512.91691 8.6441961 18.176321 2.9277374 114.27958 2 5.5899425 10.521867 0.014919473 108.14526 2 + 200 -142000.4 1481.7247 530.72462 8.5895692 18.65646 3.1725758 114.55015 2 5.5955774 10.776385 0.061469343 108.35384 2 +Loop time of 9.81677 on 4 procs for 200 steps with 21600 atoms + +Performance: 3.521 ns/day, 6.817 hours/ns, 20.373 timesteps/s, 440.063 katom-step/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.6508 | 2.6589 | 2.6698 | 0.5 | 27.09 +Neigh | 0.1516 | 0.15276 | 0.15406 | 0.3 | 1.56 +Comm | 0.047132 | 0.058969 | 0.066095 | 3.2 | 0.60 +Output | 6.8886 | 6.8886 | 6.8886 | 0.0 | 70.17 +Modify | 0.046437 | 0.04661 | 0.046825 | 0.1 | 0.47 +Other | | 0.01091 | | | 0.11 + +Nlocal: 5400 ave 5416 max 5393 min +Histogram: 2 1 0 0 0 0 0 0 0 1 +Nghost: 12902.8 ave 12911 max 12888 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Neighs: 654322 ave 655602 max 650912 min +Histogram: 1 0 0 0 0 0 0 0 0 3 +FullNghs: 1.31002e+06 ave 1.31507e+06 max 1.30683e+06 min +Histogram: 1 1 0 1 0 0 0 0 0 1 + +Total # of neighbors = 5240065 +Ave neighs/atom = 242.5956 +Neighbor list builds = 4 +Dangerous builds = 0 +Total wall time: 0:00:11 diff --git a/examples/reaxff/in.reaxff.tatb b/examples/reaxff/in.reaxff.tatb index 6cf7828cf1..967ed0a1d6 100644 --- a/examples/reaxff/in.reaxff.tatb +++ b/examples/reaxff/in.reaxff.tatb @@ -31,8 +31,15 @@ neigh_modify delay 0 every 5 check no fix 1 all nve fix 2 all qeq/reaxff 1 0.0 10.0 1.0e-6 reaxff fix 4 all reaxff/bonds 5 bonds.reaxff +compute bonds all reaxff/atom bonds yes variable nqeq equal f_2 +# dumps out the local bond information +dump 1 all local 5 bonds_local.reaxff c_bonds[1] c_bonds[2] c_bonds[3] + +# dumps out the peratom bond information +dump 2 all custom 5 bonds_atom.reaxff id type q c_bonds[*] + thermo 5 thermo_style custom step temp epair etotal press & v_eb v_ea v_elp v_emol v_ev v_epen v_ecoa & diff --git a/lib/gpu/Makefile.linux_multi b/lib/gpu/Makefile.linux_multi index 3299bbec3a..005f659079 100644 --- a/lib/gpu/Makefile.linux_multi +++ b/lib/gpu/Makefile.linux_multi @@ -65,7 +65,7 @@ CUDA_PRECISION = -D_SINGLE_DOUBLE CUDA_INCLUDE = -I$(CUDA_HOME)/include CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs -CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC +CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC -allow-unsupported-compiler CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC -std=c++11 CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias diff --git a/lib/gpu/geryon/ocl_mat.h b/lib/gpu/geryon/ocl_mat.h index 3135594dc3..66ca6ab527 100644 --- a/lib/gpu/geryon/ocl_mat.h +++ b/lib/gpu/geryon/ocl_mat.h @@ -54,6 +54,6 @@ namespace ucl_opencl { #include "ucl_print.h" #undef UCL_PRINT_ALLOW -} // namespace ucl_cudart +} // namespace ucl_opencl #endif diff --git a/lib/gpu/lal_amoeba.cpp b/lib/gpu/lal_amoeba.cpp index 5e19997913..805c4c4b26 100644 --- a/lib/gpu/lal_amoeba.cpp +++ b/lib/gpu/lal_amoeba.cpp @@ -281,13 +281,7 @@ int AmoebaT::polar_real(const int eflag, const int vflag) { const int BX=this->block_size(); const int GX=static_cast(ceil(static_cast(ainum)/(BX/this->_threads_per_atom))); - /* - const int cus = this->device->gpu->cus(); - while (GX < cus && GX > 1) { - BX /= 2; - GX=static_cast(ceil(static_cast(ainum)/(BX/this->_threads_per_atom))); - } - */ + this->time_pair.start(); // Build the short neighbor list if not done yet diff --git a/lib/gpu/lal_base_dpd.cpp b/lib/gpu/lal_base_dpd.cpp index e103699d40..0ddd24d21e 100644 --- a/lib/gpu/lal_base_dpd.cpp +++ b/lib/gpu/lal_base_dpd.cpp @@ -56,7 +56,8 @@ int BaseDPDT::init_atomic(const int nlocal, const int nall, const int max_nbors, const int maxspecial, const double cell_size, const double gpu_split, FILE *_screen, const void *pair_program, - const char *k_name, const int onetype) { + const char *k_name, const int onetype, + const int extra_fields) { screen=_screen; int gpu_nbor=0; @@ -75,7 +76,8 @@ int BaseDPDT::init_atomic(const int nlocal, const int nall, bool charge = false; bool rot = false; bool vel = true; - int success=device->init(*ans,charge,rot,nlocal,nall,maxspecial,vel); + _extra_fields = extra_fields; + int success=device->init(*ans,charge,rot,nlocal,nall,maxspecial,vel,_extra_fields/4); if (success!=0) return success; diff --git a/lib/gpu/lal_base_dpd.h b/lib/gpu/lal_base_dpd.h index 9eb56993af..64ec725d95 100644 --- a/lib/gpu/lal_base_dpd.h +++ b/lib/gpu/lal_base_dpd.h @@ -53,7 +53,7 @@ class BaseDPD { const int maxspecial, const double cell_size, const double gpu_split, FILE *screen, const void *pair_program, const char *k_name, - const int onetype=0); + const int onetype=0, const int extra_fields=0); /// Estimate the overhead for GPU context changes and CPU driver void estimate_gpu_overhead(); @@ -167,7 +167,6 @@ class BaseDPD { /// Atom Data Atom *atom; - // ------------------------ FORCE/ENERGY DATA ----------------------- Answer *ans; @@ -199,7 +198,7 @@ class BaseDPD { protected: bool _compiled; - int _block_size, _threads_per_atom, _onetype; + int _block_size, _threads_per_atom, _onetype, _extra_fields; double _max_bytes, _max_an_bytes; double _gpu_overhead, _driver_overhead; UCL_D_Vec *_nbor_data; diff --git a/lib/gpu/lal_base_sph.cpp b/lib/gpu/lal_base_sph.cpp new file mode 100644 index 0000000000..f373c0ebb6 --- /dev/null +++ b/lib/gpu/lal_base_sph.cpp @@ -0,0 +1,362 @@ +/*************************************************************************** + base_sph.cpp + ------------------- + Trung Nguyen (U Chicago) + + Base class for SPH pair styles needing per-particle data for position, + velocity, and type. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include "lal_base_sph.h" +namespace LAMMPS_AL { +#define BaseSPHT BaseSPH + +extern Device global_device; + +template +BaseSPHT::BaseSPH() : _compiled(false), _max_bytes(0) { + device=&global_device; + ans=new Answer(); + nbor=new Neighbor(); + pair_program=nullptr; + ucl_device=nullptr; + #if defined(LAL_OCL_EV_JIT) + pair_program_noev=nullptr; + #endif +} + +template +BaseSPHT::~BaseSPH() { + delete ans; + delete nbor; + k_pair_fast.clear(); + k_pair.clear(); + if (pair_program) delete pair_program; + #if defined(LAL_OCL_EV_JIT) + k_pair_noev.clear(); + if (pair_program_noev) delete pair_program_noev; + #endif +} + +template +int BaseSPHT::bytes_per_atom_atomic(const int max_nbors) const { + return device->atom.bytes_per_atom()+ans->bytes_per_atom()+ + nbor->bytes_per_atom(max_nbors); +} + +template +int BaseSPHT::init_atomic(const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, const double gpu_split, + FILE *_screen, const void *pair_program, + const char *k_name, const int onetype, + const int extra_fields) { + screen=_screen; + + int gpu_nbor=0; + if (device->gpu_mode()==Device::GPU_NEIGH) + gpu_nbor=1; + else if (device->gpu_mode()==Device::GPU_HYB_NEIGH) + gpu_nbor=2; + + int _gpu_host=0; + int host_nlocal=hd_balancer.first_host_count(nlocal,gpu_split,gpu_nbor); + if (host_nlocal>0) + _gpu_host=1; + + _threads_per_atom=device->threads_per_atom(); + + bool charge = false; + bool rot = false; + bool vel = true; + _extra_fields = extra_fields; + int success=device->init(*ans,charge,rot,nlocal,nall,maxspecial,vel,_extra_fields/4); + if (success!=0) + return success; + + if (ucl_device!=device->gpu) _compiled=false; + + ucl_device=device->gpu; + atom=&device->atom; + + _block_size=device->pair_block_size(); + compile_kernels(*ucl_device,pair_program,k_name,onetype); + + if (_threads_per_atom>1 && gpu_nbor==0) { + nbor->packing(true); + _nbor_data=&(nbor->dev_packed); + } else + _nbor_data=&(nbor->dev_nbor); + + success = device->init_nbor(nbor,nlocal,host_nlocal,nall,maxspecial,_gpu_host, + max_nbors,cell_size,false,_threads_per_atom); + if (success!=0) + return success; + + // Initialize host-device load balancer + hd_balancer.init(device,gpu_nbor,gpu_split); + + // Initialize timers for the selected GPU + time_pair.init(*ucl_device); + time_pair.zero(); + + pos_tex.bind_float(atom->x,4); + vel_tex.bind_float(atom->v,4); + + _max_an_bytes=ans->gpu_bytes()+nbor->gpu_bytes(); + + return success; +} + +template +void BaseSPHT::estimate_gpu_overhead() { + device->estimate_gpu_overhead(1,_gpu_overhead,_driver_overhead); +} + +template +void BaseSPHT::clear_atomic() { + // Output any timing information + acc_timers(); + double avg_split=hd_balancer.all_avg_split(); + _gpu_overhead*=hd_balancer.timestep(); + _driver_overhead*=hd_balancer.timestep(); + device->output_times(time_pair,*ans,*nbor,avg_split,_max_bytes+_max_an_bytes, + _gpu_overhead,_driver_overhead,_threads_per_atom,screen); + + time_pair.clear(); + hd_balancer.clear(); + + nbor->clear(); + ans->clear(); +} + +// --------------------------------------------------------------------------- +// Copy neighbor list from host +// --------------------------------------------------------------------------- +template +int * BaseSPHT::reset_nbors(const int nall, const int inum, int *ilist, + int *numj, int **firstneigh, bool &success) { + success=true; + + int mn=nbor->max_nbor_loop(inum,numj,ilist); + resize_atom(inum,nall,success); + resize_local(inum,mn,success); + if (!success) + return nullptr; + + nbor->get_host(inum,ilist,numj,firstneigh,block_size()); + + double bytes=ans->gpu_bytes()+nbor->gpu_bytes(); + if (bytes>_max_an_bytes) + _max_an_bytes=bytes; + + return ilist; +} + +// --------------------------------------------------------------------------- +// Build neighbor list on device +// --------------------------------------------------------------------------- +template +inline void BaseSPHT::build_nbor_list(const int inum, const int host_inum, + const int nall, double **host_x, + int *host_type, double *sublo, + double *subhi, tagint *tag, + int **nspecial, tagint **special, + bool &success) { + success=true; + resize_atom(inum,nall,success); + resize_local(inum,host_inum,nbor->max_nbors(),success); + if (!success) + return; + atom->cast_copy_x(host_x,host_type); + + int mn; + nbor->build_nbor_list(host_x, inum, host_inum, nall, *atom, sublo, subhi, + tag, nspecial, special, success, mn, ans->error_flag); + + double bytes=ans->gpu_bytes()+nbor->gpu_bytes(); + if (bytes>_max_an_bytes) + _max_an_bytes=bytes; +} + +// --------------------------------------------------------------------------- +// Copy nbor list from host if necessary and then calculate forces, virials,.. +// --------------------------------------------------------------------------- +template +void BaseSPHT::compute(const int f_ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag_in, const bool vflag_in, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **host_v, const int nlocal) { + acc_timers(); + int eflag, vflag; + if (eatom) eflag=2; + else if (eflag_in) eflag=1; + else eflag=0; + if (vatom) vflag=2; + else if (vflag_in) vflag=1; + else vflag=0; + + #ifdef LAL_NO_BLOCK_REDUCE + if (eflag) eflag=2; + if (vflag) vflag=2; + #endif + + set_kernel(eflag,vflag); + if (inum_full==0) { + host_start=0; + // Make sure textures are correct if realloc by a different hybrid style + resize_atom(0,nall,success); + zero_timers(); + return; + } + + int ago=hd_balancer.ago_first(f_ago); + int inum=hd_balancer.balance(ago,inum_full,cpu_time); + ans->inum(inum); + host_start=inum; + + if (ago==0) { + reset_nbors(nall, inum, ilist, numj, firstneigh, success); + if (!success) + return; + } + + atom->cast_x_data(host_x,host_type); + atom->cast_v_data(host_v,tag); + hd_balancer.start_timer(); + atom->add_x_data(host_x,host_type); + atom->add_v_data(host_v,tag); + + const int red_blocks=loop(eflag,vflag); + ans->copy_answers(eflag_in,vflag_in,eatom,vatom,ilist,red_blocks); + device->add_ans_object(ans); + hd_balancer.stop_timer(); +} + +// --------------------------------------------------------------------------- +// Reneighbor on GPU if necessary and then compute forces, virials, energies +// --------------------------------------------------------------------------- +template +int** BaseSPHT::compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag_in, const bool vflag_in, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v) { + acc_timers(); + int eflag, vflag; + if (eatom) eflag=2; + else if (eflag_in) eflag=1; + else eflag=0; + if (vatom) vflag=2; + else if (vflag_in) vflag=1; + else vflag=0; + + #ifdef LAL_NO_BLOCK_REDUCE + if (eflag) eflag=2; + if (vflag) vflag=2; + #endif + + set_kernel(eflag,vflag); + if (inum_full==0) { + host_start=0; + // Make sure textures are correct if realloc by a different hybrid style + resize_atom(0,nall,success); + zero_timers(); + return nullptr; + } + + hd_balancer.balance(cpu_time); + int inum=hd_balancer.get_gpu_count(ago,inum_full); + ans->inum(inum); + host_start=inum; + + // Build neighbor list on GPU if necessary + if (ago==0) { + build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, + sublo, subhi, tag, nspecial, special, success); + if (!success) + return nullptr; + atom->cast_v_data(host_v,tag); + hd_balancer.start_timer(); + } else { + atom->cast_x_data(host_x,host_type); + atom->cast_v_data(host_v,tag); + hd_balancer.start_timer(); + atom->add_x_data(host_x,host_type); + } + atom->add_v_data(host_v,tag); + *ilist=nbor->host_ilist.begin(); + *jnum=nbor->host_acc.begin(); + + const int red_blocks=loop(eflag,vflag); + ans->copy_answers(eflag_in,vflag_in,eatom,vatom,red_blocks); + device->add_ans_object(ans); + hd_balancer.stop_timer(); + + return nbor->host_jlist.begin()-host_start; +} + +template +double BaseSPHT::host_memory_usage_atomic() const { + return device->atom.host_memory_usage()+nbor->host_memory_usage()+ + 4*sizeof(numtyp)+sizeof(BaseSPH); +} + +template +void BaseSPHT::compile_kernels(UCL_Device &dev, const void *pair_str, + const char *kname, const int onetype) { + if (_compiled && _onetype==onetype) + return; + + _onetype=onetype; + + std::string s_fast=std::string(kname)+"_fast"; + if (pair_program) delete pair_program; + pair_program=new UCL_Program(dev); + std::string oclstring = device->compile_string()+" -DEVFLAG=1"; + if (_onetype) oclstring+=" -DONETYPE="+device->toa(_onetype); + pair_program->load_string(pair_str,oclstring.c_str(),nullptr,screen); + k_pair_fast.set_function(*pair_program,s_fast.c_str()); + k_pair.set_function(*pair_program,kname); + pos_tex.get_texture(*pair_program,"pos_tex"); + vel_tex.get_texture(*pair_program,"vel_tex"); + + #if defined(LAL_OCL_EV_JIT) + oclstring = device->compile_string()+" -DEVFLAG=0"; + if (_onetype) oclstring+=" -DONETYPE="+device->toa(_onetype); + if (pair_program_noev) delete pair_program_noev; + pair_program_noev=new UCL_Program(dev); + pair_program_noev->load_string(pair_str,oclstring.c_str(),nullptr,screen); + k_pair_noev.set_function(*pair_program_noev,s_fast.c_str()); + #else + k_pair_sel = &k_pair_fast; + #endif + + _compiled=true; + + #if defined(USE_OPENCL) && (defined(CL_VERSION_2_1) || defined(CL_VERSION_3_0)) + if (dev.has_subgroup_support()) { + size_t mx_subgroup_sz = k_pair_fast.max_subgroup_size(_block_size); + #if defined(LAL_OCL_EV_JIT) + mx_subgroup_sz = std::min(mx_subgroup_sz, k_pair_noev.max_subgroup_size(_block_size)); + #endif + if (_threads_per_atom > (int)mx_subgroup_sz) _threads_per_atom = mx_subgroup_sz; + device->set_simd_size(mx_subgroup_sz); + } + #endif + +} + +template class BaseSPH; +} diff --git a/lib/gpu/lal_base_sph.h b/lib/gpu/lal_base_sph.h new file mode 100644 index 0000000000..e1e5731573 --- /dev/null +++ b/lib/gpu/lal_base_sph.h @@ -0,0 +1,209 @@ +/*************************************************************************** + base_sph.h + ------------------- + Trung Nguyen (U Chicago) + + Base class for SPH pair styles needing per-particle data for position, + velocity, and type. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#ifndef LAL_BASE_SPH_H +#define LAL_BASE_DPD_H + +#include "lal_device.h" +#include "lal_balance.h" +#include "mpi.h" + +#ifdef USE_OPENCL +#include "geryon/ocl_texture.h" +#elif defined(USE_HIP) +#include "geryon/hip_texture.h" +#else +#include "geryon/nvd_texture.h" +#endif + +namespace LAMMPS_AL { + +template +class BaseSPH { + public: + BaseSPH(); + virtual ~BaseSPH(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * \param k_name name for the kernel for force calculation + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init_atomic(const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, + const void *pair_program, const char *k_name, + const int onetype=0, const int extra_fields=0); + + /// Estimate the overhead for GPU context changes and CPU driver + void estimate_gpu_overhead(); + + /// Check if there is enough storage for atom arrays and realloc if not + /** \param success set to false if insufficient memory **/ + inline void resize_atom(const int inum, const int nall, bool &success) { + if (atom->resize(nall, success)) { + pos_tex.bind_float(atom->x,4); + vel_tex.bind_float(atom->v,4); + } + ans->resize(inum,success); + } + + /// Check if there is enough storage for neighbors and realloc if not + /** \param nlocal number of particles whose nbors must be stored on device + * \param host_inum number of particles whose nbors need to copied to host + * \param current maximum number of neighbors + * \note olist_size=total number of local particles **/ + inline void resize_local(const int inum, const int max_nbors, bool &success) { + nbor->resize(inum,max_nbors,success); + } + + /// Check if there is enough storage for neighbors and realloc if not + /** \param nlocal number of particles whose nbors must be stored on device + * \param host_inum number of particles whose nbors need to copied to host + * \param current maximum number of neighbors + * \note host_inum is 0 if the host is performing neighboring + * \note nlocal+host_inum=total number local particles + * \note olist_size=0 **/ + inline void resize_local(const int inum, const int host_inum, + const int max_nbors, bool &success) { + nbor->resize(inum,host_inum,max_nbors,success); + } + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear_atomic(); + + /// Returns memory usage on device per atom + int bytes_per_atom_atomic(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage_atomic() const; + + /// Accumulate timers + inline void acc_timers() { + if (device->time_device()) { + nbor->acc_timers(screen); + time_pair.add_to_total(); + atom->acc_timers(); + ans->acc_timers(); + } + } + + /// Zero timers + inline void zero_timers() { + time_pair.zero(); + atom->zero_timers(); + ans->zero_timers(); + } + + /// Copy neighbor list from host + int * reset_nbors(const int nall, const int inum, int *ilist, int *numj, + int **firstneigh, bool &success); + + /// Build neighbor list on device + void build_nbor_list(const int inum, const int host_inum, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, bool &success); + + /// Pair loop with host neighboring + void compute(const int f_ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **v, const int nlocal); + + /// Pair loop with device neighboring + int** compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **numj, const double cpu_time, bool &success, + double **v); + + // -------------------------- DEVICE DATA ------------------------- + + /// Device Properties and Atom and Neighbor storage + Device *device; + + /// Geryon device + UCL_Device *ucl_device; + + /// Device Timers + UCL_Timer time_pair; + + /// Host device load balancer + Balance hd_balancer; + + /// LAMMPS pointer for screen output + FILE *screen; + + // --------------------------- ATOM DATA -------------------------- + + /// Atom Data + Atom *atom; + + // ------------------------ FORCE/ENERGY DATA ----------------------- + + Answer *ans; + + // --------------------------- NBOR DATA ---------------------------- + + /// Neighbor data + Neighbor *nbor; + + // ------------------------- DEVICE KERNELS ------------------------- + UCL_Program *pair_program, *pair_program_noev; + UCL_Kernel k_pair_fast, k_pair, k_pair_noev, *k_pair_sel; + inline int block_size() { return _block_size; } + inline void set_kernel(const int eflag, const int vflag) { + #if defined(LAL_OCL_EV_JIT) + if (eflag || vflag) k_pair_sel = &k_pair_fast; + else k_pair_sel = &k_pair_noev; + #endif + } + + + // --------------------------- TEXTURES ----------------------------- + UCL_Texture pos_tex; + UCL_Texture vel_tex; + + // ------------------------- COMMON VARS ---------------------------- + + protected: + bool _compiled; + int _block_size, _threads_per_atom, _onetype, _extra_fields; + double _max_bytes, _max_an_bytes; + double _gpu_overhead, _driver_overhead; + UCL_D_Vec *_nbor_data; + + void compile_kernels(UCL_Device &dev, const void *pair_string, + const char *k, const int onetype); + virtual int loop(const int eflag, const int vflag) = 0; +}; + +} + +#endif diff --git a/lib/gpu/lal_coul_slater_long.cpp b/lib/gpu/lal_coul_slater_long.cpp new file mode 100644 index 0000000000..42eb86e8ff --- /dev/null +++ b/lib/gpu/lal_coul_slater_long.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + coul_slater_long_ext.cpp + ------------------------ + Trung Nguyen (U Chicago) + + Class for acceleration of the coul/slater/long pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "coul_slater_long_cl.h" +#elif defined(USE_CUDART) +const char *coul_slater_long=0; +#else +#include "coul_slater_long_cubin.h" +#endif + +#include "lal_coul_slater_long.h" +#include +namespace LAMMPS_AL { +#define CoulSlaterLongT CoulSlaterLong + +extern Device pair_gpu_device; + +template +CoulSlaterLongT::CoulSlaterLong() : BaseCharge(), _allocated(false) { +} + +template +CoulSlaterLongT::~CoulSlaterLong() { + clear(); +} + +template +int CoulSlaterLongT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int CoulSlaterLongT::init(const int ntypes, double **host_scale, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *_screen, + const double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald, double lamda) { + int success; + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,coul_slater_long,"k_coul_slater_long"); + if (success!=0) + return success; + + int lj_types=ntypes; + shared_types=false; + int max_shared_types=this->device->max_shared_types(); + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack1(ntypes,lj_types,scale,host_write,host_scale); + + sp_cl.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + for (int i=0; i<4; i++) { + host_write[i]=host_special_coul[i]; + } + ucl_copy(sp_cl,host_write,4,false); + + _cut_coulsq=host_cut_coulsq; + _qqrd2e=qqrd2e; + _g_ewald=g_ewald; + _lamda=lamda; + + _allocated=true; + this->_max_bytes=scale.row_bytes()+sp_cl.row_bytes(); + return 0; +} + +template +void CoulSlaterLongT::reinit(const int ntypes, double **host_scale) { + UCL_H_Vec hscale(_lj_types*_lj_types,*(this->ucl_device), + UCL_WRITE_ONLY); + this->atom->type_pack1(ntypes,_lj_types,scale,hscale,host_scale); +} + +template +void CoulSlaterLongT::clear() { + if (!_allocated) + return; + _allocated=false; + + scale.clear(); + sp_cl.clear(); + this->clear_atomic(); +} + +template +double CoulSlaterLongT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(CoulSlaterLong); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int CoulSlaterLongT::loop(const int eflag, const int vflag) { + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &scale, &sp_cl, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, + &eflag, &vflag, &ainum, &nbor_pitch, + &this->atom->q, &_cut_coulsq, &_qqrd2e, &_g_ewald, + &_lamda, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &scale, &_lj_types, &sp_cl, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->q, &_cut_coulsq, + &_qqrd2e, &_g_ewald, &_lamda, &this->_threads_per_atom); + } + this->time_pair.stop(); + return GX; +} + +template class CoulSlaterLong; +} diff --git a/lib/gpu/lal_coul_slater_long.cu b/lib/gpu/lal_coul_slater_long.cu new file mode 100644 index 0000000000..1fc8ab8be4 --- /dev/null +++ b/lib/gpu/lal_coul_slater_long.cu @@ -0,0 +1,250 @@ +// ************************************************************************** +// coul_slater_long.cu +// ------------------- +// Trung Nguyen (U Chicago) +// +// Device code for acceleration of the coul/slater/long pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : September 2023 +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) + +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( q_tex,float); +#else +_texture_2d( pos_tex,int4); +_texture( q_tex,int2); +#endif + +#else +#define pos_tex x_ +#define q_tex q_ +#endif + +__kernel void k_coul_slater_long(const __global numtyp4 *restrict x_, + const __global numtyp *restrict scale, + const int lj_types, + const __global numtyp *restrict sp_cl_in, + const __global int *dev_nbor, + const __global int *dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp *restrict q_, + const numtyp cut_coulsq, const numtyp qqrd2e, + const numtyp g_ewald, const numtyp lamda, + const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + __local numtyp sp_cl[4]; + int n_stride; + local_allocate_store_charge(); + + sp_cl[0]=sp_cl_in[0]; + sp_cl[1]=sp_cl_in[1]; + sp_cl[2]=sp_cl_in[2]; + sp_cl[3]=sp_cl_in[3]; + + acctyp3 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp e_coul, virial[6]; + if (EVFLAG) { + e_coul=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + + if (ii (numtyp)0) force -= factor_coul*prefactor*((numtyp)1.0-slater_term); + force *= r2inv; + + f.x+=delx*force; + f.y+=dely*force; + f.z+=delz*force; + + if (EVFLAG && eflag) { + numtyp e_slater = ((numtyp)1.0 + rlamdainv)*exprlmdainv; + numtyp e = prefactor*(_erfc-e_slater); + if (factor_coul > (numtyp)0) e -= factor_coul*prefactor*((numtyp)1.0 - e_slater); + e_coul += e; + } + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + + } // for nbor + } // if ii + acctyp energy; + if (EVFLAG) energy=(acctyp)0.0; + store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag, + vflag,ans,engv); +} + +__kernel void k_coul_slater_long_fast(const __global numtyp4 *restrict x_, + const __global numtyp *restrict scale_in, + const __global numtyp *restrict sp_cl_in, + const __global int *dev_nbor, + const __global int *dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp *restrict q_, + const numtyp cut_coulsq, const numtyp qqrd2e, + const numtyp g_ewald, const numtyp lamda, + const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + __local numtyp scale[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp sp_cl[4]; + int n_stride; + local_allocate_store_charge(); + + if (tid<4) + sp_cl[tid]=sp_cl_in[tid]; + if (tid (numtyp)0) force -= factor_coul*prefactor*((numtyp)1.0-slater_term); + force *= r2inv; + + f.x+=delx*force; + f.y+=dely*force; + f.z+=delz*force; + + if (EVFLAG && eflag) { + numtyp e_slater = ((numtyp)1.0 + rlamdainv)*exprlmdainv; + numtyp e = prefactor*(_erfc-e_slater); + if (factor_coul > (numtyp)0) e -= factor_coul*prefactor*((numtyp)1.0 - e_slater); + e_coul += e; + } + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + + } // for nbor + } // if ii + acctyp energy; + if (EVFLAG) energy=(acctyp)0.0; + store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag, + vflag,ans,engv); +} + diff --git a/lib/gpu/lal_coul_slater_long.h b/lib/gpu/lal_coul_slater_long.h new file mode 100644 index 0000000000..8950fd81ef --- /dev/null +++ b/lib/gpu/lal_coul_slater_long.h @@ -0,0 +1,82 @@ +/*************************************************************************** + coul_slater_long.h + ------------------- + Trung Nguyen (U Chicago) + + Class for acceleration of the coul/slater/long pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#ifndef LAL_Coul_Slater_Long_H +#define LAL_Coul_Slater_Long_H + +#include "lal_base_charge.h" + +namespace LAMMPS_AL { + +template +class CoulSlaterLong : public BaseCharge { + public: + CoulSlaterLong(); + ~CoulSlaterLong(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **scale, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, + const double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald, const double lamda); + + /// Send updated coeffs from host to device (to be compatible with fix adapt) + void reinit(const int ntypes, double **scale); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + // --------------------------- TYPE DATA -------------------------- + + /// scale + UCL_D_Vec scale; + /// Special Coul values [0-3] + UCL_D_Vec sp_cl; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + numtyp _cut_coulsq, _qqrd2e, _g_ewald, _lamda; + + protected: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_coul_slater_long_ext.cpp b/lib/gpu/lal_coul_slater_long_ext.cpp new file mode 100644 index 0000000000..8c34cc5552 --- /dev/null +++ b/lib/gpu/lal_coul_slater_long_ext.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + coul_slater_long_ext.cpp + ------------------------ + Trung Nguyen (U Chicago) + + Functions for LAMMPS access to coul/slater/long acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_coul_slater_long.h" + +using namespace std; +using namespace LAMMPS_AL; + +static CoulSlaterLong CSLMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int csl_gpu_init(const int ntypes, double **host_scale, + const int inum, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, int &gpu_mode, + FILE *screen, double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald, const double lamda) { + CSLMF.clear(); + gpu_mode=CSLMF.device->gpu_mode(); + double gpu_split=CSLMF.device->particle_split(); + int first_gpu=CSLMF.device->first_device(); + int last_gpu=CSLMF.device->last_device(); + int world_me=CSLMF.device->world_me(); + int gpu_rank=CSLMF.device->gpu_rank(); + int procs_per_gpu=CSLMF.device->procs_per_gpu(); + + CSLMF.device->init_message(screen,"coul/slater/long",first_gpu,last_gpu); + + bool message=false; + if (CSLMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=CSLMF.init(ntypes, host_scale, inum, nall, max_nbors, maxspecial, + cell_size, gpu_split, screen, host_cut_coulsq, + host_special_coul, qqrd2e, g_ewald, lamda); + + CSLMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + CSLMF.estimate_gpu_overhead(); + return init_ok; +} + +// --------------------------------------------------------------------------- +// Copy updated coeffs from host to device +// --------------------------------------------------------------------------- +void csl_gpu_reinit(const int ntypes, double **host_scale) { + int world_me=CSLMF.device->world_me(); + int gpu_rank=CSLMF.device->gpu_rank(); + int procs_per_gpu=CSLMF.device->procs_per_gpu(); + + if (world_me==0) + CSLMF.reinit(ntypes, host_scale); + + CSLMF.device->world_barrier(); + + for (int i=0; iserialize_init(); + } +} + +void csl_gpu_clear() { + CSLMF.clear(); +} + +int** csl_gpu_compute_n(const int ago, const int inum_full, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, + bool &success, double *host_q, double *boxlo, + double *prd) { + return CSLMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_q, boxlo, prd); +} + +void csl_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, double *host_q, + const int nlocal, double *boxlo, double *prd) { + CSLMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj, + firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success, + host_q,nlocal,boxlo,prd); +} + +double csl_gpu_bytes() { + return CSLMF.host_memory_usage(); +} + + diff --git a/lib/gpu/lal_device.cpp b/lib/gpu/lal_device.cpp index 70ba373a65..e9ef2294b2 100644 --- a/lib/gpu/lal_device.cpp +++ b/lib/gpu/lal_device.cpp @@ -364,6 +364,12 @@ int DeviceT::init_device(MPI_Comm /*world*/, MPI_Comm replica, const int ngpu, } else _neighbor_shared.setup_auto_cell_size(false,_user_cell_size,_simd_size); + #ifndef LAL_USE_OLD_NEIGHBOR + _use_old_nbor_build = 0; + #else + _use_old_nbor_build = 1; + #endif + return flag; } @@ -510,9 +516,13 @@ int DeviceT::init(Answer &ans, const bool charge, gpu_nbor=1; else if (_gpu_mode==Device::GPU_HYB_NEIGH) gpu_nbor=2; + + // NOTE: enforce the hybrid mode (binning on the CPU) + // when not using sorting on the device #if !defined(USE_CUDPP) && !defined(USE_HIP_DEVICE_SORT) if (gpu_nbor==1) gpu_nbor=2; #endif + // or when the device supports subgroups #ifndef LAL_USE_OLD_NEIGHBOR if (gpu_nbor==1) gpu_nbor=2; #endif @@ -886,19 +896,31 @@ void DeviceT::output_times(UCL_Timer &time_pair, Answer &ans, } if (times[5] > 0.0) fprintf(screen,"Device Overhead: %.4f s.\n",times[5]/_replica_size); - fprintf(screen,"Average split: %.4f.\n",avg_split); - fprintf(screen,"Lanes / atom: %d.\n",threads_per_atom); - fprintf(screen,"Vector width: %d.\n", simd_size()); - fprintf(screen,"Prefetch mode: "); - if (_nbor_prefetch==2) fprintf(screen,"Intrinsics.\n"); - else if (_nbor_prefetch==1) fprintf(screen,"API.\n"); - else fprintf(screen,"None.\n"); - fprintf(screen,"Max Mem / Proc: %.2f MB.\n",max_mb); if (nbor.gpu_nbor()==2) fprintf(screen,"CPU Neighbor: %.4f s.\n",times[8]/_replica_size); fprintf(screen,"CPU Cast/Pack: %.4f s.\n",times[4]/_replica_size); fprintf(screen,"CPU Driver_Time: %.4f s.\n",times[6]/_replica_size); fprintf(screen,"CPU Idle_Time: %.4f s.\n",times[7]/_replica_size); + fprintf(screen,"Average split: %.4f.\n",avg_split); + fprintf(screen,"Max Mem / Proc: %.2f MB.\n",max_mb); + fprintf(screen,"Prefetch mode: "); + if (_nbor_prefetch==2) fprintf(screen,"Intrinsics.\n"); + else if (_nbor_prefetch==1) fprintf(screen,"API.\n"); + else fprintf(screen,"None.\n"); + fprintf(screen,"Vector width: %d.\n", simd_size()); + fprintf(screen,"Lanes / atom: %d.\n",threads_per_atom); + fprintf(screen,"Pair block: %d.\n",_block_pair); + fprintf(screen,"Neigh block: %d.\n",_block_nbor_build); + if (nbor.gpu_nbor()==2) { + fprintf(screen,"Neigh mode: Hybrid (binning on host)"); + if (_use_old_nbor_build == 1) fprintf(screen," - legacy\n"); + else fprintf(screen," with subgroup support\n"); + } else if (nbor.gpu_nbor()==1) { + fprintf(screen,"Neigh mode: Device"); + if (_use_old_nbor_build == 1) fprintf(screen," - legacy\n"); + else fprintf(screen," - with subgroup support\n"); + } else if (nbor.gpu_nbor()==0) + fprintf(screen,"Neigh mode: Host\n"); fprintf(screen,"-------------------------------------"); fprintf(screen,"--------------------------------\n\n"); diff --git a/lib/gpu/lal_device.h b/lib/gpu/lal_device.h index ba693e551a..d6b52484f1 100644 --- a/lib/gpu/lal_device.h +++ b/lib/gpu/lal_device.h @@ -347,6 +347,7 @@ class Device { int _pppm_block, _block_nbor_build, _block_cell_2d, _block_cell_id; int _max_shared_types, _max_bio_shared_types, _pppm_max_spline; int _nbor_prefetch; + int _use_old_nbor_build; UCL_Program *dev_program; UCL_Kernel k_zero, k_info; diff --git a/lib/gpu/lal_edpd.cpp b/lib/gpu/lal_edpd.cpp new file mode 100644 index 0000000000..c03591b9ed --- /dev/null +++ b/lib/gpu/lal_edpd.cpp @@ -0,0 +1,285 @@ +/*************************************************************************** + edpd.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Class for acceleration of the edpd pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "edpd_cl.h" +#elif defined(USE_CUDART) +const char *edpd=0; +#else +#include "edpd_cubin.h" +#endif + +#include "lal_edpd.h" +#include +namespace LAMMPS_AL { +#define EDPDT EDPD + +extern Device device; + +template +EDPDT::EDPD() : BaseDPD(), _allocated(false) { + _max_q_size = 0; +} + +template +EDPDT::~EDPD() { + clear(); +} + +template +int EDPDT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int EDPDT::init(const int ntypes, + double **host_cutsq, double **host_a0, + double **host_gamma, double **host_cut, + double **host_power, double **host_kappa, + double **host_powerT, double **host_cutT, + double ***host_sc, double ***host_kc, double *host_mass, + double *host_special_lj, + const int power_flag, const int kappa_flag, + const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, + const double gpu_split, FILE *_screen) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + + int success; + int extra_fields = 4; // round up to accomodate quadruples of numtyp values + // T and cv + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,edpd,"k_edpd",onetype,extra_fields); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff,host_write,host_a0,host_gamma, + host_cut); + + coeff2.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff2,host_write,host_power,host_kappa, + host_powerT,host_cutT); + + UCL_H_Vec dview_mass(ntypes, *(this->ucl_device), UCL_WRITE_ONLY); + for (int i = 0; i < ntypes; i++) + dview_mass[i] = host_mass[i]; + mass.alloc(ntypes,*(this->ucl_device), UCL_READ_ONLY); + ucl_copy(mass,dview_mass,false); + + if (host_sc) { + UCL_H_Vec dview(lj_types*lj_types,*(this->ucl_device),UCL_WRITE_ONLY);; + sc.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + int n = 0; + for (int i = 1; i < ntypes; i++) + for (int j = 1; j < ntypes; j++) { + dview[n].x = host_sc[i][j][0]; + dview[n].y = host_sc[i][j][1]; + dview[n].z = host_sc[i][j][2]; + dview[n].w = host_sc[i][j][3]; + n++; + } + ucl_copy(sc,dview,false); + } + + if (host_kc) { + UCL_H_Vec dview(lj_types*lj_types,*(this->ucl_device),UCL_WRITE_ONLY);; + kc.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + int n = 0; + for (int i = 1; i < ntypes; i++) + for (int j = 1; j < ntypes; j++) { + dview[n].x = host_kc[i][j][0]; + dview[n].y = host_kc[i][j][1]; + dview[n].z = host_kc[i][j][2]; + dview[n].w = host_kc[i][j][3]; + n++; + } + ucl_copy(kc,dview,false); + } + + UCL_H_Vec host_rsq(lj_types*lj_types,*(this->ucl_device), + UCL_WRITE_ONLY); + cutsq.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack1(ntypes,lj_types,cutsq,host_rsq,host_cutsq); + + double special_sqrt[4]; + special_sqrt[0] = sqrt(host_special_lj[0]); + special_sqrt[1] = sqrt(host_special_lj[1]); + special_sqrt[2] = sqrt(host_special_lj[2]); + special_sqrt[3] = sqrt(host_special_lj[3]); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + sp_sqrt.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(special_sqrt,4,*(this->ucl_device)); + ucl_copy(sp_sqrt,dview,false); + + _power_flag = power_flag; + _kappa_flag = kappa_flag; + + // allocate per-atom array Q + + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + + _max_q_size=static_cast(static_cast(ef_nall)*1.10); + Q.alloc(_max_q_size,*(this->ucl_device),UCL_READ_WRITE,UCL_READ_WRITE); + + _allocated=true; + this->_max_bytes=coeff.row_bytes()+coeff2.row_bytes()+Q.row_bytes()+ + sc.row_bytes()+kc.row_bytes()+mass.row_bytes()+cutsq.row_bytes()+sp_lj.row_bytes()+sp_sqrt.row_bytes(); + return 0; +} + +template +void EDPDT::clear() { + if (!_allocated) + return; + _allocated=false; + + coeff.clear(); + coeff2.clear(); + sc.clear(); + kc.clear(); + Q.clear(); + mass.clear(); + cutsq.clear(); + sp_lj.clear(); + sp_sqrt.clear(); + this->clear_atomic(); +} + +template +double EDPDT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(EDPD); +} + +template +void EDPDT::update_flux(void **flux_ptr) { + *flux_ptr=Q.host.begin(); + Q.update_host(_max_q_size,false); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int EDPDT::loop(const int eflag, const int vflag) { + + int nall = this->atom->nall(); + + // Resize Q array if necessary + if (nall > _max_q_size) { + _max_q_size=static_cast(static_cast(nall)*1.10); + Q.resize(_max_q_size); + } + + // signal that we need to transfer extra data from the host + + this->atom->extra_data_unavail(); + + numtyp4 *pextra=reinterpret_cast(&(this->atom->extra[0])); + + int n = 0; + int nstride = 1; + for (int i = 0; i < nall; i++) { + int idx = n+i*nstride; + numtyp4 v; + v.x = edpd_temp[i]; + v.y = edpd_cv[i]; + v.z = 0; + v.w = 0; + pextra[idx] = v; + } + this->atom->add_extra_data(); + + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &this->atom->extra, &coeff, &coeff2, &mass, + &sc, &kc, &sp_lj, &sp_sqrt, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &Q, &eflag, &vflag, + &_power_flag, &_kappa_flag, &ainum, &nbor_pitch, + &this->atom->v, &cutsq, &this->_dtinvsqrt, &this->_seed, + &this->_timestep, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &this->atom->extra, &coeff, &coeff2, &mass, + &sc, &kc, &_lj_types, &sp_lj, &sp_sqrt, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &Q, &eflag, &vflag, + &_power_flag, &_kappa_flag, &ainum, &nbor_pitch, + &this->atom->v, &cutsq, &this->_dtinvsqrt, &this->_seed, + &this->_timestep, &this->_threads_per_atom); + } + + this->time_pair.stop(); + return GX; +} + +// --------------------------------------------------------------------------- +// Get the extra data pointers from host +// --------------------------------------------------------------------------- + +template +void EDPDT::get_extra_data(double *host_T, double *host_cv) { + edpd_temp = host_T; + edpd_cv = host_cv; +} + +template class EDPD; +} diff --git a/lib/gpu/lal_edpd.cu b/lib/gpu/lal_edpd.cu new file mode 100644 index 0000000000..9662d15aea --- /dev/null +++ b/lib/gpu/lal_edpd.cu @@ -0,0 +1,619 @@ +// ************************************************************************** +// edpd.cu +// ------------------- +// Trung Dac Nguyen (U Chicago) +// +// Device code for acceleration of the edpd pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : September 2023 +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( vel_tex,float4); +#else +_texture_2d( pos_tex,int4); +_texture_2d( vel_tex,int4); +#endif +#else +#define pos_tex x_ +#define vel_tex v_ +#endif + +#define EPSILON (numtyp)1.0e-10 + +//#define _USE_UNIFORM_SARU_LCG +//#define _USE_UNIFORM_SARU_TEA8 +//#define _USE_GAUSSIAN_SARU_LCG + +#if !defined(_USE_UNIFORM_SARU_LCG) && !defined(_USE_UNIFORM_SARU_TEA8) && !defined(_USE_GAUSSIAN_SARU_LCG) +#define _USE_UNIFORM_SARU_LCG +#endif + +// References: +// 1. Y. Afshar, F. Schmid, A. Pishevar, S. Worley, Comput. Phys. Comm. 184 (2013), 1119–1128. +// 2. C. L. Phillips, J. A. Anderson, S. C. Glotzer, Comput. Phys. Comm. 230 (2011), 7191-7201. +// PRNG period = 3666320093*2^32 ~ 2^64 ~ 10^19 + +#define LCGA 0x4beb5d59 /* Full period 32 bit LCG */ +#define LCGC 0x2600e1f7 +#define oWeylPeriod 0xda879add /* Prime period 3666320093 */ +#define oWeylOffset 0x8009d14b +#define TWO_N32 0.232830643653869628906250e-9f /* 2^-32 */ + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] +// using the inherent LCG, then multiply u with sqrt(3) to "match" +// with a normal random distribution. +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +// Curly brackets to make variables local to the scope. +#ifdef _USE_UNIFORM_SARU_LCG +#define SQRT3 (numtyp)1.7320508075688772935274463 +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + unsigned int v = (state ^ (state>>26)) + wstate; \ + unsigned int s = (signed int)((v^(v>>20))*0x6957f5a7); \ + randnum = SQRT3*(s*TWO_N32*(numtyp)2.0-(numtyp)1.0); \ +} +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] using TEA8 +// then multiply u with sqrt(3) to "match" with a normal random distribution +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +#ifdef _USE_UNIFORM_SARU_TEA8 +#define SQRT3 (numtyp)1.7320508075688772935274463 +#define k0 0xA341316C +#define k1 0xC8013EA4 +#define k2 0xAD90777D +#define k3 0x7E95761E +#define delta 0x9e3779b9 +#define rounds 8 +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + unsigned int sum = 0; \ + for (int i=0; i < rounds; i++) { \ + sum += delta; \ + state += ((wstate<<4) + k0)^(wstate + sum)^((wstate>>5) + k1); \ + wstate += ((state<<4) + k2)^(state + sum)^((state>>5) + k3); \ + } \ + unsigned int v = (state ^ (state>>26)) + wstate; \ + unsigned int s = (signed int)((v^(v>>20))*0x6957f5a7); \ + randnum = SQRT3*(s*TWO_N32*(numtyp)2.0-(numtyp)1.0); \ +} +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns two uniformly distributed random numbers r1 and r2 in [-1.0;1.0], +// and uses the polar method (Marsaglia's) to transform to a normal random value +// This is used to compared with CPU DPD using RandMars::gaussian() +#ifdef _USE_GAUSSIAN_SARU_LCG +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state=0x12345678; \ + unsigned int wstate=12345678; \ + state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + unsigned int v, s; \ + numtyp r1, r2, rsq; \ + while (1) { \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + v = (state ^ (state>>26)) + wstate; \ + s = (signed int)((v^(v>>20))*0x6957f5a7); \ + r1 = s*TWO_N32*(numtyp)2.0-(numtyp)1.0; \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + v = (state ^ (state>>26)) + wstate; \ + s = (signed int)((v^(v>>20))*0x6957f5a7); \ + r2 = s*TWO_N32*(numtyp)2.0-(numtyp)1.0; \ + rsq = r1 * r1 + r2 * r2; \ + if (rsq < (numtyp)1.0) break; \ + } \ + numtyp fac = ucl_sqrt((numtyp)-2.0*log(rsq)/rsq); \ + randnum = r2*fac; \ +} +#endif + +#if (SHUFFLE_AVAIL == 0) + +#define store_heatflux(Qi, ii, inum, tid, t_per_atom, offset, Q) \ + if (t_per_atom>1) { \ + simdsync(); \ + simd_reduce_add1(t_per_atom, red_acc, offset, tid, Qi); \ + } \ + if (offset==0 && ii1) { \ + simd_reduce_add1(t_per_atom,Qi); \ + } \ + if (offset==0 && ii tag2) { + tag1 = jtag; tag2 = itag; + } + + numtyp randnum = (numtyp)0.0; + saru(tag1, tag2, seed, timestep, randnum); + + numtyp T_ij=(numtyp)0.5*(Ti+Tj); + numtyp4 T_pow; + T_pow.x = T_ij - (numtyp)1.0; + T_pow.y = T_pow.x*T_pow.x; + T_pow.z = T_pow.x*T_pow.y; + T_pow.w = T_pow.x*T_pow.z; + + numtyp coeff2x = coeff2[mtype].x; //power[itype][jtype] + numtyp coeff2y = coeff2[mtype].y; //kappa[itype][jtype] + numtyp coeff2z = coeff2[mtype].z; //powerT[itype][jtype] + numtyp coeff2w = coeff2[mtype].w; //cutT[itype][jtype] + numtyp power_d = coeff2x; + if (power_flag) { + numtyp factor = (numtyp)1.0; + factor += sc[mtype].x*T_pow.x + sc[mtype].y*T_pow.y + + sc[mtype].z*T_pow.z + sc[mtype].w*T_pow.w; + power_d *= factor; + } + + power_d = MAX((numtyp)0.01,power_d); + numtyp wc = (numtyp)1.0 - r/coeffz; // cut[itype][jtype] + wc = MAX((numtyp)0.0,MIN((numtyp)1.0,wc)); + numtyp wr = ucl_pow(wc, (numtyp)0.5*power_d); + + numtyp kboltz = (numtyp)1.0; + numtyp GammaIJ = coeffy; // gamma[itype][jtype] + numtyp SigmaIJ = (numtyp)4.0*GammaIJ*kboltz*Ti*Tj/(Ti+Tj); + SigmaIJ = ucl_sqrt(SigmaIJ); + + numtyp force = coeffx*T_ij*wc; // a0[itype][jtype] + force -= GammaIJ *wr*wr *dot*rinv; + force += SigmaIJ * wr *randnum * dtinvsqrt; + force *= factor_dpd*rinv; + + f.x+=delx*force; + f.y+=dely*force; + f.z+=delz*force; + + // heat transfer + + if (r < coeff2w) { + numtyp wrT = (numtyp)1.0 - r/coeff2w; + wrT = MAX((numtyp)0.0,MIN((numtyp)1.0,wrT)); + wrT = ucl_pow(wrT, (numtyp)0.5*coeff2z); // powerT[itype][jtype] + numtyp randnumT = (numtyp)0; + saru(tag1, tag2, seed+tag1+tag2, timestep, randnumT); // randomT->gaussian(); + randnumT = MAX((numtyp)-5.0,MIN(randnum,(numtyp)5.0)); + + numtyp kappaT = coeff2y; // kappa[itype][jtype] + if (kappa_flag) { + numtyp factor = (numtyp)1.0; + factor += kc[mtype].x*T_pow.x + kc[mtype].y*T_pow.y + + kc[mtype].z*T_pow.z + kc[mtype].w*T_pow.w; + kappaT *= factor; + } + + numtyp kij = cvi*cvj*kappaT * T_ij*T_ij; + numtyp alphaij = ucl_sqrt((numtyp)2.0*kboltz*kij); + + numtyp dQc = kij * wrT*wrT * (Tj - Ti)/(Ti*Tj); + numtyp dQd = wr*wr*( GammaIJ * vijeij*vijeij - SigmaIJ*SigmaIJ/mass_itype ) - SigmaIJ * wr *vijeij *randnum; + dQd /= (cvi+cvj); + numtyp dQr = alphaij * wrT * dtinvsqrt * randnumT; + Qi += (dQc + dQd + dQr ); + } + + if (EVFLAG && eflag) { + numtyp e = (numtyp)0.5*coeffx*T_ij*coeffz * wc*wc; + energy+=factor_dpd*e; + } + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + } // for nbor + } // if ii + store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, + ans,engv); + store_heatflux(Qi,ii,inum,tid,t_per_atom,offset,Q); +} + +__kernel void k_edpd_fast(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict extra, + const __global numtyp4 *restrict coeff_in, + const __global numtyp4 *restrict coeff2_in, + const __global numtyp *restrict mass, + const __global numtyp4 *restrict sc_in, + const __global numtyp4 *restrict kc_in, + const __global numtyp *restrict sp_lj_in, + const __global numtyp *restrict sp_sqrt_in, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + __global acctyp *restrict Q, + const int eflag, const int vflag, + const int power_flag, const int kappa_flag, + const int inum, const int nbor_pitch, + const __global numtyp4 *restrict v_, + const __global numtyp *restrict cutsq, + const numtyp dtinvsqrt, const int seed, + const int timestep, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + #ifndef ONETYPE + __local numtyp4 coeff[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp4 coeff2[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp4 sc[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp4 kc[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp sp_lj[4]; + __local numtyp sp_sqrt[4]; + if (tid<4) { + sp_lj[tid]=sp_lj_in[tid]; + sp_sqrt[tid]=sp_sqrt_in[tid]; + } + if (tid tag2) { + tag1 = jtag; tag2 = itag; + } + numtyp randnum = (numtyp)0.0; + saru(tag1, tag2, seed, timestep, randnum); + + numtyp T_ij=(numtyp)0.5*(Ti+Tj); + numtyp4 T_pow; + T_pow.x = T_ij - (numtyp)1.0; + T_pow.y = T_pow.x*T_pow.x; + T_pow.z = T_pow.x*T_pow.y; + T_pow.w = T_pow.x*T_pow.z; + + numtyp power_d = coeff2x; // power[itype][jtype] + if (power_flag) { + numtyp factor = (numtyp)1.0; + factor += scx*T_pow.x + scy*T_pow.y + scz*T_pow.z + scw*T_pow.w; + power_d *= factor; + } + + power_d = MAX((numtyp)0.01,power_d); + numtyp wc = (numtyp)1.0 - r/coeffz; // cut[itype][jtype] + wc = MAX((numtyp)0.0,MIN((numtyp)1.0,wc)); + numtyp wr = ucl_pow((numtyp)wc, (numtyp)0.5*power_d); + + numtyp kboltz = (numtyp)1.0; + numtyp GammaIJ = coeffy; // gamma[itype][jtype] + numtyp SigmaIJ = (numtyp)4.0*GammaIJ*kboltz*Ti*Tj/(Ti+Tj); + SigmaIJ = ucl_sqrt(SigmaIJ); + + numtyp force = coeffx*T_ij*wc; // a0[itype][jtype] + force -= GammaIJ *wr*wr *dot*rinv; + force += SigmaIJ* wr *randnum * dtinvsqrt; + #ifndef ONETYPE + force *= factor_dpd*rinv; + #else + force *= rinv; + #endif + + f.x+=delx*force; + f.y+=dely*force; + f.z+=delz*force; + + // heat transfer + + if (r < coeff2w) { + numtyp wrT = (numtyp)1.0 - r/coeff2w; + wrT = MAX((numtyp)0.0,MIN((numtyp)1.0,wrT)); + wrT = ucl_pow(wrT, (numtyp)0.5*coeff2z); // powerT[itype][jtype] + numtyp randnumT = (numtyp)0; + saru(tag1, tag2, seed+tag1+tag2, timestep, randnumT); // randomT->gaussian(); + randnumT = MAX((numtyp)-5.0,MIN(randnum,(numtyp)5.0)); + + numtyp kappaT = coeff2y; // kappa[itype][jtype] + if (kappa_flag) { + numtyp factor = (numtyp)1.0; + factor += kcx*T_pow.x + kcy*T_pow.y + kcz*T_pow.z + kcw*T_pow.w; + kappaT *= factor; + } + + numtyp kij = cvi*cvj*kappaT * T_ij*T_ij; + numtyp alphaij = ucl_sqrt((numtyp)2.0*kboltz*kij); + + numtyp dQc = kij * wrT*wrT * (Tj - Ti )/(Ti*Tj); + numtyp dQd = wr*wr*( GammaIJ * vijeij*vijeij - SigmaIJ*SigmaIJ/mass_itype ) - SigmaIJ * wr *vijeij *randnum; + dQd /= (cvi+cvj); + numtyp dQr = alphaij * wrT * dtinvsqrt * randnumT; + Qi += (dQc + dQd + dQr ); + } + + if (EVFLAG && eflag) { + numtyp e = (numtyp)0.5*coeffx*T_ij*coeffz * wc*wc; + #ifndef ONETYPE + energy+=factor_dpd*e; + #else + energy+=e; + #endif + } + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + + } + } // for nbor + } // if ii + + store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, ans,engv); + store_heatflux(Qi,ii,inum,tid,t_per_atom,offset,Q); +} + diff --git a/lib/gpu/lal_edpd.h b/lib/gpu/lal_edpd.h new file mode 100644 index 0000000000..e5f7b0633b --- /dev/null +++ b/lib/gpu/lal_edpd.h @@ -0,0 +1,102 @@ +/*************************************************************************** + edpd.h + ------------------- + Trung Dac Nguyen (U Chicago) + + Class for acceleration of the edpd pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#ifndef LAL_EDPD_H +#define LAL_EDPD_H + +#include "lal_base_dpd.h" + +namespace LAMMPS_AL { + +template +class EDPD : public BaseDPD { + public: + EDPD(); + ~EDPD(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, double **host_a0, + double **host_gamma, double **host_cut, double **host_power, + double **host_kappa, double **host_powerT, double **host_cutT, + double ***host_sc, double ***host_kc, double *host_mass, + double *host_special_lj, const int power_flag, const int kappa_flag, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, const double gpu_split, + FILE *screen); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + void get_extra_data(double *host_T, double *host_cv); + + /// copy Q (flux) from device to host + void update_flux(void **flux_ptr); + + // --------------------------- TYPE DATA -------------------------- + + /// coeff.x = a0, coeff.y = gamma, coeff.z = cut + UCL_D_Vec coeff; + /// coeff2.x = power, coeff2.y = kappa, coeff2.z = powerT, coeff2.w = cutT + UCL_D_Vec coeff2; + + UCL_D_Vec kc, sc; + UCL_D_Vec cutsq; + + /// per-type array + UCL_D_Vec mass; + + /// Special LJ values + UCL_D_Vec sp_lj, sp_sqrt; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + /// Per-atom arrays + UCL_Vector Q; + int _max_q_size; + + int _power_flag, _kappa_flag; + + /// pointer to host data + double *edpd_temp, *edpd_cv; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_edpd_ext.cpp b/lib/gpu/lal_edpd_ext.cpp new file mode 100644 index 0000000000..a9f60c3941 --- /dev/null +++ b/lib/gpu/lal_edpd_ext.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + edpd_ext.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Functions for LAMMPS access to edpd acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_edpd.h" + +using namespace std; +using namespace LAMMPS_AL; + +static EDPD EDPDMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int edpd_gpu_init(const int ntypes, double **cutsq, double **host_a0, + double **host_gamma, double **host_cut, double **host_power, + double **host_kappa, double **host_powerT, double **host_cutT, + double ***host_sc, double ***host_kc, double *host_mass, + double *special_lj, const int power_flag, const int kappa_flag, + const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen) { + EDPDMF.clear(); + gpu_mode=EDPDMF.device->gpu_mode(); + double gpu_split=EDPDMF.device->particle_split(); + int first_gpu=EDPDMF.device->first_device(); + int last_gpu=EDPDMF.device->last_device(); + int world_me=EDPDMF.device->world_me(); + int gpu_rank=EDPDMF.device->gpu_rank(); + int procs_per_gpu=EDPDMF.device->procs_per_gpu(); + + EDPDMF.device->init_message(screen,"edpd",first_gpu,last_gpu); + + bool message=false; + if (EDPDMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=EDPDMF.init(ntypes, cutsq, host_a0, host_gamma, host_cut, + host_power, host_kappa, host_powerT, + host_cutT, host_sc, host_kc, host_mass, + special_lj, power_flag, kappa_flag, + inum, nall, max_nbors, maxspecial, + cell_size, gpu_split, screen); + + EDPDMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + EDPDMF.estimate_gpu_overhead(); + return init_ok; +} + +void edpd_gpu_clear() { + EDPDMF.clear(); +} + +int ** edpd_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v, const double dtinvsqrt, + const int seed, const int timestep, + double *boxlo, double *prd) { + return EDPDMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_v, dtinvsqrt, seed, timestep, boxlo, prd); +} + +void edpd_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **host_v, const double dtinvsqrt, + const int seed, const int timestep, + const int nlocal, double *boxlo, double *prd) { + EDPDMF.compute(ago, inum_full, nall, host_x, host_type, ilist, numj, + firstneigh, eflag, vflag, eatom, vatom, host_start, cpu_time, success, + tag, host_v, dtinvsqrt, seed, timestep, nlocal, boxlo, prd); +} + +void edpd_gpu_get_extra_data(double *host_T, double *host_cv) { + EDPDMF.get_extra_data(host_T, host_cv); +} + +void edpd_gpu_update_flux(void **flux_ptr) { + EDPDMF.update_flux(flux_ptr); +} + +double edpd_gpu_bytes() { + return EDPDMF.host_memory_usage(); +} diff --git a/lib/gpu/lal_hippo.cpp b/lib/gpu/lal_hippo.cpp index 8d6ad5dfb2..3511d82b00 100644 --- a/lib/gpu/lal_hippo.cpp +++ b/lib/gpu/lal_hippo.cpp @@ -603,13 +603,7 @@ int HippoT::polar_real(const int eflag, const int vflag) { const int BX=this->block_size(); const int GX=static_cast(ceil(static_cast(ainum)/(BX/this->_threads_per_atom))); - /* - const int cus = this->device->gpu->cus(); - while (GX < cus && GX > 1) { - BX /= 2; - GX=static_cast(ceil(static_cast(ainum)/(BX/this->_threads_per_atom))); - } - */ + this->time_pair.start(); // Build the short neighbor list if not done yet diff --git a/lib/gpu/lal_lj_coul_long.h b/lib/gpu/lal_lj_coul_long.h index bc4fce40a5..ace5a26339 100644 --- a/lib/gpu/lal_lj_coul_long.h +++ b/lib/gpu/lal_lj_coul_long.h @@ -78,7 +78,7 @@ class LJCoulLong : public BaseCharge { numtyp _cut_coulsq, _qqrd2e, _g_ewald; - private: +protected: bool _allocated; int loop(const int eflag, const int vflag); }; diff --git a/lib/gpu/lal_lj_coul_long_soft.cpp b/lib/gpu/lal_lj_coul_long_soft.cpp new file mode 100644 index 0000000000..80eaaca94a --- /dev/null +++ b/lib/gpu/lal_lj_coul_long_soft.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + lj_coul_long_soft.cpp + ------------------- + Trung Nguyen (U Chicago) + + Class for acceleration of the lj/cut/coul/long/soft pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "lj_coul_long_soft_cl.h" +#elif defined(USE_CUDART) +const char *lj_coul_long_soft=0; +#else +#include "lj_coul_long_soft_cubin.h" +#endif + +#include "lal_lj_coul_long_soft.h" +#include +namespace LAMMPS_AL { +#define LJCoulLongSoftT LJCoulLongSoft + +extern Device device; + +template +LJCoulLongSoftT::LJCoulLongSoft() : BaseCharge(), + _allocated(false) { +} + +template +LJCoulLongSoftT::~LJCoulLongSoft() { + clear(); +} + +template +int LJCoulLongSoftT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int LJCoulLongSoftT::init(const int ntypes, + double **host_cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, double **host_epsilon, + double *host_special_lj, const int nlocal, + const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *_screen, + double **host_cut_ljsq, const double host_cut_coulsq, + double *host_special_coul, const double qqrd2e, + const double g_ewald) { + int success; + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size,gpu_split, + _screen,lj_coul_long_soft,"k_lj_coul_long_soft"); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + int max_shared_types=this->device->max_shared_types(); + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,lj1,host_write,host_lj1,host_lj2, + host_cutsq, host_cut_ljsq); + + lj3.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,lj3,host_write,host_lj3,host_lj4, + host_offset, host_epsilon); + + sp_lj.alloc(8,*(this->ucl_device),UCL_READ_ONLY); + for (int i=0; i<4; i++) { + host_write[i]=host_special_lj[i]; + host_write[i+4]=host_special_coul[i]; + } + ucl_copy(sp_lj,host_write,8,false); + + _cut_coulsq=host_cut_coulsq; + _qqrd2e=qqrd2e; + _g_ewald=g_ewald; + + _allocated=true; + this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+sp_lj.row_bytes(); + return 0; +} + +template +void LJCoulLongSoftT::reinit(const int ntypes, double **host_cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **host_offset, double **host_epsilon, double **host_cut_ljsq) { + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(_lj_types*_lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; i<_lj_types*_lj_types; i++) + host_write[i]=0.0; + + this->atom->type_pack4(ntypes,_lj_types,lj1,host_write,host_lj1,host_lj2, + host_cutsq, host_cut_ljsq); + this->atom->type_pack4(ntypes,_lj_types,lj3,host_write,host_lj3,host_lj4, + host_offset, host_epsilon); +} + +template +void LJCoulLongSoftT::clear() { + if (!_allocated) + return; + _allocated=false; + + lj1.clear(); + lj3.clear(); + sp_lj.clear(); + this->clear_atomic(); +} + +template +double LJCoulLongSoftT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(LJCoulLongSoft); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int LJCoulLongSoftT::loop(const int eflag, const int vflag) { + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &lj1, &lj3, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, + &vflag, &ainum, &nbor_pitch, &this->atom->q, + &_cut_coulsq, &_qqrd2e, &_g_ewald, + &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &lj1, &lj3, + &_lj_types, &sp_lj, &this->nbor->dev_nbor, + &this->_nbor_data->begin(), &this->ans->force, + &this->ans->engv, &eflag, &vflag, &ainum, + &nbor_pitch, &this->atom->q, &_cut_coulsq, + &_qqrd2e, &_g_ewald, &this->_threads_per_atom); + } + this->time_pair.stop(); + return GX; +} + +template class LJCoulLongSoft; +} diff --git a/lib/gpu/lal_lj_coul_long_soft.cu b/lib/gpu/lal_lj_coul_long_soft.cu new file mode 100644 index 0000000000..e311bb5d3b --- /dev/null +++ b/lib/gpu/lal_lj_coul_long_soft.cu @@ -0,0 +1,290 @@ +// ************************************************************************** +// lj_coul_long_soft.cu +// ------------------- +// Trung Nguyen (U Chicago) +// +// Device code for acceleration of the lj/cut/coul/long/soft pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) + +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( q_tex,float); +#else +_texture_2d( pos_tex,int4); +_texture( q_tex,int2); +#endif + +#else +#define pos_tex x_ +#define q_tex q_ +#endif + +__kernel void k_lj_coul_long_soft(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict lj1, + const __global numtyp4 *restrict lj3, + const int lj_types, + const __global numtyp *restrict sp_lj_in, + const __global int *dev_nbor, + const __global int *dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp *restrict q_, + const numtyp cut_coulsq, const numtyp qqrd2e, + const numtyp g_ewald, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + __local numtyp sp_lj[8]; + int n_stride; + local_allocate_store_charge(); + + sp_lj[0]=sp_lj_in[0]; + sp_lj[1]=sp_lj_in[1]; + sp_lj[2]=sp_lj_in[2]; + sp_lj[3]=sp_lj_in[3]; + sp_lj[4]=sp_lj_in[4]; + sp_lj[5]=sp_lj_in[5]; + sp_lj[6]=sp_lj_in[6]; + sp_lj[7]=sp_lj_in[7]; + + acctyp3 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp energy, e_coul, virial[6]; + if (EVFLAG) { + energy=(acctyp)0; + e_coul=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + + if (ii +class LJCoulLongSoft : public BaseCharge { + public: + LJCoulLongSoft(); + ~LJCoulLongSoft(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, + double **host_lj1, double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, double **host_epsilon, double *host_special_lj, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, double **host_cut_ljsq, + const double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald); + + /// Send updated coeffs from host to device (to be compatible with fix adapt) + void reinit(const int ntypes, double **host_cutsq, + double **host_lj1, double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, double **host_epsilon, double **host_cut_ljsq); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + // --------------------------- TYPE DATA -------------------------- + + /// lj1.x = lj1, lj1.y = lj2, lj1.z = cutsq, lj1.w = cutsq_vdw + UCL_D_Vec lj1; + /// lj3.x = lj3, lj3.y = lj4, lj3.z = offset, lj3.w = epsilon + UCL_D_Vec lj3; + /// Special LJ values [0-3] and Special Coul values [4-7] + UCL_D_Vec sp_lj; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + numtyp _cut_coulsq, _qqrd2e, _g_ewald; + +protected: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_lj_coul_long_soft_ext.cpp b/lib/gpu/lal_lj_coul_long_soft_ext.cpp new file mode 100644 index 0000000000..cb2657c03b --- /dev/null +++ b/lib/gpu/lal_lj_coul_long_soft_ext.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + lj_coul_long_soft_ext.cpp + ------------------------- + Trung Nguyen (U Chicago) + + Functions for LAMMPS access to lj/cut/coul/long/soft acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_lj_coul_long_soft.h" + +using namespace std; +using namespace LAMMPS_AL; + +static LJCoulLongSoft LJCLSMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int ljcls_gpu_init(const int ntypes, double **cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **offset, double **epsilon, double *special_lj, const int inum, + const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, + double **host_cut_ljsq, double host_cut_coulsq, + double *host_special_coul, const double qqrd2e, + const double g_ewald) { + LJCLSMF.clear(); + gpu_mode=LJCLSMF.device->gpu_mode(); + double gpu_split=LJCLSMF.device->particle_split(); + int first_gpu=LJCLSMF.device->first_device(); + int last_gpu=LJCLSMF.device->last_device(); + int world_me=LJCLSMF.device->world_me(); + int gpu_rank=LJCLSMF.device->gpu_rank(); + int procs_per_gpu=LJCLSMF.device->procs_per_gpu(); + + LJCLSMF.device->init_message(screen,"lj/cut/coul/long/soft",first_gpu,last_gpu); + + bool message=false; + if (LJCLSMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=LJCLSMF.init(ntypes, cutsq, host_lj1, host_lj2, host_lj3, host_lj4, + offset, epsilon, special_lj, inum, nall, max_nbors, maxspecial, + cell_size, gpu_split, screen, host_cut_ljsq, + host_cut_coulsq, host_special_coul, qqrd2e, g_ewald); + + LJCLSMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; igpu_barrier(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + LJCLSMF.estimate_gpu_overhead(); + return init_ok; +} + +// --------------------------------------------------------------------------- +// Copy updated coeffs from host to device +// --------------------------------------------------------------------------- +void ljcls_gpu_reinit(const int ntypes, double **cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **offset, double **epsilon, double **host_cut_ljsq) { + int world_me=LJCLSMF.device->world_me(); + int gpu_rank=LJCLSMF.device->gpu_rank(); + int procs_per_gpu=LJCLSMF.device->procs_per_gpu(); + + if (world_me==0) + LJCLSMF.reinit(ntypes, cutsq, host_lj1, host_lj2, host_lj3, host_lj4, + offset, epsilon, host_cut_ljsq); + LJCLSMF.device->world_barrier(); + + for (int i=0; igpu_barrier(); + } +} + +void ljcls_gpu_clear() { + LJCLSMF.clear(); +} + +int** ljcls_gpu_compute_n(const int ago, const int inum_full, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, + bool &success, double *host_q, double *boxlo, + double *prd) { + return LJCLSMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_q, boxlo, prd); +} + +void ljcls_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, double *host_q, + const int nlocal, double *boxlo, double *prd) { + LJCLSMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj, + firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success, + host_q,nlocal,boxlo,prd); +} + +double ljcls_gpu_bytes() { + return LJCLSMF.host_memory_usage(); +} + diff --git a/lib/gpu/lal_lj_coul_soft.cpp b/lib/gpu/lal_lj_coul_soft.cpp new file mode 100644 index 0000000000..9ee6486817 --- /dev/null +++ b/lib/gpu/lal_lj_coul_soft.cpp @@ -0,0 +1,157 @@ +/*************************************************************************** + lj_coul_soft.cpp + ------------------- + Trung Nguyen (U Chicago) + + Class for acceleration of the lj/cut/coul/cut/soft pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : + email : ndtrung@uchicago.edu + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "lj_coul_soft_cl.h" +#elif defined(USE_CUDART) +const char *lj_coul_soft=0; +#else +#include "lj_coul_soft_cubin.h" +#endif + +#include "lal_lj_coul_soft.h" +#include +namespace LAMMPS_AL { +#define LJCoulSoftT LJCoulSoft + +extern Device device; + +template +LJCoulSoftT::LJCoulSoft() : BaseCharge(), + _allocated(false) { +} + +template +LJCoulSoftT::~LJCoulSoft() { + clear(); +} + +template +int LJCoulSoftT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int LJCoulSoftT::init(const int ntypes, + double **host_cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, double **host_epsilon, + double *host_special_lj, const int nlocal, + const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *_screen, + double **host_cut_ljsq, double **host_cut_coulsq, + double *host_special_coul, const double qqrd2e) { + int success; + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size,gpu_split, + _screen,lj_coul_soft,"k_lj_coul_soft"); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + int max_shared_types=this->device->max_shared_types(); + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,lj1,host_write,host_lj1,host_lj2, + host_cut_ljsq, host_cut_coulsq); + + lj3.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,lj3,host_write,host_lj3,host_lj4, + host_offset, host_epsilon); + + cutsq.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack1(ntypes,lj_types,cutsq,host_write,host_cutsq); + + sp_lj.alloc(8,*(this->ucl_device),UCL_READ_ONLY); + for (int i=0; i<4; i++) { + host_write[i]=host_special_lj[i]; + host_write[i+4]=host_special_coul[i]; + } + ucl_copy(sp_lj,host_write,8,false); + + _qqrd2e=qqrd2e; + + _allocated=true; + this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+cutsq.row_bytes()+ + sp_lj.row_bytes(); + return 0; +} + +template +void LJCoulSoftT::clear() { + if (!_allocated) + return; + _allocated=false; + + lj1.clear(); + lj3.clear(); + cutsq.clear(); + sp_lj.clear(); + this->clear_atomic(); +} + +template +double LJCoulSoftT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(LJCoulSoft); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int LJCoulSoftT::loop(const int eflag, const int vflag) { + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &lj1, &lj3, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, + &vflag, &ainum, &nbor_pitch, &this->atom->q, + &cutsq, &_qqrd2e, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &lj1, &lj3, &_lj_types, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, + &eflag, &vflag, &ainum, &nbor_pitch, &this->atom->q, + &cutsq, &_qqrd2e, &this->_threads_per_atom); + } + this->time_pair.stop(); + return GX; +} + +template class LJCoulSoft; +} diff --git a/lib/gpu/lal_lj_coul_soft.cu b/lib/gpu/lal_lj_coul_soft.cu new file mode 100644 index 0000000000..1fc564bde6 --- /dev/null +++ b/lib/gpu/lal_lj_coul_soft.cu @@ -0,0 +1,276 @@ +// ************************************************************************** +// lj_coul_soft.cu +// ------------------- +// Trung Nguyen (U Chicago) +// +// Device code for acceleration of the lj/coul/cut/soft pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : +// email : ndtrung@uchicago.edu +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) + +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( q_tex,float); +#else +_texture_2d( pos_tex,int4); +_texture( q_tex,int2); +#endif + +#else +#define pos_tex x_ +#define q_tex q_ +#endif + +__kernel void k_lj_coul_soft(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict lj1, + const __global numtyp4 *restrict lj3, + const int lj_types, + const __global numtyp *restrict sp_lj_in, + const __global int *dev_nbor, + const __global int *dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp *restrict q_, + const __global numtyp *restrict cutsq, + const numtyp qqrd2e, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + __local numtyp sp_lj[8]; + int n_stride; + local_allocate_store_charge(); + + sp_lj[0]=sp_lj_in[0]; + sp_lj[1]=sp_lj_in[1]; + sp_lj[2]=sp_lj_in[2]; + sp_lj[3]=sp_lj_in[3]; + sp_lj[4]=sp_lj_in[4]; + sp_lj[5]=sp_lj_in[5]; + sp_lj[6]=sp_lj_in[6]; + sp_lj[7]=sp_lj_in[7]; + + acctyp3 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp energy, e_coul, virial[6]; + if (EVFLAG) { + energy=(acctyp)0; + e_coul=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + + if (ii +class LJCoulSoft : public BaseCharge { + public: + LJCoulSoft(); + ~LJCoulSoft(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **host_offset, double **host_epsilon, double *host_special_lj, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, double **host_cut_ljsq, + double **host_cut_coulsq, double *host_special_coul, + const double qqrd2e); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + // --------------------------- TYPE DATA -------------------------- + + /// lj1.x = lj1, lj1.y = lj2, lj1.z = cutsq_vdw, lj1.w = cutsq_coul + UCL_D_Vec lj1; + /// lj3.x = lj3, lj3.y = lj4, lj3.z = offset, lj3.w = epsilon + UCL_D_Vec lj3; + /// cutsq + UCL_D_Vec cutsq; + /// Special LJ values [0-3] and Special Coul values [4-7] + UCL_D_Vec sp_lj; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + numtyp _qqrd2e; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_lj_coul_soft_ext.cpp b/lib/gpu/lal_lj_coul_soft_ext.cpp new file mode 100644 index 0000000000..02d367b3c7 --- /dev/null +++ b/lib/gpu/lal_lj_coul_soft_ext.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** + lj_coul_soft_ext.cpp + ------------------- + Trung Nguyen (U Chicago) + + Functions for LAMMPS access to lj/cut/coul/cut/soft acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : + email : ndtrung@uchicago.edu + ***************************************************************************/ + +#include +#include +#include + +#include "lal_lj_coul_soft.h" + +using namespace std; +using namespace LAMMPS_AL; + +static LJCoulSoft LJCSMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int ljcs_gpu_init(const int ntypes, double **cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **offset, double **epsilon, double *special_lj, const int inum, + const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, + double **host_cut_ljsq, double **host_cut_coulsq, + double *host_special_coul, const double qqrd2e) { + LJCSMF.clear(); + gpu_mode=LJCSMF.device->gpu_mode(); + double gpu_split=LJCSMF.device->particle_split(); + int first_gpu=LJCSMF.device->first_device(); + int last_gpu=LJCSMF.device->last_device(); + int world_me=LJCSMF.device->world_me(); + int gpu_rank=LJCSMF.device->gpu_rank(); + int procs_per_gpu=LJCSMF.device->procs_per_gpu(); + + LJCSMF.device->init_message(screen,"lj/cut/coul/cut/soft",first_gpu,last_gpu); + + bool message=false; + if (LJCSMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=LJCSMF.init(ntypes, cutsq, host_lj1, host_lj2, host_lj3, + host_lj4, offset, epsilon, special_lj, inum, nall, max_nbors, + maxspecial, cell_size, gpu_split, screen, host_cut_ljsq, + host_cut_coulsq, host_special_coul, qqrd2e); + + LJCSMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; igpu_barrier(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + LJCSMF.estimate_gpu_overhead(); + return init_ok; +} + +void ljcs_gpu_clear() { + LJCSMF.clear(); +} + +int** ljcs_gpu_compute_n(const int ago, const int inum_full, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, + bool &success, double *host_q, double *boxlo, + double *prd) { + return LJCSMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_q, boxlo, prd); +} + +void ljcs_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, double *host_q, + const int nlocal, double *boxlo, double *prd) { + LJCSMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj,firstneigh,eflag, + vflag,eatom,vatom,host_start,cpu_time,success,host_q, + nlocal,boxlo,prd); +} + +double ljcs_gpu_bytes() { + return LJCSMF.host_memory_usage(); +} + + diff --git a/lib/gpu/lal_mdpd.cpp b/lib/gpu/lal_mdpd.cpp new file mode 100644 index 0000000000..16cf926df8 --- /dev/null +++ b/lib/gpu/lal_mdpd.cpp @@ -0,0 +1,218 @@ +/*************************************************************************** + mdpd.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Class for acceleration of the mdpd pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "mdpd_cl.h" +#elif defined(USE_CUDART) +const char *mdpd=0; +#else +#include "mdpd_cubin.h" +#endif + +#include "lal_mdpd.h" +#include +namespace LAMMPS_AL { +#define MDPDT MDPD + +extern Device device; + +template +MDPDT::MDPD() : BaseDPD(), _allocated(false) { +} + +template +MDPDT::~MDPD() { + clear(); +} + +template +int MDPDT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int MDPDT::init(const int ntypes, + double **host_cutsq, double **host_A_att, double **host_B_rep, + double **host_gamma, double **host_sigma, + double **host_cut, double **host_cut_r, + double *host_special_lj, const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, + const double gpu_split, FILE *_screen) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + + int success; + int extra_fields = 4; // round up to accomodate quadruples of numtyp values + // rho + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,mdpd,"k_mdpd",onetype,extra_fields); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff,host_write,host_A_att,host_B_rep, + host_gamma,host_sigma); + + coeff2.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff2,host_write,host_cut,host_cut_r, + host_cutsq); + + UCL_H_Vec host_rsq(lj_types*lj_types,*(this->ucl_device), + UCL_WRITE_ONLY); + cutsq.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack1(ntypes,lj_types,cutsq,host_rsq,host_cutsq); + + double special_sqrt[4]; + special_sqrt[0] = sqrt(host_special_lj[0]); + special_sqrt[1] = sqrt(host_special_lj[1]); + special_sqrt[2] = sqrt(host_special_lj[2]); + special_sqrt[3] = sqrt(host_special_lj[3]); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + sp_sqrt.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(special_sqrt,4,*(this->ucl_device)); + ucl_copy(sp_sqrt,dview,false); + + // allocate per-atom array Q + + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + + _allocated=true; + this->_max_bytes=coeff.row_bytes()+coeff2.row_bytes()+cutsq.row_bytes()+ + sp_lj.row_bytes()+sp_sqrt.row_bytes(); + return 0; +} + +template +void MDPDT::clear() { + if (!_allocated) + return; + _allocated=false; + + coeff.clear(); + coeff2.clear(); + cutsq.clear(); + sp_lj.clear(); + sp_sqrt.clear(); + this->clear_atomic(); +} + +template +double MDPDT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(MDPD); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int MDPDT::loop(const int eflag, const int vflag) { + + int nall = this->atom->nall(); + + // signal that we need to transfer extra data from the host + + this->atom->extra_data_unavail(); + + numtyp4 *pextra=reinterpret_cast(&(this->atom->extra[0])); + + int n = 0; + int nstride = 1; + for (int i = 0; i < nall; i++) { + int idx = n+i*nstride; + numtyp4 v; + v.x = mdpd_rho[i]; + v.y = 0; + v.z = 0; + v.w = 0; + pextra[idx] = v; + } + this->atom->add_extra_data(); + + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &this->atom->extra, &coeff, &coeff2, + &sp_lj, &sp_sqrt, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &cutsq, &this->_dtinvsqrt, &this->_seed, + &this->_timestep, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &this->atom->extra, &coeff, &coeff2, + &_lj_types, &sp_lj, &sp_sqrt, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &cutsq, &this->_dtinvsqrt, &this->_seed, + &this->_timestep, &this->_threads_per_atom); + } + + this->time_pair.stop(); + return GX; +} + +// --------------------------------------------------------------------------- +// Get the extra data pointers from host +// --------------------------------------------------------------------------- + +template +void MDPDT::get_extra_data(double *host_rho) { + mdpd_rho = host_rho; +} + +template class MDPD; +} diff --git a/lib/gpu/lal_mdpd.cu b/lib/gpu/lal_mdpd.cu new file mode 100644 index 0000000000..6230cb2496 --- /dev/null +++ b/lib/gpu/lal_mdpd.cu @@ -0,0 +1,475 @@ +// ************************************************************************** +// mdpd.cu +// ------------------- +// Trung Dac Nguyen (ORNL) +// +// Device code for acceleration of the mdpd pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : December 2023 +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( vel_tex,float4); +#else +_texture_2d( pos_tex,int4); +_texture_2d( vel_tex,int4); +#endif +#else +#define pos_tex x_ +#define vel_tex v_ +#endif + +#define EPSILON (numtyp)1.0e-10 + +//#define _USE_UNIFORM_SARU_LCG +//#define _USE_UNIFORM_SARU_TEA8 +//#define _USE_GAUSSIAN_SARU_LCG + +#if !defined(_USE_UNIFORM_SARU_LCG) && !defined(_USE_UNIFORM_SARU_TEA8) && !defined(_USE_GAUSSIAN_SARU_LCG) +#define _USE_UNIFORM_SARU_LCG +#endif + +// References: +// 1. Y. Afshar, F. Schmid, A. Pishevar, S. Worley, Comput. Phys. Comm. 184 (2013), 1119–1128. +// 2. C. L. Phillips, J. A. Anderson, S. C. Glotzer, Comput. Phys. Comm. 230 (2011), 7191-7201. +// PRNG period = 3666320093*2^32 ~ 2^64 ~ 10^19 + +#define LCGA 0x4beb5d59 /* Full period 32 bit LCG */ +#define LCGC 0x2600e1f7 +#define oWeylPeriod 0xda879add /* Prime period 3666320093 */ +#define oWeylOffset 0x8009d14b +#define TWO_N32 0.232830643653869628906250e-9f /* 2^-32 */ + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] +// using the inherent LCG, then multiply u with sqrt(3) to "match" +// with a normal random distribution. +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +// Curly brackets to make variables local to the scope. +#ifdef _USE_UNIFORM_SARU_LCG +#define SQRT3 (numtyp)1.7320508075688772935274463 +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + unsigned int v = (state ^ (state>>26)) + wstate; \ + unsigned int s = (signed int)((v^(v>>20))*0x6957f5a7); \ + randnum = SQRT3*(s*TWO_N32*(numtyp)2.0-(numtyp)1.0); \ +} +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns uniformly distributed random numbers u in [-1.0;1.0] using TEA8 +// then multiply u with sqrt(3) to "match" with a normal random distribution +// Afshar et al. mutlplies u in [-0.5;0.5] with sqrt(12) +#ifdef _USE_UNIFORM_SARU_TEA8 +#define SQRT3 (numtyp)1.7320508075688772935274463 +#define k0 0xA341316C +#define k1 0xC8013EA4 +#define k2 0xAD90777D +#define k3 0x7E95761E +#define delta 0x9e3779b9 +#define rounds 8 +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + unsigned int wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + unsigned int sum = 0; \ + for (int i=0; i < rounds; i++) { \ + sum += delta; \ + state += ((wstate<<4) + k0)^(wstate + sum)^((wstate>>5) + k1); \ + wstate += ((state<<4) + k2)^(state + sum)^((state>>5) + k3); \ + } \ + unsigned int v = (state ^ (state>>26)) + wstate; \ + unsigned int s = (signed int)((v^(v>>20))*0x6957f5a7); \ + randnum = SQRT3*(s*TWO_N32*(numtyp)2.0-(numtyp)1.0); \ +} +#endif + +// specifically implemented for steps = 1; high = 1.0; low = -1.0 +// returns two uniformly distributed random numbers r1 and r2 in [-1.0;1.0], +// and uses the polar method (Marsaglia's) to transform to a normal random value +// This is used to compared with CPU DPD using RandMars::gaussian() +#ifdef _USE_GAUSSIAN_SARU_LCG +#define saru(seed1, seed2, seed, timestep, randnum) { \ + unsigned int seed3 = seed + timestep; \ + seed3^=(seed1<<7)^(seed2>>6); \ + seed2+=(seed1>>4)^(seed3>>15); \ + seed1^=(seed2<<9)+(seed3<<8); \ + seed3^=0xA5366B4D*((seed2>>11) ^ (seed1<<1)); \ + seed2+=0x72BE1579*((seed1<<4) ^ (seed3>>16)); \ + seed1^=0x3F38A6ED*((seed3>>5) ^ (((signed int)seed2)>>22)); \ + seed2+=seed1*seed3; \ + seed1+=seed3 ^ (seed2>>2); \ + seed2^=((signed int)seed2)>>17; \ + unsigned int state=0x12345678; \ + unsigned int wstate=12345678; \ + state = 0x79dedea3*(seed1^(((signed int)seed1)>>14)); \ + wstate = (state + seed2) ^ (((signed int)state)>>8); \ + state = state + (wstate*(wstate^0xdddf97f5)); \ + wstate = 0xABCB96F7 + (wstate>>1); \ + unsigned int v, s; \ + numtyp r1, r2, rsq; \ + while (1) { \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + v = (state ^ (state>>26)) + wstate; \ + s = (signed int)((v^(v>>20))*0x6957f5a7); \ + r1 = s*TWO_N32*(numtyp)2.0-(numtyp)1.0; \ + state = LCGA*state + LCGC; \ + wstate = wstate + oWeylOffset+((((signed int)wstate)>>31) & oWeylPeriod); \ + v = (state ^ (state>>26)) + wstate; \ + s = (signed int)((v^(v>>20))*0x6957f5a7); \ + r2 = s*TWO_N32*(numtyp)2.0-(numtyp)1.0; \ + rsq = r1 * r1 + r2 * r2; \ + if (rsq < (numtyp)1.0) break; \ + } \ + numtyp fac = ucl_sqrt((numtyp)-2.0*log(rsq)/rsq); \ + randnum = r2*fac; \ +} +#endif + +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) < (B) ? (B) : (A)) + +// coeff.x = A_att, coeff.y = B_rep, coeff.z = gamma, coeff.w = sigma +// coeff2.x = cut, coeff2.y = cut_r, coeff2.z = cutsq + +__kernel void k_mdpd(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict extra, + const __global numtyp4 *restrict coeff, + const __global numtyp4 *restrict coeff2, + const int lj_types, + const __global numtyp *restrict sp_lj, + const __global numtyp *restrict sp_sqrt, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp4 *restrict v_, + const __global numtyp *restrict cutsq, + const numtyp dtinvsqrt, const int seed, + const int timestep, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + int n_stride; + local_allocate_store_pair(); + + acctyp3 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp energy, virial[6]; + if (EVFLAG) { + energy=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + + if (ii tag2) { + tag1 = jtag; tag2 = itag; + } + + numtyp randnum = (numtyp)0.0; + saru(tag1, tag2, seed, timestep, randnum); + + // conservative force = A_att * wc + B_rep*(rhoi+rhoj)*wc_r + // drag force = -gamma * wr^2 * (delx dot delv) / r + // random force = sigma * wr * rnd * dtinvsqrt; + + numtyp force = A_attij*wc + B_repij*(rhoi+rhoj)*wc_r; + force -= gammaij*wr*wr*dot*rinv; + force += sigmaij*wr*randnum*dtinvsqrt; + force *= factor_dpd*rinv; + + f.x+=delx*force; + f.y+=dely*force; + f.z+=delz*force; + + if (EVFLAG && eflag) { + // unshifted eng of conservative term: + // eng shifted to 0.0 at cutoff + numtyp e = (numtyp)0.5*A_attij*cutij * wr*wr + (numtyp)0.5*B_repij*cut_rij*(rhoi+rhoj)*wc_r*wc_r; + energy+=factor_dpd*e; + } + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + + } // for nbor + } // if ii + store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, + ans,engv); +} + +__kernel void k_mdpd_fast(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict extra, + const __global numtyp4 *restrict coeff_in, + const __global numtyp4 *restrict coeff2_in, + const __global numtyp *restrict sp_lj_in, + const __global numtyp *restrict sp_sqrt_in, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, + const __global numtyp4 *restrict v_, + const __global numtyp *restrict cutsq, + const numtyp dtinvsqrt, const int seed, + const int timestep, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + #ifndef ONETYPE + __local numtyp4 coeff[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp4 coeff2[MAX_SHARED_TYPES*MAX_SHARED_TYPES]; + __local numtyp sp_lj[4]; + __local numtyp sp_sqrt[4]; + if (tid<4) { + sp_lj[tid]=sp_lj_in[tid]; + sp_sqrt[tid]=sp_sqrt_in[tid]; + } + if (tid tag2) { + tag1 = jtag; tag2 = itag; + } + + numtyp randnum = (numtyp)0.0; + saru(tag1, tag2, seed, timestep, randnum); + + // conservative force = A_att * wc + B_rep*(rhoi+rhoj)*wc_r + // drag force = -gamma * wr^2 * (delx dot delv) / r + // random force = sigma * wr * rnd * dtinvsqrt; + + numtyp force = A_attij*wc + B_repij*(rhoi+rhoj)*wc_r; + force -= gammaij*wr*wr*dot*rinv; + force += sigmaij*wr*randnum*dtinvsqrt; + #ifndef ONETYPE + force *= factor_dpd*rinv; + #else + force*=rinv; + #endif + + f.x+=delx*force; + f.y+=dely*force; + f.z+=delz*force; + + if (EVFLAG && eflag) { + // unshifted eng of conservative term: + // eng shifted to 0.0 at cutoff + numtyp e = (numtyp)0.5*A_attij*cutij * wr*wr + (numtyp)0.5*B_repij*cut_rij*(rhoi+rhoj)*wc_r*wc_r; + #ifndef ONETYPE + energy+=factor_dpd*e; + #else + energy+=e; + #endif + } + if (EVFLAG && vflag) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; + } + } + + } // for nbor + } // if ii + store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, + ans,engv); +} + diff --git a/lib/gpu/lal_mdpd.h b/lib/gpu/lal_mdpd.h new file mode 100644 index 0000000000..0e95185714 --- /dev/null +++ b/lib/gpu/lal_mdpd.h @@ -0,0 +1,88 @@ +/*************************************************************************** + mdpd.h + ------------------- + Trung Dac Nguyen (U Chicago) + + Class for acceleration of the mdpd pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#ifndef LAL_MDPD_H +#define LAL_MDPD_H + +#include "lal_base_dpd.h" + +namespace LAMMPS_AL { + +template +class MDPD : public BaseDPD { + public: + MDPD(); + ~MDPD(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, + double **host_A_att, double **host_B_rep, + double **host_gamma, double **host_sigma, + double **host_cut, double **host_cut_r, double *host_special_lj, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, const double gpu_split, + FILE *screen); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + void get_extra_data(double *host_rho); + + // --------------------------- TYPE DATA -------------------------- + + /// coeff.x = A_att, coeff.x = B_rep, coeff.z = gamma, coeff.w = sigma + UCL_D_Vec coeff; + /// coeff2.x = cut, coeff2.y = cut_r, coeff2.z = cutsq + UCL_D_Vec coeff2; + + UCL_D_Vec cutsq; + + /// Special LJ values + UCL_D_Vec sp_lj, sp_sqrt; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + /// pointer to host data + double *mdpd_rho; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_mdpd_ext.cpp b/lib/gpu/lal_mdpd_ext.cpp new file mode 100644 index 0000000000..def6adb1f6 --- /dev/null +++ b/lib/gpu/lal_mdpd_ext.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + mdpd_ext.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Functions for LAMMPS access to mdpd acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_mdpd.h" + +using namespace std; +using namespace LAMMPS_AL; + +static MDPD MDPDMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int mdpd_gpu_init(const int ntypes, double **cutsq, + double **host_A_att, double **host_B_rep, + double **host_gamma, double **host_sigma, + double **host_cut, double **host_cut_r, + double *special_lj, const int inum, + const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen) { + MDPDMF.clear(); + gpu_mode=MDPDMF.device->gpu_mode(); + double gpu_split=MDPDMF.device->particle_split(); + int first_gpu=MDPDMF.device->first_device(); + int last_gpu=MDPDMF.device->last_device(); + int world_me=MDPDMF.device->world_me(); + int gpu_rank=MDPDMF.device->gpu_rank(); + int procs_per_gpu=MDPDMF.device->procs_per_gpu(); + + MDPDMF.device->init_message(screen,"mdpd",first_gpu,last_gpu); + + bool message=false; + if (MDPDMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=MDPDMF.init(ntypes, cutsq, host_A_att, host_B_rep, host_gamma, host_sigma, + host_cut, host_cut_r, special_lj, inum, nall, max_nbors, + maxspecial, cell_size, gpu_split, screen); + + MDPDMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + MDPDMF.estimate_gpu_overhead(); + return init_ok; +} + +void mdpd_gpu_clear() { + MDPDMF.clear(); +} + +int ** mdpd_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v, const double dtinvsqrt, + const int seed, const int timestep, + double *boxlo, double *prd) { + return MDPDMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_v, dtinvsqrt, seed, timestep, boxlo, prd); +} + +void mdpd_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **host_v, const double dtinvsqrt, + const int seed, const int timestep, + const int nlocal, double *boxlo, double *prd) { + MDPDMF.compute(ago, inum_full, nall, host_x, host_type, ilist, numj, + firstneigh, eflag, vflag, eatom, vatom, host_start, cpu_time, success, + tag, host_v, dtinvsqrt, seed, timestep, nlocal, boxlo, prd); +} + +void mdpd_gpu_get_extra_data(double *host_rho) { + MDPDMF.get_extra_data(host_rho); +} + +double mdpd_gpu_bytes() { + return MDPDMF.host_memory_usage(); +} + + diff --git a/lib/gpu/lal_sph_heatconduction.cpp b/lib/gpu/lal_sph_heatconduction.cpp new file mode 100644 index 0000000000..e8e366e93a --- /dev/null +++ b/lib/gpu/lal_sph_heatconduction.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + sph_heatconduction.cpp + ------------------- + Trung Nguyen (U Chicago) + + Class for acceleration of the sph_heatconduction pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "sph_heatconduction_cl.h" +#elif defined(USE_CUDART) +const char *sph_heatconduction=0; +#else +#include "sph_heatconduction_cubin.h" +#endif + +#include "lal_sph_heatconduction.h" +#include +namespace LAMMPS_AL { +#define SPHHeatConductionT SPHHeatConduction + +extern Device device; + +template +SPHHeatConductionT::SPHHeatConduction() : BaseSPH(), _allocated(false) { + _max_dE_size = 0; +} + +template +SPHHeatConductionT::~SPHHeatConduction() { + clear(); +} + +template +int SPHHeatConductionT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int SPHHeatConductionT::init(const int ntypes, + double **host_cutsq, double **host_cut, + double **host_alpha, double* host_mass, + const int dimension, double *host_special_lj, + const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, + const double gpu_split, FILE *_screen) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + + int success; + int extra_fields = 4; // round up to accomodate quadruples of numtyp values + // rho, esph + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,sph_heatconduction,"k_sph_heatconduction", + onetype,extra_fields); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff,host_write,host_alpha, + host_cut, host_cutsq); + + UCL_H_Vec dview_mass(ntypes, *(this->ucl_device), UCL_WRITE_ONLY); + for (int i = 0; i < ntypes; i++) + dview_mass[i] = host_mass[i]; + mass.alloc(ntypes,*(this->ucl_device), UCL_READ_ONLY); + ucl_copy(mass,dview_mass,false); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + + // allocate per-atom array Q + + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + + _max_dE_size=static_cast(static_cast(ef_nall)*1.10); + dE.alloc(_max_dE_size,*(this->ucl_device),UCL_READ_WRITE,UCL_READ_WRITE); + + _dimension = dimension; + + _allocated=true; + this->_max_bytes=coeff.row_bytes()+dE.row_bytes()+sp_lj.row_bytes(); + return 0; +} + +template +void SPHHeatConductionT::clear() { + if (!_allocated) + return; + _allocated=false; + + coeff.clear(); + mass.clear(); + dE.clear(); + sp_lj.clear(); + this->clear_atomic(); +} + +template +double SPHHeatConductionT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(SPHHeatConduction); +} + +template +void SPHHeatConductionT::update_dE(void **dE_ptr) { + *dE_ptr=dE.host.begin(); + dE.update_host(_max_dE_size,false); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int SPHHeatConductionT::loop(const int eflag, const int vflag) { + + int nall = this->atom->nall(); + + // Resize dE array if necessary + if (nall > _max_dE_size) { + _max_dE_size=static_cast(static_cast(nall)*1.10); + dE.resize(_max_dE_size); + } + + // signal that we need to transfer extra data from the host + + this->atom->extra_data_unavail(); + + numtyp4 *pextra=reinterpret_cast(&(this->atom->extra[0])); + + int n = 0; + int nstride = 1; + for (int i = 0; i < nall; i++) { + int idx = n+i*nstride; + numtyp4 v; + v.x = rho[i]; + v.y = esph[i]; + v.z = 0; + v.w = 0; + pextra[idx] = v; + } + this->atom->add_extra_data(); + + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &this->atom->extra, &coeff, &mass, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &dE, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &_dimension, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &this->atom->extra, &coeff, &mass, + &_lj_types, &sp_lj, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &dE, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &_dimension, &this->_threads_per_atom); + } + + this->time_pair.stop(); + return GX; +} + +// --------------------------------------------------------------------------- +// Get the extra data pointers from host +// --------------------------------------------------------------------------- + +template +void SPHHeatConductionT::get_extra_data(double *host_rho, double *host_esph) { + rho = host_rho; + esph = host_esph; +} + +template class SPHHeatConduction; +} diff --git a/lib/gpu/lal_sph_heatconduction.cu b/lib/gpu/lal_sph_heatconduction.cu new file mode 100644 index 0000000000..21c936347a --- /dev/null +++ b/lib/gpu/lal_sph_heatconduction.cu @@ -0,0 +1,253 @@ +// ************************************************************************** +// sph_heatconduction.cu +// --------------------- +// Trung Dac Nguyen (U Chicago) +// +// Device code for acceleration of the sph/heatconduction pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : September 2023 +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( vel_tex,float4); +#else +_texture_2d( pos_tex,int4); +_texture_2d( vel_tex,int4); +#endif +#else +#define pos_tex x_ +#define vel_tex v_ +#endif + +#if (SHUFFLE_AVAIL == 0) + +#define store_dE(dEacc, ii, inum, tid, t_per_atom, offset, dE) \ + if (t_per_atom>1) { \ + simdsync(); \ + simd_reduce_add1(t_per_atom, red_acc, offset, tid, dEacc); \ + } \ + if (offset==0 && ii1) { \ + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ + dEacc += shfl_down(dEacc, s, t_per_atom); \ + } \ + } \ + if (offset==0 && ii +class SPHHeatConduction : public BaseSPH { + public: + SPHHeatConduction(); + ~SPHHeatConduction(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, + double** host_cut, double **host_alpha, double *host_mass, + const int dimension, double *host_special_lj, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + void get_extra_data(double *host_rho, double *host_esph); + + /// copy desph from device to host + void update_dE(void **dE_ptr); + + // --------------------------- TYPE DATA -------------------------- + + /// coeff.x = alpha, coeff.y = cut, coeff.z = cutsq + UCL_D_Vec coeff; + + /// per-type coeffs + UCL_D_Vec mass; + + /// Special LJ values + UCL_D_Vec sp_lj; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + /// Per-atom arrays + UCL_Vector dE; + int _max_dE_size; + + int _dimension; + + /// pointer to host data + double *rho, *esph, *cv; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_sph_heatconduction_ext.cpp b/lib/gpu/lal_sph_heatconduction_ext.cpp new file mode 100644 index 0000000000..92e0e342d2 --- /dev/null +++ b/lib/gpu/lal_sph_heatconduction_ext.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + sph_heatconduction_ext.cpp + -------------------------- + Trung Dac Nguyen (U Chicago) + + Functions for LAMMPS access to sph/heatconduction acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_sph_heatconduction.h" + +using namespace std; +using namespace LAMMPS_AL; + +static SPHHeatConduction SPHHeatConductionMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int sph_heatconduction_gpu_init(const int ntypes, double **cutsq, double** host_cut, + double **host_alpha, double* host_mass, const int dimension, + double *special_lj, const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen) { + SPHHeatConductionMF.clear(); + gpu_mode=SPHHeatConductionMF.device->gpu_mode(); + double gpu_split=SPHHeatConductionMF.device->particle_split(); + int first_gpu=SPHHeatConductionMF.device->first_device(); + int last_gpu=SPHHeatConductionMF.device->last_device(); + int world_me=SPHHeatConductionMF.device->world_me(); + int gpu_rank=SPHHeatConductionMF.device->gpu_rank(); + int procs_per_gpu=SPHHeatConductionMF.device->procs_per_gpu(); + + SPHHeatConductionMF.device->init_message(screen,"sph_heatconduction",first_gpu,last_gpu); + + bool message=false; + if (SPHHeatConductionMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=SPHHeatConductionMF.init(ntypes, cutsq, host_cut, host_alpha, host_mass, + dimension, special_lj, inum, nall, max_nbors, maxspecial, + cell_size, gpu_split, screen); + + SPHHeatConductionMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + SPHHeatConductionMF.estimate_gpu_overhead(); + return init_ok; +} + +void sph_heatconduction_gpu_clear() { + SPHHeatConductionMF.clear(); +} + +int ** sph_heatconduction_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *host_tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v) { + return SPHHeatConductionMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, host_tag, nspecial, special, eflag, vflag, + eatom, vatom, host_start, ilist, jnum, cpu_time, success, + host_v); +} + +void sph_heatconduction_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *host_tag, + double **host_v, const int nlocal) { + SPHHeatConductionMF.compute(ago, inum_full, nall, host_x, host_type, ilist, numj, + firstneigh, eflag, vflag, eatom, vatom, host_start, cpu_time, success, + host_tag, host_v, nlocal); +} + +void sph_heatconduction_gpu_get_extra_data(double *host_rho, double *host_esph) { + SPHHeatConductionMF.get_extra_data(host_rho, host_esph); +} + +void sph_heatconduction_gpu_update_dE(void **dE_ptr) { + SPHHeatConductionMF.update_dE(dE_ptr); +} + +double sph_heatconduction_gpu_bytes() { + return SPHHeatConductionMF.host_memory_usage(); +} diff --git a/lib/gpu/lal_sph_lj.cpp b/lib/gpu/lal_sph_lj.cpp new file mode 100644 index 0000000000..66c2a5c302 --- /dev/null +++ b/lib/gpu/lal_sph_lj.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + sph_lj.cpp + ------------------- + Trung Nguyen (U Chicago) + + Class for acceleration of the sph_lj pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : September 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "sph_lj_cl.h" +#elif defined(USE_CUDART) +const char *sph_lj=0; +#else +#include "sph_lj_cubin.h" +#endif + +#include "lal_sph_lj.h" +#include +namespace LAMMPS_AL { +#define SPHLJT SPHLJ + +extern Device device; + +template +SPHLJT::SPHLJ() : BaseSPH(), _allocated(false) { + _max_drhoE_size = 0; +} + +template +SPHLJT::~SPHLJ() { + clear(); +} + +template +int SPHLJT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int SPHLJT::init(const int ntypes, + double **host_cutsq, double **host_cut, + double **host_viscosity, double* host_mass, + const int dimension, double *host_special_lj, + const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, + const double gpu_split, FILE *_screen) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + + int success; + int extra_fields = 4; // round up to accomodate quadruples of numtyp values + // rho, cv + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,sph_lj,"k_sph_lj",onetype,extra_fields); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff,host_write,host_viscosity, + host_cut, host_cutsq); + + UCL_H_Vec dview_mass(ntypes, *(this->ucl_device), UCL_WRITE_ONLY); + for (int i = 0; i < ntypes; i++) + dview_mass[i] = host_mass[i]; + mass.alloc(ntypes,*(this->ucl_device), UCL_READ_ONLY); + ucl_copy(mass,dview_mass,false); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + + // allocate per-atom array Q + + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + + _max_drhoE_size=static_cast(static_cast(ef_nall)*1.10); + drhoE.alloc(_max_drhoE_size*2,*(this->ucl_device),UCL_READ_WRITE,UCL_READ_WRITE); + + _dimension = dimension; + + _allocated=true; + this->_max_bytes=coeff.row_bytes()+drhoE.row_bytes()+sp_lj.row_bytes(); + return 0; +} + +template +void SPHLJT::clear() { + if (!_allocated) + return; + _allocated=false; + + coeff.clear(); + mass.clear(); + drhoE.clear(); + sp_lj.clear(); + this->clear_atomic(); +} + +template +double SPHLJT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(SPHLJ); +} + +template +void SPHLJT::update_drhoE(void **drhoE_ptr) { + *drhoE_ptr=drhoE.host.begin(); + drhoE.update_host(_max_drhoE_size*2,false); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int SPHLJT::loop(const int eflag, const int vflag) { + + int nall = this->atom->nall(); + + // Resize drhoE array if necessary + if (nall > _max_drhoE_size) { + _max_drhoE_size=static_cast(static_cast(nall)*1.10); + drhoE.resize(_max_drhoE_size*2); + } + + // signal that we need to transfer extra data from the host + + this->atom->extra_data_unavail(); + + numtyp4 *pextra=reinterpret_cast(&(this->atom->extra[0])); + + int n = 0; + int nstride = 1; + for (int i = 0; i < nall; i++) { + int idx = n+i*nstride; + numtyp4 v; + v.x = rho[i]; + v.y = esph[i]; + v.z = cv[i]; + v.w = 0; + pextra[idx] = v; + } + this->atom->add_extra_data(); + + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &this->atom->extra, &coeff, &mass, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &drhoE, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &_dimension, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &this->atom->extra, &coeff, &mass, + &_lj_types, &sp_lj, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &drhoE, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &_dimension, &this->_threads_per_atom); + } + + this->time_pair.stop(); + return GX; +} + +// --------------------------------------------------------------------------- +// Get the extra data pointers from host +// --------------------------------------------------------------------------- + +template +void SPHLJT::get_extra_data(double *host_rho, double *host_esph, double *host_cv) { + rho = host_rho; + esph = host_esph; + cv = host_cv; +} + +template class SPHLJ; +} diff --git a/lib/gpu/lal_sph_lj.cu b/lib/gpu/lal_sph_lj.cu new file mode 100644 index 0000000000..23863b5e28 --- /dev/null +++ b/lib/gpu/lal_sph_lj.cu @@ -0,0 +1,426 @@ +// ************************************************************************** +// sph_lj.cu +// ------------------- +// Trung Dac Nguyen (U Chicago) +// +// Device code for acceleration of the sph/lj pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : September 2023 +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( vel_tex,float4); +#else +_texture_2d( pos_tex,int4); +_texture_2d( vel_tex,int4); +#endif +#else +#define pos_tex x_ +#define vel_tex v_ +#endif + +#if (SHUFFLE_AVAIL == 0) + +#define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, drhoE) \ + if (t_per_atom>1) { \ + simdsync(); \ + simd_reduce_add2(t_per_atom, red_acc, offset, tid, \ + drhoEacc.x, drhoEacc.y); \ + } \ + if (offset==0 && ii1) { \ + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ + drhoEacc.x += shfl_down(drhoEacc.x, s, t_per_atom); \ + drhoEacc.y += shfl_down(drhoEacc.y, s, t_per_atom); \ + } \ + } \ + if (offset==0 && ii (numtyp)0.0) { + pc[1] = ucl_sqrt(csq); // soundspeed + } else { + pc[1] = (numtyp)0.0; + } +} + + +__kernel void k_sph_lj(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict extra, + const __global numtyp4 *restrict coeff, + const __global numtyp *restrict mass, + const int lj_types, + const __global numtyp *restrict sp_lj, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp3 *restrict ans, + __global acctyp *restrict engv, + __global acctyp2 *restrict drhoE, + const int eflag, const int vflag, + const int inum, const int nbor_pitch, + const __global numtyp4 *restrict v_, + const int dimension, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + int n_stride; + local_allocate_store_pair(); + + acctyp3 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp energy, virial[6]; + if (EVFLAG) { + energy=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + acctyp2 drhoEacc; + drhoEacc.x = drhoEacc.x = (acctyp)0; + + if (ii +class SPHLJ : public BaseSPH { + public: + SPHLJ(); + ~SPHLJ(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, + double** host_cut, double **host_viscosity, double *host_mass, + const int dimension, + double *host_special_lj, const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, const double gpu_split, + FILE *screen); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + void get_extra_data(double *host_rho, double *host_esph, + double *host_cv); + + /// copy drho and desph from device to host + void update_drhoE(void **drhoE_ptr); + + // --------------------------- TYPE DATA -------------------------- + + /// coeff.x = viscosity, coeff.y = cut, coeff.z = cutsq + UCL_D_Vec coeff; + + /// per-type coeffs + UCL_D_Vec mass; + + /// Special LJ values + UCL_D_Vec sp_lj; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + /// Per-atom arrays + UCL_Vector drhoE; + int _max_drhoE_size; + + int _dimension; + + /// pointer to host data + double *rho, *esph, *cv; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_sph_lj_ext.cpp b/lib/gpu/lal_sph_lj_ext.cpp new file mode 100644 index 0000000000..55f85c030e --- /dev/null +++ b/lib/gpu/lal_sph_lj_ext.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + sph_lj_ext.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Functions for LAMMPS access to sph/lj acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_sph_lj.h" + +using namespace std; +using namespace LAMMPS_AL; + +static SPHLJ SPHLJMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int sph_lj_gpu_init(const int ntypes, double **cutsq, double** host_cut, + double **host_viscosity, double* host_mass, const int dimension, + double *special_lj, const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen) { + SPHLJMF.clear(); + gpu_mode=SPHLJMF.device->gpu_mode(); + double gpu_split=SPHLJMF.device->particle_split(); + int first_gpu=SPHLJMF.device->first_device(); + int last_gpu=SPHLJMF.device->last_device(); + int world_me=SPHLJMF.device->world_me(); + int gpu_rank=SPHLJMF.device->gpu_rank(); + int procs_per_gpu=SPHLJMF.device->procs_per_gpu(); + + SPHLJMF.device->init_message(screen,"sph_lj",first_gpu,last_gpu); + + bool message=false; + if (SPHLJMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=SPHLJMF.init(ntypes, cutsq, host_cut, host_viscosity, host_mass, + dimension, special_lj, inum, nall, max_nbors, maxspecial, + cell_size, gpu_split, screen); + + SPHLJMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + SPHLJMF.estimate_gpu_overhead(); + return init_ok; +} + +void sph_lj_gpu_clear() { + SPHLJMF.clear(); +} + +int ** sph_lj_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *host_tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v) { + return SPHLJMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, host_tag, nspecial, special, eflag, vflag, + eatom, vatom, host_start, ilist, jnum, cpu_time, success, + host_v); +} + +void sph_lj_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *host_tag, + double **host_v, const int nlocal) { + SPHLJMF.compute(ago, inum_full, nall, host_x, host_type, ilist, numj, + firstneigh, eflag, vflag, eatom, vatom, host_start, cpu_time, success, + host_tag, host_v, nlocal); +} + +void sph_lj_gpu_get_extra_data(double *host_rho, double *host_esph, double *host_cv) { + SPHLJMF.get_extra_data(host_rho, host_esph, host_cv); +} + +void sph_lj_gpu_update_drhoE(void **drhoE_ptr) { + SPHLJMF.update_drhoE(drhoE_ptr); +} + +double sph_lj_gpu_bytes() { + return SPHLJMF.host_memory_usage(); +} diff --git a/lib/gpu/lal_sph_taitwater.cpp b/lib/gpu/lal_sph_taitwater.cpp new file mode 100644 index 0000000000..7a584d435e --- /dev/null +++ b/lib/gpu/lal_sph_taitwater.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** + sph_taitwater.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Class for acceleration of the sph/taitwater pair style. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "sph_taitwater_cl.h" +#elif defined(USE_CUDART) +const char *sph_taitwater=0; +#else +#include "sph_taitwater_cubin.h" +#endif + +#include "lal_sph_taitwater.h" +#include +namespace LAMMPS_AL { +#define SPHTaitwaterT SPHTaitwater + +extern Device device; + +template +SPHTaitwaterT::SPHTaitwater() : BaseSPH(), _allocated(false) { + _max_drhoE_size = 0; +} + +template +SPHTaitwaterT::~SPHTaitwater() { + clear(); +} + +template +int SPHTaitwaterT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int SPHTaitwaterT::init(const int ntypes, double **host_cutsq, + double **host_cut, double **host_viscosity, + double* host_mass, double* host_rho0, + double* host_soundspeed, double* host_B, const int dimension, + double *host_special_lj, const int nlocal, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, + const double gpu_split, FILE *_screen) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + + int success; + int extra_fields = 4; // round up to accomodate quadruples of numtyp values + // rho + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size, + gpu_split,_screen,sph_taitwater,"k_sph_taitwater", + onetype,extra_fields); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,coeff,host_write,host_viscosity, + host_cut, host_cutsq); + + UCL_H_Vec dview_coeff2(ntypes, *(this->ucl_device), UCL_WRITE_ONLY); + for (int i = 0; i < ntypes; i++) { + dview_coeff2[i].x = host_mass[i]; + dview_coeff2[i].y = host_rho0[i]; + dview_coeff2[i].z = host_soundspeed[i]; + dview_coeff2[i].w = host_B[i]; + } + coeff2.alloc(ntypes,*(this->ucl_device), UCL_READ_ONLY); + ucl_copy(coeff2,dview_coeff2,false); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + + // allocate per-atom array Q + + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + + _max_drhoE_size=static_cast(static_cast(ef_nall)*1.10); + drhoE.alloc(_max_drhoE_size*2,*(this->ucl_device),UCL_READ_WRITE,UCL_READ_WRITE); + + _dimension = dimension; + + _allocated=true; + this->_max_bytes=coeff.row_bytes()+coeff2.row_bytes()+drhoE.row_bytes()+sp_lj.row_bytes(); + return 0; +} + +template +void SPHTaitwaterT::clear() { + if (!_allocated) + return; + _allocated=false; + + coeff.clear(); + coeff2.clear(); + drhoE.clear(); + sp_lj.clear(); + this->clear_atomic(); +} + +template +double SPHTaitwaterT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(SPHTaitwater); +} + +template +void SPHTaitwaterT::update_drhoE(void **drhoE_ptr) { + *drhoE_ptr=drhoE.host.begin(); + drhoE.update_host(_max_drhoE_size*2,false); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int SPHTaitwaterT::loop(const int eflag, const int vflag) { + + int nall = this->atom->nall(); + + // Resize drhoE array if necessary + if (nall > _max_drhoE_size) { + _max_drhoE_size=static_cast(static_cast(nall)*1.10); + drhoE.resize(_max_drhoE_size*2); + } + + // signal that we need to transfer extra data from the host + + this->atom->extra_data_unavail(); + + numtyp4 *pextra=reinterpret_cast(&(this->atom->extra[0])); + + int n = 0; + int nstride = 1; + for (int i = 0; i < nall; i++) { + int idx = n+i*nstride; + numtyp4 v; + v.x = rho[i]; + v.y = 0; + v.z = 0; + v.w = 0; + pextra[idx] = v; + } + this->atom->add_extra_data(); + + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &this->atom->extra, &coeff, &coeff2, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &drhoE, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &_dimension, &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &this->atom->extra, &coeff, &coeff2, + &_lj_types, &sp_lj, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &drhoE, &eflag, &vflag, + &ainum, &nbor_pitch, &this->atom->v, &_dimension, &this->_threads_per_atom); + } + + this->time_pair.stop(); + return GX; +} + +// --------------------------------------------------------------------------- +// Get the extra data pointers from host +// --------------------------------------------------------------------------- + +template +void SPHTaitwaterT::get_extra_data(double *host_rho) { + rho = host_rho; +} + +template class SPHTaitwater; +} diff --git a/lib/gpu/lal_sph_taitwater.cu b/lib/gpu/lal_sph_taitwater.cu new file mode 100644 index 0000000000..708d3ae43b --- /dev/null +++ b/lib/gpu/lal_sph_taitwater.cu @@ -0,0 +1,377 @@ +// ************************************************************************** +// sph_taitwater.cu +// ------------------- +// Trung Dac Nguyen (U Chicago) +// +// Device code for acceleration of the sph/taitwater pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : September 2023 +// email : ndactrung@gmail.com +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +_texture( vel_tex,float4); +#else +_texture_2d( pos_tex,int4); +_texture_2d( vel_tex,int4); +#endif +#else +#define pos_tex x_ +#define vel_tex v_ +#endif + +#if (SHUFFLE_AVAIL == 0) + +#define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, drhoE) \ + if (t_per_atom>1) { \ + simdsync(); \ + simd_reduce_add2(t_per_atom, red_acc, offset, tid, \ + drhoEacc.x, drhoEacc.y); \ + } \ + if (offset==0 && ii1) { \ + for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ + drhoEacc.x += shfl_down(drhoEacc.x, s, t_per_atom); \ + drhoEacc.y += shfl_down(drhoEacc.y, s, t_per_atom); \ + } \ + } \ + if (offset==0 && ii +class SPHTaitwater : public BaseSPH { + public: + SPHTaitwater(); + ~SPHTaitwater(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, + double** host_cut, double **host_viscosity, double *host_mass, + double* host_rho0, double* host_soundspeed, double* host_B, + const int dimension, double *host_special_lj, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + void get_extra_data(double *host_rho); + + /// copy drho and desph from device to host + void update_drhoE(void **drhoE_ptr); + + // --------------------------- TYPE DATA -------------------------- + + /// per-pair coeffs: coeff.x = viscosity, coeff.y = cut, coeff.z = cutsq + UCL_D_Vec coeff; + + /// per-type coeffs + UCL_D_Vec coeff2; + + /// Special LJ values + UCL_D_Vec sp_lj; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + /// Per-atom arrays + UCL_Vector drhoE; + int _max_drhoE_size; + + int _dimension; + + /// pointer to host data + double *rho; + + private: + bool _allocated; + int loop(const int eflag, const int vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_sph_taitwater_ext.cpp b/lib/gpu/lal_sph_taitwater_ext.cpp new file mode 100644 index 0000000000..9d125a6395 --- /dev/null +++ b/lib/gpu/lal_sph_taitwater_ext.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + sph_taitwater_ext.cpp + ------------------- + Trung Dac Nguyen (U Chicago) + + Functions for LAMMPS access to sph taitwater acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : December 2023 + email : ndactrung@gmail.com + ***************************************************************************/ + +#include +#include +#include + +#include "lal_sph_taitwater.h" + +using namespace std; +using namespace LAMMPS_AL; + +static SPHTaitwater SPHTaitwaterMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int sph_taitwater_gpu_init(const int ntypes, double **cutsq, double** host_cut, + double **host_viscosity, double* host_mass, + double* host_rho0, double* host_soundspeed, double* host_B, + const int dimension, double *special_lj, + const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen) { + SPHTaitwaterMF.clear(); + gpu_mode=SPHTaitwaterMF.device->gpu_mode(); + double gpu_split=SPHTaitwaterMF.device->particle_split(); + int first_gpu=SPHTaitwaterMF.device->first_device(); + int last_gpu=SPHTaitwaterMF.device->last_device(); + int world_me=SPHTaitwaterMF.device->world_me(); + int gpu_rank=SPHTaitwaterMF.device->gpu_rank(); + int procs_per_gpu=SPHTaitwaterMF.device->procs_per_gpu(); + + SPHTaitwaterMF.device->init_message(screen,"sph_taitwater",first_gpu,last_gpu); + + bool message=false; + if (SPHTaitwaterMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=SPHTaitwaterMF.init(ntypes, cutsq, host_cut, host_viscosity, host_mass, + host_rho0, host_soundspeed, host_B, dimension, + special_lj, inum, nall, max_nbors, maxspecial, + cell_size, gpu_split, screen); + + SPHTaitwaterMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; iserialize_init(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + SPHTaitwaterMF.estimate_gpu_overhead(); + return init_ok; +} + +void sph_taitwater_gpu_clear() { + SPHTaitwaterMF.clear(); +} + +int ** sph_taitwater_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *host_tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v) { + return SPHTaitwaterMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, host_tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success, + host_v); +} + +void sph_taitwater_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *host_tag, + double **host_v, const int nlocal) { + SPHTaitwaterMF.compute(ago, inum_full, nall, host_x, host_type, ilist, numj, + firstneigh, eflag, vflag, eatom, vatom, host_start, cpu_time, success, + host_tag, host_v, nlocal); +} + +void sph_taitwater_gpu_get_extra_data(double *host_rho) { + SPHTaitwaterMF.get_extra_data(host_rho); +} + +void sph_taitwater_gpu_update_drhoE(void **drhoE_ptr) { + SPHTaitwaterMF.update_drhoE(drhoE_ptr); +} + +double sph_taitwater_gpu_bytes() { + return SPHTaitwaterMF.host_memory_usage(); +} diff --git a/lib/pace/Makefile b/lib/pace/Makefile index 5a1588ef93..a7ac753d28 100644 --- a/lib/pace/Makefile +++ b/lib/pace/Makefile @@ -21,7 +21,7 @@ OBJ = $(SRC:.cpp=.o) # ------ SETTINGS ------ -CXXFLAGS = -O3 -fPIC -Isrc/ML-PACE -I$(YAML_CPP_INC) -I$(WIGNER_CPP_INC) -I$(CNPY_CPP_INC) -DEXTRA_C_PROJECTIONS +CXXFLAGS = -O3 -fPIC -Isrc/ML-PACE -I$(YAML_CPP_INC) -I$(WIGNER_CPP_INC) -I$(CNPY_CPP_INC) -DEXTRA_C_PROJECTIONS -DCOMPUTE_B_GRAD ARCHIVE = ar ARCHFLAG = -rc diff --git a/lib/pace/Makefile.lammps b/lib/pace/Makefile.lammps index 6411e49a07..e221918056 100644 --- a/lib/pace/Makefile.lammps +++ b/lib/pace/Makefile.lammps @@ -1,3 +1,3 @@ -pace_SYSINC =-I../../lib/pace/src/ML-PACE -I../../lib/pace/src/yaml-cpp/include -I../../lib/pace/src/wigner-cpp/include -DEXTRA_C_PROJECTIONS +pace_SYSINC =-I../../lib/pace/src/ML-PACE -I../../lib/pace/src/yaml-cpp/include -I../../lib/pace/src/wigner-cpp/include -DEXTRA_C_PROJECTIONS -DCOMPUTE_B_GRAD pace_SYSLIB = -L../../lib/pace/ -lpace -L../../lib/pace/src/yaml-cpp/ -lyaml-cpp pace_SYSPATH = diff --git a/potentials/CBNOH.aip.water.2dm b/potentials/CBNOH.aip.water.2dm new file mode 100755 index 0000000000..83205c354f --- /dev/null +++ b/potentials/CBNOH.aip.water.2dm @@ -0,0 +1,58 @@ +# DATE: 2023-12-20 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com +# CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127(18), 8704 (2023). +# CITATION: Z. Feng, ..., and W. Ouyang, Langmuir 39(50), 18198-18207 (2023). +# Anisotropic Potential (AIP) for water/graphene and water/hBN heterojunctions +# The parameters below are fitted against the PBE + MBD-NL (graphene/water) and SCAN (hBN/water) DFT reference data. + +# The parameters for bilayer graphene/graphene, graphene/hBN and hBN/hBN junctions are taken from +# CITATION: Ouyang, Mandelli, Urbakh, Hod, Nano Letters 18, 6009-6016 (2018). +# +# -------------------Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ +# beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut +# +# For water-graphene +C Ow 5.453696 6.181724 1.250255 3.349092 0.687806 9.057065 1.232495 2.775772 100226.555031 1.0 2.0 +C Hw 2.553809 9.686644 1.964892 41.776171 -16.300128 9.015685 0.744155 2.415456 7409.128564 1.0 2.0 +Ow C 5.453696 6.181724 1.250255 3.349092 0.687806 9.057065 1.232495 2.775772 100226.555031 1.0 1.2 +Hw C 2.553809 9.686644 1.964892 41.776171 -16.300128 9.015685 0.744155 2.415456 7409.128564 1.0 1.2 + +# For water-hBN +N Ow 3.530598 16.377816 1.285374 1.717537 1.339337 24.797794 0.771411 3.928357 33589.850651 1.0 2.0 +N Hw 4.029390 5.360546 0.950352 15.945549 -1.486701 10.797276 1.352684 2.293775 41247.181447 1.0 2.0 +B Ow 3.907514 7.842519 2.380078 32.122737 1.190485 17.482482 0.788174 2.368217 139539.370785 1.0 2.0 +B Hw 3.804966 2.356248 1.114761 9.193309 -5.922514 9.000572 1.334703 1.746122 43796.489158 1.0 2.0 +Ow N 3.530598 16.377816 1.285374 1.717537 1.339337 24.797794 0.771411 3.928357 33589.850651 1.0 1.2 +Hw N 4.029390 5.360546 0.950352 15.945549 -1.486701 10.797276 1.352684 2.293775 41247.181447 1.0 1.2 +Ow B 3.907514 7.842519 2.380078 32.122737 1.190485 17.482482 0.788174 2.368217 139539.370785 1.0 1.2 +Hw B 3.804966 2.356248 1.114761 9.193309 -5.922514 9.000572 1.334703 1.746122 43796.489158 1.0 1.2 + +# For graphene and hydrocarbons +C C 3.205843 7.511126 1.235334 1.528338E-5 37.530428 15.499947 0.7954443 3.681440 25.714535E3 1.0 2.0 +H H 3.974540 6.53799 1.080633 0.6700556 0.8333833 15.022371 0.7490632 2.767223 1.6159581E3 1.0 1.2 +C H 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 +H C 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 + +# For hBN +B B 3.143737 9.825139 1.936405 2.7848400 14.495957 15.199263 0.7834022 3.682950 49.498013E3 1.0 2.0 +N N 3.443196 7.084490 1.747349 2.9139991 46.508553 15.020370 0.8008370 3.551843 14.810151E3 1.0 2.0 +B N 3.295257 7.224311 2.872667 1.3715032 0.4347152 14.594578 0.8044028 3.765728 24.669996E3 1.0 2.0 +B H 2.718657 9.214551 3.273063 14.015714 14.760509 15.084752 0.7768383 3.640866 7.9642467E3 1.0 1.5 +N B 3.295257 7.224311 2.872667 1.3715032 0.4347152 14.594578 0.8044028 3.765728 24.669996E3 1.0 2.0 +H B 2.718657 9.214551 3.273063 14.015714 14.760509 15.084752 0.7768383 3.640866 7.9642467E3 1.0 1.5 + +# For graphene-hBN +C B 3.303662 10.54415 2.926741 16.719972 0.3571734 15.305254 0.7001581 3.097327 30.162869E3 1.0 2.0 +C N 3.253564 8.825921 1.059550 18.344740 21.913573 15.000000 0.7234983 3.013117 19.063095E3 1.0 2.0 +B C 3.303662 10.54415 2.926741 16.719972 0.3571734 15.305254 0.7001581 3.097327 30.162869E3 1.0 2.0 +N C 3.253564 8.825921 1.059550 18.344740 21.913573 15.000000 0.7234983 3.013117 19.063095E3 1.0 2.0 + +# The AIPs for other elements are turned off +H Ow 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 +H Hw 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 +Ow H 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 +Hw H 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 + +Ow Ow 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 +Hw Hw 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 +Ow Hw 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 +Hw Ow 5.453696 6.181724 1.250255 0.000000 0.000000 9.057065 1.232495 2.775772 0.000000 1.0 1.2 diff --git a/potentials/COH.aip.water.2dm b/potentials/COH.aip.water.2dm deleted file mode 100644 index 5325399abe..0000000000 --- a/potentials/COH.aip.water.2dm +++ /dev/null @@ -1,28 +0,0 @@ -# DATE: 2022-12-02 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). -# Anisotropic Interfacial Potential (AIP) parameters for water/graphene heterojunctions -# The parameters below are fitted against the PBE + MBD-NL DFT reference data from 2.5 A to 15 A. -# -# ----------------- Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ -# beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut -# For graphene and hydrocarbons -C C 3.205843 7.511126 1.235334 1.528338E-5 37.530428 15.499947 0.7954443 3.681440 25.714535E3 1.0 2.0 -H H 3.974540 6.53799 1.080633 0.6700556 0.8333833 15.022371 0.7490632 2.767223 1.6159581E3 1.0 1.2 -C H 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 -H C 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 - -# For water-graphene -C Ow 5.45369612 6.18172364 1.25025450 3.34909245 0.68780636 9.05706482 1.23249498 2.77577173 100226.55503127 1.0 2.0 -C Hw 2.55380862 9.68664390 1.96489198 41.77617053 -16.30012807 9.01568534 0.74415463 2.41545571 7409.12856378 1.0 2.0 -Ow C 5.45369612 6.18172364 1.25025450 3.34909245 0.68780636 9.05706482 1.23249498 2.77577173 100226.55503127 1.0 1.2 -Hw C 2.55380862 9.68664390 1.96489198 41.77617053 -16.30012807 9.01568534 0.74415463 2.41545571 7409.12856378 1.0 1.2 - -# # The ILPs for other systems are set to zero -H Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -H Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -Ow H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -Hw H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 - -Ow Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -Hw Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -Ow Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -Hw Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 diff --git a/potentials/PSiO.nb3b.screened b/potentials/PSiO.nb3b.screened new file mode 100644 index 0000000000..445da13e7a --- /dev/null +++ b/potentials/PSiO.nb3b.screened @@ -0,0 +1,41 @@ +# DATE: 2023-10-30 UNITS: metal CONTRIBUTOR: Federica Lodesani CITATION: Bertani, Menziani, Pedone (2021). Physical Review Materials, 5(4), 045602 +# +# Multiple entries can be added to this file, LAMMPS only reads the ones it needs +# +# These entries are in LAMMPS "metal" units: +# +# Format of a single entry (one or more lines): +# element 1 (central atom), element 2, element 3, +# k_theta, theta_0, rho, cutoff +# +# (ijj)-->determines cutoff for i-j distance +# (jik)-->determines k, theta_0 for i-j-k angle term +# +# i j k K theta0 rho cutoff +O P P 32.5 109.47 1.0 3.3 +O P Si 60.0 109.47 1.0 0.000 +O P O 0.000 0.000 1.0 0.000 +O Si P 60.0 109.47 1.0 0.000 +O Si Si 12.5 109.47 1.0 3.3 +O Si O 0.000 0.000 1.0 0.000 +O O P 0.000 0.000 1.0 0.000 +O O Si 0.000 0.000 1.0 0.000 +O O O 0.000 0.000 1.0 0.000 +P P P 0.000 0.000 1.0 0.000 +P P Si 0.000 0.000 1.0 0.000 +P P O 0.000 0.000 1.0 0.000 +P Si P 0.000 0.000 1.0 0.000 +P Si Si 0.000 0.000 1.0 0.000 +P Si O 0.000 0.000 1.0 0.000 +P O P 0.000 0.000 1.0 0.000 +P O Si 0.000 0.000 1.0 0.000 +P O O 0.000 0.000 1.0 0.000 +Si P P 0.000 0.000 1.0 0.000 +Si P Si 0.000 0.000 1.0 0.000 +Si P O 0.000 0.000 1.0 0.000 +Si Si P 0.000 0.000 1.0 0.000 +Si Si Si 0.000 0.000 1.0 0.000 +Si Si O 0.000 0.000 1.0 0.000 +Si O P 0.000 0.000 1.0 0.000 +Si O Si 0.000 0.000 1.0 0.000 +Si O O 0.000 0.000 1.0 0.000 diff --git a/potentials/TMD.ILP b/potentials/TMD.ILP new file mode 100644 index 0000000000..18563199c9 --- /dev/null +++ b/potentials/TMD.ILP @@ -0,0 +1,25 @@ +# DATE: 2021-12-02 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com +# CITATION: W. Ouyang, et al., J. Chem. Theory Comput. 17, 7237 (2021). +# CITATION: W. Jiang, et al., J. Phys. Chem. A, 127, 46, 9820–9830 (2023). +# Interlayer Potential (ILP) for bilayer and bulk Group-VI Transition Metal Dichalcogenides. +# The parameters below are fitted against the HSE + MBD-NL DFT reference data. +# +# -------------------- Repulsion Potential -------------------++++++++++++++++ Vdw Potential ++++++++++++++++********* +# beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut +Mo Mo 5.579450 9.377662 2.027222 144.151775 97.978570 89.437597 2.059031 5.122055 491850.316195 1.0 4.0 +W W 5.530854 6.624992 1.983208 0.271792 140.174059 107.392585 1.356333 4.437591 691850.243962 1.0 4.0 +S S 3.161402 8.093263 1.953140 4.586764 118.065466 58.809416 0.215367 4.299600 148811.243409 1.0 4.0 +Se Se 3.938627 10.515924 2.415783 3.012583 22.400612 116.864517 0.151121 5.884241 112506.195626 1.0 4.0 +Mo W 5.412298 8.647128 2.108665 51.177950 184.342860 201.281256 2.547743 2.492287 99996.913401 1.0 4.0 +Mo S 3.627152 19.971375 7.585031 76.101931 3.317496 45.720328 0.947470 4.410425 150597.857716 1.0 4.0 +Mo Se 6.196447 4.844134 14.362005 7.407221 0.058823 27.156223 0.976771 3.979186 786029.840651 1.0 4.0 +W S 3.680136 11.163004 32.254117 110.019679 79.381335 138.340438 0.900750 8.875776 250600.809034 1.0 4.0 +W Se 3.559392 20.638856 1.202717 20.478669 197.422484 10.005271 1.052738 3.815817 288321.561114 1.0 4.0 +S Se 2.820092 7.491151 1.933323 141.532559 293.127817 90.470904 0.390492 4.170885 117688.987069 1.0 4.0 +# Symmetric Atom Pair +W Mo 5.412298 8.647128 2.108665 51.177950 184.342860 201.281256 2.547743 2.492287 99996.913401 1.0 4.0 +S Mo 3.627152 19.971375 7.585031 76.101931 3.317496 45.720328 0.947470 4.410425 150597.857716 1.0 4.0 +Se Mo 6.196447 4.844134 14.362005 7.407221 0.058823 27.156223 0.976771 3.979186 786029.840651 1.0 4.0 +S W 3.680136 11.163004 32.254117 110.019679 79.381335 138.340438 0.900750 8.875776 250600.809034 1.0 4.0 +Se W 3.559392 20.638856 1.202717 20.478669 197.422484 10.005271 1.052738 3.815817 288321.561114 1.0 4.0 +Se S 2.820092 7.491151 1.933323 141.532559 293.127817 90.470904 0.390492 4.170885 117688.987069 1.0 4.0 diff --git a/src/.gitignore b/src/.gitignore index e2c9fa6d5b..112a1486f7 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -100,6 +100,8 @@ /lepton_utils.cpp /lepton_utils.h +/compute_pace.cpp +/compute_pace.h /pair_pace.cpp /pair_pace.h /pair_pace_extrapolation.cpp @@ -631,8 +633,12 @@ /compute_ptm_atom.h /compute_rattlers_atom.cpp /compute_rattlers_atom.h +/compute_reaxff_atom.cpp +/compute_reaxff_atom.h /compute_rigid_local.cpp /compute_rigid_local.h +/compute_slcsa_atom.cpp +/compute_slcsa_atom.h /compute_smd_triangle_vertices.cpp /compute_smd_triangle_vertices.h /compute_spec_atom.cpp diff --git a/src/DRUDE/fix_tgnh_drude.cpp b/src/DRUDE/fix_tgnh_drude.cpp index 987408fe63..b23acd349b 100644 --- a/src/DRUDE/fix_tgnh_drude.cpp +++ b/src/DRUDE/fix_tgnh_drude.cpp @@ -1076,7 +1076,6 @@ void FixTGNHDrude::couple() void FixTGNHDrude::remap() { - int i; double oldlo,oldhi; double expfac; diff --git a/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp b/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp new file mode 100644 index 0000000000..509362a73b --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp @@ -0,0 +1,416 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Paul Lafourcade (CEA-DAM-DIF, Arpajon, France) +------------------------------------------------------------------------- */ + +#include "compute_slcsa_atom.h" + +#include "arg_info.h" +#include "atom.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "modify.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "pair.h" +#include "potential_file_reader.h" +#include "update.h" + +#include +#include +#include + +using namespace LAMMPS_NS; + +static const char cite_compute_slcsa_atom_c[] = + "compute slcsa/atom command: doi:10.1088/0965-0393/21/5/055020\n\n" + "@Article{Lafourcade2023,\n" + " author = {P. Lafourcade and J.-B. Maillet and C. Denoual and E. Duval and A. Allera and A. " + "M. Goryaeva and M.-C. Marinica},\n" + " title = {Robust crystal structure identification at extreme conditions using a " + "density-independent spectral descriptor and supervised learning},\n" + " journal = {Computational Materials Science},\n" + " year = 2023,\n" + " volume = XX,\n" + " pages = {XXXXXX}\n" + "}\n\n"; + +/* ---------------------------------------------------------------------- */ +ComputeSLCSAAtom::ComputeSLCSAAtom(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), list(nullptr), lda_scalings(nullptr), + database_mean_descriptor(nullptr), lr_bias(nullptr), lr_decision(nullptr), icov_list(nullptr), + mean_projected_descriptors(nullptr), maha_thresholds(nullptr), full_descriptor(nullptr), + projected_descriptor(nullptr), scores(nullptr), probas(nullptr), prodright(nullptr), + dmaha(nullptr), classification(nullptr) +{ + // command : compute c1 all slcsa/atom jmax nclasses parameters_file.dat + // example : compute c1 all slcsa/atom 8 4 slcsa_parameters.dat + // example : compute c1 all slcsa/atom 8 4 database_mean_descriptor.dat lda_scalings.dat lr_decision.dat lr_bias.dat mahalanobis_data.dat c_b1[*] + // Steps : + // 1. bs=bs-xbar + // 2. dred=coefs_lda*bs + // 3. scores=decision_lr*dred + lr_bias + // 4. probas=exp(scores)/sum(exp(scores)) + // 5. cs=argmax(probas) + + // Read the parameters file in one bloc + // File structure : + // # database mean descriptor + // vector with bso4dim rows x 1 col + // # LDA dimension reduction matrix + // matrix bso4dim rows x nclasses-1 cols + // # LR decision matrix + // matrix with nclasses rows x nclasses-1 cols + // # LR bias vector + // vector with 1 row x nclasses cols + + if (narg != 11) utils::missing_cmd_args(FLERR, "compute slcsa/atom", error); + + int twojmax = utils::inumeric(FLERR, arg[3], false, lmp); + if (twojmax < 0) + error->all(FLERR, "Illegal compute slcsa/atom command: twojmax must be a non-negative integer"); + ncomps = compute_ncomps(twojmax); + + nclasses = utils::inumeric(FLERR, arg[4], false, lmp); + if (nclasses < 2) + error->all(FLERR, "Illegal compute slcsa/atom command: nclasses must be greater than 1"); + + database_mean_descriptor_file = arg[5]; + lda_scalings_file = arg[6]; + lr_decision_file = arg[7]; + lr_bias_file = arg[8]; + maha_file = arg[9]; + + if (comm->me == 0) { + auto mesg = fmt::format( + "Files used:\n {:24}: {}\n {:24}: {}\n {:24}: {}\n {:24}: {}\n {:24}: {}\n", + "database mean descriptor", database_mean_descriptor_file, "lda scalings", + lda_scalings_file, "lr decision", lr_decision_file, "lr bias", lr_bias_file, "maha stats", + maha_file); + utils::logmesg(lmp, mesg); + } + + int expand = 0; + char **earg; + int nvalues = utils::expand_args(FLERR, narg - 10, &arg[10], 1, earg, lmp); + if (earg != &arg[10]) expand = 1; + arg = earg; + + ArgInfo argi(arg[0]); + value_t val; + val.id = ""; + val.val.c = nullptr; + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); + if ((val.which == ArgInfo::FIX) || (val.which == ArgInfo::VARIABLE) || + (val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi.get_dim() > 1)) + error->all(FLERR, "Invalid compute slcsa/atom argument: {}", arg[0]); + + // if wildcard expansion occurred, free earg memory from exapnd_args() + + if (expand) { + for (int i = 0; i < nvalues; i++) delete[] earg[i]; + memory->sfree(earg); + } + + val.val.c = modify->get_compute_by_id(val.id); + if (!val.val.c) error->all(FLERR, "Compute ID {} for fix slcsa/atom does not exist", val.id); + if (val.val.c->peratom_flag == 0) + error->all(FLERR, "Compute slcsa/atom compute {} does not calculate per-atom values", val.id); + if (val.argindex == 0 && val.val.c->size_peratom_cols != 0) + error->all(FLERR, "Compute slcsa/atom compute {} does not calculate a per-atom vector", val.id); + if (val.argindex && val.val.c->size_peratom_cols == 0) + error->all(FLERR, "Compute slcsa/atom compute {} does not calculate a per-atom array", val.id); + if (val.argindex && val.argindex > val.val.c->size_peratom_cols) + error->all(FLERR, "Compute slcsa/atom compute {} array is accessed out-of-range", val.id); + descriptorval = val; + memory->create(database_mean_descriptor, ncomps, "slcsa/atom:database_mean_descriptor"); + memory->create(lda_scalings, ncomps, nclasses - 1, "slcsa/atom:lda_scalings"); + memory->create(lr_decision, nclasses, nclasses - 1, "slcsa/atom:lr_decision"); + memory->create(lr_bias, nclasses, "slcsa/atom:lr_bias"); + memory->create(maha_thresholds, nclasses, "slcsa/atom:maha_thresholds"); + memory->create(icov_list, nclasses, nclasses - 1, nclasses - 1, "slcsa/atom:icov_list"); + memory->create(mean_projected_descriptors, nclasses, nclasses - 1, + "slcsa/atom:mean_projected_descriptors"); + + if (comm->me == 0) { + + if (strcmp(database_mean_descriptor_file, "NULL") == 0) { + error->one(FLERR, + "Cannot open database mean descriptor file {}: ", database_mean_descriptor_file, + utils::getsyserror()); + } else { + PotentialFileReader reader(lmp, database_mean_descriptor_file, + "database mean descriptor file"); + int nread = 0; + while (nread < ncomps) { + auto values = reader.next_values(0); + database_mean_descriptor[nread] = values.next_double(); + nread++; + } + } + + if (strcmp(lda_scalings_file, "NULL") == 0) { + error->one(FLERR, "Cannot open database linear discriminant analysis scalings file {}: ", + lda_scalings_file, utils::getsyserror()); + } else { + PotentialFileReader reader(lmp, lda_scalings_file, "lda scalings file"); + int nread = 0; + while (nread < ncomps) { + auto values = reader.next_values(nclasses - 1); + lda_scalings[nread][0] = values.next_double(); + lda_scalings[nread][1] = values.next_double(); + lda_scalings[nread][2] = values.next_double(); + nread++; + } + } + + if (strcmp(lr_decision_file, "NULL") == 0) { + error->one(FLERR, "Cannot open logistic regression decision file {}: ", lr_decision_file, + utils::getsyserror()); + } else { + PotentialFileReader reader(lmp, lr_decision_file, "lr decision file"); + int nread = 0; + while (nread < nclasses) { + auto values = reader.next_values(nclasses - 1); + lr_decision[nread][0] = values.next_double(); + lr_decision[nread][1] = values.next_double(); + lr_decision[nread][2] = values.next_double(); + nread++; + } + } + + if (strcmp(lr_bias_file, "NULL") == 0) { + error->one(FLERR, "Cannot open logistic regression bias file {}: ", lr_bias_file, + utils::getsyserror()); + } else { + PotentialFileReader reader(lmp, lr_bias_file, "lr bias file"); + auto values = reader.next_values(nclasses); + lr_bias[0] = values.next_double(); + lr_bias[1] = values.next_double(); + lr_bias[2] = values.next_double(); + lr_bias[3] = values.next_double(); + } + + if (strcmp(maha_file, "NULL") == 0) { + error->one(FLERR, "Cannot open mahalanobis stats file {}: ", maha_file, utils::getsyserror()); + } else { + PotentialFileReader reader(lmp, maha_file, "mahalanobis stats file"); + int nvalues = nclasses * ((nclasses - 1) * (nclasses - 1) + nclasses); + auto values = reader.next_values(nvalues); + + for (int i = 0; i < nclasses; i++) { + maha_thresholds[i] = values.next_double(); + for (int j = 0; j < nclasses - 1; j++) + mean_projected_descriptors[i][j] = values.next_double(); + for (int k = 0; k < nclasses - 1; k++) + for (int l = 0; l < nclasses - 1; l++) icov_list[i][k][l] = values.next_double(); + } + + for (int i = 0; i < nclasses; i++) { + auto mesg = fmt::format("For class {} maha threshold = {:.6}\n", i, maha_thresholds[i]); + mesg += " mean B:\n"; + for (int j = 0; j < nclasses - 1; j++) + mesg += fmt::format(" {:11.6}\n", mean_projected_descriptors[i][j]); + mesg += " icov:\n"; + for (int j = 0; j < nclasses - 1; j++) { + mesg += fmt::format(" {:11.6} {:11.6} {:11.6}\n", icov_list[i][j][0], + icov_list[i][j][1], icov_list[i][j][2]); + } + utils::logmesg(lmp, mesg); + } + } + } + + MPI_Bcast(&database_mean_descriptor[0], ncomps, MPI_DOUBLE, 0, world); + MPI_Bcast(&lda_scalings[0][0], ncomps * (nclasses - 1), MPI_DOUBLE, 0, world); + MPI_Bcast(&lr_decision[0][0], nclasses * (nclasses - 1), MPI_DOUBLE, 0, world); + MPI_Bcast(&lr_bias[0], nclasses, MPI_DOUBLE, 0, world); + MPI_Bcast(&maha_thresholds[0], nclasses, MPI_DOUBLE, 0, world); + MPI_Bcast(&mean_projected_descriptors[0][0], nclasses * (nclasses - 1), MPI_DOUBLE, 0, world); + MPI_Bcast(&icov_list[0][0][0], nclasses * (nclasses - 1) * (nclasses - 1), MPI_DOUBLE, 0, world); + + peratom_flag = 1; + size_peratom_cols = nclasses + 1; + ncols = nclasses + 1; + nmax = 0; +} + +/* ---------------------------------------------------------------------- */ + +ComputeSLCSAAtom::~ComputeSLCSAAtom() +{ + memory->destroy(classification); + memory->destroy(database_mean_descriptor); + memory->destroy(lda_scalings); + memory->destroy(lr_decision); + memory->destroy(lr_bias); + memory->destroy(maha_thresholds); + memory->destroy(mean_projected_descriptors); + memory->destroy(icov_list); + memory->destroy(full_descriptor); + memory->destroy(projected_descriptor); + memory->destroy(scores); + memory->destroy(probas); + memory->destroy(prodright); + memory->destroy(dmaha); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeSLCSAAtom::init() +{ + + if (modify->get_compute_by_style(style).size() > 1) + if (comm->me == 0) error->warning(FLERR, "More than one compute {}", style); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeSLCSAAtom::init_list(int /*id*/, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeSLCSAAtom::compute_peratom() +{ + invoked_peratom = update->ntimestep; + + // grow per-atom if necessary + + if (atom->nmax > nmax) { + memory->destroy(classification); + nmax = atom->nmax; + memory->create(classification, nmax, ncols, "slcsa/atom:classification"); + array_atom = classification; + } + + int *mask = atom->mask; + int nlocal = atom->nlocal; + + if (descriptorval.which == ArgInfo::COMPUTE) { + if (!(descriptorval.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + descriptorval.val.c->compute_peratom(); + descriptorval.val.c->invoked_flag |= Compute::INVOKED_PERATOM; + } + double **compute_array = descriptorval.val.c->array_atom; + + memory->create(full_descriptor, ncomps, "slcsa/atom:local descriptor"); + memory->create(projected_descriptor, nclasses - 1, "slcsa/atom:reduced descriptor"); + memory->create(scores, nclasses, "slcsa/atom:scores"); + memory->create(probas, nclasses, "slcsa/atom:probas"); + memory->create(prodright, nclasses - 1, "slcsa/atom:prodright"); + memory->create(dmaha, nclasses, "slcsa/atom:prodright"); + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + for (int j = 0; j < ncomps; j++) full_descriptor[j] = compute_array[i][j]; + // Here comes the LDA + LR process + // 1st step : Retrieve mean database descriptor + for (int j = 0; j < ncomps; j++) full_descriptor[j] -= database_mean_descriptor[j]; + // 2nd step : Matrix multiplication to go from ncompsx1 -> (nclasses-1)*1 + for (int j = 0; j < nclasses - 1; j++) { + projected_descriptor[j] = 0.0; + for (int k = 0; k < ncomps; k++) { + projected_descriptor[j] += full_descriptor[k] * lda_scalings[k][j]; + } + } + // 3rd step : Matrix multiplication + for (int j = 0; j < nclasses; j++) { + scores[j] = lr_bias[j]; + for (int k = 0; k < nclasses - 1; k++) { + scores[j] += lr_decision[j][k] * projected_descriptor[k]; + } + } + // 4th step : Matrix multiplication + double sumexpscores = 0.0; + for (int j = 0; j < nclasses; j++) sumexpscores += exp(scores[j]); + for (int j = 0; j < nclasses; j++) probas[j] = exp(scores[j]) / sumexpscores; + + classification[i][nclasses] = argmax(probas, nclasses); + + // 5th step : Mahalanobis distance + for (int j = 0; j < nclasses; j++) { + prodright[0] = 0.0; + prodright[1] = 0.0; + prodright[2] = 0.0; + for (int k = 0; k < nclasses - 1; k++) { + for (int l = 0; l < nclasses - 1; l++) { + prodright[k] += (icov_list[j][k][l] * + (projected_descriptor[k] - mean_projected_descriptors[j][k])); + } + } + double prodleft = 0.0; + for (int k = 0; k < nclasses - 1; k++) { + prodleft += + (prodright[k] * (projected_descriptor[k] - mean_projected_descriptors[j][k])); + } + classification[i][j] = sqrt(prodleft); + } + // 6th step : Sanity check + int locclass = classification[i][nclasses]; + + if (classification[i][locclass] > maha_thresholds[locclass]) { + classification[i][nclasses] = -1.0; + } + + } else { + for (int j = 0; j < ncols; j++) classification[i][j] = -1.0; + } + } + memory->destroy(full_descriptor); + memory->destroy(projected_descriptor); + memory->destroy(scores); + memory->destroy(probas); + memory->destroy(prodright); + memory->destroy(dmaha); + } +} + +int ComputeSLCSAAtom::compute_ncomps(int twojmax) +{ + int ncount; + + ncount = 0; + + for (int j1 = 0; j1 <= twojmax; j1++) + for (int j2 = 0; j2 <= j1; j2++) + for (int j = j1 - j2; j <= MIN(twojmax, j1 + j2); j += 2) + if (j >= j1) ncount++; + + return ncount; +} + +int ComputeSLCSAAtom::argmax(double arr[], int size) +{ + int maxIndex = 0; // Initialize the index of the maximum value to the first element. + double maxValue = arr[0]; // Initialize the maximum value to the first element. + + for (int i = 1; i < size; ++i) { + if (arr[i] > maxValue) { + // If a greater value is found, update the maxIndex and maxValue. + maxIndex = i; + maxValue = arr[i]; + } + } + + return maxIndex; +} diff --git a/src/EXTRA-COMPUTE/compute_slcsa_atom.h b/src/EXTRA-COMPUTE/compute_slcsa_atom.h new file mode 100644 index 0000000000..6d7cd90c31 --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_slcsa_atom.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Paul Lafourcade (CEA-DAM-DIF, Arpajon, France) +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(slcsa/atom,ComputeSLCSAAtom); +// clang-format on +#else + +#ifndef LMP_COMPUTE_SLCSA_ATOM_H +#define LMP_COMPUTE_SLCSA_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeSLCSAAtom : public Compute { + public: + ComputeSLCSAAtom(class LAMMPS *, int, char **); + ~ComputeSLCSAAtom() override; + void init() override; + void init_list(int, class NeighList *) override; + void compute_peratom() override; + // double memory_usage() override; + int compute_ncomps(int); + int argmax(double *, int); + + private: + struct value_t { + int which; // type of data: COMPUTE, FIX, VARIABLE + int argindex; // 1-based index if data is vector, else 0 + std::string id; // compute/fix/variable ID + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + value_t descriptorval; + int nmax; + int ncols; + int nevery; + int ncomps; + int nclasses; + const char *database_mean_descriptor_file; + const char *lda_scalings_file; + const char *lr_decision_file; + const char *lr_bias_file; + const char *covmat_file; + const char *maha_file; + class NeighList *list; + + // LDA dimension reduction + double **lda_scalings; + double *database_mean_descriptor; + + // LR classification + double *lr_bias; + double **lr_decision; + + // Mahalanobis distance calculation + double ***icov_list; + double **mean_projected_descriptors; + double *maha_thresholds; + + // Per-atom local arrays + double *full_descriptor; + double *projected_descriptor; + double *scores; + double *probas; + double *prodright; + double *dmaha; + + // Output array + double **classification; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index fc9de602a7..6c35b4ba07 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -23,6 +23,7 @@ #include "atom_vec.h" #include "bond.h" #include "comm.h" +#include "dihedral.h" #include "domain.h" #include "error.h" #include "force.h" @@ -38,8 +39,10 @@ using namespace LAMMPS_NS; +#define SMALL 0.001 + enum { X, Y, Z }; -enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE }; +enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE, DIHEDRAL }; /* ---------------------------------------------------------------------- */ @@ -49,6 +52,7 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute( bondflag = 0; angleflag = 0; + dihedralflag = 0; // set compute mode and direction of plane(s) for pressure calculation @@ -129,6 +133,11 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute( which[nvalues] = ANGLE; nvalues++; } + } else if (strcmp(arg[iarg],"dihedral") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = DIHEDRAL; + nvalues++; + } } else error->all(FLERR, "Illegal compute stress/mop command"); //break; @@ -152,6 +161,8 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute( bond_global = nullptr; angle_local = nullptr; angle_global = nullptr; + dihedral_local = nullptr; + dihedral_global = nullptr; // this fix produces a global vector @@ -162,6 +173,8 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute( memory->create(bond_global, nvalues, "stress/mop:bond_global"); memory->create(angle_local, nvalues, "stress/mop:angle_local"); memory->create(angle_global, nvalues, "stress/mop:angle_global"); + memory->create(dihedral_local,nvalues,"stress/mop:dihedral_local"); + memory->create(dihedral_global,nvalues,"stress/mop:dihedral_global"); size_vector = nvalues; vector_flag = 1; @@ -180,6 +193,8 @@ ComputeStressMop::~ComputeStressMop() memory->destroy(bond_global); memory->destroy(angle_local); memory->destroy(angle_global); + memory->destroy(dihedral_local); + memory->destroy(dihedral_global); memory->destroy(vector); } @@ -233,9 +248,13 @@ void ComputeStressMop::init() } } if (force->dihedral) { - if ((strcmp(force->dihedral_style, "zero") != 0) && - (strcmp(force->dihedral_style, "none") != 0)) - error->all(FLERR, "compute stress/mop does not account for dihedral potentials"); + if (force->dihedral->born_matrix_enable == 0) { + if ((strcmp(force->dihedral_style, "zero") != 0) && + (strcmp(force->dihedral_style, "none") != 0)) + error->all(FLERR, "compute stress/mop does not account for dihedral potentials"); + } else { + dihedralflag = 1; + } } if (force->improper) { if ((strcmp(force->improper_style, "zero") != 0) && @@ -297,8 +316,18 @@ void ComputeStressMop::compute_vector() MPI_Allreduce(angle_local, angle_global, nvalues, MPI_DOUBLE, MPI_SUM, world); + if (dihedralflag) { + //Compute dihedral contribution on separate procs + compute_dihedrals(); + } else { + for (int i=0; ix[i][1]; xi[2] = atom->x[i][2]; - // velocities at t + // minimum image of xi with respect to the plane + xi[dir] -= pos; + domain->minimum_image(xi[0], xi[1], xi[2]); + xi[dir] += pos; + + //velocities at t vi[0] = atom->v[i][0]; vi[1] = atom->v[i][1]; @@ -454,10 +488,8 @@ void ComputeStressMop::compute_pairs() // at each timestep, must check atoms going through the // image of the plane that is closest to the box - double pos_temp = pos + copysign(1.0, domain->prd_half[dir] - pos) * domain->prd[dir]; - if (fabs(xi[dir] - pos) < fabs(xi[dir] - pos_temp)) pos_temp = pos; - - if (((xi[dir] - pos_temp) * (xj[dir] - pos_temp)) < 0) { + double tau = (xi[dir] - pos) / (xi[dir] - xj[dir]); + if ((tau <= 1) && (tau >= 0)) { // sgn = copysign(1.0,vi[dir]-vcm[dir]); @@ -786,3 +818,308 @@ void ComputeStressMop::compute_angles() m += 3; } } + +/*------------------------------------------------------------------------ + compute dihedral contribution to pressure of local proc + -------------------------------------------------------------------------*/ + +void ComputeStressMop::compute_dihedrals() +{ + int i, nd, atom1, atom2, atom3, atom4, imol, iatom; + tagint tagprev; + double vb1x, vb1y, vb1z, vb2x, vb2y, vb2z, vb3x, vb3y, vb3z; + double vb2xm, vb2ym, vb2zm; + double sb1, sb2, sb3, rb1, rb3, c0, b1mag2, b1mag, b2mag2; + double b2mag, b3mag2, b3mag, c2mag, ctmp, r12c1, c1mag, r12c2; + double s1, s2, s12, sc1, sc2, a11, a22, a33, a12, a13, a23; + double df[3], f1[3], f2[3], f3[3], f4[3]; + double c, sx2, sy2, sz2, sin2; + + double **x = atom->x; + tagint *tag = atom->tag; + int *num_dihedral = atom->num_dihedral; + tagint **dihedral_atom1 = atom->dihedral_atom1; + tagint **dihedral_atom2 = atom->dihedral_atom2; + tagint **dihedral_atom3 = atom->dihedral_atom3; + tagint **dihedral_atom4 = atom->dihedral_atom4; + int *mask = atom->mask; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int nlocal = atom->nlocal; + int molecular = atom->molecular; + + // loop over all atoms and their dihedrals + + Dihedral *dihedral = force->dihedral; + + double dudih, du2dih; + + double diffx[3] = {0.0, 0.0, 0.0}; + double x_atom_1[3] = {0.0, 0.0, 0.0}; + double x_atom_2[3] = {0.0, 0.0, 0.0}; + double x_atom_3[3] = {0.0, 0.0, 0.0}; + double x_atom_4[3] = {0.0, 0.0, 0.0}; + + // initialization + for (int i = 0; i < nvalues; i++) { + dihedral_local[i] = 0.0; + } + double local_contribution[3] = {0.0, 0.0, 0.0}; + + for (atom2 = 0; atom2 < nlocal; atom2++) { + if (!(mask[atom2] & groupbit)) continue; + + if (molecular == Atom::MOLECULAR) + nd = num_dihedral[atom2]; + else { + if (molindex[atom2] < 0) continue; + imol = molindex[atom2]; + iatom = molatom[atom2]; + nd = onemols[imol]->num_dihedral[iatom]; + } + + for (i = 0; i < nd; i++) { + if (molecular == 1) { + if (tag[atom2] != dihedral_atom2[atom2][i]) continue; + atom1 = atom->map(dihedral_atom1[atom2][i]); + atom3 = atom->map(dihedral_atom3[atom2][i]); + atom4 = atom->map(dihedral_atom4[atom2][i]); + } else { + if (tag[atom2] != onemols[imol]->dihedral_atom2[atom2][i]) continue; + tagprev = tag[atom2] - iatom - 1; + atom1 = atom->map(onemols[imol]->dihedral_atom1[atom2][i] + tagprev); + atom3 = atom->map(onemols[imol]->dihedral_atom3[atom2][i] + tagprev); + atom4 = atom->map(onemols[imol]->dihedral_atom4[atom2][i] + tagprev); + } + + if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; + if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; + if (atom4 < 0 || !(mask[atom4] & groupbit)) continue; + + // minimum image of atom1 with respect to the plane of interest + x_atom_1[0] = x[atom1][0]; + x_atom_1[1] = x[atom1][1]; + x_atom_1[2] = x[atom1][2]; + x_atom_1[dir] -= pos; + domain->minimum_image(x_atom_1[0], x_atom_1[1], x_atom_1[2]); + x_atom_1[dir] += pos; + + // minimum image of atom2 with respect to atom1 + diffx[0] = x[atom2][0] - x_atom_1[0]; + diffx[1] = x[atom2][1] - x_atom_1[1]; + diffx[2] = x[atom2][2] - x_atom_1[2]; + domain->minimum_image(diffx[0], diffx[1], diffx[2]); + x_atom_2[0] = x_atom_1[0] + diffx[0]; + x_atom_2[1] = x_atom_1[1] + diffx[1]; + x_atom_2[2] = x_atom_1[2] + diffx[2]; + + // minimum image of atom3 with respect to atom2 + diffx[0] = x[atom3][0] - x_atom_2[0]; + diffx[1] = x[atom3][1] - x_atom_2[1]; + diffx[2] = x[atom3][2] - x_atom_2[2]; + domain->minimum_image(diffx[0], diffx[1], diffx[2]); + x_atom_3[0] = x_atom_2[0] + diffx[0]; + x_atom_3[1] = x_atom_2[1] + diffx[1]; + x_atom_3[2] = x_atom_2[2] + diffx[2]; + + // minimum image of atom3 with respect to atom2 + diffx[0] = x[atom4][0] - x_atom_3[0]; + diffx[1] = x[atom4][1] - x_atom_3[1]; + diffx[2] = x[atom4][2] - x_atom_3[2]; + domain->minimum_image(diffx[0], diffx[1], diffx[2]); + x_atom_4[0] = x_atom_3[0] + diffx[0]; + x_atom_4[1] = x_atom_3[1] + diffx[1]; + x_atom_4[2] = x_atom_3[2] + diffx[2]; + + // check if any bond vector crosses the plane of interest + double tau_right = (x_atom_2[dir] - pos) / (x_atom_2[dir] - x_atom_1[dir]); + double tau_middle = (x_atom_3[dir] - pos) / (x_atom_3[dir] - x_atom_2[dir]); + double tau_left = (x_atom_4[dir] - pos) / (x_atom_4[dir] - x_atom_3[dir]); + bool right_cross = ((tau_right >=0) && (tau_right <= 1)); + bool middle_cross = ((tau_middle >= 0) && (tau_middle <= 1)); + bool left_cross = ((tau_left >=0) && (tau_left <= 1)); + + // no bonds crossing the plane + if (!right_cross && !middle_cross && !left_cross) continue; + + dihedral->born_matrix(i, atom1, atom2, atom3, atom4, dudih, du2dih); + + // first bond + vb1x = x_atom_1[0] - x_atom_2[0]; + vb1y = x_atom_1[1] - x_atom_2[1]; + vb1z = x_atom_1[2] - x_atom_2[2]; + + // second bond + vb2x = x_atom_3[0] - x_atom_2[0]; + vb2y = x_atom_3[1] - x_atom_2[1]; + vb2z = x_atom_3[2] - x_atom_2[2]; + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + + // third bond + vb3x = x_atom_4[0] - x_atom_3[0]; + vb3y = x_atom_4[1] - x_atom_3[1]; + vb3z = x_atom_4[2] - x_atom_3[2]; + + // c0 calculation + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + // 1st and 2nd angle + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + // error check + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + // forces on each particle + double a = dudih; + c = c * a; + s12 = s12 * a; + a11 = c*sb1*s1; + a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2)); + a33 = c*sb3*s2; + a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12); + a13 = -rb1*rb3*s12; + a23 = r12c2 * (c2mag*c*s2 + c1mag*s12); + + sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + + f1[0] = a11*vb1x + a12*vb2x + a13*vb3x; + f1[1] = a11*vb1y + a12*vb2y + a13*vb3y; + f1[2] = a11*vb1z + a12*vb2z + a13*vb3z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a13*vb1x + a23*vb2x + a33*vb3x; + f4[1] = a13*vb1y + a23*vb2y + a33*vb3y; + f4[2] = a13*vb1z + a23*vb2z + a33*vb3z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // only right bond crossing the plane + if (right_cross && !middle_cross && !left_cross) + { + double sgn = copysign(1.0, x_atom_1[dir] - pos); + df[0] = sgn * f1[0]; + df[1] = sgn * f1[1]; + df[2] = sgn * f1[2]; + } + + // only middle bond crossing the plane + if (!right_cross && middle_cross && !left_cross) + { + double sgn = copysign(1.0, x_atom_2[dir] - pos); + df[0] = sgn * (f2[0] + f1[0]); + df[1] = sgn * (f2[1] + f1[1]); + df[2] = sgn * (f2[2] + f1[2]); + } + + // only left bond crossing the plane + if (!right_cross && !middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_4[dir] - pos); + df[0] = sgn * f4[0]; + df[1] = sgn * f4[1]; + df[2] = sgn * f4[2]; + } + + // only right & middle bonds crossing the plane + if (right_cross && middle_cross && !left_cross) + { + double sgn = copysign(1.0, x_atom_2[dir] - pos); + df[0] = sgn * f2[0]; + df[1] = sgn * f2[1]; + df[2] = sgn * f2[2]; + } + + // only right & left bonds crossing the plane + if (right_cross && !middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_1[dir] - pos); + df[0] = sgn * (f1[0] + f4[0]); + df[1] = sgn * (f1[1] + f4[1]); + df[2] = sgn * (f1[2] + f4[2]); + } + + // only middle & left bonds crossing the plane + if (!right_cross && middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_3[dir] - pos); + df[0] = sgn * f3[0]; + df[1] = sgn * f3[1]; + df[2] = sgn * f3[2]; + } + + // all three bonds crossing the plane + if (right_cross && middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_1[dir] - pos); + df[0] = sgn * (f1[0] + f3[0]); + df[1] = sgn * (f1[1] + f3[1]); + df[2] = sgn * (f1[2] + f3[2]); + } + + local_contribution[0] += df[0]/area*nktv2p; + local_contribution[1] += df[1]/area*nktv2p; + local_contribution[2] += df[2]/area*nktv2p; + } + } + + // loop over the keywords and if necessary add the dihedral contribution + int m = 0; + while (m < nvalues) { + if ((which[m] == CONF) || (which[m] == TOTAL) || (which[m] == DIHEDRAL)) { + dihedral_local[m] = local_contribution[0]; + dihedral_local[m+1] = local_contribution[1]; + dihedral_local[m+2] = local_contribution[2]; + } + m += 3; + } + +} diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.h b/src/EXTRA-COMPUTE/compute_stress_mop.h index 86140dc278..0a0ea8b55a 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop.h @@ -40,15 +40,17 @@ class ComputeStressMop : public Compute { void compute_pairs(); void compute_bonds(); void compute_angles(); + void compute_dihedrals(); int nvalues, dir; int *which; - int bondflag, angleflag; + int bondflag, angleflag, dihedralflag; double *values_local, *values_global; double *bond_local, *bond_global; double *angle_local, *angle_global; + double *dihedral_local, *dihedral_global; double pos, pos1, dt, nktv2p, ftm2v; double area; class NeighList *list; diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index cc201fdbaa..41b5f64a67 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -13,15 +13,17 @@ /*------------------------------------------------------------------------ Contributing Authors : Romain Vermorel (LFCR), Laurent Joly (ULyon) - Support for bonds added by : Evangelos Voyiatzis (NovaMechanics) + Support for bonds, angles and dihedrals added by : Evangelos Voyiatzis (NovaMechanics) --------------------------------------------------------------------------*/ #include "compute_stress_mop_profile.h" +#include "angle.h" #include "atom.h" #include "atom_vec.h" #include "bond.h" #include "comm.h" +#include "dihedral.h" #include "domain.h" #include "error.h" #include "force.h" @@ -37,9 +39,10 @@ using namespace LAMMPS_NS; +#define SMALL 0.001 + enum { X, Y, Z }; -enum { LOWER, CENTER, UPPER, COORD }; -enum { TOTAL, CONF, KIN, PAIR, BOND }; +enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE, DIHEDRAL }; /* ---------------------------------------------------------------------- */ @@ -49,6 +52,8 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a if (narg < 7) utils::missing_cmd_args(FLERR, "compute stress/mop/profile", error); bondflag = 0; + angleflag = 0; + dihedralflag = 0; // set compute mode and direction of plane(s) for pressure calculation @@ -63,15 +68,15 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a // bin parameters - if (strcmp(arg[4], "lower") == 0) - originflag = LOWER; - else if (strcmp(arg[4], "center") == 0) - originflag = CENTER; - else if (strcmp(arg[4], "upper") == 0) - originflag = UPPER; - else - originflag = COORD; - if (originflag == COORD) origin = utils::numeric(FLERR, arg[4], false, lmp); + if (strcmp(arg[4], "lower") == 0) { + origin = domain->boxlo[dir]; + } else if (strcmp(arg[4], "center") == 0) { + origin = 0.5 * (domain->boxlo[dir] + domain->boxhi[dir]); + } else if (strcmp(arg[4], "upper") == 0) { + origin = domain->boxhi[dir]; + } else { + origin = utils::numeric(FLERR, arg[4], false, lmp); + } delta = utils::numeric(FLERR, arg[5], false, lmp); invdelta = 1.0 / delta; @@ -108,6 +113,16 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a which[nvalues] = BOND; nvalues++; } + } else if (strcmp(arg[iarg], "angle") == 0) { + for (i = 0; i < 3; i++) { + which[nvalues] = ANGLE; + nvalues++; + } + } else if (strcmp(arg[iarg],"dihedral") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = DIHEDRAL; + nvalues++; + } } else error->all(FLERR, "Illegal compute stress/mop/profile command"); //break; @@ -133,6 +148,10 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a values_local = values_global = array = nullptr; bond_local = nullptr; bond_global = nullptr; + angle_local = nullptr; + angle_global = nullptr; + dihedral_local = nullptr; + dihedral_global = nullptr; local_contribution = nullptr; // bin setup @@ -161,6 +180,10 @@ ComputeStressMopProfile::~ComputeStressMopProfile() memory->destroy(values_global); memory->destroy(bond_local); memory->destroy(bond_global); + memory->destroy(angle_local); + memory->destroy(angle_global); + memory->destroy(dihedral_local); + memory->destroy(dihedral_global); memory->destroy(local_contribution); memory->destroy(array); } @@ -208,13 +231,25 @@ void ComputeStressMopProfile::init() if (force->bond) bondflag = 1; - if (force->angle) - if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0)) - error->all(FLERR, "compute stress/mop/profile does not account for angle potentials"); - if (force->dihedral) - if ((strcmp(force->dihedral_style, "zero") != 0) && - (strcmp(force->dihedral_style, "none") != 0)) - error->all(FLERR, "compute stress/mop/profile does not account for dihedral potentials"); + if (force->angle) { + if (force->angle->born_matrix_enable == 0) { + if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0)) + error->all(FLERR,"compute stress/mop/profile does not account for angle potentials"); + } else { + angleflag = 1; + } + } + + if (force->dihedral) { + if (force->dihedral->born_matrix_enable == 0) { + if ((strcmp(force->dihedral_style, "zero") != 0) && + (strcmp(force->dihedral_style, "none") != 0)) + error->all(FLERR, "compute stress/mop/profile does not account for dihedral potentials"); + } else { + dihedralflag = 1; + } + } + if (force->improper) if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) @@ -263,16 +298,43 @@ void ComputeStressMopProfile::compute_array() } // sum bond contribution over all procs - MPI_Allreduce(&bond_local[0][0], &bond_global[0][0], nbins * nvalues, MPI_DOUBLE, MPI_SUM, world); + if (angleflag) { + //Compute angle contribution on separate procs + compute_angles(); + } else { + for (int m = 0; m < nbins; m++) { + for (int i = 0; i < nvalues; i++) { + angle_local[m][i] = 0.0; + } + } + } + + // sum angle contribution over all procs + MPI_Allreduce(&angle_local[0][0],&angle_global[0][0],nbins*nvalues,MPI_DOUBLE,MPI_SUM,world); + + if (dihedralflag) { + //Compute dihedral contribution on separate procs + compute_dihedrals(); + } else { + for (int m = 0; m < nbins; m++) { + for (int i = 0; i < nvalues; i++) { + dihedral_local[m][i] = 0.0; + } + } + } + + // sum dihedral contribution over all procs + MPI_Allreduce(&dihedral_local[0][0],&dihedral_global[0][0],nbins*nvalues,MPI_DOUBLE,MPI_SUM,world); + for (int ibin = 0; ibin < nbins; ibin++) { - array[ibin][0] = coord[ibin][0]; + array[ibin][0] = coord[ibin]; int mo = 1; int m = 0; while (m < nvalues) { - array[ibin][m + mo] = values_global[ibin][m] + bond_global[ibin][m]; + array[ibin][m + mo] = values_global[ibin][m] + bond_global[ibin][m] + angle_global[ibin][m] + dihedral_global[ibin][m]; m++; } } @@ -366,8 +428,8 @@ void ComputeStressMopProfile::compute_pairs() if (newton_pair || j < nlocal) { for (ibin = 0; ibin < nbins; ibin++) { - pos = coord[ibin][0]; - pos1 = coordp[ibin][0]; + pos = coord[ibin]; + pos1 = coordp[ibin]; // check if ij pair is across plane, add contribution to pressure @@ -392,8 +454,8 @@ void ComputeStressMopProfile::compute_pairs() } else { for (ibin = 0; ibin < nbins; ibin++) { - pos = coord[ibin][0]; - pos1 = coordp[ibin][0]; + pos = coord[ibin]; + pos1 = coordp[ibin]; //check if ij pair is across plane, add contribution to pressure @@ -454,15 +516,29 @@ void ComputeStressMopProfile::compute_pairs() xj[2] = xi[2] - vi[2] * dt + fi[2] * iterm * dt; for (ibin = 0; ibin < nbins; ibin++) { - pos = coord[ibin][0]; - pos1 = coordp[ibin][0]; + pos = coord[ibin]; + pos1 = coordp[ibin]; - if (((xi[dir] - pos) * (xj[dir] - pos) * (xi[dir] - pos1) * (xj[dir] - pos1) < 0)) { + // minimum image of xi with respect to the plane + xi[dir] -= pos; + domain->minimum_image(xi[0], xi[1], xi[2]); + xi[dir] += pos; + + // minimum image of xj with respect to xi + xj[0] -= xi[0]; + xj[1] -= xi[1]; + xj[2] -= xi[2]; + domain->minimum_image(xi[0], xi[1], xi[2]); + xj[0] += xi[0]; + xj[1] += xi[1]; + xj[2] += xi[2]; + + double tau = (xi[dir] - pos) / (xi[dir] - xj[dir]); + if ((tau <= 1) && (tau >= 0)) { sgn = copysign(1.0, vi[dir]); - // approximate crossing velocity by v(t-dt/2) (based on Velocity-Verlet alg.) - + //approximate crossing velocity by v(t-dt/2) (based on Velocity-Verlet alg.) double vcross[3]; vcross[0] = vi[0] - fi[0] * iterm; vcross[1] = vi[1] - fi[1] * iterm; @@ -549,7 +625,7 @@ void ComputeStressMopProfile::compute_bonds() if (btype <= 0) continue; for (int ibin = 0; ibin < nbins; ibin++) { - double pos = coord[ibin][0]; + double pos = coord[ibin]; // minimum image of atom1 with respect to the plane of interest @@ -607,6 +683,506 @@ void ComputeStressMopProfile::compute_bonds() } } +/*------------------------------------------------------------------------ + compute angle contribution to pressure of local proc + -------------------------------------------------------------------------*/ + +void ComputeStressMopProfile::compute_angles() +{ + int na, atom1, atom2, atom3, imol, iatom, atype; + tagint tagprev; + double r1, r2, cos_theta; + + double **x = atom->x; + tagint *tag = atom->tag; + int *num_angle = atom->num_angle; + tagint **angle_atom1 = atom->angle_atom1; + tagint **angle_atom2 = atom->angle_atom2; + tagint **angle_atom3 = atom->angle_atom3; + int **angle_type = atom->angle_type; + int *mask = atom->mask; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int nlocal = atom->nlocal; + int molecular = atom->molecular; + + // loop over all atoms and their angles + Angle *angle = force->angle; + + double duang, du2ang; + double dx[3] = {0.0, 0.0, 0.0}; + double dx_left[3] = {0.0, 0.0, 0.0}; + double dx_right[3] = {0.0, 0.0, 0.0}; + double x_angle_left[3] = {0.0, 0.0, 0.0}; + double x_angle_middle[3] = {0.0, 0.0, 0.0}; + double x_angle_right[3] = {0.0, 0.0, 0.0}; + double dcos_theta[3] = {0.0, 0.0, 0.0}; + + // initialization + for (int m = 0; m < nbins; m++) { + for (int i = 0; i < nvalues; i++) { + angle_local[m][i] = 0.0; + } + local_contribution[m][0] = 0.0; + local_contribution[m][1] = 0.0; + local_contribution[m][2] = 0.0; + } + + + for (atom2 = 0; atom2 < nlocal; atom2++) { + if (!(mask[atom2] & groupbit)) continue; + + if (molecular == 1) + na = num_angle[atom2]; + else { + if (molindex[atom2] < 0) continue; + imol = molindex[atom2]; + iatom = molatom[atom2]; + na = onemols[imol]->num_angle[iatom]; + } + + for (int i = 0; i < na; i++) { + if (molecular == 1) { + if (tag[atom2] != angle_atom2[atom2][i]) continue; + atype = angle_type[atom2][i]; + atom1 = atom->map(angle_atom1[atom2][i]); + atom3 = atom->map(angle_atom3[atom2][i]); + } else { + if (tag[atom2] != onemols[imol]->angle_atom2[atom2][i]) continue; + atype = onemols[imol]->angle_type[atom2][i]; + tagprev = tag[atom2] - iatom - 1; + atom1 = atom->map(onemols[imol]->angle_atom1[atom2][i] + tagprev); + atom3 = atom->map(onemols[imol]->angle_atom3[atom2][i] + tagprev); + } + + if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; + if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; + if (atype <= 0) continue; + + for (int ibin = 0; ibinminimum_image(dx[0], dx[1], dx[2]); + x_angle_left[0] = dx[0]; + x_angle_left[1] = dx[1]; + x_angle_left[2] = dx[2]; + x_angle_left[dir] += pos; + + // minimum image of atom2 with respect to atom1 + dx_left[0] = x[atom2][0] - x_angle_left[0]; + dx_left[1] = x[atom2][1] - x_angle_left[1]; + dx_left[2] = x[atom2][2] - x_angle_left[2]; + domain->minimum_image(dx_left[0], dx_left[1], dx_left[2]); + x_angle_middle[0] = x_angle_left[0] + dx_left[0]; + x_angle_middle[1] = x_angle_left[1] + dx_left[1]; + x_angle_middle[2] = x_angle_left[2] + dx_left[2]; + + // minimum image of atom3 with respect to atom2 + dx_right[0] = x[atom3][0] - x_angle_middle[0]; + dx_right[1] = x[atom3][1] - x_angle_middle[1]; + dx_right[2] = x[atom3][2] - x_angle_middle[2]; + domain->minimum_image(dx_right[0], dx_right[1], dx_right[2]); + x_angle_right[0] = x_angle_middle[0] + dx_right[0]; + x_angle_right[1] = x_angle_middle[1] + dx_right[1]; + x_angle_right[2] = x_angle_middle[2] + dx_right[2]; + + // check if any bond vector crosses the plane of interest + double tau_right = (x_angle_right[dir] - pos) / (x_angle_right[dir] - x_angle_middle[dir]); + double tau_left = (x_angle_middle[dir] - pos) / (x_angle_middle[dir] - x_angle_left[dir]); + bool right_cross = ((tau_right >=0) && (tau_right <= 1)); + bool left_cross = ((tau_left >=0) && (tau_left <= 1)); + + // no bonds crossing the plane + if (!right_cross && !left_cross) continue; + + // compute the cos(theta) of the angle + r1 = sqrt(dx_left[0]*dx_left[0] + dx_left[1]*dx_left[1] + dx_left[2]*dx_left[2]); + r2 = sqrt(dx_right[0]*dx_right[0] + dx_right[1]*dx_right[1] + dx_right[2]*dx_right[2]); + cos_theta = -(dx_right[0]*dx_left[0] + dx_right[1]*dx_left[1] + dx_right[2]*dx_left[2])/(r1*r2); + + if (cos_theta > 1.0) cos_theta = 1.0; + if (cos_theta < -1.0) cos_theta = -1.0; + + // The method returns derivative with regards to cos(theta) + angle->born_matrix(atype, atom1, atom2, atom3, duang, du2ang); + // only right bond crossing the plane + if (right_cross && !left_cross) + { + double sgn = copysign(1.0, x_angle_right[dir] - pos); + dcos_theta[0] = sgn*(dx_right[0]*cos_theta/r2 + dx_left[0]/r1)/r2; + dcos_theta[1] = sgn*(dx_right[1]*cos_theta/r2 + dx_left[1]/r1)/r2; + dcos_theta[2] = sgn*(dx_right[2]*cos_theta/r2 + dx_left[2]/r1)/r2; + } + + // only left bond crossing the plane + if (!right_cross && left_cross) + { + double sgn = copysign(1.0, x_angle_left[dir] - pos); + dcos_theta[0] = -sgn*(dx_left[0]*cos_theta/r1 + dx_right[0]/r2)/r1; + dcos_theta[1] = -sgn*(dx_left[1]*cos_theta/r1 + dx_right[1]/r2)/r1; + dcos_theta[2] = -sgn*(dx_left[2]*cos_theta/r1 + dx_right[2]/r2)/r1; + } + + // both bonds crossing the plane + if (right_cross && left_cross) + { + // due to right bond + double sgn = copysign(1.0, x_angle_middle[dir] - pos); + dcos_theta[0] = -sgn*(dx_right[0]*cos_theta/r2 + dx_left[0]/r1)/r2; + dcos_theta[1] = -sgn*(dx_right[1]*cos_theta/r2 + dx_left[1]/r1)/r2; + dcos_theta[2] = -sgn*(dx_right[2]*cos_theta/r2 + dx_left[2]/r1)/r2; + + // due to left bond + dcos_theta[0] += sgn*(dx_left[0]*cos_theta/r1 + dx_right[0]/r2)/r1; + dcos_theta[1] += sgn*(dx_left[1]*cos_theta/r1 + dx_right[1]/r2)/r1; + dcos_theta[2] += sgn*(dx_left[2]*cos_theta/r1 + dx_right[2]/r2)/r1; + } + + // final contribution of the given angle term + local_contribution[ibin][0] += duang*dcos_theta[0]/area*nktv2p; + local_contribution[ibin][1] += duang*dcos_theta[1]/area*nktv2p; + local_contribution[ibin][2] += duang*dcos_theta[2]/area*nktv2p; + } + } + } + + // loop over the keywords and if necessary add the angle contribution + int m = 0; + while (m < nvalues) { + if (which[m] == CONF || which[m] == TOTAL || which[m] == ANGLE) { + for (int ibin = 0; ibin < nbins; ibin++) { + angle_local[ibin][m] = local_contribution[ibin][0]; + angle_local[ibin][m+1] = local_contribution[ibin][1]; + angle_local[ibin][m+2] = local_contribution[ibin][2]; + } + } + m += 3; + } +} + +/*------------------------------------------------------------------------ + compute dihedral contribution to pressure of local proc + -------------------------------------------------------------------------*/ + +void ComputeStressMopProfile::compute_dihedrals() +{ + int i, nd, atom1, atom2, atom3, atom4, imol, iatom; + tagint tagprev; + double vb1x, vb1y, vb1z, vb2x, vb2y, vb2z, vb3x, vb3y, vb3z; + double vb2xm, vb2ym, vb2zm; + double sb1, sb2, sb3, rb1, rb3, c0, b1mag2, b1mag, b2mag2; + double b2mag, b3mag2, b3mag, c2mag, ctmp, r12c1, c1mag, r12c2; + double s1, s2, s12, sc1, sc2, a11, a22, a33, a12, a13, a23; + double df[3], f1[3], f2[3], f3[3], f4[3]; + double c, sx2, sy2, sz2, sin2; + + double **x = atom->x; + tagint *tag = atom->tag; + int *num_dihedral = atom->num_dihedral; + tagint **dihedral_atom1 = atom->dihedral_atom1; + tagint **dihedral_atom2 = atom->dihedral_atom2; + tagint **dihedral_atom3 = atom->dihedral_atom3; + tagint **dihedral_atom4 = atom->dihedral_atom4; + int *mask = atom->mask; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int nlocal = atom->nlocal; + int molecular = atom->molecular; + + // loop over all atoms and their dihedrals + + Dihedral *dihedral = force->dihedral; + + double dudih, du2dih; + + double diffx[3] = {0.0, 0.0, 0.0}; + double x_atom_1[3] = {0.0, 0.0, 0.0}; + double x_atom_2[3] = {0.0, 0.0, 0.0}; + double x_atom_3[3] = {0.0, 0.0, 0.0}; + double x_atom_4[3] = {0.0, 0.0, 0.0}; + + // initialization + for (int m = 0; m < nbins; m++) { + for (int i = 0; i < nvalues; i++) { + dihedral_local[m][i] = 0.0; + } + local_contribution[m][0] = 0.0; + local_contribution[m][1] = 0.0; + local_contribution[m][2] = 0.0; + } + + for (atom2 = 0; atom2 < nlocal; atom2++) { + if (!(mask[atom2] & groupbit)) continue; + + if (molecular == Atom::MOLECULAR) + nd = num_dihedral[atom2]; + else { + if (molindex[atom2] < 0) continue; + imol = molindex[atom2]; + iatom = molatom[atom2]; + nd = onemols[imol]->num_dihedral[iatom]; + } + + for (i = 0; i < nd; i++) { + if (molecular == 1) { + if (tag[atom2] != dihedral_atom2[atom2][i]) continue; + atom1 = atom->map(dihedral_atom1[atom2][i]); + atom3 = atom->map(dihedral_atom3[atom2][i]); + atom4 = atom->map(dihedral_atom4[atom2][i]); + } else { + if (tag[atom2] != onemols[imol]->dihedral_atom2[atom2][i]) continue; + tagprev = tag[atom2] - iatom - 1; + atom1 = atom->map(onemols[imol]->dihedral_atom1[atom2][i] + tagprev); + atom3 = atom->map(onemols[imol]->dihedral_atom3[atom2][i] + tagprev); + atom4 = atom->map(onemols[imol]->dihedral_atom4[atom2][i] + tagprev); + } + + if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; + if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; + if (atom4 < 0 || !(mask[atom4] & groupbit)) continue; + + for (int ibin = 0; ibinminimum_image(x_atom_1[0], x_atom_1[1], x_atom_1[2]); + x_atom_1[dir] += pos; + + // minimum image of atom2 with respect to atom1 + diffx[0] = x[atom2][0] - x_atom_1[0]; + diffx[1] = x[atom2][1] - x_atom_1[1]; + diffx[2] = x[atom2][2] - x_atom_1[2]; + domain->minimum_image(diffx[0], diffx[1], diffx[2]); + x_atom_2[0] = x_atom_1[0] + diffx[0]; + x_atom_2[1] = x_atom_1[1] + diffx[1]; + x_atom_2[2] = x_atom_1[2] + diffx[2]; + + // minimum image of atom3 with respect to atom2 + diffx[0] = x[atom3][0] - x_atom_2[0]; + diffx[1] = x[atom3][1] - x_atom_2[1]; + diffx[2] = x[atom3][2] - x_atom_2[2]; + domain->minimum_image(diffx[0], diffx[1], diffx[2]); + x_atom_3[0] = x_atom_2[0] + diffx[0]; + x_atom_3[1] = x_atom_2[1] + diffx[1]; + x_atom_3[2] = x_atom_2[2] + diffx[2]; + + // minimum image of atom3 with respect to atom2 + diffx[0] = x[atom4][0] - x_atom_3[0]; + diffx[1] = x[atom4][1] - x_atom_3[1]; + diffx[2] = x[atom4][2] - x_atom_3[2]; + domain->minimum_image(diffx[0], diffx[1], diffx[2]); + x_atom_4[0] = x_atom_3[0] + diffx[0]; + x_atom_4[1] = x_atom_3[1] + diffx[1]; + x_atom_4[2] = x_atom_3[2] + diffx[2]; + + // check if any bond vector crosses the plane of interest + double tau_right = (x_atom_2[dir] - pos) / (x_atom_2[dir] - x_atom_1[dir]); + double tau_middle = (x_atom_3[dir] - pos) / (x_atom_3[dir] - x_atom_2[dir]); + double tau_left = (x_atom_4[dir] - pos) / (x_atom_4[dir] - x_atom_3[dir]); + bool right_cross = ((tau_right >=0) && (tau_right <= 1)); + bool middle_cross = ((tau_middle >= 0) && (tau_middle <= 1)); + bool left_cross = ((tau_left >=0) && (tau_left <= 1)); + + // no bonds crossing the plane + if (!right_cross && !middle_cross && !left_cross) continue; + + dihedral->born_matrix(i, atom1, atom2, atom3, atom4, dudih, du2dih); + + // first bond + vb1x = x_atom_1[0] - x_atom_2[0]; + vb1y = x_atom_1[1] - x_atom_2[1]; + vb1z = x_atom_1[2] - x_atom_2[2]; + + // second bond + vb2x = x_atom_3[0] - x_atom_2[0]; + vb2y = x_atom_3[1] - x_atom_2[1]; + vb2z = x_atom_3[2] - x_atom_2[2]; + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + + // third bond + vb3x = x_atom_4[0] - x_atom_3[0]; + vb3y = x_atom_4[1] - x_atom_3[1]; + vb3z = x_atom_4[2] - x_atom_3[2]; + + // c0 calculation + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + // 1st and 2nd angle + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + // error check + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + // forces on each particle + double a = dudih; + c = c * a; + s12 = s12 * a; + a11 = c*sb1*s1; + a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2)); + a33 = c*sb3*s2; + a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12); + a13 = -rb1*rb3*s12; + a23 = r12c2 * (c2mag*c*s2 + c1mag*s12); + + sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + + f1[0] = a11*vb1x + a12*vb2x + a13*vb3x; + f1[1] = a11*vb1y + a12*vb2y + a13*vb3y; + f1[2] = a11*vb1z + a12*vb2z + a13*vb3z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a13*vb1x + a23*vb2x + a33*vb3x; + f4[1] = a13*vb1y + a23*vb2y + a33*vb3y; + f4[2] = a13*vb1z + a23*vb2z + a33*vb3z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // only right bond crossing the plane + if (right_cross && !middle_cross && !left_cross) + { + double sgn = copysign(1.0, x_atom_1[dir] - pos); + df[0] = sgn * f1[0]; + df[1] = sgn * f1[1]; + df[2] = sgn * f1[2]; + } + + // only middle bond crossing the plane + if (!right_cross && middle_cross && !left_cross) + { + double sgn = copysign(1.0, x_atom_2[dir] - pos); + df[0] = sgn * (f2[0] + f1[0]); + df[1] = sgn * (f2[1] + f1[1]); + df[2] = sgn * (f2[2] + f1[2]); + } + + // only left bond crossing the plane + if (!right_cross && !middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_4[dir] - pos); + df[0] = sgn * f4[0]; + df[1] = sgn * f4[1]; + df[2] = sgn * f4[2]; + } + + // only right & middle bonds crossing the plane + if (right_cross && middle_cross && !left_cross) + { + double sgn = copysign(1.0, x_atom_2[dir] - pos); + df[0] = sgn * f2[0]; + df[1] = sgn * f2[1]; + df[2] = sgn * f2[2]; + } + + // only right & left bonds crossing the plane + if (right_cross && !middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_1[dir] - pos); + df[0] = sgn * (f1[0] + f4[0]); + df[1] = sgn * (f1[1] + f4[1]); + df[2] = sgn * (f1[2] + f4[2]); + } + + // only middle & left bonds crossing the plane + if (!right_cross && middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_3[dir] - pos); + df[0] = sgn * f3[0]; + df[1] = sgn * f3[1]; + df[2] = sgn * f3[2]; + } + + // all three bonds crossing the plane + if (right_cross && middle_cross && left_cross) + { + double sgn = copysign(1.0, x_atom_1[dir] - pos); + df[0] = sgn * (f1[0] + f3[0]); + df[1] = sgn * (f1[1] + f3[1]); + df[2] = sgn * (f1[2] + f3[2]); + } + + local_contribution[ibin][0] += df[0]/area*nktv2p; + local_contribution[ibin][1] += df[1]/area*nktv2p; + local_contribution[ibin][2] += df[2]/area*nktv2p; + } + } + } + + // loop over the keywords and if necessary add the dihedral contribution + int m = 0; + while (m < nvalues) { + if ((which[m] == CONF) || (which[m] == TOTAL) || (which[m] == DIHEDRAL)) { + for (int ibin = 0; ibin < nbins; ibin++) { + dihedral_local[ibin][m] = local_contribution[ibin][0]; + dihedral_local[ibin][m+1] = local_contribution[ibin][1]; + dihedral_local[ibin][m+2] = local_contribution[ibin][2]; + } + } + m += 3; + } + +} + /* ---------------------------------------------------------------------- setup 1d bins and their extent and coordinates called at init() @@ -621,47 +1197,39 @@ void ComputeStressMopProfile::setup_bins() boxlo = domain->boxlo; boxhi = domain->boxhi; - if (originflag == LOWER) - origin = boxlo[dir]; - else if (originflag == UPPER) - origin = boxhi[dir]; - else if (originflag == CENTER) - origin = 0.5 * (boxlo[dir] + boxhi[dir]); + if ((origin > domain->boxhi[dir]) || (origin < domain->boxlo[dir])) + error->all(FLERR, "Origin of bins for compute stress/mop/profile is out of bounds"); - if (origin < boxlo[dir]) { - error->all(FLERR, "Origin of bins for compute stress/mop/profile is out of bounds"); - } else { - n = static_cast((origin - boxlo[dir]) * invdelta); - lo = origin - n * delta; - } - if (origin < boxhi[dir]) { - n = static_cast((boxhi[dir] - origin) * invdelta); - hi = origin + n * delta; - } else { - error->all(FLERR, "Origin of bins for compute stress/mop/profile is out of bounds"); - } + n = static_cast ((origin - boxlo[dir]) * invdelta); + lo = origin - n*delta; + + n = static_cast ((boxhi[dir] - origin) * invdelta); + hi = origin + n*delta; offset = lo; nbins = static_cast((hi - lo) * invdelta + 1.5); - // allocate bin arrays - - memory->create(coord, nbins, 1, "stress/mop/profile:coord"); - memory->create(coordp, nbins, 1, "stress/mop/profile:coordp"); + //allocate bin arrays + memory->create(coord, nbins, "stress/mop/profile:coord"); + memory->create(coordp, nbins, "stress/mop/profile:coordp"); memory->create(values_local, nbins, nvalues, "stress/mop/profile:values_local"); memory->create(values_global, nbins, nvalues, "stress/mop/profile:values_global"); memory->create(bond_local, nbins, nvalues, "stress/mop/profile:bond_local"); memory->create(bond_global, nbins, nvalues, "stress/mop/profile:bond_global"); + memory->create(angle_local, nbins, nvalues, "stress/mop/profile:angle_local"); + memory->create(angle_global, nbins, nvalues, "stress/mop/profile:angle_global"); + memory->create(dihedral_local,nbins,nvalues,"stress/mop/profile:dihedral_local"); + memory->create(dihedral_global,nbins,nvalues,"stress/mop/profile:dihedral_global"); memory->create(local_contribution, nbins, 3, "stress/mop/profile:local_contribution"); // set bin coordinates for (i = 0; i < nbins; i++) { - coord[i][0] = offset + i * delta; - if (coord[i][0] < (domain->boxlo[dir] + domain->prd_half[dir])) { - coordp[i][0] = coord[i][0] + domain->prd[dir]; + coord[i] = offset + i * delta; + if (coord[i] < (domain->boxlo[dir] + domain->prd_half[dir])) { + coordp[i] = coord[i] + domain->prd[dir]; } else { - coordp[i][0] = coord[i][0] - domain->prd[dir]; + coordp[i] = coord[i] - domain->prd[dir]; } } } diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.h b/src/EXTRA-COMPUTE/compute_stress_mop_profile.h index 2b0ffef0f8..b9b97617c0 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.h @@ -39,19 +39,22 @@ class ComputeStressMopProfile : public Compute { private: void compute_pairs(); void compute_bonds(); + void compute_angles(); + void compute_dihedrals(); void setup_bins(); int nvalues, dir; int *which; - int bondflag; + int bondflag, angleflag, dihedralflag; - int originflag; double origin, delta, offset, invdelta; int nbins; - double **coord, **coordp; + double *coord, *coordp; double **values_local, **values_global; double **bond_local, **bond_global; + double **angle_local, **angle_global; + double **dihedral_local, **dihedral_global; double **local_contribution; double dt, nktv2p, ftm2v; diff --git a/src/EXTRA-FIX/fix_nonaffine_displacement.cpp b/src/EXTRA-FIX/fix_nonaffine_displacement.cpp index ef5481601f..c1de50c41d 100644 --- a/src/EXTRA-FIX/fix_nonaffine_displacement.cpp +++ b/src/EXTRA-FIX/fix_nonaffine_displacement.cpp @@ -71,6 +71,7 @@ FixNonaffineDisplacement::FixNonaffineDisplacement(LAMMPS *lmp, int narg, char * nevery = utils::inumeric(FLERR, arg[3], false, lmp); if (nevery <= 0) error->all(FLERR,"Illegal nevery value {} in fix nonaffine/displacement", nevery); + reference_timestep = update_timestep = offset_timestep = -1; int iarg = 4; if (strcmp(arg[iarg], "integrated") == 0) { nad_style = INTEGRATED; @@ -99,7 +100,7 @@ FixNonaffineDisplacement::FixNonaffineDisplacement(LAMMPS *lmp, int narg, char * if (strcmp(arg[iarg], "fixed") == 0) { reference_style = FIXED; reference_timestep = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); - if (update_timestep < 0) + if (reference_timestep < 0) error->all(FLERR, "Illegal reference timestep {} in fix nonaffine/displacement", arg[iarg + 1]); } else if (strcmp(arg[iarg], "update") == 0) { reference_style = UPDATE; diff --git a/src/EXTRA-FIX/fix_nonaffine_displacement.h b/src/EXTRA-FIX/fix_nonaffine_displacement.h index 0a195dc08e..3341ab1834 100644 --- a/src/EXTRA-FIX/fix_nonaffine_displacement.h +++ b/src/EXTRA-FIX/fix_nonaffine_displacement.h @@ -32,7 +32,7 @@ class FixNonaffineDisplacement : public Fix { void post_constructor() override; void init() override; void init_list(int, class NeighList *) override; - void setup(int); + void setup(int) override; void post_force(int) override; void write_restart(FILE *fp) override; void restart(char *buf) override; @@ -62,7 +62,7 @@ class FixNonaffineDisplacement : public Fix { void calculate_D2Min(); void save_reference_state(); void minimum_image0(double *); - void grow_arrays(int); + void grow_arrays(int) override; }; } // namespace LAMMPS_NS diff --git a/src/EXTRA-MOLECULE/angle_cosine_periodic.cpp b/src/EXTRA-MOLECULE/angle_cosine_periodic.cpp index 15d0575f6d..34a8e9d8e5 100644 --- a/src/EXTRA-MOLECULE/angle_cosine_periodic.cpp +++ b/src/EXTRA-MOLECULE/angle_cosine_periodic.cpp @@ -38,7 +38,10 @@ using namespace MathSpecial; /* ---------------------------------------------------------------------- */ -AngleCosinePeriodic::AngleCosinePeriodic(LAMMPS *lmp) : Angle(lmp) {} +AngleCosinePeriodic::AngleCosinePeriodic(LAMMPS *lmp) : Angle(lmp) +{ + born_matrix_enable = 1; +} /* ---------------------------------------------------------------------- */ @@ -298,3 +301,38 @@ double AngleCosinePeriodic::single(int type, int i1, int i2, int i3) c = cos(acos(c)*multiplicity[type]); return 2.0*k[type]*(1.0-b[type]*powsign(multiplicity[type])*c); } + +/* ---------------------------------------------------------------------- */ + +void AngleCosinePeriodic::born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) +{ + double **x = atom->x; + + double delx1 = x[i1][0] - x[i2][0]; + double dely1 = x[i1][1] - x[i2][1]; + double delz1 = x[i1][2] - x[i2][2]; + domain->minimum_image(delx1,dely1,delz1); + double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); + + double delx2 = x[i3][0] - x[i2][0]; + double dely2 = x[i3][1] - x[i2][1]; + double delz2 = x[i3][2] - x[i2][2]; + domain->minimum_image(delx2,dely2,delz2); + double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); + + double c = delx1*delx2 + dely1*dely2 + delz1*delz2; + c /= r1*r2; + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + double theta = acos(c); + + double s = sqrt(1.0 - c*c); + if (s < SMALL) s = SMALL; + s = 1.0/s; + + double m_angle = multiplicity[type] * theta; + double prefactor = -2.0 * k[type] * b[type] * powsign(multiplicity[type]) * multiplicity[type]; + + du = prefactor * sin(m_angle) / s; + du2 = prefactor * (c * sin(m_angle) - s * cos(m_angle) * multiplicity[type]) / (s * s * s); +} diff --git a/src/EXTRA-MOLECULE/angle_cosine_periodic.h b/src/EXTRA-MOLECULE/angle_cosine_periodic.h index 4e584b4543..f04ed04784 100644 --- a/src/EXTRA-MOLECULE/angle_cosine_periodic.h +++ b/src/EXTRA-MOLECULE/angle_cosine_periodic.h @@ -35,6 +35,7 @@ class AngleCosinePeriodic : public Angle { void read_restart(FILE *) override; void write_data(FILE *) override; double single(int, int, int, int) override; + void born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) override; protected: double *k; diff --git a/src/EXTRA-MOLECULE/angle_fourier.cpp b/src/EXTRA-MOLECULE/angle_fourier.cpp index 549da0c196..c7eb3d4fe4 100644 --- a/src/EXTRA-MOLECULE/angle_fourier.cpp +++ b/src/EXTRA-MOLECULE/angle_fourier.cpp @@ -39,6 +39,7 @@ using namespace MathConst; AngleFourier::AngleFourier(LAMMPS *lmp) : Angle(lmp) { + born_matrix_enable = 1; k = nullptr; C0 = nullptr; C1 = nullptr; diff --git a/src/EXTRA-MOLECULE/angle_quartic.cpp b/src/EXTRA-MOLECULE/angle_quartic.cpp index f28e209a77..eaccdbe608 100644 --- a/src/EXTRA-MOLECULE/angle_quartic.cpp +++ b/src/EXTRA-MOLECULE/angle_quartic.cpp @@ -37,7 +37,10 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -AngleQuartic::AngleQuartic(LAMMPS *lmp) : Angle(lmp) {} +AngleQuartic::AngleQuartic(LAMMPS *lmp) : Angle(lmp) +{ + born_matrix_enable = 1; +} /* ---------------------------------------------------------------------- */ @@ -286,3 +289,39 @@ double AngleQuartic::single(int type, int i1, int i2, int i3) double dtheta4 = dtheta3 * dtheta; return k2[type] * dtheta2 + k3[type] * dtheta3 + k4[type] * dtheta4; } + +/* ---------------------------------------------------------------------- */ + +void AngleQuartic::born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) +{ + double **x = atom->x; + + double delx1 = x[i1][0] - x[i2][0]; + double dely1 = x[i1][1] - x[i2][1]; + double delz1 = x[i1][2] - x[i2][2]; + domain->minimum_image(delx1,dely1,delz1); + double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); + + double delx2 = x[i3][0] - x[i2][0]; + double dely2 = x[i3][1] - x[i2][1]; + double delz2 = x[i3][2] - x[i2][2]; + domain->minimum_image(delx2,dely2,delz2); + double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); + + double c = delx1*delx2 + dely1*dely2 + delz1*delz2; + c /= r1*r2; + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + double theta = acos(c); + + double s = sqrt(1.0 - c*c); + if (s < SMALL) s = SMALL; + + double dtheta = theta - theta0[type]; + double dtheta2 = dtheta * dtheta; + double dtheta3 = dtheta2 * dtheta; + + du = -(2.0 * k2[type] * dtheta + 3.0 * k3[type] * dtheta2 + 4.0 * k4[type] * dtheta3) / s; + du2 = (2.0 * k2[type] + 6.0 * k3[type] * dtheta + 12.0 * k4[type] * dtheta2) / (s*s) - + (2.0 * k2[type] * dtheta + 3.0 * k3[type] * dtheta2 + 4.0 * k4[type] * dtheta3) * c / (s*s*s); +} diff --git a/src/EXTRA-MOLECULE/angle_quartic.h b/src/EXTRA-MOLECULE/angle_quartic.h index 3f0396f27b..7de51b24d1 100644 --- a/src/EXTRA-MOLECULE/angle_quartic.h +++ b/src/EXTRA-MOLECULE/angle_quartic.h @@ -35,6 +35,7 @@ class AngleQuartic : public Angle { void read_restart(FILE *) override; void write_data(FILE *) override; double single(int, int, int, int) override; + void born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) override; protected: double *k2, *k3, *k4, *theta0; diff --git a/src/EXTRA-MOLECULE/bond_gaussian.cpp b/src/EXTRA-MOLECULE/bond_gaussian.cpp index baca0b6e1a..9a8546e278 100644 --- a/src/EXTRA-MOLECULE/bond_gaussian.cpp +++ b/src/EXTRA-MOLECULE/bond_gaussian.cpp @@ -35,6 +35,7 @@ BondGaussian::BondGaussian(LAMMPS *lmp) : Bond(lmp), nterms(nullptr), bond_temperature(nullptr), alpha(nullptr), width(nullptr), r0(nullptr) { + born_matrix_enable = 1; } /* ---------------------------------------------------------------------- */ @@ -294,3 +295,45 @@ double BondGaussian::single(int type, double rsq, int /*i*/, int /*j*/, double & return -(force->boltz * bond_temperature[type]) * log(sum_g_i); } + +/* ---------------------------------------------------------------------- */ + +void BondGaussian::born_matrix(int type, double rsq, int /*i*/, int /*j*/, double &du, double &du2) +{ + double r = sqrt(rsq); + + // first derivative of energy with respect to distance + double sum_g_i = 0.0; + double sum_numerator = 0.0; + for (int i = 0; i < nterms[type]; i++) { + double dr = r - r0[type][i]; + double prefactor = (alpha[type][i] / (width[type][i] * sqrt(MY_PI2))); + double exponent = -2 * dr * dr / (width[type][i] * width[type][i]); + double g_i = prefactor * exp(exponent); + sum_g_i += g_i; + sum_numerator += g_i * dr / (width[type][i] * width[type][i]); + } + + if (sum_g_i < SMALL) sum_g_i = SMALL; + du = 4.0 * (force->boltz * bond_temperature[type]) * (sum_numerator / sum_g_i); + + // second derivative of energy with respect to distance + sum_g_i = 0.0; + double sum_dg_i = 0.0; + double sum_d2g_i = 0.0; + for (int i = 0; i < nterms[type]; i++) { + double dr = r - r0[type][i]; + double prefactor = (alpha[type][i] / (width[type][i] * sqrt(MY_PI2))); + double exponent = -2 * dr * dr / (width[type][i] * width[type][i]); + double g_i = prefactor * exp(exponent); + sum_g_i += g_i; + sum_dg_i -= 4.0 * g_i * dr / pow(width[type][i], 2); + sum_d2g_i += 4.0 * g_i * (4.0 * pow(r0[type][i], 2) - 8.0 * r0[type][i] * r - pow(width[type][i], 2) + 4.0 * r * r) / pow(width[type][i], 4) ; + } + + if (sum_g_i < SMALL) sum_g_i = SMALL; + double numerator = sum_d2g_i*sum_g_i - sum_dg_i*sum_dg_i; + double denominator = sum_g_i * sum_g_i; + + du2 = - (force->boltz * bond_temperature[type]) * numerator / denominator; +} diff --git a/src/EXTRA-MOLECULE/bond_gaussian.h b/src/EXTRA-MOLECULE/bond_gaussian.h index 7af6f1f4d9..e466df47d4 100644 --- a/src/EXTRA-MOLECULE/bond_gaussian.h +++ b/src/EXTRA-MOLECULE/bond_gaussian.h @@ -35,6 +35,7 @@ class BondGaussian : public Bond { void read_restart(FILE *) override; void write_data(FILE *) override; double single(int, double, int, int, double &) override; + void born_matrix(int, double, int, int, double &, double &) override; protected: int *nterms; diff --git a/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.cpp b/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.cpp index fedcb95ee8..ebcfdb0258 100644 --- a/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.cpp +++ b/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.cpp @@ -31,7 +31,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -BondHarmonicShiftCut::BondHarmonicShiftCut(LAMMPS *lmp) : Bond(lmp) {} +BondHarmonicShiftCut::BondHarmonicShiftCut(LAMMPS *lmp) : Bond(lmp) +{ + born_matrix_enable = 1; +} /* ---------------------------------------------------------------------- */ @@ -219,3 +222,19 @@ double BondHarmonicShiftCut::single(int type, double rsq, int /*i*/, int /*j*/, fforce = -2.0*k[type]*dr/r; return k[type]*(dr*dr - dr2*dr2); } + +/* ---------------------------------------------------------------------- */ + +void BondHarmonicShiftCut::born_matrix(int type, double rsq, int /*i*/, int /*j*/, double &du, double &du2) +{ + du = 0.0; + du2 = 0.0; + + double r = sqrt(rsq); + if (r>r1[type]) return; + + double dr = r - r0[type]; + + du2 = 2 * k[type]; + if (r > 0.0) du = du2 * dr; +} diff --git a/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.h b/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.h index 752ac010d9..09d6ab5330 100644 --- a/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.h +++ b/src/EXTRA-MOLECULE/bond_harmonic_shift_cut.h @@ -35,6 +35,7 @@ class BondHarmonicShiftCut : public Bond { void read_restart(FILE *) override; void write_data(FILE *) override; double single(int, double, int, int, double &) override; + void born_matrix(int, double, int, int, double &, double &) override; protected: double *k, *r0, *r1; diff --git a/src/EXTRA-MOLECULE/dihedral_helix.cpp b/src/EXTRA-MOLECULE/dihedral_helix.cpp index 059bef74a4..1d99de6ba9 100644 --- a/src/EXTRA-MOLECULE/dihedral_helix.cpp +++ b/src/EXTRA-MOLECULE/dihedral_helix.cpp @@ -41,6 +41,7 @@ using namespace MathConst; DihedralHelix::DihedralHelix(LAMMPS *lmp) : Dihedral(lmp) { writedata = 1; + born_matrix_enable = 1; } /* ---------------------------------------------------------------------- */ @@ -324,3 +325,108 @@ void DihedralHelix::write_data(FILE *fp) for (int i = 1; i <= atom->ndihedraltypes; i++) fprintf(fp,"%d %g %g %g\n",i,aphi[i],bphi[i],cphi[i]); } + +/* ----------------------------------------------------------------------*/ + +void DihedralHelix::born_matrix(int nd, int i1, int i2, int i3, int i4, + double &du, double &du2) +{ + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double sb1,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; + double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; + double c2mag,sc1,sc2,s12,c; + double cx,cy,cz,cmag,dx,phi,si,siinv,sin2; + + int **dihedrallist = neighbor->dihedrallist; + double **x = atom->x; + + int type = dihedrallist[nd][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + + // 3rd bond + + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + + // c0 calculation + + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // 1st and 2nd angle + + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + cx = vb1y*vb2z - vb1z*vb2y; + cy = vb1z*vb2x - vb1x*vb2z; + cz = vb1x*vb2y - vb1y*vb2x; + cmag = sqrt(cx*cx + cy*cy + cz*cz); + dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) problem(FLERR, i1, i2, i3, i4); + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + phi = acos(c); + if (dx > 0.0) phi *= -1.0; + si = sin(phi); + if (fabs(si) < SMALLER) si = SMALLER; + siinv = 1.0/si; + + du = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + + cphi[type]*sin(phi + MY_PI4)*siinv; + du2 = -(9.0*bphi[type]*cos(3.0*phi) + cphi[type]*cos(phi + MY_PI4))*siinv*siinv + + (3.0*bphi[type]*sin(3.0*phi) + cphi[type]*sin(phi + MY_PI4))*c*siinv*siinv*siinv; +} diff --git a/src/EXTRA-MOLECULE/dihedral_helix.h b/src/EXTRA-MOLECULE/dihedral_helix.h index 436895c5c3..172a8c3469 100644 --- a/src/EXTRA-MOLECULE/dihedral_helix.h +++ b/src/EXTRA-MOLECULE/dihedral_helix.h @@ -33,6 +33,7 @@ class DihedralHelix : public Dihedral { void write_restart(FILE *) override; void read_restart(FILE *) override; void write_data(FILE *) override; + void born_matrix(int, int, int, int, int, double &, double &) override; protected: double *aphi, *bphi, *cphi; diff --git a/src/EXTRA-MOLECULE/dihedral_quadratic.cpp b/src/EXTRA-MOLECULE/dihedral_quadratic.cpp index cbe9e3e3a2..f576e6efdd 100644 --- a/src/EXTRA-MOLECULE/dihedral_quadratic.cpp +++ b/src/EXTRA-MOLECULE/dihedral_quadratic.cpp @@ -41,6 +41,7 @@ using namespace MathConst; DihedralQuadratic::DihedralQuadratic(LAMMPS *lmp) : Dihedral(lmp) { writedata = 1; + born_matrix_enable = 1; } /* ---------------------------------------------------------------------- */ @@ -327,3 +328,112 @@ void DihedralQuadratic::write_data(FILE *fp) for (int i = 1; i <= atom->ndihedraltypes; i++) fprintf(fp,"%d %g %g \n",i,k[i],phi0[i]*180.0/MY_PI); } + +/* ----------------------------------------------------------------------*/ + +void DihedralQuadratic::born_matrix(int nd, int i1, int i2, int i3, int i4, + double &du, double &du2) +{ + double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; + double sb1,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; + double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; + double c2mag,sc1,sc2,s12,c; + double s1,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; + + int **dihedrallist = neighbor->dihedrallist; + double **x = atom->x; + + int type = dihedrallist[nd][4]; + + // 1st bond + + vb1x = x[i1][0] - x[i2][0]; + vb1y = x[i1][1] - x[i2][1]; + vb1z = x[i1][2] - x[i2][2]; + + // 2nd bond + + vb2x = x[i3][0] - x[i2][0]; + vb2y = x[i3][1] - x[i2][1]; + vb2z = x[i3][2] - x[i2][2]; + + vb2xm = -vb2x; + vb2ym = -vb2y; + vb2zm = -vb2z; + + // 3rd bond + vb3x = x[i4][0] - x[i3][0]; + vb3y = x[i4][1] - x[i3][1]; + vb3z = x[i4][2] - x[i3][2]; + + // c0 calculation + + sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + rb1 = sqrt(sb1); + rb3 = sqrt(sb3); + + c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // 1st and 2nd angle + + b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + b1mag = sqrt(b1mag2); + b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + b2mag = sqrt(b2mag2); + b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + b3mag = sqrt(b3mag2); + + ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + r12c1 = 1.0 / (b1mag*b2mag); + c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + r12c2 = 1.0 / (b2mag*b3mag); + c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + + sin2 = MAX(1.0 - c1mag*c1mag,0.0); + sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + s1 = sc1 * sc1; + s2 = sc2 * sc2; + s12 = sc1 * sc2; + c = (c0 + c1mag*c2mag) * s12; + + cx = vb1y*vb2z - vb1z*vb2y; + cy = vb1z*vb2x - vb1x*vb2z; + cz = vb1x*vb2y - vb1y*vb2x; + cmag = sqrt(cx*cx + cy*cy + cz*cz); + dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; + + // error check + + if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) + problem(FLERR, i1, i2, i3, i4); + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + phi = acos(c); + if (dx > 0.0) phi *= -1.0; + si = sin(phi); + if (fabs(si) < SMALLER) si = SMALLER; + siinv = 1.0/si; + + double dphi = phi-phi0[type]; + if (dphi > MY_PI) dphi -= 2*MY_PI; + else if (dphi < -MY_PI) dphi += 2*MY_PI; + + du = - 2.0 * k[type] * dphi * siinv; + du2 = 2.0 * k[type] * siinv * siinv * ( 1.0 - dphi * c * siinv) ; +} diff --git a/src/EXTRA-MOLECULE/dihedral_quadratic.h b/src/EXTRA-MOLECULE/dihedral_quadratic.h index 90d8c3be6e..89f6fa3b25 100644 --- a/src/EXTRA-MOLECULE/dihedral_quadratic.h +++ b/src/EXTRA-MOLECULE/dihedral_quadratic.h @@ -33,6 +33,7 @@ class DihedralQuadratic : public Dihedral { void write_restart(FILE *) override; void read_restart(FILE *) override; void write_data(FILE *) override; + void born_matrix(int, int, int, int, int, double &, double &) override; protected: double *k, *phi0; diff --git a/src/FEP/fix_adapt_fep.cpp b/src/FEP/fix_adapt_fep.cpp index c32b44b081..e0c5868e96 100644 --- a/src/FEP/fix_adapt_fep.cpp +++ b/src/FEP/fix_adapt_fep.cpp @@ -48,9 +48,9 @@ enum{DIAMETER, CHARGE}; FixAdaptFEP::FixAdaptFEP(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 5) error->all(FLERR,"Illegal fix adapt/fep command"); + if (narg < 5) utils::missing_cmd_args(FLERR,"fix adapt/fep", error); nevery = utils::inumeric(FLERR,arg[3],false,lmp); - if (nevery < 0) error->all(FLERR,"Illegal fix adapt/fep command"); + if (nevery < 0) error->all(FLERR,"Illegal fix adapt/fep every value {}", nevery); dynamic_group_allow = 1; create_attribute = 1; @@ -62,21 +62,21 @@ FixAdaptFEP::FixAdaptFEP(LAMMPS *lmp, int narg, char **arg) : int iarg = 4; while (iarg < narg) { if (strcmp(arg[iarg],"pair") == 0) { - if (iarg+6 > narg) error->all(FLERR,"Illegal fix adapt/fep command"); + if (iarg+6 > narg) utils::missing_cmd_args(FLERR,"fix adapt/fep pair", error); nadapt++; iarg += 6; } else if (strcmp(arg[iarg],"kspace") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt/fep command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR,"fix adapt/fep kspace", error); nadapt++; iarg += 2; } else if (strcmp(arg[iarg],"atom") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal fix adapt/fep command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR,"fix adapt/fep atom", error); nadapt++; iarg += 4; } else break; } - if (nadapt == 0) error->all(FLERR,"Illegal fix adapt/fep command"); + if (nadapt == 0) error->all(FLERR,"Nothing to adapt in fix adapt/fep command"); adapt = new Adapt[nadapt]; // parse keywords @@ -136,11 +136,11 @@ FixAdaptFEP::FixAdaptFEP(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"reset") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt/fep command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR,"fix adapt/fep reset", error); resetflag = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"scale") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix adapt/fep command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR,"fix adapt/fep scale", error); scaleflag = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"after") == 0) { @@ -208,7 +208,7 @@ void FixAdaptFEP::post_constructor() id_fix_diam = nullptr; id_fix_chg = nullptr; - if (diam_flag) { + if (diam_flag && atom->radius_flag) { id_fix_diam = utils::strdup(id + std::string("_FIX_STORE_DIAM")); fix_diam = dynamic_cast( modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1", id_fix_diam,group->names[igroup]))); @@ -226,7 +226,7 @@ void FixAdaptFEP::post_constructor() } } - if (chgflag) { + if (chgflag && atom->q_flag) { id_fix_chg = utils::strdup(id + std::string("_FIX_STORE_CHG")); fix_chg = dynamic_cast( modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1",id_fix_chg,group->names[igroup]))); @@ -267,9 +267,9 @@ void FixAdaptFEP::init() ad->ivar = input->variable->find(ad->var); if (ad->ivar < 0) - error->all(FLERR,"Variable name for fix adapt/fep does not exist"); + error->all(FLERR,"Variable name {} for fix adapt/fep does not exist", ad->var); if (!input->variable->equalstyle(ad->ivar)) - error->all(FLERR,"Variable for fix adapt/fep is invalid style"); + error->all(FLERR,"Variable {} for fix adapt/fep is invalid style", ad->var); if (ad->which == PAIR) { anypair = 1; @@ -285,8 +285,9 @@ void FixAdaptFEP::init() if (ptr == nullptr) error->all(FLERR,"Fix adapt/fep pair style param not supported"); - ad->pdim = 2; - if (ad->pdim == 0) ad->scalar = (double *) ptr; + if (ad->pdim != 2) + error->all(FLERR,"Pair style parameter {} is not compatible with fix adapt/fep", ad->pparam); + if (ad->pdim == 2) ad->array = (double **) ptr; // if pair hybrid, test that ilo,ihi,jlo,jhi are valid for sub-style diff --git a/src/GPU/pair_coul_slater_long_gpu.cpp b/src/GPU/pair_coul_slater_long_gpu.cpp new file mode 100644 index 0000000000..4ace8bd761 --- /dev/null +++ b/src/GPU/pair_coul_slater_long_gpu.cpp @@ -0,0 +1,254 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_coul_slater_long_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "kspace.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" + +#include + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int csl_gpu_init(const int ntypes, double **scale, const int nlocal, const int nall, + const int max_nbors, const int maxspecial, const double cell_size, int &gpu_mode, + FILE *screen, double host_cut_coulsq, double *host_special_coul, + const double qqrd2e, const double g_ewald, const double lamda); +void csl_gpu_reinit(const int ntypes, double **scale); +void csl_gpu_clear(); +int **csl_gpu_compute_n(const int ago, const int inum, const int nall, double **host_x, + int *host_type, double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, const bool eatom, + const bool vatom, int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success, double *host_q, double *boxlo, + double *prd); +void csl_gpu_compute(const int ago, const int inum, const int nall, double **host_x, int *host_type, + int *ilist, int *numj, int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, const double cpu_time, + bool &success, double *host_q, const int nlocal, double *boxlo, double *prd); +double csl_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairCoulSlaterLongGPU::PairCoulSlaterLongGPU(LAMMPS *lmp) : PairCoulSlaterLong(lmp), gpu_mode(GPU_FORCE) +{ + respa_enable = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairCoulSlaterLongGPU::~PairCoulSlaterLongGPU() +{ + csl_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulSlaterLongGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = csl_gpu_compute_n(neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, + atom->tag, atom->nspecial, atom->special, eflag, vflag, + eflag_atom, vflag_atom, host_start, &ilist, &numneigh, cpu_time, + success, atom->q, domain->boxlo, domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + csl_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, atom->q, + atom->nlocal, domain->boxlo, domain->prd); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); + if (host_start < inum) { + cpu_time = platform::walltime(); + cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh); + cpu_time = platform::walltime() - cpu_time; + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairCoulSlaterLongGPU::init_style() +{ + if (!atom->q_flag) error->all(FLERR, "Pair style coul/slater/long/gpu requires atom attribute q"); + + // Call init_one calculation make sure scale is correct + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { init_one(i, j); } + } + } + double cell_size = cut_coul + neighbor->skin; + + cut_coulsq = cut_coul * cut_coul; + + // ensure use of KSpace long-range solver, set g_ewald + + if (force->kspace == nullptr) error->all(FLERR, "Pair style requires a KSpace style"); + g_ewald = force->kspace->g_ewald; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = csl_gpu_init(atom->ntypes + 1, scale, atom->nlocal, atom->nlocal + atom->nghost, mnf, + maxspecial, cell_size, gpu_mode, screen, cut_coulsq, + force->special_coul, force->qqrd2e, g_ewald, lamda); + + GPU_EXTRA::check_flag(success, error, world); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulSlaterLongGPU::reinit() +{ + Pair::reinit(); + + csl_gpu_reinit(atom->ntypes + 1, scale); +} + +/* ---------------------------------------------------------------------- */ + +double PairCoulSlaterLongGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + csl_gpu_bytes(); +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulSlaterLongGPU::cpu_compute(int start, int inum, int eflag, int /* vflag */, int *ilist, + int *numneigh, int **firstneigh) +{ + int i, j, ii, jj, jnum; + double qtmp, xtmp, ytmp, ztmp, delx, dely, delz, ecoul, fpair; + double r, r2inv, forcecoul, factor_coul; + double grij, expm2, prefactor, t, erfc; + int *jlist; + double rsq; + + ecoul = 0.0; + + double **x = atom->x; + double **f = atom->f; + double *q = atom->q; + double *special_coul = force->special_coul; + double qqrd2e = force->qqrd2e; + + // loop over neighbors of my atoms + + for (ii = start; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + r2inv = 1.0 / rsq; + + if (rsq < cut_coulsq) { + r2inv = 1.0/rsq; + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij*grij); + t = 1.0 / (1.0 + EWALD_P*grij); + erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + double slater_term = exp(-2*r/lamda)*(1 + (2*r/lamda*(1+r/lamda))); + prefactor = qqrd2e * qtmp*q[j]/r; + forcecoul = prefactor * (erfc + EWALD_F*grij*expm2 - slater_term); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor*(1-slater_term); + + fpair = forcecoul * r2inv; + + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; + + if (eflag) { + if (rsq < cut_coulsq) { + ecoul = prefactor*(erfc - (1 + r/lamda)*exp(-2*r/lamda)); + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor*(1.0-(1 + r/lamda)*exp(-2*r/lamda)); + } else + ecoul = 0.0; + } + + if (evflag) ev_tally_full(i, 0.0, ecoul, fpair, delx, dely, delz); + } + } + } +} diff --git a/src/GPU/pair_coul_slater_long_gpu.h b/src/GPU/pair_coul_slater_long_gpu.h new file mode 100644 index 0000000000..4a30a71d25 --- /dev/null +++ b/src/GPU/pair_coul_slater_long_gpu.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(coul/slater/long/gpu,PairCoulSlaterLongGPU); +// clang-format on +#else + +#ifndef LMP_PAIR_COUL_SLATER_LONG_GPU_H +#define LMP_PAIR_COUL_SLATER_LONG_GPU_H + +#include "pair_coul_slater_long.h" + +namespace LAMMPS_NS { + +class PairCoulSlaterLongGPU : public PairCoulSlaterLong { + public: + PairCoulSlaterLongGPU(LAMMPS *lmp); + ~PairCoulSlaterLongGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + void reinit() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + private: + int gpu_mode; + double cpu_time; +}; + +} // namespace LAMMPS_NS +#endif +#endif diff --git a/src/GPU/pair_edpd_gpu.cpp b/src/GPU/pair_edpd_gpu.cpp new file mode 100644 index 0000000000..5bee0cadb8 --- /dev/null +++ b/src/GPU/pair_edpd_gpu.cpp @@ -0,0 +1,195 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Dac Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_edpd_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "info.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int edpd_gpu_init(const int ntypes, double **cutsq, double **host_a0, double **host_gamma, + double **host_cut, double **host_power, double **host_kappa, + double **host_powerT, double** host_cutT, double*** host_sc, double ***host_kc, + double *host_mass, double *special_lj, const int power_flag, const int kappa_flag, + const int inum, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, int &gpu_mode, FILE *screen); +void edpd_gpu_clear(); +int **edpd_gpu_compute_n(const int ago, const int inum_full, const int nall, double **host_x, + int *host_type, double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, const bool eatom, + const bool vatom, int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success, double **host_v, + const double dtinvsqrt, const int seed, const int timestep, double *boxlo, + double *prd); +void edpd_gpu_compute(const int ago, const int inum_full, const int nall, double **host_x, + int *host_type, int *ilist, int *numj, int **firstneigh, const bool eflag, + const bool vflag, const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, double **host_v, + const double dtinvsqrt, const int seed, const int timestep, const int nlocal, + double *boxlo, double *prd); +void edpd_gpu_get_extra_data(double *host_T, double *host_cv); +void edpd_gpu_update_flux(void **flux_ptr); +double edpd_gpu_bytes(); + +#define EPSILON 1.0e-10 + +/* ---------------------------------------------------------------------- */ + +PairEDPDGPU::PairEDPDGPU(LAMMPS *lmp) : PairEDPD(lmp), gpu_mode(GPU_FORCE) +{ + flux_pinned = nullptr; + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairEDPDGPU::~PairEDPDGPU() +{ + edpd_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairEDPDGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + double dtinvsqrt = 1.0 / sqrt(update->dt); + + bool success = true; + int *ilist, *numneigh, **firstneigh; + + double *T = atom->edpd_temp; + double *cv = atom->edpd_cv; + edpd_gpu_get_extra_data(T, cv); + + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = edpd_gpu_compute_n( + neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, atom->nspecial, + atom->special, eflag, vflag, eflag_atom, vflag_atom, host_start, &ilist, &numneigh, + cpu_time, success, atom->v, dtinvsqrt, seed, update->ntimestep, domain->boxlo, domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + edpd_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, atom->tag, + atom->v, dtinvsqrt, seed, update->ntimestep, atom->nlocal, domain->boxlo, domain->prd); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + // get the heat flux from device + + double *Q = atom->edpd_flux; + edpd_gpu_update_flux(&flux_pinned); + + int nlocal = atom->nlocal; + if (acc_float) { + auto flux_ptr = (float *)flux_pinned; + for (int i = 0; i < nlocal; i++) + Q[i] = flux_ptr[i]; + + } else { + auto flux_ptr = (double *)flux_pinned; + for (int i = 0; i < nlocal; i++) + Q[i] = flux_ptr[i]; + } + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairEDPDGPU::init_style() +{ + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double mcut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + mcut = init_one(i, j); + mcut *= mcut; + if (mcut > maxcut) maxcut = mcut; + cutsq[i][j] = cutsq[j][i] = mcut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + edpd_gpu_init(atom->ntypes + 1, cutsq, a0, gamma, cut, power, kappa, + powerT, cutT, sc, kc, atom->mass, force->special_lj, + power_flag, kappa_flag, atom->nlocal, atom->nlocal + atom->nghost, + mnf, maxspecial, cell_size, gpu_mode, screen); + GPU_EXTRA::check_flag(success, error, world); + + acc_float = Info::has_accelerator_feature("GPU", "precision", "single"); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +double PairEDPDGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + edpd_gpu_bytes(); +} diff --git a/src/npair_half_size_nsq_newton.h b/src/GPU/pair_edpd_gpu.h similarity index 61% rename from src/npair_half_size_nsq_newton.h rename to src/GPU/pair_edpd_gpu.h index d55785bd72..75495b2ca4 100644 --- a/src/npair_half_size_nsq_newton.h +++ b/src/GPU/pair_edpd_gpu.h @@ -11,28 +11,38 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef PAIR_CLASS // clang-format off -NPairStyle(half/size/nsq/newton, - NPairHalfSizeNsqNewton, - NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTON | NP_ORTHO | NP_TRI); +PairStyle(edpd/gpu,PairEDPDGPU); // clang-format on #else -#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_H -#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_H +#ifndef LMP_PAIR_EDPD_GPU_H +#define LMP_PAIR_EDPD_GPU_H -#include "npair.h" +#include "pair_edpd.h" namespace LAMMPS_NS { -class NPairHalfSizeNsqNewton : public NPair { +class PairEDPDGPU : public PairEDPD { public: - NPairHalfSizeNsqNewton(class LAMMPS *); - void build(class NeighList *) override; + PairEDPDGPU(LAMMPS *lmp); + ~PairEDPDGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + void *flux_pinned; + bool acc_float; + + private: + int gpu_mode; + double cpu_time; }; } // namespace LAMMPS_NS - #endif #endif diff --git a/src/GPU/pair_lj_cut_coul_cut_soft_gpu.cpp b/src/GPU/pair_lj_cut_coul_cut_soft_gpu.cpp new file mode 100644 index 0000000000..cfde3ab632 --- /dev/null +++ b/src/GPU/pair_lj_cut_coul_cut_soft_gpu.cpp @@ -0,0 +1,249 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS Development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_lj_cut_coul_cut_soft_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" + +#include + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int ljcs_gpu_init(const int ntypes, double **cutsq, double **host_lj1, double **host_lj2, + double **host_lj3, double **host_lj4, double **offset, double **epsilon, double *special_lj, + const int nlocal, const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, double **host_cut_ljsq, + double **host_cut_coulsq, double *host_special_coul, const double qqrd2e); +void ljcs_gpu_clear(); +int **ljcs_gpu_compute_n(const int ago, const int inum, const int nall, double **host_x, + int *host_type, double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, const bool eatom, + const bool vatom, int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success, double *host_q, double *boxlo, + double *prd); +void ljcs_gpu_compute(const int ago, const int inum, const int nall, double **host_x, int *host_type, + int *ilist, int *numj, int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, const double cpu_time, + bool &success, double *host_q, const int nlocal, double *boxlo, double *prd); +double ljcs_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulCutSoftGPU::PairLJCutCoulCutSoftGPU(LAMMPS *lmp) : + PairLJCutCoulCutSoft(lmp), gpu_mode(GPU_FORCE) +{ + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairLJCutCoulCutSoftGPU::~PairLJCutCoulCutSoftGPU() +{ + ljcs_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulCutSoftGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = ljcs_gpu_compute_n(neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, + atom->tag, atom->nspecial, atom->special, eflag, vflag, + eflag_atom, vflag_atom, host_start, &ilist, &numneigh, cpu_time, + success, atom->q, domain->boxlo, domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + ljcs_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, atom->q, + atom->nlocal, domain->boxlo, domain->prd); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); + if (host_start < inum) { + cpu_time = platform::walltime(); + cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh); + cpu_time = platform::walltime() - cpu_time; + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairLJCutCoulCutSoftGPU::init_style() +{ + if (!atom->q_flag) error->all(FLERR, "Pair style lj/cut/coul/cut/soft/gpu requires atom attribute q"); + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double cut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + cut = init_one(i, j); + cut *= cut; + if (cut > maxcut) maxcut = cut; + cutsq[i][j] = cutsq[j][i] = cut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + ljcs_gpu_init(atom->ntypes + 1, cutsq, lj1, lj2, lj3, lj4, offset, epsilon, force->special_lj, + atom->nlocal, atom->nlocal + atom->nghost, mnf, maxspecial, cell_size, gpu_mode, + screen, cut_ljsq, cut_coulsq, force->special_coul, force->qqrd2e); + GPU_EXTRA::check_flag(success, error, world); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCutCoulCutSoftGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + ljcs_gpu_bytes(); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulCutSoftGPU::cpu_compute(int start, int inum, int eflag, int /* vflag */, int *ilist, + int *numneigh, int **firstneigh) +{ + int i, j, ii, jj, jnum, itype, jtype; + double qtmp, xtmp, ytmp, ztmp, delx, dely, delz, evdwl, ecoul, fpair; + double forcecoul, forcelj, factor_coul, factor_lj; + double denc, denlj, r4sig6; + int *jlist; + double rsq; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double **f = atom->f; + double *q = atom->q; + int *type = atom->type; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + + // loop over neighbors of my atoms + + for (ii = start; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + + if (rsq < cut_coulsq[itype][jtype]) { + denc = sqrt(lj4[itype][jtype] + rsq); + forcecoul = qqrd2e * lj1[itype][jtype] * qtmp*q[j] / (denc*denc*denc); + } else forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r4sig6 = rsq*rsq / lj2[itype][jtype]; + denlj = lj3[itype][jtype] + rsq*r4sig6; + forcelj = lj1[itype][jtype] * epsilon[itype][jtype] * + (48.0*r4sig6/(denlj*denlj*denlj) - 24.0*r4sig6/(denlj*denlj)); + } else forcelj = 0.0; + + fpair = factor_coul*forcecoul + factor_lj*forcelj; + + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; + + if (eflag) { + if (rsq < cut_coulsq[itype][jtype]) + ecoul = factor_coul * qqrd2e * lj1[itype][jtype] * qtmp*q[j] / denc; + else + ecoul = 0.0; + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = lj1[itype][jtype] * 4.0 * epsilon[itype][jtype] * + (1.0/(denlj*denlj) - 1.0/denlj) - offset[itype][jtype]; + evdwl *= factor_lj; + } else + evdwl = 0.0; + } + + if (evflag) ev_tally_full(i, evdwl, ecoul, fpair, delx, dely, delz); + } + } + } +} diff --git a/src/GPU/pair_lj_cut_coul_cut_soft_gpu.h b/src/GPU/pair_lj_cut_coul_cut_soft_gpu.h new file mode 100644 index 0000000000..0776695ba3 --- /dev/null +++ b/src/GPU/pair_lj_cut_coul_cut_soft_gpu.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS Development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(lj/cut/coul/cut/soft/gpu,PairLJCutCoulCutSoftGPU); +// clang-format on +#else + +#ifndef LMP_PAIR_LJ_CUT_COUL_CUT_SOFT_GPU_H +#define LMP_PAIR_LJ_CUT_COUL_CUT_SOFT_GPU_H + +#include "pair_lj_cut_coul_cut_soft.h" + +namespace LAMMPS_NS { + +class PairLJCutCoulCutSoftGPU : public PairLJCutCoulCutSoft { + public: + PairLJCutCoulCutSoftGPU(LAMMPS *lmp); + ~PairLJCutCoulCutSoftGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + private: + int gpu_mode; + double cpu_time; +}; + +} // namespace LAMMPS_NS +#endif +#endif diff --git a/src/GPU/pair_lj_cut_coul_long_soft_gpu.cpp b/src/GPU/pair_lj_cut_coul_long_soft_gpu.cpp new file mode 100644 index 0000000000..e8342b6530 --- /dev/null +++ b/src/GPU/pair_lj_cut_coul_long_soft_gpu.cpp @@ -0,0 +1,297 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS Development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_lj_cut_coul_long_soft_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "kspace.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" + +#include + +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int ljcls_gpu_init(const int ntypes, double **cutsq, double **host_lj1, double **host_lj2, + double **host_lj3, double **host_lj4, double **offset, double **epsilon, double *special_lj, + const int nlocal, const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, double **host_cut_ljsq, + double host_cut_coulsq, double *host_special_coul, const double qqrd2e, + const double g_ewald); +void ljcls_gpu_reinit(const int ntypes, double **cutsq, double **host_lj1, double **host_lj2, + double **host_lj3, double **host_lj4, double **offset, double **epsilon, + double **host_lj_cutsq); +void ljcls_gpu_clear(); +int **ljcls_gpu_compute_n(const int ago, const int inum, const int nall, double **host_x, + int *host_type, double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, const bool eatom, + const bool vatom, int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success, double *host_q, double *boxlo, + double *prd); +void ljcls_gpu_compute(const int ago, const int inum, const int nall, double **host_x, + int *host_type, int *ilist, int *numj, int **firstneigh, const bool eflag, + const bool vflag, const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, double *host_q, const int nlocal, + double *boxlo, double *prd); +double ljcls_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairLJCutCoulLongSoftGPU::PairLJCutCoulLongSoftGPU(LAMMPS *lmp) : + PairLJCutCoulLongSoft(lmp), gpu_mode(GPU_FORCE) +{ + respa_enable = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairLJCutCoulLongSoftGPU::~PairLJCutCoulLongSoftGPU() +{ + ljcls_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulLongSoftGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = ljcls_gpu_compute_n(neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, + atom->tag, atom->nspecial, atom->special, eflag, vflag, + eflag_atom, vflag_atom, host_start, &ilist, &numneigh, cpu_time, + success, atom->q, domain->boxlo, domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + ljcls_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, atom->q, + atom->nlocal, domain->boxlo, domain->prd); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + if (host_start < inum) { + cpu_time = platform::walltime(); + cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh); + cpu_time = platform::walltime() - cpu_time; + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairLJCutCoulLongSoftGPU::init_style() +{ + cut_respa = nullptr; + + if (!atom->q_flag) error->all(FLERR, "Pair style lj/cut/coul/long/soft/gpu requires atom attribute q"); + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double cut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + cut = init_one(i, j); + cut *= cut; + if (cut > maxcut) maxcut = cut; + cutsq[i][j] = cutsq[j][i] = cut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + cut_coulsq = cut_coul * cut_coul; + + // insure use of KSpace long-range solver, set g_ewald + + if (force->kspace == nullptr) error->all(FLERR, "Pair style requires a KSpace style"); + g_ewald = force->kspace->g_ewald; + + // setup force tables + + if (ncoultablebits) init_tables(cut_coul, cut_respa); + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + ljcls_gpu_init(atom->ntypes + 1, cutsq, lj1, lj2, lj3, lj4, offset, epsilon, force->special_lj, + atom->nlocal, atom->nlocal + atom->nghost, mnf, maxspecial, cell_size, gpu_mode, + screen, cut_ljsq, cut_coulsq, force->special_coul, force->qqrd2e, g_ewald); + GPU_EXTRA::check_flag(success, error, world); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulLongSoftGPU::reinit() +{ + Pair::reinit(); + + ljcls_gpu_reinit(atom->ntypes + 1, cutsq, lj1, lj2, lj3, lj4, offset, epsilon, cut_ljsq); +} + +/* ---------------------------------------------------------------------- */ + +double PairLJCutCoulLongSoftGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + ljcls_gpu_bytes(); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCutCoulLongSoftGPU::cpu_compute(int start, int inum, int eflag, int /* vflag */, int *ilist, + int *numneigh, int **firstneigh) +{ + int i, j, ii, jj, jnum, itype, jtype; + double qtmp, xtmp, ytmp, ztmp, delx, dely, delz, evdwl, ecoul, fpair; + double r, r2inv, forcecoul, forcelj, factor_coul, factor_lj; + double denc, denlj, r4sig6; + double grij, expm2, prefactor, t, erfc; + int *jlist; + double rsq; + + evdwl = ecoul = 0.0; + + double **x = atom->x; + double **f = atom->f; + double *q = atom->q; + int *type = atom->type; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + double qqrd2e = force->qqrd2e; + + // loop over neighbors of my atoms + + for (ii = start; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0 / rsq; + + if (rsq < cut_coulsq) { + r = sqrt(rsq); + grij = g_ewald * r; + expm2 = exp(-grij * grij); + t = 1.0 / (1.0 + EWALD_P * grij); + erfc = t * (A1 + t * (A2 + t * (A3 + t * (A4 + t * A5)))) * expm2; + + denc = sqrt(lj4[itype][jtype] + rsq); + prefactor = qqrd2e * lj1[itype][jtype] * qtmp*q[j] / (denc*denc*denc); + + forcecoul = prefactor * (erfc + EWALD_F * grij * expm2); + if (factor_coul < 1.0) forcecoul -= (1.0 - factor_coul) * prefactor; + } else + forcecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + r4sig6 = rsq*rsq / lj2[itype][jtype]; + denlj = lj3[itype][jtype] + rsq*r4sig6; + forcelj = lj1[itype][jtype] * epsilon[itype][jtype] * + (48.0*r4sig6/(denlj*denlj*denlj) - 24.0*r4sig6/(denlj*denlj)); + } else + forcelj = 0.0; + + fpair = (forcecoul + factor_lj * forcelj) * r2inv; + + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; + + if (eflag) { + if (rsq < cut_coulsq) { + prefactor = qqrd2e * lj1[itype][jtype] * qtmp*q[j] / denc; + ecoul = prefactor*erfc; + } else + ecoul = 0.0; + + if (rsq < cut_ljsq[itype][jtype]) { + evdwl = lj1[itype][jtype] * 4.0 * epsilon[itype][jtype] * + (1.0/(denlj*denlj) - 1.0/denlj) - offset[itype][jtype]; + evdwl *= factor_lj; + } else + evdwl = 0.0; + } + + if (evflag) ev_tally_full(i, evdwl, ecoul, fpair, delx, dely, delz); + } + } + } +} diff --git a/src/GPU/pair_lj_cut_coul_long_soft_gpu.h b/src/GPU/pair_lj_cut_coul_long_soft_gpu.h new file mode 100644 index 0000000000..cb6790d333 --- /dev/null +++ b/src/GPU/pair_lj_cut_coul_long_soft_gpu.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS Development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(lj/cut/coul/long/soft/gpu,PairLJCutCoulLongSoftGPU); +// clang-format on +#else + +#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_SOFT_GPU_H +#define LMP_PAIR_LJ_CUT_COUL_LONG_SOFT_GPU_H + +#include "pair_lj_cut_coul_long_soft.h" + +namespace LAMMPS_NS { + +class PairLJCutCoulLongSoftGPU : public PairLJCutCoulLongSoft { + public: + PairLJCutCoulLongSoftGPU(LAMMPS *lmp); + ~PairLJCutCoulLongSoftGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + void reinit() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + private: + int gpu_mode; + double cpu_time; +}; + +} // namespace LAMMPS_NS +#endif +#endif diff --git a/src/GPU/pair_mdpd_gpu.cpp b/src/GPU/pair_mdpd_gpu.cpp new file mode 100644 index 0000000000..bebe1e9736 --- /dev/null +++ b/src/GPU/pair_mdpd_gpu.cpp @@ -0,0 +1,171 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Dac Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_mdpd_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "info.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int mdpd_gpu_init(const int ntypes, double **cutsq, double **host_A_att, double **host_B_rep, + double **host_gamma, double **host_sigma, double **host_cut, double **host_cut_r, + double *special_lj, const int inum, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, int &gpu_mode, FILE *screen); +void mdpd_gpu_clear(); +int **mdpd_gpu_compute_n(const int ago, const int inum_full, const int nall, double **host_x, + int *host_type, double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, const bool eatom, + const bool vatom, int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success, double **host_v, + const double dtinvsqrt, const int seed, const int timestep, double *boxlo, + double *prd); +void mdpd_gpu_compute(const int ago, const int inum_full, const int nall, double **host_x, + int *host_type, int *ilist, int *numj, int **firstneigh, const bool eflag, + const bool vflag, const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, double **host_v, + const double dtinvsqrt, const int seed, const int timestep, const int nlocal, + double *boxlo, double *prd); +void mdpd_gpu_get_extra_data(double *host_rho); +double mdpd_gpu_bytes(); + +#define EPSILON 1.0e-10 + +/* ---------------------------------------------------------------------- */ + +PairMDPDGPU::PairMDPDGPU(LAMMPS *lmp) : PairMDPD(lmp), gpu_mode(GPU_FORCE) +{ + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairMDPDGPU::~PairMDPDGPU() +{ + mdpd_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairMDPDGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + double dtinvsqrt = 1.0 / sqrt(update->dt); + + bool success = true; + int *ilist, *numneigh, **firstneigh; + + double *rho = atom->rho; + mdpd_gpu_get_extra_data(rho); + + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = mdpd_gpu_compute_n( + neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, atom->nspecial, + atom->special, eflag, vflag, eflag_atom, vflag_atom, host_start, &ilist, &numneigh, + cpu_time, success, atom->v, dtinvsqrt, seed, update->ntimestep, domain->boxlo, domain->prd); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + mdpd_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, atom->tag, + atom->v, dtinvsqrt, seed, update->ntimestep, atom->nlocal, domain->boxlo, domain->prd); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairMDPDGPU::init_style() +{ + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double mcut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + mcut = init_one(i, j); + mcut *= mcut; + if (mcut > maxcut) maxcut = mcut; + cutsq[i][j] = cutsq[j][i] = mcut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + mdpd_gpu_init(atom->ntypes + 1, cutsq, A_att, B_rep, gamma, sigma, + cut, cut_r, force->special_lj, + atom->nlocal, atom->nlocal + atom->nghost, + mnf, maxspecial, cell_size, gpu_mode, screen); + GPU_EXTRA::check_flag(success, error, world); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +double PairMDPDGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + mdpd_gpu_bytes(); +} diff --git a/src/npair_half_size_bin_newton.h b/src/GPU/pair_mdpd_gpu.h similarity index 63% rename from src/npair_half_size_bin_newton.h rename to src/GPU/pair_mdpd_gpu.h index de11284a8a..5f27c4014e 100644 --- a/src/npair_half_size_bin_newton.h +++ b/src/GPU/pair_mdpd_gpu.h @@ -11,28 +11,35 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef PAIR_CLASS // clang-format off -NPairStyle(half/size/bin/newton, - NPairHalfSizeBinNewton, - NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_ORTHO); +PairStyle(mdpd/gpu,PairMDPDGPU); // clang-format on #else -#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_H -#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_H +#ifndef LMP_PAIR_MDPD_GPU_H +#define LMP_PAIR_MDPD_GPU_H -#include "npair.h" +#include "pair_mdpd.h" namespace LAMMPS_NS { -class NPairHalfSizeBinNewton : public NPair { +class PairMDPDGPU : public PairMDPD { public: - NPairHalfSizeBinNewton(class LAMMPS *); - void build(class NeighList *) override; + PairMDPDGPU(LAMMPS *lmp); + ~PairMDPDGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + private: + int gpu_mode; + double cpu_time; }; } // namespace LAMMPS_NS - #endif #endif diff --git a/src/GPU/pair_sph_heatconduction_gpu.cpp b/src/GPU/pair_sph_heatconduction_gpu.cpp new file mode 100644 index 0000000000..0f0aa079c8 --- /dev/null +++ b/src/GPU/pair_sph_heatconduction_gpu.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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Dac Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_sph_heatconduction_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "info.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int sph_heatconduction_gpu_init(const int ntypes, double **cutsq, double** host_cut, + double **host_alpha, double* host_mass, + const int dimension, double *special_lj, + const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen); +void sph_heatconduction_gpu_clear(); +int **sph_heatconduction_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *host_tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v); +void sph_heatconduction_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *host_tag, + double **host_v, const int nlocal); +void sph_heatconduction_gpu_get_extra_data(double *host_rho, double *host_esph); +void sph_heatconduction_gpu_update_dE(void **dE_ptr); +double sph_heatconduction_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairSPHHeatConductionGPU::PairSPHHeatConductionGPU(LAMMPS *lmp) : + PairSPHHeatConduction(lmp), gpu_mode(GPU_FORCE) +{ + dE_pinned = nullptr; + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairSPHHeatConductionGPU::~PairSPHHeatConductionGPU() +{ + sph_heatconduction_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairSPHHeatConductionGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + + double *rho = atom->rho; + double *esph = atom->esph; + sph_heatconduction_gpu_get_extra_data(rho, esph); + + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = sph_heatconduction_gpu_compute_n( + neighbor->ago, inum, nall, atom->x, atom->type, + sublo, subhi, atom->tag, atom->nspecial, atom->special, eflag, vflag, + eflag_atom, vflag_atom, host_start, &ilist, &numneigh, + cpu_time, success, atom->v); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + sph_heatconduction_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, + ilist, numneigh, firstneigh, eflag, vflag, + eflag_atom, vflag_atom, host_start, cpu_time, success, + atom->tag, atom->v, atom->nlocal); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + // get the drho and dE from device + + double *desph = atom->desph; + sph_heatconduction_gpu_update_dE(&dE_pinned); + + int nlocal = atom->nlocal; + if (acc_float) { + auto dE_ptr = (float *)dE_pinned; + for (int i = 0; i < nlocal; i++) { + desph[i] = dE_ptr[i]; + } + + } else { + auto dE_ptr = (double *)dE_pinned; + for (int i = 0; i < nlocal; i++) { + desph[i] = dE_ptr[i]; + } + } + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSPHHeatConductionGPU::init_style() +{ + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double mcut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + mcut = init_one(i, j); + mcut *= mcut; + if (mcut > maxcut) maxcut = mcut; + cutsq[i][j] = cutsq[j][i] = mcut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + sph_heatconduction_gpu_init(atom->ntypes + 1, cutsq, cut, alpha, atom->mass, + domain->dimension, force->special_lj, atom->nlocal, + atom->nlocal + atom->nghost, + mnf, maxspecial, cell_size, gpu_mode, screen); + GPU_EXTRA::check_flag(success, error, world); + + acc_float = Info::has_accelerator_feature("GPU", "precision", "single"); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +double PairSPHHeatConductionGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + sph_heatconduction_gpu_bytes(); +} diff --git a/src/npair_half_multi_newton.h b/src/GPU/pair_sph_heatconduction_gpu.h similarity index 57% rename from src/npair_half_multi_newton.h rename to src/GPU/pair_sph_heatconduction_gpu.h index 98552db81a..571334017d 100644 --- a/src/npair_half_multi_newton.h +++ b/src/GPU/pair_sph_heatconduction_gpu.h @@ -11,28 +11,38 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef PAIR_CLASS // clang-format off -NPairStyle(half/multi/newton, - NPairHalfMultiNewton, - NP_HALF | NP_MULTI | NP_NEWTON | NP_ORTHO); +PairStyle(sph/heatconduction/gpu,PairSPHHeatConductionGPU); // clang-format on #else -#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_H -#define LMP_NPAIR_HALF_MULTI_NEWTON_H +#ifndef LMP_PAIR_SPH_HEATCONDUCTION_GPU_H +#define LMP_PAIR_SPH_HEATCONDUCTION_GPU_H -#include "npair.h" +#include "pair_sph_heatconduction.h" namespace LAMMPS_NS { -class NPairHalfMultiNewton : public NPair { +class PairSPHHeatConductionGPU : public PairSPHHeatConduction { public: - NPairHalfMultiNewton(class LAMMPS *); - void build(class NeighList *) override; + PairSPHHeatConductionGPU(LAMMPS *lmp); + ~PairSPHHeatConductionGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + void *dE_pinned; + bool acc_float; + + private: + int gpu_mode; + double cpu_time; }; } // namespace LAMMPS_NS - #endif #endif diff --git a/src/GPU/pair_sph_lj_gpu.cpp b/src/GPU/pair_sph_lj_gpu.cpp new file mode 100644 index 0000000000..942a3c33bd --- /dev/null +++ b/src/GPU/pair_sph_lj_gpu.cpp @@ -0,0 +1,204 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Dac Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_sph_lj_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "info.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int sph_lj_gpu_init(const int ntypes, double **cutsq, double** host_cut, + double **host_viscosity, double* host_mass, + const int dimension, double *special_lj, + const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen); +void sph_lj_gpu_clear(); +int **sph_lj_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *host_tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v); +void sph_lj_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *host_tag, + double **host_v, const int nlocal); +void sph_lj_gpu_get_extra_data(double *host_rho, double *host_esph, + double *host_cv); +void sph_lj_gpu_update_drhoE(void **drhoE_ptr); +double sph_lj_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairSPHLJGPU::PairSPHLJGPU(LAMMPS *lmp) : PairSPHLJ(lmp), gpu_mode(GPU_FORCE) +{ + drhoE_pinned = nullptr; + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairSPHLJGPU::~PairSPHLJGPU() +{ + sph_lj_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairSPHLJGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + + double *rho = atom->rho; + double *esph = atom->esph; + double *cv = atom->cv; + sph_lj_gpu_get_extra_data(rho, esph, cv); + + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = sph_lj_gpu_compute_n( + neighbor->ago, inum, nall, atom->x, atom->type, + sublo, subhi, atom->tag, atom->nspecial, atom->special, eflag, vflag, + eflag_atom, vflag_atom, host_start, &ilist, &numneigh, + cpu_time, success, atom->v); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + sph_lj_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, + ilist, numneigh, firstneigh, eflag, vflag, + eflag_atom, vflag_atom, host_start, cpu_time, success, + atom->tag, atom->v, atom->nlocal); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + // get the drho and dE from device + + double *drho = atom->drho; + double *desph = atom->desph; + sph_lj_gpu_update_drhoE(&drhoE_pinned); + + int nlocal = atom->nlocal; + if (acc_float) { + auto drhoE_ptr = (float *)drhoE_pinned; + int idx = 0; + for (int i = 0; i < nlocal; i++) { + drho[i] = drhoE_ptr[idx]; + desph[i] = drhoE_ptr[idx+1]; + idx += 2; + } + + } else { + auto drhoE_ptr = (double *)drhoE_pinned; + int idx = 0; + for (int i = 0; i < nlocal; i++) { + drho[i] = drhoE_ptr[idx]; + desph[i] = drhoE_ptr[idx+1]; + idx += 2; + } + } + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSPHLJGPU::init_style() +{ + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double mcut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + mcut = init_one(i, j); + mcut *= mcut; + if (mcut > maxcut) maxcut = mcut; + cutsq[i][j] = cutsq[j][i] = mcut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + sph_lj_gpu_init(atom->ntypes + 1, cutsq, cut, viscosity, atom->mass, + domain->dimension, force->special_lj, atom->nlocal, + atom->nlocal + atom->nghost, + mnf, maxspecial, cell_size, gpu_mode, screen); + GPU_EXTRA::check_flag(success, error, world); + + acc_float = Info::has_accelerator_feature("GPU", "precision", "single"); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +double PairSPHLJGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + sph_lj_gpu_bytes(); +} diff --git a/src/INTEL/npair_full_bin_intel.h b/src/GPU/pair_sph_lj_gpu.h similarity index 59% rename from src/INTEL/npair_full_bin_intel.h rename to src/GPU/pair_sph_lj_gpu.h index 58ff21d22c..9aae3c2d6a 100644 --- a/src/INTEL/npair_full_bin_intel.h +++ b/src/GPU/pair_sph_lj_gpu.h @@ -1,4 +1,3 @@ -// clang-format off /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -12,33 +11,38 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef PAIR_CLASS // clang-format off -NPairStyle(full/bin/intel, - NPairFullBinIntel, - NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | - NP_INTEL); +PairStyle(sph/lj/gpu,PairSPHLJGPU); // clang-format on #else -#ifndef LMP_NPAIR_FULL_BIN_INTEL_H -#define LMP_NPAIR_FULL_BIN_INTEL_H +#ifndef LMP_PAIR_SPH_LJ_GPU_H +#define LMP_PAIR_SPH_LJ_GPU_H -#include "fix_intel.h" -#include "npair_intel.h" +#include "pair_sph_lj.h" namespace LAMMPS_NS { -class NPairFullBinIntel : public NPairIntel { +class PairSPHLJGPU : public PairSPHLJ { public: - NPairFullBinIntel(class LAMMPS *); - void build(class NeighList *) override; + PairSPHLJGPU(LAMMPS *lmp); + ~PairSPHLJGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + void *drhoE_pinned; + bool acc_float; private: - template void fbi(NeighList *, IntelBuffers *); + int gpu_mode; + double cpu_time; }; } // namespace LAMMPS_NS - #endif #endif diff --git a/src/GPU/pair_sph_taitwater_gpu.cpp b/src/GPU/pair_sph_taitwater_gpu.cpp new file mode 100644 index 0000000000..37a1b0feb5 --- /dev/null +++ b/src/GPU/pair_sph_taitwater_gpu.cpp @@ -0,0 +1,199 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Trung Dac Nguyen (U Chicago) +------------------------------------------------------------------------- */ + +#include "pair_sph_taitwater_gpu.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "info.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "suffix.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +// External functions from cuda library for atom decomposition + +int sph_taitwater_gpu_init(const int ntypes, double **cutsq, double** host_cut, + double **host_viscosity, double* host_mass, double* host_rho0, + double* host_soundspeed, double* host_B, const int dimension, + double *special_lj, const int inum, const int nall, + const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen); +void sph_taitwater_gpu_clear(); +int **sph_taitwater_gpu_compute_n(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, double *sublo, + double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, bool &success, + double **host_v); +void sph_taitwater_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success, tagint *tag, + double **host_v, const int nlocal); +void sph_taitwater_gpu_get_extra_data(double *host_rho); +void sph_taitwater_gpu_update_drhoE(void **drhoE_ptr); +double sph_taitwater_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairSPHTaitwaterGPU::PairSPHTaitwaterGPU(LAMMPS *lmp) : PairSPHTaitwater(lmp), gpu_mode(GPU_FORCE) +{ + drhoE_pinned = nullptr; + respa_enable = 0; + reinitflag = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairSPHTaitwaterGPU::~PairSPHTaitwaterGPU() +{ + sph_taitwater_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairSPHTaitwaterGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + + double *rho = atom->rho; + sph_taitwater_gpu_get_extra_data(rho); + + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = sph_taitwater_gpu_compute_n( + neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, atom->nspecial, + atom->special, eflag, vflag, eflag_atom, vflag_atom, host_start, &ilist, &numneigh, + cpu_time, success, atom->v); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + sph_taitwater_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, + atom->tag, atom->v, atom->nlocal); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + // get the drho and dE from device + + double *drho = atom->drho; + double *desph = atom->desph; + sph_taitwater_gpu_update_drhoE(&drhoE_pinned); + + int nlocal = atom->nlocal; + if (acc_float) { + auto drhoE_ptr = (float *)drhoE_pinned; + int idx = 0; + for (int i = 0; i < nlocal; i++) { + drho[i] = drhoE_ptr[idx]; + desph[i] = drhoE_ptr[idx+1]; + idx += 2; + } + + } else { + auto drhoE_ptr = (double *)drhoE_pinned; + int idx = 0; + for (int i = 0; i < nlocal; i++) { + drho[i] = drhoE_ptr[idx]; + desph[i] = drhoE_ptr[idx+1]; + idx += 2; + } + } + + if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) + neighbor->build_topology(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSPHTaitwaterGPU::init_style() +{ + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double mcut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + mcut = init_one(i, j); + mcut *= mcut; + if (mcut > maxcut) maxcut = mcut; + cutsq[i][j] = cutsq[j][i] = mcut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular != Atom::ATOMIC) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + sph_taitwater_gpu_init(atom->ntypes + 1, cutsq, cut, viscosity, atom->mass, + rho0, soundspeed, B, domain->dimension, force->special_lj, + atom->nlocal, atom->nlocal + atom->nghost, + mnf, maxspecial, cell_size, gpu_mode, screen); + GPU_EXTRA::check_flag(success, error, world); + + acc_float = Info::has_accelerator_feature("GPU", "precision", "single"); + + if (gpu_mode == GPU_FORCE) neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- */ + +double PairSPHTaitwaterGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + sph_taitwater_gpu_bytes(); +} diff --git a/src/npair_full_multi_old.h b/src/GPU/pair_sph_taitwater_gpu.h similarity index 58% rename from src/npair_full_multi_old.h rename to src/GPU/pair_sph_taitwater_gpu.h index cb78cf3d76..df8119a3c0 100644 --- a/src/npair_full_multi_old.h +++ b/src/GPU/pair_sph_taitwater_gpu.h @@ -11,28 +11,38 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef PAIR_CLASS // clang-format off -NPairStyle(full/multi/old, - NPairFullMultiOld, - NP_FULL | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); +PairStyle(sph/taitwater/gpu,PairSPHTaitwaterGPU); // clang-format on #else -#ifndef LMP_NPAIR_FULL_MULTI_OLD_H -#define LMP_NPAIR_FULL_MULTI_OLD_H +#ifndef LMP_PAIR_SPH_TAITWATER_GPU_H +#define LMP_PAIR_SPH_TAITWATER_GPU_H -#include "npair.h" +#include "pair_sph_taitwater.h" namespace LAMMPS_NS { -class NPairFullMultiOld : public NPair { +class PairSPHTaitwaterGPU : public PairSPHTaitwater { public: - NPairFullMultiOld(class LAMMPS *); - void build(class NeighList *) override; + PairSPHTaitwaterGPU(LAMMPS *lmp); + ~PairSPHTaitwaterGPU() override; + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int) override; + void init_style() override; + double memory_usage() override; + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + void *drhoE_pinned; + bool acc_float; + + private: + int gpu_mode; + double cpu_time; }; } // namespace LAMMPS_NS - #endif #endif diff --git a/src/INTEL/fix_intel.cpp b/src/INTEL/fix_intel.cpp index cb60149885..30d119dd6a 100644 --- a/src/INTEL/fix_intel.cpp +++ b/src/INTEL/fix_intel.cpp @@ -553,6 +553,9 @@ void FixIntel::kspace_init_check() if (intel_pair == 0) error->all(FLERR,"Intel styles for kspace require intel pair style."); + + if (utils::strmatch(update->integrate_style, "^verlet/split")) + error->all(FLERR,"Intel styles for kspace are not compatible with run_style verlet/split"); } /* ---------------------------------------------------------------------- */ diff --git a/src/INTEL/npair_full_bin_ghost_intel.cpp b/src/INTEL/npair_bin_ghost_intel.cpp similarity index 99% rename from src/INTEL/npair_full_bin_ghost_intel.cpp rename to src/INTEL/npair_bin_ghost_intel.cpp index 920c0c559a..1210f33b9a 100644 --- a/src/INTEL/npair_full_bin_ghost_intel.cpp +++ b/src/INTEL/npair_bin_ghost_intel.cpp @@ -16,7 +16,7 @@ Contributing authors: W. Michael Brown (Intel) ------------------------------------------------------------------------- */ -#include "npair_full_bin_ghost_intel.h" +#include "npair_bin_ghost_intel.h" #include "atom.h" #include "comm.h" diff --git a/src/INTEL/npair_full_bin_ghost_intel.h b/src/INTEL/npair_bin_ghost_intel.h similarity index 95% rename from src/INTEL/npair_full_bin_ghost_intel.h rename to src/INTEL/npair_bin_ghost_intel.h index 4ae5ddad5f..eada3237bc 100644 --- a/src/INTEL/npair_full_bin_ghost_intel.h +++ b/src/INTEL/npair_bin_ghost_intel.h @@ -25,8 +25,8 @@ NPairStyle(full/bin/ghost/intel, // clang-format on #else -#ifndef LMP_NPAIR_FULL_BIN_GHOST_INTEL_H -#define LMP_NPAIR_FULL_BIN_GHOST_INTEL_H +#ifndef LMP_NPAIR_BIN_GHOST_INTEL_H +#define LMP_NPAIR_BIN_GHOST_INTEL_H #include "npair_intel.h" diff --git a/src/INTEL/npair_bin_intel.cpp b/src/INTEL/npair_bin_intel.cpp new file mode 100644 index 0000000000..f4942022ec --- /dev/null +++ b/src/INTEL/npair_bin_intel.cpp @@ -0,0 +1,298 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_bin_intel.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "neigh_list.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; + + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtonIntel::NPairHalfBinNewtonIntel(LAMMPS *lmp) : + NPairIntel(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfBinNewtonIntel::build(NeighList *list) +{ + if (nstencil / 2 > INTEL_MAX_STENCIL_CHECK) + error->all(FLERR, "Too many neighbor bins for INTEL package."); + + #ifdef _LMP_INTEL_OFFLOAD + if (exclude) + error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); + #endif + + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) + hbni(list, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + hbni(list, _fix->get_double_buffers()); + else + hbni(list, _fix->get_single_buffers()); + + _fix->stop_watch(TIME_HOST_NEIGHBOR); +} + +template +void NPairHalfBinNewtonIntel:: +hbni(NeighList *list, IntelBuffers *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + + int host_start = _fix->host_start_neighbor(); + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end); + + int need_ic = 0; + if (atom->molecular != Atom::ATOMIC) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (need_ic) { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, + off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, + off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + bin_newton(0, list, buffers, host_start, nlocal); + else + bin_newton(0, list, buffers, host_start, nlocal); + #endif +} + + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtonTriIntel::NPairHalfBinNewtonTriIntel(LAMMPS *lmp) : + NPairIntel(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction with Newton's 3rd law for triclinic + each owned atom i checks its own bin and other bins in triclinic stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfBinNewtonTriIntel::build(NeighList *list) +{ + if (nstencil > INTEL_MAX_STENCIL) + error->all(FLERR, "Too many neighbor bins for INTEL package."); + + #ifdef _LMP_INTEL_OFFLOAD + if (exclude) + error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); + #endif + + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) + hbnti(list, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + hbnti(list, _fix->get_double_buffers()); + else + hbnti(list, _fix->get_single_buffers()); + + _fix->stop_watch(TIME_HOST_NEIGHBOR); +} + +template +void NPairHalfBinNewtonTriIntel:: +hbnti(NeighList *list, IntelBuffers *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + + int host_start = _fix->host_start_neighbor(); + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end); + + int need_ic = 0; + if (atom->molecular != Atom::ATOMIC) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (need_ic) { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, + off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, + off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + bin_newton(0, list, buffers, host_start, nlocal); + else + bin_newton(0, list, buffers, host_start, nlocal); + #endif +} + +/* ---------------------------------------------------------------------- */ + +NPairFullBinIntel::NPairFullBinIntel(LAMMPS *lmp) : NPairIntel(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j +------------------------------------------------------------------------- */ + +void NPairFullBinIntel::build(NeighList *list) +{ + if (nstencil > INTEL_MAX_STENCIL_CHECK) + error->all(FLERR, "Too many neighbor bins for INTEL package."); + + #ifdef _LMP_INTEL_OFFLOAD + if (exclude) + error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); + #endif + + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) + fbi(list, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + fbi(list, _fix->get_double_buffers()); + else + fbi(list, _fix->get_single_buffers()); + + _fix->stop_watch(TIME_HOST_NEIGHBOR); +} + +template +void NPairFullBinIntel:: +fbi(NeighList *list, IntelBuffers *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + list->gnum = 0; + + int host_start = _fix->host_start_neighbor();; + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, + _fix->three_body_neighbor(), off_end, + _fix->nbor_pack_width()); + + int need_ic = 0; + if (atom->molecular != Atom::ATOMIC) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (_fix->three_body_neighbor()) { + if (need_ic) { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } + } else { + if (need_ic) { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal, off_end); + } else { + bin_newton(1, list, buffers, 0, off_end); + bin_newton(0, list, buffers, host_start, nlocal); + } + } + } + #else + if (_fix->three_body_neighbor()) { + if (need_ic) + bin_newton(0, list, buffers, host_start, nlocal); + else + bin_newton(0, list, buffers, host_start, nlocal); + } else { + if (need_ic) + bin_newton(0, list, buffers, host_start, nlocal); + else + bin_newton(0, list, buffers, host_start, nlocal); + } + #endif +} diff --git a/src/INTEL/npair_half_bin_newton_tri_intel.h b/src/INTEL/npair_bin_intel.h similarity index 59% rename from src/INTEL/npair_half_bin_newton_tri_intel.h rename to src/INTEL/npair_bin_intel.h index 8ef65c12e5..fd18f20be5 100644 --- a/src/INTEL/npair_half_bin_newton_tri_intel.h +++ b/src/INTEL/npair_bin_intel.h @@ -14,20 +14,38 @@ #ifdef NPAIR_CLASS // clang-format off +NPairStyle(half/bin/newton/intel, + NPairHalfBinNewtonIntel, + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_INTEL); + NPairStyle(half/bin/newton/tri/intel, NPairHalfBinNewtonTriIntel, NP_HALF | NP_BIN | NP_NEWTON | NP_TRI | NP_INTEL); + +NPairStyle(full/bin/intel, + NPairFullBinIntel, + NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | + NP_INTEL); // clang-format on #else -#ifndef LMP_NPAIR_HALF_BIN_NEWTON_INTEL_TRI_H -#define LMP_NPAIR_HALF_BIN_NEWTON_INTEL_TRI_H +#ifndef LMP_NPAIR_BIN_INTEL_H +#define LMP_NPAIR_BIN_INTEL_H #include "fix_intel.h" #include "npair_intel.h" namespace LAMMPS_NS { +class NPairHalfBinNewtonIntel : public NPairIntel { + public: + NPairHalfBinNewtonIntel(class LAMMPS *); + void build(class NeighList *) override; + + private: + template void hbni(NeighList *, IntelBuffers *); +}; + class NPairHalfBinNewtonTriIntel : public NPairIntel { public: NPairHalfBinNewtonTriIntel(class LAMMPS *); @@ -37,6 +55,15 @@ class NPairHalfBinNewtonTriIntel : public NPairIntel { template void hbnti(NeighList *, IntelBuffers *); }; +class NPairFullBinIntel : public NPairIntel { + public: + NPairFullBinIntel(class LAMMPS *); + void build(class NeighList *) override; + + private: + template void fbi(NeighList *, IntelBuffers *); +}; + } // namespace LAMMPS_NS #endif diff --git a/src/INTEL/npair_half_bin_newton_intel.cpp b/src/INTEL/npair_half_bin_newton_intel.cpp deleted file mode 100644 index 24e8b01572..0000000000 --- a/src/INTEL/npair_half_bin_newton_intel.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) -------------------------------------------------------------------------- */ - -#include "npair_half_bin_newton_intel.h" - -#include "atom.h" -#include "comm.h" -#include "error.h" -#include "neigh_list.h" -#include "neighbor.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtonIntel::NPairHalfBinNewtonIntel(LAMMPS *lmp) : - NPairIntel(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtonIntel::build(NeighList *list) -{ - if (nstencil / 2 > INTEL_MAX_STENCIL_CHECK) - error->all(FLERR, "Too many neighbor bins for INTEL package."); - - #ifdef _LMP_INTEL_OFFLOAD - if (exclude) - error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); - #endif - - if (_fix->precision() == FixIntel::PREC_MODE_MIXED) - hbni(list, _fix->get_mixed_buffers()); - else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) - hbni(list, _fix->get_double_buffers()); - else - hbni(list, _fix->get_single_buffers()); - - _fix->stop_watch(TIME_HOST_NEIGHBOR); -} - -template -void NPairHalfBinNewtonIntel:: -hbni(NeighList *list, IntelBuffers *buffers) { - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - list->inum = nlocal; - - int host_start = _fix->host_start_neighbor(); - const int off_end = _fix->offload_end_neighbor(); - - #ifdef _LMP_INTEL_OFFLOAD - if (off_end) grow_stencil(); - if (_fix->full_host_list()) host_start = 0; - int offload_noghost = _fix->offload_noghost(); - #endif - - buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end); - - int need_ic = 0; - if (atom->molecular != Atom::ATOMIC) - dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, - neighbor->cutneighmax); - - #ifdef _LMP_INTEL_OFFLOAD - if (need_ic) { - if (offload_noghost) { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal, - off_end); - } else { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal); - } - } else { - if (offload_noghost) { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal, - off_end); - } else { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal); - } - } - #else - if (need_ic) - bin_newton(0, list, buffers, host_start, nlocal); - else - bin_newton(0, list, buffers, host_start, nlocal); - #endif -} diff --git a/src/INTEL/npair_half_bin_newton_tri_intel.cpp b/src/INTEL/npair_half_bin_newton_tri_intel.cpp deleted file mode 100644 index a903ef8e9a..0000000000 --- a/src/INTEL/npair_half_bin_newton_tri_intel.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) -------------------------------------------------------------------------- */ - -#include "npair_half_bin_newton_tri_intel.h" - -#include "atom.h" -#include "comm.h" -#include "error.h" -#include "neigh_list.h" -#include "neighbor.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtonTriIntel::NPairHalfBinNewtonTriIntel(LAMMPS *lmp) : - NPairIntel(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtonTriIntel::build(NeighList *list) -{ - if (nstencil > INTEL_MAX_STENCIL) - error->all(FLERR, "Too many neighbor bins for INTEL package."); - - #ifdef _LMP_INTEL_OFFLOAD - if (exclude) - error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); - #endif - - if (_fix->precision() == FixIntel::PREC_MODE_MIXED) - hbnti(list, _fix->get_mixed_buffers()); - else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) - hbnti(list, _fix->get_double_buffers()); - else - hbnti(list, _fix->get_single_buffers()); - - _fix->stop_watch(TIME_HOST_NEIGHBOR); -} - -template -void NPairHalfBinNewtonTriIntel:: -hbnti(NeighList *list, IntelBuffers *buffers) { - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - list->inum = nlocal; - - int host_start = _fix->host_start_neighbor(); - const int off_end = _fix->offload_end_neighbor(); - - #ifdef _LMP_INTEL_OFFLOAD - if (off_end) grow_stencil(); - if (_fix->full_host_list()) host_start = 0; - int offload_noghost = _fix->offload_noghost(); - #endif - - buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end); - - int need_ic = 0; - if (atom->molecular != Atom::ATOMIC) - dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, - neighbor->cutneighmax); - - #ifdef _LMP_INTEL_OFFLOAD - if (need_ic) { - if (offload_noghost) { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal, - off_end); - } else { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal); - } - } else { - if (offload_noghost) { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal, - off_end); - } else { - bin_newton(1, list, buffers, 0, off_end); - bin_newton(0, list, buffers, host_start, nlocal); - } - } - #else - if (need_ic) - bin_newton(0, list, buffers, host_start, nlocal); - else - bin_newton(0, list, buffers, host_start, nlocal); - #endif -} diff --git a/src/INTEL/npair_halffull_trim_newton_intel.cpp b/src/INTEL/npair_halffull_intel.cpp similarity index 56% rename from src/INTEL/npair_halffull_trim_newton_intel.cpp rename to src/INTEL/npair_halffull_intel.cpp index b1b69734a4..134b768cc5 100644 --- a/src/INTEL/npair_halffull_trim_newton_intel.cpp +++ b/src/INTEL/npair_halffull_intel.cpp @@ -13,10 +13,10 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Stan Moore (SNL) + Contributing author: W. Michael Brown (Intel) ------------------------------------------------------------------------- */ -#include "npair_halffull_trim_newton_intel.h" +#include "npair_halffull_intel.h" #include "atom.h" #include "comm.h" @@ -31,6 +31,232 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ +NPairHalffullNewtonIntel::NPairHalffullNewtonIntel(LAMMPS *lmp) : NPair(lmp) { + _fix = static_cast(modify->get_fix_by_id("package_intel")); + if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles"); +} + +/* ---------------------------------------------------------------------- + build half list from full list + pair stored once if i,j are both owned and i < j + if j is ghost, only store if j coords are "above and to the right" of i + works if full list is a skip list +------------------------------------------------------------------------- */ + +template +void NPairHalffullNewtonIntel::build_t(NeighList *list, + IntelBuffers *buffers) +{ + const int inum_full = list->listfull->inum; + const int nlocal = atom->nlocal; + const int e_nall = nlocal + atom->nghost; + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const ilist = list->ilist; + int * _noalias const numneigh = list->numneigh; + int ** _noalias const firstneigh = list->firstneigh; + const int * _noalias const ilist_full = list->listfull->ilist; + const int * _noalias const numneigh_full = list->listfull->numneigh; + const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT + + const double delta = 0.01 * force->angstrom; + const int triclinic = domain->triclinic; + + #if defined(_OPENMP) + #pragma omp parallel + #endif + { + int tid, ifrom, ito; + IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, comm->nthreads); + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over parent full list + for (int ii = ifrom; ii < ito; ii++) { + int n = 0; + int *neighptr = ipage.vget(); + + const int i = ilist_full[ii]; + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + + // loop over full neighbor list + + const int * _noalias const jlist = firstneigh_full[i]; + const int jnum = numneigh_full[i]; + + if (!triclinic) { + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma ivdep + #endif + for (int jj = 0; jj < jnum; jj++) { + const int joriginal = jlist[jj]; + const int j = joriginal & NEIGHMASK; + int addme = 1; + if (j < nlocal) { + if (i > j) addme = 0; + } else { + if (x[j].z < ztmp) addme = 0; + if (x[j].z == ztmp) { + if (x[j].y < ytmp) addme = 0; + if (x[j].y == ytmp && x[j].x < xtmp) addme = 0; + } + } + if (addme) + neighptr[n++] = joriginal; + } + } else { + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma ivdep + #endif + for (int jj = 0; jj < jnum; jj++) { + const int joriginal = jlist[jj]; + const int j = joriginal & NEIGHMASK; + int addme = 1; + if (j < nlocal) { + if (i > j) addme = 0; + } else { + if (fabs(x[j].z-ztmp) > delta) { + if (x[j].z < ztmp) addme = 0; + } else if (fabs(x[j].y-ytmp) > delta) { + if (x[j].y < ytmp) addme = 0; + } else { + if (x[j].x < xtmp) addme = 0; + } + } + if (addme) + neighptr[n++] = joriginal; + } + } + + ilist[ii] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + + int pad_end = n; + IP_PRE_neighbor_pad(pad_end, 0); + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \ + avg=INTEL_COMPILE_WIDTH/2 + #endif + for ( ; n < pad_end; n++) + neighptr[n] = e_nall; + + ipage.vgot(n); + if (ipage.status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + } + list->inum = inum_full; +} + +/* ---------------------------------------------------------------------- + build half list from full 3-body list + half list is already stored as first part of 3-body list +------------------------------------------------------------------------- */ + +template +void NPairHalffullNewtonIntel::build_t3(NeighList *list, int *numhalf) +{ + const int inum_full = list->listfull->inum; + const int e_nall = atom->nlocal + atom->nghost; + int * _noalias const ilist = list->ilist; + int * _noalias const numneigh = list->numneigh; + int ** _noalias const firstneigh = list->firstneigh; + const int * _noalias const ilist_full = list->listfull->ilist; + const int * _noalias const numneigh_full = numhalf; + const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT + + int packthreads = 1; + if (comm->nthreads > INTEL_HTHREADS) packthreads = comm->nthreads; + + #if defined(_OPENMP) + #pragma omp parallel if (packthreads > 1) + #endif + { + int tid, ifrom, ito; + IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, packthreads); + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over parent full list + for (int ii = ifrom; ii < ito; ii++) { + int n = 0; + int *neighptr = ipage.vget(); + + const int i = ilist_full[ii]; + + // loop over full neighbor list + + const int * _noalias const jlist = firstneigh_full[i]; + const int jnum = numneigh_full[ii]; + + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma ivdep + #endif + for (int jj = 0; jj < jnum; jj++) { + const int joriginal = jlist[jj]; + neighptr[n++] = joriginal; + } + + ilist[ii] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + + int pad_end = n; + IP_PRE_neighbor_pad(pad_end, 0); + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \ + avg=INTEL_COMPILE_WIDTH/2 + #endif + for ( ; n < pad_end; n++) + neighptr[n] = e_nall; + + ipage.vgot(n); + if (ipage.status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + } + list->inum = inum_full; +} + +/* ---------------------------------------------------------------------- */ + +void NPairHalffullNewtonIntel::build(NeighList *list) +{ + if (_fix->three_body_neighbor() == 0 || domain->triclinic) { + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) + build_t(list, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + build_t(list, _fix->get_double_buffers()); + else + build_t(list, _fix->get_single_buffers()); + } else { + int *nhalf, *cnum; + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) { + _fix->get_mixed_buffers()->get_list_data3(list->listfull, nhalf, cnum); + build_t3(list, nhalf); + } else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) { + _fix->get_double_buffers()->get_list_data3(list->listfull, nhalf, cnum); + build_t3(list, nhalf); + } else { + _fix->get_single_buffers()->get_list_data3(list->listfull, nhalf, cnum); + build_t3(list, nhalf); + } + } +} + +/* ---------------------------------------------------------------------- */ + NPairHalffullTrimNewtonIntel::NPairHalffullTrimNewtonIntel(LAMMPS *lmp) : NPair(lmp) { _fix = static_cast(modify->get_fix_by_id("package_intel")); if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles"); diff --git a/src/INTEL/npair_halffull_intel.h b/src/INTEL/npair_halffull_intel.h new file mode 100644 index 0000000000..a1f9adbbc4 --- /dev/null +++ b/src/INTEL/npair_halffull_intel.h @@ -0,0 +1,128 @@ +// clang-format off +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +// For Newton off, only used for hybrid to generate list for non-intel style. +// Use standard routines. + +#ifdef NPAIR_CLASS +// clang-format off +NPairStyle(halffull/newton/intel, + NPairHalffullNewtonIntel, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | + NP_ORTHO | NP_TRI| NP_INTEL); + +NPairStyle(halffull/newton/skip/intel, + NPairHalffullNewtonIntel, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | + NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL); + +NPairStyle(halffull/newtoff/intel, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_INTEL); + +NPairStyle(halffull/newtoff/skip/intel, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL); + +NPairStyle(halffull/newtoff/ghost/intel, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST | NP_INTEL); + +NPairStyle(halffull/newtoff/skip/ghost/intel, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_INTEL); + + +NPairStyle(halffull/trim/newton/intel, + NPairHalffullTrimNewtonIntel, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | + NP_ORTHO | NP_TRI| NP_TRIM | NP_INTEL); + +NPairStyle(halffull/trim/newton/skip/intel, + NPairHalffullTrimNewtonIntel, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | + NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_INTEL); + +NPairStyle(halffull/trim/newtoff/intel, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL); + +NPairStyle(halffull/trim/newtoff/skip/intel, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_INTEL); + +NPairStyle(halffull/trim/newtoff/ghost/intel, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM | NP_INTEL); + +NPairStyle(halffull/trim/newtoff/skip/ghost/intel, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_TRIM | NP_INTEL); +// clang-format on +#else + +#ifndef LMP_NPAIR_HALFFULL_INTEL_H +#define LMP_NPAIR_HALFFULL_INTEL_H + +#include "fix_intel.h" +#include "npair.h" + +#if defined(_OPENMP) +#include +#endif + +namespace LAMMPS_NS { + +class NPairHalffullNewtonIntel : public NPair { + public: + NPairHalffullNewtonIntel(class LAMMPS *); + void build(class NeighList *) override; + + protected: + FixIntel *_fix; + + template void build_t(NeighList *, IntelBuffers *); + + template void build_t3(NeighList *, int *); +}; + +class NPairHalffullTrimNewtonIntel : public NPair { + public: + NPairHalffullTrimNewtonIntel(class LAMMPS *); + void build(class NeighList *) override; + + protected: + FixIntel *_fix; + + template void build_t(NeighList *, IntelBuffers *); + + template void build_t3(NeighList *, int *, IntelBuffers *); +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/INTEL/npair_halffull_newtoff_intel.h b/src/INTEL/npair_halffull_newtoff_intel.h deleted file mode 100644 index f77ddb74d6..0000000000 --- a/src/INTEL/npair_halffull_newtoff_intel.h +++ /dev/null @@ -1,44 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) -------------------------------------------------------------------------- */ - -// Only used for hybrid to generate list for non-intel style. Use -// standard routines. - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/newtoff/intel, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_INTEL); - -NPairStyle(halffull/newtoff/skip/intel, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL); - -NPairStyle(halffull/newtoff/ghost/intel, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_GHOST | NP_INTEL); - -NPairStyle(halffull/newtoff/skip/ghost/intel, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_INTEL); -// clang-format on -#endif diff --git a/src/INTEL/npair_halffull_newton_intel.cpp b/src/INTEL/npair_halffull_newton_intel.cpp deleted file mode 100644 index adcf2527ab..0000000000 --- a/src/INTEL/npair_halffull_newton_intel.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) -------------------------------------------------------------------------- */ - -#include "npair_halffull_newton_intel.h" - -#include "atom.h" -#include "comm.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "modify.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullNewtonIntel::NPairHalffullNewtonIntel(LAMMPS *lmp) : NPair(lmp) { - _fix = static_cast(modify->get_fix_by_id("package_intel")); - if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles"); -} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - if j is ghost, only store if j coords are "above and to the right" of i - works if full list is a skip list -------------------------------------------------------------------------- */ - -template -void NPairHalffullNewtonIntel::build_t(NeighList *list, - IntelBuffers *buffers) -{ - const int inum_full = list->listfull->inum; - const int nlocal = atom->nlocal; - const int e_nall = nlocal + atom->nghost; - const ATOM_T * _noalias const x = buffers->get_x(); - int * _noalias const ilist = list->ilist; - int * _noalias const numneigh = list->numneigh; - int ** _noalias const firstneigh = list->firstneigh; - const int * _noalias const ilist_full = list->listfull->ilist; - const int * _noalias const numneigh_full = list->listfull->numneigh; - const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT - - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - #if defined(_OPENMP) - #pragma omp parallel - #endif - { - int tid, ifrom, ito; - IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, comm->nthreads); - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over parent full list - for (int ii = ifrom; ii < ito; ii++) { - int n = 0; - int *neighptr = ipage.vget(); - - const int i = ilist_full[ii]; - const flt_t xtmp = x[i].x; - const flt_t ytmp = x[i].y; - const flt_t ztmp = x[i].z; - - // loop over full neighbor list - - const int * _noalias const jlist = firstneigh_full[i]; - const int jnum = numneigh_full[i]; - - if (!triclinic) { - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma ivdep - #endif - for (int jj = 0; jj < jnum; jj++) { - const int joriginal = jlist[jj]; - const int j = joriginal & NEIGHMASK; - int addme = 1; - if (j < nlocal) { - if (i > j) addme = 0; - } else { - if (x[j].z < ztmp) addme = 0; - if (x[j].z == ztmp) { - if (x[j].y < ytmp) addme = 0; - if (x[j].y == ytmp && x[j].x < xtmp) addme = 0; - } - } - if (addme) - neighptr[n++] = joriginal; - } - } else { - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma ivdep - #endif - for (int jj = 0; jj < jnum; jj++) { - const int joriginal = jlist[jj]; - const int j = joriginal & NEIGHMASK; - int addme = 1; - if (j < nlocal) { - if (i > j) addme = 0; - } else { - if (fabs(x[j].z-ztmp) > delta) { - if (x[j].z < ztmp) addme = 0; - } else if (fabs(x[j].y-ytmp) > delta) { - if (x[j].y < ytmp) addme = 0; - } else { - if (x[j].x < xtmp) addme = 0; - } - } - if (addme) - neighptr[n++] = joriginal; - } - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - - int pad_end = n; - IP_PRE_neighbor_pad(pad_end, 0); - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \ - avg=INTEL_COMPILE_WIDTH/2 - #endif - for ( ; n < pad_end; n++) - neighptr[n] = e_nall; - - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - } - list->inum = inum_full; -} - -/* ---------------------------------------------------------------------- - build half list from full 3-body list - half list is already stored as first part of 3-body list -------------------------------------------------------------------------- */ - -template -void NPairHalffullNewtonIntel::build_t3(NeighList *list, int *numhalf) -{ - const int inum_full = list->listfull->inum; - const int e_nall = atom->nlocal + atom->nghost; - int * _noalias const ilist = list->ilist; - int * _noalias const numneigh = list->numneigh; - int ** _noalias const firstneigh = list->firstneigh; - const int * _noalias const ilist_full = list->listfull->ilist; - const int * _noalias const numneigh_full = numhalf; - const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT - - int packthreads = 1; - if (comm->nthreads > INTEL_HTHREADS) packthreads = comm->nthreads; - - #if defined(_OPENMP) - #pragma omp parallel if (packthreads > 1) - #endif - { - int tid, ifrom, ito; - IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, packthreads); - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over parent full list - for (int ii = ifrom; ii < ito; ii++) { - int n = 0; - int *neighptr = ipage.vget(); - - const int i = ilist_full[ii]; - - // loop over full neighbor list - - const int * _noalias const jlist = firstneigh_full[i]; - const int jnum = numneigh_full[ii]; - - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma ivdep - #endif - for (int jj = 0; jj < jnum; jj++) { - const int joriginal = jlist[jj]; - neighptr[n++] = joriginal; - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - - int pad_end = n; - IP_PRE_neighbor_pad(pad_end, 0); - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \ - avg=INTEL_COMPILE_WIDTH/2 - #endif - for ( ; n < pad_end; n++) - neighptr[n] = e_nall; - - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - } - list->inum = inum_full; -} - -/* ---------------------------------------------------------------------- */ - -void NPairHalffullNewtonIntel::build(NeighList *list) -{ - if (_fix->three_body_neighbor() == 0 || domain->triclinic) { - if (_fix->precision() == FixIntel::PREC_MODE_MIXED) - build_t(list, _fix->get_mixed_buffers()); - else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) - build_t(list, _fix->get_double_buffers()); - else - build_t(list, _fix->get_single_buffers()); - } else { - int *nhalf, *cnum; - if (_fix->precision() == FixIntel::PREC_MODE_MIXED) { - _fix->get_mixed_buffers()->get_list_data3(list->listfull, nhalf, cnum); - build_t3(list, nhalf); - } else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - _fix->get_double_buffers()->get_list_data3(list->listfull, nhalf, cnum); - build_t3(list, nhalf); - } else { - _fix->get_single_buffers()->get_list_data3(list->listfull, nhalf, cnum); - build_t3(list, nhalf); - } - } -} diff --git a/src/INTEL/npair_halffull_newton_intel.h b/src/INTEL/npair_halffull_newton_intel.h deleted file mode 100644 index 149983d08e..0000000000 --- a/src/INTEL/npair_halffull_newton_intel.h +++ /dev/null @@ -1,61 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/newton/intel, - NPairHalffullNewtonIntel, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | - NP_ORTHO | NP_TRI| NP_INTEL); - -NPairStyle(halffull/newton/skip/intel, - NPairHalffullNewtonIntel, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | - NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_NEWTON_INTEL_H -#define LMP_NPAIR_HALFFULL_NEWTON_INTEL_H - -#include "fix_intel.h" -#include "npair.h" - -#if defined(_OPENMP) -#include -#endif - -namespace LAMMPS_NS { - -class NPairHalffullNewtonIntel : public NPair { - public: - NPairHalffullNewtonIntel(class LAMMPS *); - void build(class NeighList *) override; - - protected: - FixIntel *_fix; - - template void build_t(NeighList *, IntelBuffers *); - - template void build_t3(NeighList *, int *); -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/INTEL/npair_halffull_trim_newtoff_intel.h b/src/INTEL/npair_halffull_trim_newtoff_intel.h deleted file mode 100644 index 5e8b01cd09..0000000000 --- a/src/INTEL/npair_halffull_trim_newtoff_intel.h +++ /dev/null @@ -1,44 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Stan Moore (SNL) -------------------------------------------------------------------------- */ - -// Only used for hybrid to generate list for non-intel style. Use -// standard routines. - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/trim/newtoff/intel, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL); - -NPairStyle(halffull/trim/newtoff/skip/intel, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP | NP_INTEL); - -NPairStyle(halffull/trim/newtoff/ghost/intel, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST | NP_INTEL); - -NPairStyle(halffull/trim/newtoff/skip/ghost/intel, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP | NP_GHOST | NP_INTEL); -// clang-format on -#endif diff --git a/src/INTEL/npair_halffull_trim_newton_intel.h b/src/INTEL/npair_halffull_trim_newton_intel.h deleted file mode 100644 index dfce63e93d..0000000000 --- a/src/INTEL/npair_halffull_trim_newton_intel.h +++ /dev/null @@ -1,61 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Stan Moore (SNL) -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/trim/newton/intel, - NPairHalffullTrimNewtonIntel, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | - NP_ORTHO | NP_TRI| NP_TRIM | NP_INTEL); - -NPairStyle(halffull/trim/newton/skip/intel, - NPairHalffullTrimNewtonIntel, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | - NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_INTEL); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_TRIM_NEWTON_INTEL_H -#define LMP_NPAIR_HALFFULL_TRIM_NEWTON_INTEL_H - -#include "fix_intel.h" -#include "npair.h" - -#if defined(_OPENMP) -#include -#endif - -namespace LAMMPS_NS { - -class NPairHalffullTrimNewtonIntel : public NPair { - public: - NPairHalffullTrimNewtonIntel(class LAMMPS *); - void build(class NeighList *) override; - - protected: - FixIntel *_fix; - - template void build_t(NeighList *, IntelBuffers *); - - template void build_t3(NeighList *, int *, IntelBuffers *); -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/INTEL/npair_skip_intel.cpp b/src/INTEL/npair_skip_intel.cpp index b023955dd9..8840f7ee43 100644 --- a/src/INTEL/npair_skip_intel.cpp +++ b/src/INTEL/npair_skip_intel.cpp @@ -13,7 +13,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) + Contributing author: W. Michael Brown (Intel), Stan Moore (SNL) ------------------------------------------------------------------------- */ #include "npair_skip_intel.h" @@ -224,3 +224,244 @@ void NPairSkipIntel::build(NeighList *list) } } } + +/* ---------------------------------------------------------------------- */ + +NPairSkipTrimIntel::NPairSkipTrimIntel(LAMMPS *lmp) : NPair(lmp) { + _fix = static_cast(modify->get_fix_by_id("package_intel")); + if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles"); + _inum_starts = new int[comm->nthreads]; + _inum_counts = new int[comm->nthreads]; + _full_props = nullptr; +} + +/* ---------------------------------------------------------------------- */ + +NPairSkipTrimIntel::~NPairSkipTrimIntel() { + delete []_inum_starts; + delete []_inum_counts; + delete[] _full_props; +} + +/* ---------------------------------------------------------------------- */ + +void NPairSkipTrimIntel::copy_neighbor_info() +{ + NPair::copy_neighbor_info(); + // Only need to set _full_props once; npair object deleted for changes + if (_full_props) return; + _full_props = new int[neighbor->nrequest]; + for (int i = 0; i < neighbor->nrequest; i++) + _full_props[i] = neighbor->requests[i]->full; +} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + works for half and full lists + works for owned (non-ghost) list, also for ghost list + iskip and ijskip flag which atom types and type pairs to skip + if ghost, also store neighbors of ghost atoms & set inum,gnum correctly +------------------------------------------------------------------------- */ + +template +void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, + int *numhalf_skip, IntelBuffers *buffers) +{ + const int nlocal = atom->nlocal; + const int e_nall = nlocal + atom->nghost; + const ATOM_T * _noalias const x = buffers->get_x(); + const int * _noalias const type = atom->type; + int * _noalias const ilist = list->ilist; + int * _noalias const numneigh = list->numneigh; + int ** _noalias const firstneigh = (int ** const)list->firstneigh; // NOLINT + const int * _noalias const ilist_skip = list->listskip->ilist; + const int * _noalias const numneigh_skip = list->listskip->numneigh; + const int ** _noalias const firstneigh_skip = (const int ** const)list->listskip->firstneigh; // NOLINT + const int * _noalias const iskip = list->iskip; + const int ** _noalias const ijskip = (const int ** const)list->ijskip; // NOLINT + + const flt_t cutsq_custom = cutoff_custom * cutoff_custom; + int num_skip = list->listskip->inum; + if (list->ghost) num_skip += list->listskip->gnum; + + int packthreads; + if (comm->nthreads > INTEL_HTHREADS && THREE==0) + packthreads = comm->nthreads; + else + packthreads = 1; + + #if defined(_OPENMP) + #pragma omp parallel if (packthreads > 1) + #endif + { + int tid, ifrom, ito; + IP_PRE_omp_range_id(ifrom, ito, tid, num_skip, packthreads); + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + int my_inum = ifrom; + _inum_starts[tid] = ifrom; + + // loop over parent full list + for (int ii = ifrom; ii < ito; ii++) { + const int i = ilist_skip[ii]; + const int itype = type[i]; + if (iskip[itype]) continue; + + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + + int n = 0; + int *neighptr = ipage.vget(); + + // loop over parent non-skip list + + const int * _noalias const jlist = firstneigh_skip[i]; + const int jnum = numneigh_skip[i]; + + if (THREE) { + const int jnumhalf = numhalf_skip[ii]; + for (int jj = 0; jj < jnumhalf; jj++) { + const int joriginal = jlist[jj]; + const int j = joriginal & NEIGHMASK; + + int addme = 1; + if (ijskip[itype][type[j]]) addme = 0; + + // trim to shorter cutoff + + const flt_t delx = xtmp - x[j].x; + const flt_t dely = ytmp - x[j].y; + const flt_t delz = ztmp - x[j].z; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) addme = 0; + + if (addme) + neighptr[n++] = joriginal; + } + numhalf[my_inum] = n; + + for (int jj = jnumhalf; jj < jnum; jj++) { + const int joriginal = jlist[jj]; + const int j = joriginal & NEIGHMASK; + + int addme = 1; + if (ijskip[itype][type[j]]) addme = 0; + + // trim to shorter cutoff + + const flt_t delx = xtmp - x[j].x; + const flt_t dely = ytmp - x[j].y; + const flt_t delz = ztmp - x[j].z; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) addme = 0; + + if (addme) + neighptr[n++] = joriginal; + } + } else { + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma ivdep + #endif + for (int jj = 0; jj < jnum; jj++) { + const int joriginal = jlist[jj]; + const int j = joriginal & NEIGHMASK; + + int addme = 1; + if (ijskip[itype][type[j]]) addme = 0; + + // trim to shorter cutoff + + const flt_t delx = xtmp - x[j].x; + const flt_t dely = ytmp - x[j].y; + const flt_t delz = ztmp - x[j].z; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) addme = 0; + + if (addme) + neighptr[n++] = joriginal; + } + } + + ilist[my_inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + + int pad_end = n; + IP_PRE_neighbor_pad(pad_end, 0); + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \ + avg=INTEL_COMPILE_WIDTH/2 + #endif + for ( ; n < pad_end; n++) + neighptr[n] = e_nall; + + ipage.vgot(n); + if (ipage.status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + int last_inum = 0, loop_end; + _inum_counts[tid] = my_inum; + } + int inum = _inum_counts[0]; + for (int tid = 1; tid < packthreads; tid++) { + for (int i = _inum_starts[tid]; i < _inum_counts[tid]; i++) { + if (THREE) numhalf[inum] = numhalf[i]; + ilist[inum++] = ilist[i]; + } + } + list->inum = inum; + + if (THREE && num_skip > 0) { + int * const list_start = firstneigh[ilist[0]]; + for (int ii = 0; ii < inum; ii++) { + int i = ilist[ii]; + cnumneigh[ii] = static_cast(firstneigh[i] - list_start); + } + } + if (list->ghost) { + int num = 0; + int my_inum = list->inum; + for (int i = 0; i < my_inum; i++) + if (ilist[i] < nlocal) num++; + else break; + list->inum = num; + list->gnum = my_inum - num; + } +} + +/* ---------------------------------------------------------------------- */ + +void NPairSkipTrimIntel::build(NeighList *list) +{ + if (_fix->three_body_neighbor()==0 || + _full_props[list->listskip->index] == 0) { + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) + build_t(list, nullptr, nullptr, nullptr, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + build_t(list, nullptr, nullptr, nullptr, _fix->get_double_buffers()); + else + build_t(list, nullptr, nullptr, nullptr, _fix->get_single_buffers()); + } else { + int *nhalf, *cnumneigh, *nhalf_skip, *u; + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) { + _fix->get_mixed_buffers()->get_list_data3(list->listskip,nhalf_skip,u); + _fix->get_mixed_buffers()->grow_data3(list, nhalf, cnumneigh); + build_t(list, nhalf, cnumneigh, nhalf_skip, _fix->get_mixed_buffers()); + } else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) { + _fix->get_double_buffers()->get_list_data3(list->listskip,nhalf_skip,u); + _fix->get_double_buffers()->grow_data3(list, nhalf, cnumneigh); + build_t(list, nhalf, cnumneigh, nhalf_skip, _fix->get_double_buffers()); + } else { + _fix->get_single_buffers()->get_list_data3(list->listskip,nhalf_skip,u); + _fix->get_single_buffers()->grow_data3(list,nhalf,cnumneigh); + build_t(list, nhalf, cnumneigh, nhalf_skip, _fix->get_single_buffers()); + } + } +} diff --git a/src/INTEL/npair_skip_intel.h b/src/INTEL/npair_skip_intel.h index d38173895a..993f64bf96 100644 --- a/src/INTEL/npair_skip_intel.h +++ b/src/INTEL/npair_skip_intel.h @@ -25,6 +25,18 @@ NPairStyle(skip/ghost/intel, NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_GHOST | NP_INTEL); + +NPairStyle(skip/trim/intel, + NPairSkipTrimIntel, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL); + +NPairStyle(skip/trim/ghost/intel, + NPairSkipTrimIntel, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST | NP_INTEL); // clang-format on #else @@ -55,6 +67,22 @@ class NPairSkipIntel : public NPair { void build_t(NeighList *, int *numhalf, int *cnumneigh, int *numhalf_skip); }; +class NPairSkipTrimIntel : public NPair { + public: + NPairSkipTrimIntel(class LAMMPS *); + ~NPairSkipTrimIntel() override; + void copy_neighbor_info() override; + void build(class NeighList *) override; + + protected: + FixIntel *_fix; + int *_inum_starts, *_inum_counts, *_full_props; + + template + void build_t(NeighList *, int *numhalf, int *cnumneigh, int *numhalf_skip, + IntelBuffers *); +}; + } // namespace LAMMPS_NS #endif diff --git a/src/INTEL/npair_skip_trim_intel.cpp b/src/INTEL/npair_skip_trim_intel.cpp deleted file mode 100644 index e16e1bc413..0000000000 --- a/src/INTEL/npair_skip_trim_intel.cpp +++ /dev/null @@ -1,271 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: Stan Moore (SNL) -------------------------------------------------------------------------- */ - -#include "npair_skip_trim_intel.h" - -#include "atom.h" -#include "comm.h" -#include "error.h" -#include "modify.h" -#include "my_page.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "neighbor.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrimIntel::NPairSkipTrimIntel(LAMMPS *lmp) : NPair(lmp) { - _fix = static_cast(modify->get_fix_by_id("package_intel")); - if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles"); - _inum_starts = new int[comm->nthreads]; - _inum_counts = new int[comm->nthreads]; - _full_props = nullptr; -} - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrimIntel::~NPairSkipTrimIntel() { - delete []_inum_starts; - delete []_inum_counts; - delete[] _full_props; -} - -/* ---------------------------------------------------------------------- */ - -void NPairSkipTrimIntel::copy_neighbor_info() -{ - NPair::copy_neighbor_info(); - // Only need to set _full_props once; npair object deleted for changes - if (_full_props) return; - _full_props = new int[neighbor->nrequest]; - for (int i = 0; i < neighbor->nrequest; i++) - _full_props[i] = neighbor->requests[i]->full; -} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - works for half and full lists - works for owned (non-ghost) list, also for ghost list - iskip and ijskip flag which atom types and type pairs to skip - if ghost, also store neighbors of ghost atoms & set inum,gnum correctly -------------------------------------------------------------------------- */ - -template -void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh, - int *numhalf_skip, IntelBuffers *buffers) -{ - const int nlocal = atom->nlocal; - const int e_nall = nlocal + atom->nghost; - const ATOM_T * _noalias const x = buffers->get_x(); - const int * _noalias const type = atom->type; - int * _noalias const ilist = list->ilist; - int * _noalias const numneigh = list->numneigh; - int ** _noalias const firstneigh = (int ** const)list->firstneigh; // NOLINT - const int * _noalias const ilist_skip = list->listskip->ilist; - const int * _noalias const numneigh_skip = list->listskip->numneigh; - const int ** _noalias const firstneigh_skip = (const int ** const)list->listskip->firstneigh; // NOLINT - const int * _noalias const iskip = list->iskip; - const int ** _noalias const ijskip = (const int ** const)list->ijskip; // NOLINT - - const flt_t cutsq_custom = cutoff_custom * cutoff_custom; - int num_skip = list->listskip->inum; - if (list->ghost) num_skip += list->listskip->gnum; - - int packthreads; - if (comm->nthreads > INTEL_HTHREADS && THREE==0) - packthreads = comm->nthreads; - else - packthreads = 1; - - #if defined(_OPENMP) - #pragma omp parallel if (packthreads > 1) - #endif - { - int tid, ifrom, ito; - IP_PRE_omp_range_id(ifrom, ito, tid, num_skip, packthreads); - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - int my_inum = ifrom; - _inum_starts[tid] = ifrom; - - // loop over parent full list - for (int ii = ifrom; ii < ito; ii++) { - const int i = ilist_skip[ii]; - const int itype = type[i]; - if (iskip[itype]) continue; - - const flt_t xtmp = x[i].x; - const flt_t ytmp = x[i].y; - const flt_t ztmp = x[i].z; - - int n = 0; - int *neighptr = ipage.vget(); - - // loop over parent non-skip list - - const int * _noalias const jlist = firstneigh_skip[i]; - const int jnum = numneigh_skip[i]; - - if (THREE) { - const int jnumhalf = numhalf_skip[ii]; - for (int jj = 0; jj < jnumhalf; jj++) { - const int joriginal = jlist[jj]; - const int j = joriginal & NEIGHMASK; - - int addme = 1; - if (ijskip[itype][type[j]]) addme = 0; - - // trim to shorter cutoff - - const flt_t delx = xtmp - x[j].x; - const flt_t dely = ytmp - x[j].y; - const flt_t delz = ztmp - x[j].z; - const flt_t rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) addme = 0; - - if (addme) - neighptr[n++] = joriginal; - } - numhalf[my_inum] = n; - - for (int jj = jnumhalf; jj < jnum; jj++) { - const int joriginal = jlist[jj]; - const int j = joriginal & NEIGHMASK; - - int addme = 1; - if (ijskip[itype][type[j]]) addme = 0; - - // trim to shorter cutoff - - const flt_t delx = xtmp - x[j].x; - const flt_t dely = ytmp - x[j].y; - const flt_t delz = ztmp - x[j].z; - const flt_t rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) addme = 0; - - if (addme) - neighptr[n++] = joriginal; - } - } else { - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma ivdep - #endif - for (int jj = 0; jj < jnum; jj++) { - const int joriginal = jlist[jj]; - const int j = joriginal & NEIGHMASK; - - int addme = 1; - if (ijskip[itype][type[j]]) addme = 0; - - // trim to shorter cutoff - - const flt_t delx = xtmp - x[j].x; - const flt_t dely = ytmp - x[j].y; - const flt_t delz = ztmp - x[j].z; - const flt_t rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) addme = 0; - - if (addme) - neighptr[n++] = joriginal; - } - } - - ilist[my_inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - - int pad_end = n; - IP_PRE_neighbor_pad(pad_end, 0); - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \ - avg=INTEL_COMPILE_WIDTH/2 - #endif - for ( ; n < pad_end; n++) - neighptr[n] = e_nall; - - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - int last_inum = 0, loop_end; - _inum_counts[tid] = my_inum; - } - int inum = _inum_counts[0]; - for (int tid = 1; tid < packthreads; tid++) { - for (int i = _inum_starts[tid]; i < _inum_counts[tid]; i++) { - if (THREE) numhalf[inum] = numhalf[i]; - ilist[inum++] = ilist[i]; - } - } - list->inum = inum; - - if (THREE && num_skip > 0) { - int * const list_start = firstneigh[ilist[0]]; - for (int ii = 0; ii < inum; ii++) { - int i = ilist[ii]; - cnumneigh[ii] = static_cast(firstneigh[i] - list_start); - } - } - if (list->ghost) { - int num = 0; - int my_inum = list->inum; - for (int i = 0; i < my_inum; i++) - if (ilist[i] < nlocal) num++; - else break; - list->inum = num; - list->gnum = my_inum - num; - } -} - -/* ---------------------------------------------------------------------- */ - -void NPairSkipTrimIntel::build(NeighList *list) -{ - if (_fix->three_body_neighbor()==0 || - _full_props[list->listskip->index] == 0) { - if (_fix->precision() == FixIntel::PREC_MODE_MIXED) - build_t(list, nullptr, nullptr, nullptr, _fix->get_mixed_buffers()); - else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) - build_t(list, nullptr, nullptr, nullptr, _fix->get_double_buffers()); - else - build_t(list, nullptr, nullptr, nullptr, _fix->get_single_buffers()); - } else { - int *nhalf, *cnumneigh, *nhalf_skip, *u; - if (_fix->precision() == FixIntel::PREC_MODE_MIXED) { - _fix->get_mixed_buffers()->get_list_data3(list->listskip,nhalf_skip,u); - _fix->get_mixed_buffers()->grow_data3(list, nhalf, cnumneigh); - build_t(list, nhalf, cnumneigh, nhalf_skip, _fix->get_mixed_buffers()); - } else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - _fix->get_double_buffers()->get_list_data3(list->listskip,nhalf_skip,u); - _fix->get_double_buffers()->grow_data3(list, nhalf, cnumneigh); - build_t(list, nhalf, cnumneigh, nhalf_skip, _fix->get_double_buffers()); - } else { - _fix->get_single_buffers()->get_list_data3(list->listskip,nhalf_skip,u); - _fix->get_single_buffers()->grow_data3(list,nhalf,cnumneigh); - build_t(list, nhalf, cnumneigh, nhalf_skip, _fix->get_single_buffers()); - } - } -} diff --git a/src/INTEL/npair_skip_trim_intel.h b/src/INTEL/npair_skip_trim_intel.h deleted file mode 100644 index f0018e5df4..0000000000 --- a/src/INTEL/npair_skip_trim_intel.h +++ /dev/null @@ -1,62 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim/intel, - NPairSkipTrimIntel, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL); - -NPairStyle(skip/trim/ghost/intel, - NPairSkipTrimIntel, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST | NP_INTEL); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_TRIM_INTEL_H -#define LMP_NPAIR_SKIP_TRIM_INTEL_H - -#include "fix_intel.h" -#include "npair.h" - -#if defined(_OPENMP) -#include -#endif - -namespace LAMMPS_NS { - -class NPairSkipTrimIntel : public NPair { - public: - NPairSkipTrimIntel(class LAMMPS *); - ~NPairSkipTrimIntel() override; - void copy_neighbor_info() override; - void build(class NeighList *) override; - - protected: - FixIntel *_fix; - int *_inum_starts, *_inum_counts, *_full_props; - - template - void build_t(NeighList *, int *numhalf, int *cnumneigh, int *numhalf_skip, - IntelBuffers *); -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/INTEL/nstencil_bin_intel.cpp b/src/INTEL/nstencil_bin_intel.cpp new file mode 100644 index 0000000000..426fcec33c --- /dev/null +++ b/src/INTEL/nstencil_bin_intel.cpp @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------- + 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 "nstencil_bin_intel.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NStencilBinIntel::NStencilBinIntel(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +template +void NStencilBinIntel::create() +{ + int i, j, k; + + // For half stencils, only the upper plane is needed + int sy_min = sy; + int sz_min = sz; + if ((!TRI) && HALF && (!DIM_3D)) sy_min = 0; + if ((!TRI) && HALF && DIM_3D) sz_min = 0; + + nstencil = 0; + + // For Intel, half and ortho stencils do not include central bin + // as, historically, this was never included in a stencil. + // Non-Intel npair classes were updated to account for this change, + // but the Intel npair classes have not yet been updated + // if (HALF && (!TRI)) stencil[nstencil++] = 0; + + for (k = -sz_min; k <= sz; k++) { + for (j = -sy_min; j <= sy; j++) { + for (i = -sx; i <= sx; i++) { + + // Now only include "upper right" bins for half and ortho stencils + if (HALF && (!DIM_3D) && (!TRI)) + if (! (j > 0 || (j == 0 && i > 0))) continue; + if (HALF && DIM_3D && (!TRI)) + if (! (k > 0 || j > 0 || (j == 0 && i > 0))) continue; + + if (bin_distance(i, j, k) < cutneighmaxsq) + stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i; + } + } + } +} + +namespace LAMMPS_NS { +template class NStencilBinIntel<0,0,0>; +template class NStencilBinIntel<0,1,0>; +template class NStencilBinIntel<1,0,0>; +template class NStencilBinIntel<1,0,1>; +template class NStencilBinIntel<1,1,0>; +template class NStencilBinIntel<1,1,1>; +} diff --git a/src/INTEL/nstencil_bin_intel.h b/src/INTEL/nstencil_bin_intel.h new file mode 100644 index 0000000000..e377db5fe5 --- /dev/null +++ b/src/INTEL/nstencil_bin_intel.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS +// clang-format off +typedef NStencilBinIntel<0, 0, 0> NStencilFullBin2dIntel; +NStencilStyle(full/bin/2d/intel, + NStencilFullBin2dIntel, + NS_FULL | NS_BIN | NS_2D | NS_ORTHO | NS_TRI | NS_INTEL); + +typedef NStencilBinIntel<0, 1, 0> NStencilFullBin3dIntel; +NStencilStyle(full/bin/3d/intel, + NStencilFullBin3dIntel, + NS_FULL | NS_BIN | NS_3D | NS_ORTHO | NS_TRI | NS_INTEL); + +typedef NStencilBinIntel<1, 0, 0> NStencilHalfBin2dIntel; +NStencilStyle(half/bin/2d/intel, + NStencilHalfBin2dIntel, + NS_HALF | NS_BIN | NS_2D | NS_ORTHO | NS_INTEL); + +typedef NStencilBinIntel<1, 0, 1> NStencilHalfBin2dTriIntel; +NStencilStyle(half/bin/2d/tri/intel, + NStencilHalfBin2dTriIntel, + NS_HALF | NS_BIN | NS_2D | NS_TRI | NS_INTEL); + +typedef NStencilBinIntel<1, 1, 0> NStencilHalfBin3dIntel; +NStencilStyle(half/bin/3d/intel, + NStencilHalfBin3dIntel, + NS_HALF | NS_BIN | NS_3D | NS_ORTHO | NS_INTEL); + +typedef NStencilBinIntel<1, 1, 1> NStencilHalfBin3dTriIntel; +NStencilStyle(half/bin/3d/tri/intel, + NStencilHalfBin3dTriIntel, + NS_HALF | NS_BIN | NS_3D | NS_TRI | NS_INTEL); +// clang-format on +#else + +#ifndef LMP_NSTENCIL_BIN_INTEL_H +#define LMP_NSTENCIL_BIN_INTEL_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +template +class NStencilBinIntel : public NStencil { + public: + NStencilBinIntel(class LAMMPS *); + void create() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/nstencil_half_bin_3d_tri.cpp b/src/INTEL/nstencil_ghost_bin_intel.cpp similarity index 62% rename from src/nstencil_half_bin_3d_tri.cpp rename to src/INTEL/nstencil_ghost_bin_intel.cpp index 72bef7fb76..23d4930cc0 100644 --- a/src/nstencil_half_bin_3d_tri.cpp +++ b/src/INTEL/nstencil_ghost_bin_intel.cpp @@ -11,34 +11,44 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "nstencil_half_bin_3d_tri.h" +#include "nstencil_ghost_bin_intel.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NStencilHalfBin3dTri::NStencilHalfBin3dTri(LAMMPS *lmp) : NStencil(lmp) {} +template +NStencilGhostBinIntel::NStencilGhostBinIntel(LAMMPS *lmp) : NStencil(lmp) +{ + xyzflag = 1; +} /* ---------------------------------------------------------------------- create stencil based on bin geometry and cutoff ------------------------------------------------------------------------- */ -void NStencilHalfBin3dTri::create() +template +void NStencilGhostBinIntel::create() { int i, j, k; - // for triclinic, need to use full stencil in all dims - // not a half stencil in z - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - // thus for an I/J owned/ghost pair, the xyz coords - // and bin assignments can be different on I proc vs J proc - nstencil = 0; - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i, j, k) < cutneighmaxsq) + for (k = -sz; k <= sz; k++) { + for (j = -sy; j <= sy; j++) { + for (i = -sx; i <= sx; i++) { + if (bin_distance(i, j, k) < cutneighmaxsq) { + stencilxyz[nstencil][0] = i; + stencilxyz[nstencil][1] = j; + stencilxyz[nstencil][2] = k; stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i; + } + } + } + } +} + +namespace LAMMPS_NS { +template class NStencilGhostBinIntel<0>; +template class NStencilGhostBinIntel<1>; } diff --git a/src/nstencil_full_ghost_bin_3d.h b/src/INTEL/nstencil_ghost_bin_intel.h similarity index 60% rename from src/nstencil_full_ghost_bin_3d.h rename to src/INTEL/nstencil_ghost_bin_intel.h index 5fea44f48e..f4ae9f9804 100644 --- a/src/nstencil_full_ghost_bin_3d.h +++ b/src/INTEL/nstencil_ghost_bin_intel.h @@ -13,22 +13,29 @@ #ifdef NSTENCIL_CLASS // clang-format off -NStencilStyle(full/ghost/bin/3d, - NStencilFullGhostBin3d, - NS_FULL | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO | NS_TRI); +typedef NStencilGhostBinIntel<0> NStencilFullGhostBin2dIntel; +NStencilStyle(full/ghost/bin/2d/intel, + NStencilFullGhostBin2dIntel, + NS_FULL | NS_GHOST | NS_BIN | NS_2D | NS_ORTHO | NS_TRI | NS_INTEL); + +typedef NStencilGhostBinIntel<1> NStencilFullGhostBin3dIntel; +NStencilStyle(full/ghost/bin/3d/intel, + NStencilFullGhostBin3dIntel, + NS_FULL | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO | NS_TRI | NS_INTEL); // clang-format on #else -#ifndef LMP_NSTENCIL_FULL_GHOST_BIN_3D_H -#define LMP_NSTENCIL_FULL_GHOST_BIN_3D_H +#ifndef LMP_NSTENCIL_GHOST_BIN_INTEL_H +#define LMP_NSTENCIL_GHOST_BIN_INTEL_H #include "nstencil.h" namespace LAMMPS_NS { -class NStencilFullGhostBin3d : public NStencil { +template +class NStencilGhostBinIntel : public NStencil { public: - NStencilFullGhostBin3d(class LAMMPS *); + NStencilGhostBinIntel(class LAMMPS *); void create() override; }; diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index 8b08de39c0..73f89803c2 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -210,7 +210,7 @@ void PairILPTMD::calc_FRep(int eflag, int /* vflag */) delki[1] = x[k][1] - x[i][1]; delki[2] = x[k][2] - x[i][2]; if (evflag) - ev_tally_xyz(k, j, nlocal, newton_pair, 0.0, 0.0, fk[0], fk[1], fk[2], delki[0], + ev_tally_xyz(k, i, nlocal, newton_pair, 0.0, 0.0, fk[0], fk[1], fk[2], delki[0], delki[1], delki[2]); } diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp index b497ae3568..ad42ba1922 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp +++ b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp @@ -590,7 +590,7 @@ void PairKolmogorovCrespiFull::calc_FRep(int eflag, int /* vflag */) delki[1] = x[k][1] - x[i][1]; delki[2] = x[k][2] - x[i][2]; if (evflag) - ev_tally_xyz(k, j, nlocal, newton_pair, 0.0, 0.0, fk[0], fk[1], fk[2], delki[0], + ev_tally_xyz(k, i, nlocal, newton_pair, 0.0, 0.0, fk[0], fk[1], fk[2], delki[0], delki[1], delki[2]); } diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 489efc55a0..af80420d7a 100755 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -165,6 +165,8 @@ action fix_qeq_reaxff_kokkos.cpp fix_qeq_reaxff.cpp action fix_qeq_reaxff_kokkos.h fix_qeq_reaxff.h action fix_reaxff_bonds_kokkos.cpp fix_reaxff_bonds.cpp action fix_reaxff_bonds_kokkos.h fix_reaxff_bonds.h +action compute_reaxff_atom_kokkos.cpp compute_reaxff_atom.cpp +action compute_reaxff_atom_kokkos.h compute_reaxff_atom.h action fix_reaxff_species_kokkos.cpp fix_reaxff_species.cpp action fix_reaxff_species_kokkos.h fix_reaxff_species.h action fix_rx_kokkos.cpp fix_rx.cpp @@ -177,6 +179,10 @@ action fix_shardlow_kokkos.cpp fix_shardlow.cpp action fix_shardlow_kokkos.h fix_shardlow.h action fix_spring_self_kokkos.cpp action fix_spring_self_kokkos.h +action fix_temp_berendsen_kokkos.cpp +action fix_temp_berendsen_kokkos.h +action fix_temp_rescale_kokkos.cpp +action fix_temp_rescale_kokkos.h action fix_viscous_kokkos.cpp action fix_viscous_kokkos.h action fix_wall_gran_kokkos.cpp fix_wall_gran.cpp diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index bc393b29d8..c55c1d315b 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -25,6 +25,7 @@ #include "kokkos_base.h" #include "modify.h" #include "fix.h" +#include "fix_property_atom_kokkos.h" using namespace LAMMPS_NS; diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index 21a9aeebbd..6a3036375d 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -14,7 +14,6 @@ #include "atom.h" // IWYU pragma: export #include "kokkos_type.h" -#include "fix_property_atom_kokkos.h" #include @@ -27,7 +26,7 @@ class AtomKokkos : public Atom { public: bool sort_classic; int nprop_atom; - FixPropertyAtomKokkos** fix_prop_atom; + class FixPropertyAtomKokkos **fix_prop_atom; DAT::tdual_tagint_1d k_tag; DAT::tdual_int_1d k_type, k_mask; diff --git a/src/KOKKOS/compute_reaxff_atom_kokkos.cpp b/src/KOKKOS/compute_reaxff_atom_kokkos.cpp new file mode 100644 index 0000000000..8dbcb9441e --- /dev/null +++ b/src/KOKKOS/compute_reaxff_atom_kokkos.cpp @@ -0,0 +1,195 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Richard Berger (LANL) +------------------------------------------------------------------------- */ + +#include "compute_reaxff_atom_kokkos.h" +#include "atom.h" +#include "molecule.h" +#include "update.h" +#include "force.h" +#include "memory.h" +#include "error.h" +#include "neigh_list.h" + +#include "memory_kokkos.h" +#include "pair_reaxff_kokkos.h" +#include "reaxff_api.h" + +using namespace LAMMPS_NS; +using namespace ReaxFF; + +/* ---------------------------------------------------------------------- */ + +template +ComputeReaxFFAtomKokkos::ComputeReaxFFAtomKokkos(LAMMPS *lmp, int narg, char **arg) : + ComputeReaxFFAtom(lmp, narg, arg), + nbuf(-1), buf(nullptr) +{ + kokkosable = 1; +} + +/* ---------------------------------------------------------------------- */ + +template +ComputeReaxFFAtomKokkos::~ComputeReaxFFAtomKokkos() +{ + memoryKK->destroy_kokkos(k_buf, buf); +} + +/* ---------------------------------------------------------------------- */ + +template +void ComputeReaxFFAtomKokkos::init() +{ + ComputeReaxFFAtom::init(); + + if (!reaxff || !reaxff->kokkosable) { + error->all(FLERR,"Cannot use compute reaxff/atom/kk without " + "pair_style reaxff/kk"); + } +} + +/* ---------------------------------------------------------------------- */ +template +void ComputeReaxFFAtomKokkos::compute_bonds() +{ + if (atom->nlocal > nlocal) { + memory->destroy(array_atom); + nlocal = atom->nlocal; + memory->create(array_atom, nlocal, 3, "reaxff/atom:array_atom"); + } + + // retrieve bond information from kokkos pair style. the data potentially + // lives on device. it is copied into buf on the host in a condensed format + // compute_local and compute_atom then expand the data from this buffer into + // appropiate arrays for consumption by others (e.g. dump local, dump custom + // or library interface) + + int maxnumbonds = 0; + if (reaxff->execution_space == Device) + device_pair()->FindBond(maxnumbonds, groupbit); + else + host_pair()->FindBond(maxnumbonds, groupbit); + + nbuf = ((store_bonds ? maxnumbonds*2 : 0) + 3)*nlocal; + + if (!buf || k_buf.extent(0) < nbuf) { + memoryKK->destroy_kokkos(k_buf, buf); + memoryKK->create_kokkos(k_buf, buf, nbuf, "reaxff/atom:buf"); + } + + // Pass information to buffer, will sync to host + + int nbuf_local; + if (reaxff->execution_space == Device) + device_pair()->PackReducedBondBuffer(k_buf, nbuf_local, store_bonds); + else + host_pair()->PackReducedBondBuffer(k_buf, nbuf_local, store_bonds); + + // Extract number of bonds from buffer + + nbonds = 0; + int j = 0; + for (int i = 0; i < nlocal; i++) { + int numbonds = static_cast(buf[j+2]); + nbonds += numbonds; + j += (store_bonds ? 2*numbonds : 0) + 3; + } +} + +/* ---------------------------------------------------------------------- */ + +template +void ComputeReaxFFAtomKokkos::compute_local() +{ + invoked_local = update->ntimestep; + + if (invoked_bonds < update->ntimestep) + compute_bonds(); + + if (nbonds > prev_nbonds) { + // grow array_local + memory->destroy(array_local); + memory->create(array_local, nbonds, 3, "reaxff/atom:array_local"); + prev_nbonds = nbonds; + } + + size_local_rows = nbonds; + + // extract local bond information from buffer + + int b = 0; + int j = 0; + auto tag = atom->tag; + + for (int i = 0; i < nlocal; ++i) { + const int numbonds = static_cast(buf[j+2]); + const int neigh_offset = j + 3; + const int bo_offset = neigh_offset + numbonds; + for (int k = 0; k < numbonds; k++) { + auto bond = array_local[b++]; + bond[0] = tag[i]; + bond[1] = static_cast (buf[neigh_offset+k]); + bond[2] = buf[bo_offset+k]; + } + j += 2*numbonds + 3; + } +} + +/* ---------------------------------------------------------------------- */ + +template +void ComputeReaxFFAtomKokkos::compute_peratom() +{ + invoked_peratom = update->ntimestep; + + if (invoked_bonds < update->ntimestep) + compute_bonds(); + + // extract peratom bond information from buffer + + int j = 0; + for (int i = 0; i < nlocal; ++i) { + auto ptr = array_atom[i]; + int numbonds = static_cast(buf[j+2]); + ptr[0] = buf[j]; // sbo + ptr[1] = buf[j+1]; // nlp + ptr[2] = numbonds; + j += (store_bonds ? 2*numbonds : 0) + 3; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local data +------------------------------------------------------------------------- */ + +template +double ComputeReaxFFAtomKokkos::memory_usage() +{ + double bytes = (double)(nlocal*3) * sizeof(double); + if (store_bonds) + bytes += (double)(nbonds*3) * sizeof(double); + bytes += (double)(nbuf > 0 ? nbuf * sizeof(double) : 0); + return bytes; +} + +namespace LAMMPS_NS { +template class ComputeReaxFFAtomKokkos; +#ifdef LMP_KOKKOS_GPU +template class ComputeReaxFFAtomKokkos; +#endif +} diff --git a/src/KOKKOS/compute_reaxff_atom_kokkos.h b/src/KOKKOS/compute_reaxff_atom_kokkos.h new file mode 100644 index 0000000000..7037c7e308 --- /dev/null +++ b/src/KOKKOS/compute_reaxff_atom_kokkos.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Richard Berger (LANL) +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(reaxff/atom/kk,ComputeReaxFFAtomKokkos); +ComputeStyle(reaxff/atom/kk/device,ComputeReaxFFAtomKokkos); +ComputeStyle(reaxff/atom/kk/host,ComputeReaxFFAtomKokkos); +// clang-format on +#else + +#ifndef LMP_COMPUTE_REAXFF_BONDS_KOKKOS_H +#define LMP_COMPUTE_REAXFF_BONDS_KOKKOS_H + +#include "compute_reaxff_atom.h" +#include "pair_reaxff_kokkos.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +class ComputeReaxFFAtomKokkos : public ComputeReaxFFAtom { + public: + using device_type = DeviceType; + using AT = ArrayTypes; + + ComputeReaxFFAtomKokkos(class LAMMPS *, int, char **); + ~ComputeReaxFFAtomKokkos() override; + void init() override; + void compute_local() override; + void compute_peratom() override; + void compute_bonds() override; + double memory_usage() override; + + private: + int nbuf; + double *buf; + typename AT::tdual_float_1d k_buf; + + auto device_pair() { + return static_cast*>(reaxff); + } + + auto host_pair() { + return static_cast*>(reaxff); + } +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/KOKKOS/fix_temp_berendsen_kokkos.cpp b/src/KOKKOS/fix_temp_berendsen_kokkos.cpp new file mode 100644 index 0000000000..b986b3189a --- /dev/null +++ b/src/KOKKOS/fix_temp_berendsen_kokkos.cpp @@ -0,0 +1,135 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "fix_temp_berendsen_kokkos.h" + +#include "atom_kokkos.h" +#include "comm.h" +#include "compute.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "input.h" +#include "modify.h" +#include "update.h" +#include "variable.h" +#include "atom_masks.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace FixConst; + +enum{NOBIAS,BIAS}; +enum{CONSTANT,EQUAL}; + +/* ---------------------------------------------------------------------- */ + +template +FixTempBerendsenKokkos::FixTempBerendsenKokkos(LAMMPS *lmp, int narg, char **arg) : + FixTempBerendsen(lmp, narg, arg) +{ + kokkosable = 1; + atomKK = (AtomKokkos *)atom; + execution_space = ExecutionSpaceFromDevice::space; + + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixTempBerendsenKokkos::end_of_step() +{ + atomKK->sync(temperature->execution_space,temperature->datamask_read); + double t_current = temperature->compute_scalar(); + atomKK->modified(temperature->execution_space,temperature->datamask_modify); + atomKK->sync(execution_space,temperature->datamask_modify); + + double tdof = temperature->dof; + + // there is nothing to do, if there are no degrees of freedom + + if (tdof < 1) return; + + if (t_current == 0.0) + error->all(FLERR, "Computed current temperature for fix temp/berendsen must not be 0.0"); + + double delta = update->ntimestep - update->beginstep; + if (delta != 0.0) delta /= update->endstep - update->beginstep; + + // set current t_target + // if variable temp, evaluate variable, wrap with clear/add + + if (tstyle == CONSTANT) + t_target = t_start + delta * (t_stop-t_start); + else { + modify->clearstep_compute(); + t_target = input->variable->compute_equal(tvar); + if (t_target < 0.0) + error->one(FLERR, "Fix temp/berendsen variable {} returned negative temperature", + input->variable->names[tvar]); + modify->addstep_compute(update->ntimestep + nevery); + } + + // rescale velocities by lamda + // for BIAS: + // temperature is current, so do not need to re-compute + // OK to not test returned v = 0, since lamda is multiplied by v + + double lamda = sqrt(1.0 + update->dt/t_period*(t_target/t_current - 1.0)); + double efactor = 0.5 * force->boltz * tdof; + energy += t_current * (1.0-lamda*lamda) * efactor; + + auto v = atomKK->k_v.view(); + auto mask = atomKK->k_mask.view(); + int nlocal = atom->nlocal; + auto groupbit = this->groupbit; + + if (which == NOBIAS) { + atomKK->sync(temperature->execution_space,temperature->datamask_read); + temperature->remove_bias_all(); + atomKK->modified(temperature->execution_space,temperature->datamask_modify); + atomKK->sync(execution_space,temperature->datamask_modify); + } + + atomKK->sync(execution_space,V_MASK|MASK_MASK); + + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal), LAMMPS_LAMBDA(int i) { + if (mask[i] & groupbit) { + v(i,0) *= lamda; + v(i,1) *= lamda; + v(i,2) *= lamda; + } + }); + + atomKK->modified(execution_space,V_MASK); + + if (which == NOBIAS) { + atomKK->sync(temperature->execution_space,temperature->datamask_read); + temperature->restore_bias_all(); + atomKK->modified(temperature->execution_space,temperature->datamask_modify); + atomKK->sync(execution_space,temperature->datamask_modify); + } +} +/* ---------------------------------------------------------------------- */ + +namespace LAMMPS_NS { +template class FixTempBerendsenKokkos; +#ifdef LMP_KOKKOS_GPU +template class FixTempBerendsenKokkos; +#endif +} diff --git a/src/npair_half_bin_atomonly_newton.h b/src/KOKKOS/fix_temp_berendsen_kokkos.h similarity index 55% rename from src/npair_half_bin_atomonly_newton.h rename to src/KOKKOS/fix_temp_berendsen_kokkos.h index b17f7608fc..6a0aa5ce98 100644 --- a/src/npair_half_bin_atomonly_newton.h +++ b/src/KOKKOS/fix_temp_berendsen_kokkos.h @@ -11,25 +11,31 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef FIX_CLASS // clang-format off -NPairStyle(half/bin/atomonly/newton, - NPairHalfBinAtomonlyNewton, - NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); +FixStyle(temp/berendsen/kk,FixTempBerendsenKokkos); +FixStyle(temp/berendsen/kk/device,FixTempBerendsenKokkos); +FixStyle(temp/berendsen/kk/host,FixTempBerendsenKokkos); // clang-format on #else -#ifndef LMP_NPAIR_HALF_BIN_ATOMONLY_NEWTON_H -#define LMP_NPAIR_HALF_BIN_ATOMONLY_NEWTON_H +// clang-format off +#ifndef LMP_FIX_TEMP_BERENDSEN_KOKKOS_H +#define LMP_FIX_TEMP_BERENDSEN_KOKKOS_H -#include "npair.h" +#include "fix_temp_berendsen.h" +#include "kokkos_type.h" namespace LAMMPS_NS { -class NPairHalfBinAtomonlyNewton : public NPair { +template +class FixTempBerendsenKokkos : public FixTempBerendsen { public: - NPairHalfBinAtomonlyNewton(class LAMMPS *); - void build(class NeighList *) override; + typedef DeviceType device_type; + + FixTempBerendsenKokkos(class LAMMPS *, int, char **); + ~FixTempBerendsenKokkos() override {} + void end_of_step() override; }; } // namespace LAMMPS_NS diff --git a/src/KOKKOS/fix_temp_rescale_kokkos.cpp b/src/KOKKOS/fix_temp_rescale_kokkos.cpp new file mode 100644 index 0000000000..3a1c6ddd26 --- /dev/null +++ b/src/KOKKOS/fix_temp_rescale_kokkos.cpp @@ -0,0 +1,140 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "fix_temp_rescale_kokkos.h" + +#include "atom_kokkos.h" +#include "comm.h" +#include "compute.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "input.h" +#include "modify.h" +#include "update.h" +#include "variable.h" +#include "atom_masks.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace FixConst; + +enum{NOBIAS,BIAS}; +enum{CONSTANT,EQUAL}; + +/* ---------------------------------------------------------------------- */ + +template +FixTempRescaleKokkos::FixTempRescaleKokkos(LAMMPS *lmp, int narg, char **arg) : + FixTempRescale(lmp, narg, arg) +{ + kokkosable = 1; + atomKK = (AtomKokkos *)atom; + execution_space = ExecutionSpaceFromDevice::space; + + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixTempRescaleKokkos::end_of_step() +{ + atomKK->sync(temperature->execution_space,temperature->datamask_read); + double t_current = temperature->compute_scalar(); + atomKK->modified(temperature->execution_space,temperature->datamask_modify); + atomKK->sync(execution_space,temperature->datamask_modify); + + // there is nothing to do, if there are no degrees of freedom + + if (temperature->dof < 1) return; + + // protect against division by zero + + if (t_current == 0.0) + error->all(FLERR,"Computed temperature for fix temp/rescale cannot be 0.0"); + + double delta = update->ntimestep - update->beginstep; + if (delta != 0.0) delta /= update->endstep - update->beginstep; + + // set current t_target + // if variable temp, evaluate variable, wrap with clear/add + + if (tstyle == CONSTANT) + t_target = t_start + delta * (t_stop-t_start); + else { + modify->clearstep_compute(); + t_target = input->variable->compute_equal(tvar); + if (t_target < 0.0) + error->one(FLERR, "Fix temp/rescale variable returned negative temperature"); + modify->addstep_compute(update->ntimestep + nevery); + } + + // rescale velocity of appropriate atoms if outside window + // for BIAS: + // temperature is current, so do not need to re-compute + // OK to not test returned v = 0, since factor is multiplied by v + + if (fabs(t_current-t_target) > t_window) { + t_target = t_current - fraction*(t_current-t_target); + double factor = sqrt(t_target/t_current); + double efactor = 0.5 * force->boltz * temperature->dof; + + energy += (t_current-t_target) * efactor; + + auto v = atomKK->k_v.view(); + auto mask = atomKK->k_mask.view(); + int nlocal = atom->nlocal; + auto groupbit = this->groupbit; + + if (which == NOBIAS) { + atomKK->sync(temperature->execution_space,temperature->datamask_read); + temperature->remove_bias_all(); + atomKK->modified(temperature->execution_space,temperature->datamask_modify); + atomKK->sync(execution_space,temperature->datamask_modify); + } + + atomKK->sync(execution_space,V_MASK|MASK_MASK); + + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal), LAMMPS_LAMBDA(int i) { + if (mask[i] & groupbit) { + v(i,0) *= factor; + v(i,1) *= factor; + v(i,2) *= factor; + } + }); + + atomKK->modified(execution_space,V_MASK); + + if (which == NOBIAS) { + atomKK->sync(temperature->execution_space,temperature->datamask_read); + temperature->restore_bias_all(); + atomKK->modified(temperature->execution_space,temperature->datamask_modify); + atomKK->sync(execution_space,temperature->datamask_modify); + + } + } +} + +/* ---------------------------------------------------------------------- */ + +namespace LAMMPS_NS { +template class FixTempRescaleKokkos; +#ifdef LMP_KOKKOS_GPU +template class FixTempRescaleKokkos; +#endif +} diff --git a/src/INTEL/npair_half_bin_newton_intel.h b/src/KOKKOS/fix_temp_rescale_kokkos.h similarity index 57% rename from src/INTEL/npair_half_bin_newton_intel.h rename to src/KOKKOS/fix_temp_rescale_kokkos.h index 092d4f2101..7dd3111325 100644 --- a/src/INTEL/npair_half_bin_newton_intel.h +++ b/src/KOKKOS/fix_temp_rescale_kokkos.h @@ -1,4 +1,3 @@ -// clang-format off /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -12,29 +11,31 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifdef NPAIR_CLASS +#ifdef FIX_CLASS // clang-format off -NPairStyle(half/bin/newton/intel, - NPairHalfBinNewtonIntel, - NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_INTEL); +FixStyle(temp/rescale/kk,FixTempRescaleKokkos); +FixStyle(temp/rescale/kk/device,FixTempRescaleKokkos); +FixStyle(temp/rescale/kk/host,FixTempRescaleKokkos); // clang-format on #else -#ifndef LMP_NPAIR_HALF_BIN_NEWTON_INTEL_H -#define LMP_NPAIR_HALF_BIN_NEWTON_INTEL_H +// clang-format off +#ifndef LMP_FIX_TEMP_RESCALE_KOKKOS_H +#define LMP_FIX_TEMP_RESCALE_KOKKOS_H -#include "fix_intel.h" -#include "npair_intel.h" +#include "fix_temp_rescale.h" +#include "kokkos_type.h" namespace LAMMPS_NS { -class NPairHalfBinNewtonIntel : public NPairIntel { +template +class FixTempRescaleKokkos : public FixTempRescale { public: - NPairHalfBinNewtonIntel(class LAMMPS *); - void build(class NeighList *) override; + typedef DeviceType device_type; - private: - template void hbni(NeighList *, IntelBuffers *); + FixTempRescaleKokkos(class LAMMPS *, int, char **); + ~FixTempRescaleKokkos() override {} + void end_of_step() override; }; } // namespace LAMMPS_NS diff --git a/src/KOKKOS/grid3d_kokkos.cpp b/src/KOKKOS/grid3d_kokkos.cpp index 9a82e0157d..7b97c417dd 100644 --- a/src/KOKKOS/grid3d_kokkos.cpp +++ b/src/KOKKOS/grid3d_kokkos.cpp @@ -640,7 +640,7 @@ void Grid3dKokkos::forward_comm(int caller, void *ptr, int which, in MPI_Datatype datatype) { if (caller == KSPACE) { - if (layout != Comm::LAYOUT_TILED) + if (comm->layout != Comm::LAYOUT_TILED) forward_comm_kspace_brick((KSpace *) ptr,which,nper,k_buf1,k_buf2,datatype); else forward_comm_kspace_tiled((KSpace *) ptr,which,nper,k_buf1,k_buf2,datatype); @@ -780,7 +780,7 @@ void Grid3dKokkos::reverse_comm(int caller, void *ptr, int which, in MPI_Datatype datatype) { if (caller == KSPACE) { - if (layout != Comm::LAYOUT_TILED) + if (comm->layout != Comm::LAYOUT_TILED) reverse_comm_kspace_brick((KSpace *) ptr,which,nper,k_buf1,k_buf2,datatype); else reverse_comm_kspace_tiled((KSpace *) ptr,which,nper,k_buf1,k_buf2,datatype); diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index c963cd52d0..5572f69901 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -608,8 +608,8 @@ void KokkosLMP::accelerator(int narg, char **arg) force->newton = force->newton_pair = force->newton_bond = newtonflag; - if (neigh_thread && neighflag != FULL) - error->all(FLERR,"Must use KOKKOS package option 'neigh full' with 'neigh/thread on'"); + if (neigh_thread && newtonflag) + error->all(FLERR,"Must use KOKKOS package option 'newton off' with 'neigh/thread on'"); neighbor->binsize_user = binsize; if (binsize <= 0.0) neighbor->binsizeflag = 0; diff --git a/src/KOKKOS/min_kokkos.cpp b/src/KOKKOS/min_kokkos.cpp index c01a53c7b3..3460fe9009 100644 --- a/src/KOKKOS/min_kokkos.cpp +++ b/src/KOKKOS/min_kokkos.cpp @@ -21,6 +21,7 @@ #include "angle.h" #include "atom_kokkos.h" #include "atom_masks.h" +#include "atom_vec.h" #include "bond.h" #include "comm.h" #include "compute.h" diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index d3c766f5ae..9521268284 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -19,10 +19,12 @@ #ifndef LMP_PAIR_KOKKOS_H #define LMP_PAIR_KOKKOS_H -#include "Kokkos_Macros.hpp" #include "pair.h" // IWYU pragma: export #include "neighbor_kokkos.h" #include "neigh_list_kokkos.h" +#include "math_special.h" +#include "update.h" +#include "Kokkos_Macros.hpp" #include "Kokkos_ScatterView.hpp" namespace LAMMPS_NS { @@ -63,6 +65,7 @@ struct PairComputeFunctor { typename AT::t_f_array f; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; + int inum; using KKDeviceType = typename KKDevice::value; using DUP = NeedDup_v; @@ -81,8 +84,6 @@ struct PairComputeFunctor { // typename KKDevice::value,Kokkos::MemoryTraits::value> > vatom; KKScatterView dup_vatom; - - NeighListKokkos list; PairComputeFunctor(PairStyle* c_ptr, @@ -95,6 +96,7 @@ struct PairComputeFunctor { dup_f = Kokkos::Experimental::create_scatter_view(c.f); dup_eatom = Kokkos::Experimental::create_scatter_view(c.d_eatom); dup_vatom = Kokkos::Experimental::create_scatter_view(c.d_vatom); + inum = list.inum; }; // Set copymode = 1 so parent allocations aren't destructed by copies of the style @@ -105,17 +107,22 @@ struct PairComputeFunctor { } void contribute() { - Kokkos::Experimental::contribute(c.f, dup_f); + int need_dup = std::is_same_v; - if (c.eflag_atom) - Kokkos::Experimental::contribute(c.d_eatom, dup_eatom); + if (need_dup) { + Kokkos::Experimental::contribute(c.f, dup_f); - if (c.vflag_atom) - Kokkos::Experimental::contribute(c.d_vatom, dup_vatom); + if (c.eflag_atom) + Kokkos::Experimental::contribute(c.d_eatom, dup_eatom); + + if (c.vflag_atom) + Kokkos::Experimental::contribute(c.d_vatom, dup_vatom); + } } // Loop over neighbors of one atom without coulomb interaction // This function is called in parallel + template KOKKOS_FUNCTION EV_FLOAT compute_item(const int& ii, @@ -161,7 +168,7 @@ struct PairComputeFunctor { fytmp += dely*fpair; fztmp += delz*fpair; - if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < c.nlocal)) { + if ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && (NEWTON_PAIR || j < c.nlocal)) { a_f(j,0) -= delx*fpair; a_f(j,1) -= dely*fpair; a_f(j,2) -= delz*fpair; @@ -169,9 +176,9 @@ struct PairComputeFunctor { if (EVFLAG) { F_FLOAT evdwl = 0.0; - if (c.eflag) { + if (c.eflag_either) { evdwl = factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); - ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j KOKKOS_FUNCTION EV_FLOAT compute_item(const int& ii, @@ -241,7 +249,7 @@ struct PairComputeFunctor { fytmp += dely*fpair; fztmp += delz*fpair; - if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < c.nlocal)) { + if ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && (NEWTON_PAIR || j < c.nlocal)) { a_f(j,0) -= delx*fpair; a_f(j,1) -= dely*fpair; a_f(j,2) -= delz*fpair; @@ -250,14 +258,14 @@ struct PairComputeFunctor { if (EVFLAG) { F_FLOAT evdwl = 0.0; F_FLOAT ecoul = 0.0; - if (c.eflag) { + if (c.eflag_either) { if (rsq < (STACKPARAMS?c.m_cut_ljsq[itype][jtype]:c.d_cut_ljsq(itype,jtype))) { evdwl = factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); - ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j(rsq,i,j,itype,jtype,factor_coul,qtmp); - ev.ecoul += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(j::member_type team, const NeighListKokkos &list, const NoCoulTag&) const { - const int inum = team.league_size(); + auto a_f = dup_f.template access::value>(); + const int atoms_per_team = team.team_size(); const int firstatom = team.league_rank()*atoms_per_team; const int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; @@ -292,7 +302,7 @@ struct PairComputeFunctor { const X_FLOAT ztmp = c.x(i,2); const int itype = c.type(i); - if (ZEROFLAG) { + if (NEIGHFLAG == FULL && ZEROFLAG) { Kokkos::single(Kokkos::PerThread(team), [&] (){ f(i,0) = 0.0; f(i,1) = 0.0; @@ -321,30 +331,42 @@ struct PairComputeFunctor { const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); - ftmp.x += delx*fpair; - ftmp.y += dely*fpair; - ftmp.z += delz*fpair; + const F_FLOAT fx = delx*fpair; + const F_FLOAT fy = dely*fpair; + const F_FLOAT fz = delz*fpair; + + ftmp.x += fx; + ftmp.y += fy; + ftmp.z += fz; + + if ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && j < c.nlocal) { + a_f(j,0) -= fx; + a_f(j,1) -= fy; + a_f(j,2) -= fz; + } } },fsum); Kokkos::single(Kokkos::PerThread(team), [&] () { - f(i,0) += fsum.x; - f(i,1) += fsum.y; - f(i,2) += fsum.z; + a_f(i,0) += fsum.x; + a_f(i,1) += fsum.y; + a_f(i,2) += fsum.z; }); }); } - // Use TeamPolicy, assume Newton off, Full Neighborlist, and no energy/virial + // TeamPolicy, newton off, and no energy/virial // Loop over neighbors of one atom with coulomb interaction // This function is called in parallel + KOKKOS_FUNCTION void compute_item_team(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const CoulTag& ) const { - const int inum = team.league_size(); + auto a_f = dup_f.template access::value>(); + const int atoms_per_team = team.team_size(); int firstatom = team.league_rank()*atoms_per_team; int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; @@ -357,8 +379,9 @@ struct PairComputeFunctor { const int itype = c.type(i); const F_FLOAT qtmp = c.q(i); - if (ZEROFLAG) { - Kokkos::single(Kokkos::PerThread(team), [&] (){ + if (NEIGHFLAG == FULL && ZEROFLAG) { + Kokkos::single(Kokkos::PerThread(team), [&] () + { f(i,0) = 0.0; f(i,1) = 0.0; f(i,2) = 0.0; @@ -391,31 +414,45 @@ struct PairComputeFunctor { if (rsq < (STACKPARAMS?c.m_cut_coulsq[itype][jtype]:c.d_cut_coulsq(itype,jtype))) fpair+=c.template compute_fcoul(rsq,i,j,itype,jtype,factor_coul,qtmp); - ftmp.x += delx*fpair; - ftmp.y += dely*fpair; - ftmp.z += delz*fpair; + const F_FLOAT fx = delx*fpair; + const F_FLOAT fy = dely*fpair; + const F_FLOAT fz = delz*fpair; + + ftmp.x += fx; + ftmp.y += fy; + ftmp.z += fz; + + if ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && j < c.nlocal) { + a_f(j,0) -= fx; + a_f(j,1) -= fy; + a_f(j,2) -= fz; + } } + },fsum); Kokkos::single(Kokkos::PerThread(team), [&] () { - f(i,0) += fsum.x; - f(i,1) += fsum.y; - f(i,2) += fsum.z; + a_f(i,0) += fsum.x; + a_f(i,1) += fsum.y; + a_f(i,2) += fsum.z; }); }); } - - // Use TeamPolicy, assume Newton off, Full Neighborlist, and energy/virial + // TeamPolicy, newton off, and energy/virial // Loop over neighbors of one atom without coulomb interaction // This function is called in parallel + KOKKOS_FUNCTION EV_FLOAT compute_item_team_ev(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const NoCoulTag&) const { + auto a_f = dup_f.template access::value>(); + auto a_eatom = dup_eatom.template access::value>(); + auto a_vatom = dup_vatom.template access::value>(); + EV_FLOAT ev; - const int inum = team.league_size(); const int atoms_per_team = team.team_size(); const int firstatom = team.league_rank()*atoms_per_team; const int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; @@ -427,8 +464,9 @@ struct PairComputeFunctor { const X_FLOAT ztmp = c.x(i,2); const int itype = c.type(i); - if (ZEROFLAG) { - Kokkos::single(Kokkos::PerThread(team), [&] (){ + if (NEIGHFLAG == FULL && ZEROFLAG) { + Kokkos::single(Kokkos::PerThread(team), [&] () + { f(i,0) = 0.0; f(i,1) = 0.0; f(i,2) = 0.0; @@ -456,37 +494,85 @@ struct PairComputeFunctor { const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); - fev_tmp.f[0] += delx*fpair; - fev_tmp.f[1] += dely*fpair; - fev_tmp.f[2] += delz*fpair; + const F_FLOAT fx = delx*fpair; + const F_FLOAT fy = dely*fpair; + const F_FLOAT fz = delz*fpair; + + fev_tmp.f[0] += fx; + fev_tmp.f[1] += fy; + fev_tmp.f[2] += fz; + + const int I_CONTRIB = (NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD); + const int J_CONTRIB = ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && j < c.nlocal); + const E_FLOAT factor = J_CONTRIB?1.0:0.5; + + if (J_CONTRIB) { + a_f(j,0) -= fx; + a_f(j,1) -= fy; + a_f(j,2) -= fz; + } F_FLOAT evdwl = 0.0; - if (c.eflag) { + if (c.eflag_either) { evdwl = factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); - fev_tmp.evdwl += 0.5*evdwl; + fev_tmp.evdwl += factor * evdwl; + + if (c.eflag_atom) { + const E_FLOAT epairhalf = 0.5 * evdwl; + + if (I_CONTRIB) + a_eatom[i] += epairhalf; + + if (J_CONTRIB) + a_eatom[j] += epairhalf; + } } + if (c.vflag_either) { - fev_tmp.v[0] += 0.5*delx*delx*fpair; - fev_tmp.v[1] += 0.5*dely*dely*fpair; - fev_tmp.v[2] += 0.5*delz*delz*fpair; - fev_tmp.v[3] += 0.5*delx*dely*fpair; - fev_tmp.v[4] += 0.5*delx*delz*fpair; - fev_tmp.v[5] += 0.5*dely*delz*fpair; + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + fev_tmp.v[0] += factor*v0; + fev_tmp.v[1] += factor*v1; + fev_tmp.v[2] += factor*v2; + fev_tmp.v[3] += factor*v3; + fev_tmp.v[4] += factor*v4; + fev_tmp.v[5] += factor*v5; + + if (c.vflag_atom) { + if (I_CONTRIB) { + a_vatom(i,0) += 0.5*v0; + a_vatom(i,1) += 0.5*v1; + a_vatom(i,2) += 0.5*v2; + a_vatom(i,3) += 0.5*v3; + a_vatom(i,4) += 0.5*v4; + a_vatom(i,5) += 0.5*v5; + } + if (J_CONTRIB) { + a_vatom(j,0) += 0.5*v0; + a_vatom(j,1) += 0.5*v1; + a_vatom(j,2) += 0.5*v2; + a_vatom(j,3) += 0.5*v3; + a_vatom(j,4) += 0.5*v4; + a_vatom(j,5) += 0.5*v5; + } + } } } },fev); Kokkos::single(Kokkos::PerThread(team), [&] () { - f(i,0) += fev.f[0]; - f(i,1) += fev.f[1]; - f(i,2) += fev.f[2]; + a_f(i,0) += fev.f[0]; + a_f(i,1) += fev.f[1]; + a_f(i,2) += fev.f[2]; if (c.eflag_global) ev.evdwl += fev.evdwl; - if (c.eflag_atom) - d_eatom(i) += fev.evdwl; - if (c.vflag_global) { ev.v[0] += fev.v[0]; ev.v[1] += fev.v[1]; @@ -496,29 +582,39 @@ struct PairComputeFunctor { ev.v[5] += fev.v[5]; } - if (c.vflag_atom) { - d_vatom(i,0) += fev.v[0]; - d_vatom(i,1) += fev.v[1]; - d_vatom(i,2) += fev.v[2]; - d_vatom(i,3) += fev.v[3]; - d_vatom(i,4) += fev.v[4]; - d_vatom(i,5) += fev.v[5]; + if (NEIGHFLAG == FULL) { + + if (c.eflag_atom) + a_eatom(i) += fev.evdwl; + + if (c.vflag_atom) { + a_vatom(i,0) += fev.v[0]; + a_vatom(i,1) += fev.v[1]; + a_vatom(i,2) += fev.v[2]; + a_vatom(i,3) += fev.v[3]; + a_vatom(i,4) += fev.v[4]; + a_vatom(i,5) += fev.v[5]; + } } }); }); return ev; } - // Use TeamPolicy, assume Newton off, Full Neighborlist, and energy/virial + // TeamPolicy, newton off, and energy/virial // Loop over neighbors of one atom with coulomb interaction // This function is called in parallel + KOKKOS_FUNCTION EV_FLOAT compute_item_team_ev(typename Kokkos::TeamPolicy::member_type team, const NeighListKokkos &list, const CoulTag& ) const { + auto a_f = dup_f.template access::value>(); + auto a_eatom = dup_eatom.template access::value>(); + auto a_vatom = dup_vatom.template access::value>(); + EV_FLOAT ev; - const int inum = team.league_size(); const int atoms_per_team = team.team_size(); const int firstatom = team.league_rank()*atoms_per_team; const int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; @@ -566,45 +662,92 @@ struct PairComputeFunctor { if (rsq < (STACKPARAMS?c.m_cut_coulsq[itype][jtype]:c.d_cut_coulsq(itype,jtype))) fpair+=c.template compute_fcoul(rsq,i,j,itype,jtype,factor_coul,qtmp); - fev_tmp.f[0] += delx*fpair; - fev_tmp.f[1] += dely*fpair; - fev_tmp.f[2] += delz*fpair; + const F_FLOAT fx = delx*fpair; + const F_FLOAT fy = dely*fpair; + const F_FLOAT fz = delz*fpair; + + fev_tmp.f[0] += fx; + fev_tmp.f[1] += fy; + fev_tmp.f[2] += fz; + + const int I_CONTRIB = (NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD); + const int J_CONTRIB = ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && j < c.nlocal); + const E_FLOAT factor = J_CONTRIB?1.0:0.5; + + if ((NEIGHFLAG == HALF || NEIGHFLAG == HALFTHREAD) && j < c.nlocal) { + a_f(j,0) -= fx; + a_f(j,1) -= fy; + a_f(j,2) -= fz; + } F_FLOAT evdwl = 0.0; F_FLOAT ecoul = 0.0; - if (c.eflag) { + if (c.eflag_either) { if (rsq < (STACKPARAMS?c.m_cut_ljsq[itype][jtype]:c.d_cut_ljsq(itype,jtype))) { evdwl = factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); - fev_tmp.evdwl += 0.5*evdwl; + fev_tmp.evdwl += factor * evdwl; } if (rsq < (STACKPARAMS?c.m_cut_coulsq[itype][jtype]:c.d_cut_coulsq(itype,jtype))) { ecoul = c.template compute_ecoul(rsq,i,j,itype,jtype,factor_coul,qtmp); - fev_tmp.ecoul += 0.5*ecoul; + fev_tmp.ecoul += factor * ecoul; + } + + + if (c.eflag_atom) { + const E_FLOAT epairhalf = 0.5 * (evdwl + ecoul); + + if (I_CONTRIB) + a_eatom[i] += epairhalf; + + if (J_CONTRIB) + a_eatom[j] += epairhalf; } } + if (c.vflag_either) { - fev_tmp.v[0] += 0.5*delx*delx*fpair; - fev_tmp.v[1] += 0.5*dely*dely*fpair; - fev_tmp.v[2] += 0.5*delz*delz*fpair; - fev_tmp.v[3] += 0.5*delx*dely*fpair; - fev_tmp.v[4] += 0.5*delx*delz*fpair; - fev_tmp.v[5] += 0.5*dely*delz*fpair; + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + fev_tmp.v[0] += factor*v0; + fev_tmp.v[1] += factor*v1; + fev_tmp.v[2] += factor*v2; + fev_tmp.v[3] += factor*v3; + fev_tmp.v[4] += factor*v4; + fev_tmp.v[5] += factor*v5; + + if (c.vflag_atom) { + if (I_CONTRIB) { + a_vatom(i,0) += 0.5*v0; + a_vatom(i,1) += 0.5*v1; + a_vatom(i,2) += 0.5*v2; + a_vatom(i,3) += 0.5*v3; + a_vatom(i,4) += 0.5*v4; + a_vatom(i,5) += 0.5*v5; + } + if (J_CONTRIB) { + a_vatom(j,0) += 0.5*v0; + a_vatom(j,1) += 0.5*v1; + a_vatom(j,2) += 0.5*v2; + a_vatom(j,3) += 0.5*v3; + a_vatom(j,4) += 0.5*v4; + a_vatom(j,5) += 0.5*v5; + } + } } } },fev); Kokkos::single(Kokkos::PerThread(team), [&] () { - f(i,0) += fev.f[0]; - f(i,1) += fev.f[1]; - f(i,2) += fev.f[2]; + a_f(i,0) += fev.f[0]; + a_f(i,1) += fev.f[1]; + a_f(i,2) += fev.f[2]; - if (c.eflag_global) { + if (c.eflag_global) ev.evdwl += fev.evdwl; - ev.ecoul += fev.ecoul; - } - - if (c.eflag_atom) - d_eatom(i) += fev.evdwl + fev.ecoul; if (c.vflag_global) { ev.v[0] += fev.v[0]; @@ -615,13 +758,19 @@ struct PairComputeFunctor { ev.v[5] += fev.v[5]; } - if (c.vflag_atom) { - d_vatom(i,0) += fev.v[0]; - d_vatom(i,1) += fev.v[1]; - d_vatom(i,2) += fev.v[2]; - d_vatom(i,3) += fev.v[3]; - d_vatom(i,4) += fev.v[4]; - d_vatom(i,5) += fev.v[5]; + if (NEIGHFLAG == FULL) { + + if (c.eflag_atom) + a_eatom(i) += fev.evdwl; + + if (c.vflag_atom) { + a_vatom(i,0) += fev.v[0]; + a_vatom(i,1) += fev.v[1]; + a_vatom(i,2) += fev.v[2]; + a_vatom(i,3) += fev.v[3]; + a_vatom(i,4) += fev.v[4]; + a_vatom(i,5) += fev.v[5]; + } } }); }); @@ -636,7 +785,7 @@ struct PairComputeFunctor { auto a_eatom = dup_eatom.template access::value>(); auto a_vatom = dup_vatom.template access::value>(); - const int EFLAG = c.eflag; + const int EFLAG = c.eflag_either; const int NEWTON_PAIR = c.newton_pair; const int VFLAG = c.vflag_either; @@ -657,7 +806,7 @@ struct PairComputeFunctor { const E_FLOAT v5 = dely*delz*fpair; if (c.vflag_global) { - if (NEIGHFLAG!=FULL) { + if (NEIGHFLAG != FULL) { if (NEWTON_PAIR) { ev.v[0] += v0; ev.v[1] += v1; @@ -747,7 +896,8 @@ struct PairComputeFunctor { // This uses the fact that failure to match template parameters is not an error. // By having the enable_if with a ! and without it, exactly one of the functions // pair_compute_neighlist will match - either the dummy version -// or the real one further below. +// or the real one further below + template EV_FLOAT pair_compute_neighlist (PairStyle* fpair, std::enable_if_t*> list) { EV_FLOAT ev; @@ -757,24 +907,29 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, std::enable_if_t +int GetMaxNeighs(NeighStyle* list) +{ + auto d_ilist = list->d_ilist; + auto d_numneigh = list->d_numneigh; + int inum = list->inum; + + int maxneigh = 0; + Kokkos::parallel_reduce(inum, LAMMPS_LAMBDA(const int ii, int &maxneigh) { + const int i = d_ilist[ii]; + const int num_neighs = d_numneigh[i]; + maxneigh = MAX(maxneigh,num_neighs); + }, Kokkos::Max(maxneigh)); + + return maxneigh; +} + template -int GetTeamSize(FunctorStyle& KOKKOS_GPU_ARG(functor), int KOKKOS_GPU_ARG(inum), - int KOKKOS_GPU_ARG(reduce_flag), int team_size, int KOKKOS_GPU_ARG(vector_length)) { - -#ifdef LMP_KOKKOS_GPU - int team_size_max; - - if (reduce_flag) - team_size_max = Kokkos::TeamPolicy(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelReduceTag()); - else - team_size_max = Kokkos::TeamPolicy(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelForTag()); - - if (team_size*vector_length > team_size_max) - team_size = team_size_max/vector_length; -#else - team_size = 1; -#endif - return team_size; +void GetMaxTeamSize(FunctorStyle& functor, int inum, + int &teamsize_max_for, int &teamsize_max_reduce) +{ + teamsize_max_for = Kokkos::TeamPolicy(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelForTag()); + teamsize_max_reduce = Kokkos::TeamPolicy(inum,Kokkos::AUTO).team_size_max(functor,Kokkos::ParallelReduceTag()); } // Submit ParallelFor for NEIGHFLAG=HALF,HALFTHREAD,FULL @@ -782,38 +937,77 @@ template*> list) { EV_FLOAT ev; + const int inum = list->inum; + if (!fpair->lmp->kokkos->neigh_thread_set) - if (list->inum <= 16384 && NEIGHFLAG == FULL) - fpair->lmp->kokkos->neigh_thread = 1; + if (fpair->lmp->kokkos->ngpus && inum <= 16000) + if (NEIGHFLAG == FULL || !fpair->newton_pair) + fpair->lmp->kokkos->neigh_thread = 1; if (fpair->lmp->kokkos->neigh_thread) { - int vector_length = 8; - int atoms_per_team = 32; + static int vectorsize = 0; + static int atoms_per_team = 0; + static int lastcall = -1; + +#if defined(LMP_KOKKOS_GPU) + if (!vectorsize || lastcall < fpair->lmp->neighbor->lastcall) { + lastcall = fpair->lmp->update->ntimestep; + vectorsize = GetMaxNeighs(list); + vectorsize = MathSpecial::powint(2,(int(log2(vectorsize) + 0.5))); // round to nearest power of 2 + + #if defined(KOKKOS_ENABLE_HIP) + int max_vectorsize = 64; + #else + int max_vectorsize = 32; + #endif + + vectorsize = MIN(vectorsize,max_vectorsize); + + int teamsize_max_for,teamsize_max_reduce; + if (fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { + PairComputeFunctor ff(fpair,list); + GetMaxTeamSize(ff, inum, teamsize_max_for, teamsize_max_reduce); + } else { + PairComputeFunctor ff(fpair,list); + GetMaxTeamSize(ff, inum, teamsize_max_for, teamsize_max_reduce); + } + + int teamsize_max = teamsize_max_for; + if (fpair->eflag || fpair->vflag) + teamsize_max = teamsize_max_reduce; + atoms_per_team = teamsize_max/vectorsize; + } +#else + vectorsize = 1; + atoms_per_team = 1; +#endif + + const int num_teams = inum / atoms_per_team + (inum % atoms_per_team ? 1 : 0); if (fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { PairComputeFunctor ff(fpair,list); - atoms_per_team = GetTeamSize(ff, list->inum, (fpair->eflag || fpair->vflag), atoms_per_team, vector_length); - Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); + Kokkos::TeamPolicy > policy(num_teams,atoms_per_team,vectorsize); if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); else Kokkos::parallel_for(policy,ff); + ff.contribute(); } else { PairComputeFunctor ff(fpair,list); - atoms_per_team = GetTeamSize(ff, list->inum, (fpair->eflag || fpair->vflag), atoms_per_team, vector_length); - Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); + Kokkos::TeamPolicy > policy(num_teams,atoms_per_team,vectorsize); if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); else Kokkos::parallel_for(policy,ff); + ff.contribute(); } } else { if (fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { PairComputeFunctor ff(fpair,list); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); - else Kokkos::parallel_for(list->inum,ff); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(inum,ff,ev); + else Kokkos::parallel_for(inum,ff); ff.contribute(); } else { PairComputeFunctor ff(fpair,list); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); - else Kokkos::parallel_for(list->inum,ff); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(inum,ff,ev); + else Kokkos::parallel_for(inum,ff); ff.contribute(); } } diff --git a/src/KOKKOS/pair_reaxff_kokkos.cpp b/src/KOKKOS/pair_reaxff_kokkos.cpp index c7d54b80cd..11a40970c2 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.cpp +++ b/src/KOKKOS/pair_reaxff_kokkos.cpp @@ -4162,22 +4162,23 @@ double PairReaxFFKokkos::memory_usage() /* ---------------------------------------------------------------------- */ template -void PairReaxFFKokkos::FindBond(int &numbonds) +void PairReaxFFKokkos::FindBond(int &numbonds, int groupbit) { copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy(0,nmax),*this); bo_cut_bond = api->control->bg_cut; - atomKK->sync(execution_space,TAG_MASK); + atomKK->sync(execution_space,TAG_MASK|MASK_MASK); tag = atomKK->k_tag.view(); + mask = atomKK->k_mask.view(); const int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); d_ilist = k_list->d_ilist; numbonds = 0; - PairReaxKokkosFindBondFunctor find_bond_functor(this); + PairReaxKokkosFindBondFunctor find_bond_functor(this, groupbit); Kokkos::parallel_reduce(inum,find_bond_functor,numbonds); copymode = 0; } @@ -4194,24 +4195,28 @@ void PairReaxFFKokkos::operator()(TagPairReaxFindBondZero, const int template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::calculate_find_bond_item(int ii, int &numbonds) const +void PairReaxFFKokkos::calculate_find_bond_item(int ii, int &numbonds, int groupbit) const { const int i = d_ilist[ii]; int nj = 0; - const int j_start = d_bo_first[i]; - const int j_end = j_start + d_bo_num[i]; - for (int jj = j_start; jj < j_end; jj++) { - int j = d_bo_list[jj]; - j &= NEIGHMASK; - const tagint jtag = tag[j]; - const int j_index = jj - j_start; - double bo_tmp = d_BO(i,j_index); + if (mask[i] & groupbit) { + const int j_start = d_bo_first[i]; + const int j_end = j_start + d_bo_num[i]; + for (int jj = j_start; jj < j_end; jj++) { + int j = d_bo_list[jj]; + j &= NEIGHMASK; + if (mask[j] & groupbit) { + const tagint jtag = tag[j]; + const int j_index = jj - j_start; + double bo_tmp = d_BO(i,j_index); - if (bo_tmp > bo_cut_bond) { - d_neighid(i,nj) = jtag; - d_abo(i,nj) = bo_tmp; - nj++; + if (bo_tmp > bo_cut_bond) { + d_neighid(i,nj) = jtag; + d_abo(i,nj) = bo_tmp; + nj++; + } + } } } d_numneigh_bonds[i] = nj; @@ -4247,6 +4252,36 @@ void PairReaxFFKokkos::PackBondBuffer(DAT::tdual_ffloat_1d k_buf, in nbuf_local = k_nbuf_local.h_view(); } +/* ---------------------------------------------------------------------- */ + +template +void PairReaxFFKokkos::PackReducedBondBuffer(DAT::tdual_ffloat_1d k_buf, int &nbuf_local, bool store_bonds) +{ + d_buf = k_buf.view(); + k_params_sing.template sync(); + + copymode = 1; + nlocal = atomKK->nlocal; + if (store_bonds) { + PairReaxKokkosPackReducedBondBufferFunctor pack_bond_buffer_functor(this); + Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor); + } else { + PairReaxKokkosPackReducedBondBufferFunctor pack_bond_buffer_functor(this); + Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor); + } + + copymode = 0; + + k_buf.modify(); + k_nbuf_local.modify(); + + k_buf.sync(); + k_nbuf_local.sync(); + nbuf_local = k_nbuf_local.h_view(); +} + +/* ---------------------------------------------------------------------- */ + template KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::pack_bond_buffer_item(int i, int &j, const bool &final) const @@ -4288,6 +4323,42 @@ void PairReaxFFKokkos::pack_bond_buffer_item(int i, int &j, const bo k_nbuf_local.view()() = j - 1; } +template +template +KOKKOS_INLINE_FUNCTION +void PairReaxFFKokkos::pack_reduced_bond_buffer_item(int i, int &j, const bool &final) const +{ + const int numbonds = d_numneigh_bonds[i]; + if (final) { + d_buf[j] = d_total_bo[i]; + d_buf[j+1] = paramssing(type[i]).nlp_opt - d_Delta_lp[i]; + d_buf[j+2] = numbonds; + } + + j += 3; + + if constexpr(STORE_BONDS) { + if (final) { + for (int k = 0; k < numbonds; ++k) { + d_buf[j+k] = d_neighid(i,k); + } + } + + j += numbonds; + + if (final) { + for (int k = 0; k < numbonds; k++) { + d_buf[j+k] = d_abo(i,k); + } + } + + j += numbonds; + } + + if (final && i == nlocal-1) + k_nbuf_local.view()() = j - 1; +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/pair_reaxff_kokkos.h b/src/KOKKOS/pair_reaxff_kokkos.h index 421d704d03..fba7c03ec4 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.h +++ b/src/KOKKOS/pair_reaxff_kokkos.h @@ -130,8 +130,9 @@ class PairReaxFFKokkos : public PairReaxFF { void compute(int, int); void init_style(); double memory_usage(); - void FindBond(int &); + void FindBond(int &, int groupbit = 1); void PackBondBuffer(DAT::tdual_ffloat_1d, int &); + void PackReducedBondBuffer(DAT::tdual_ffloat_1d, int &, bool); void FindBondSpecies(); template @@ -284,11 +285,15 @@ class PairReaxFFKokkos : public PairReaxFF { void operator()(TagPairReaxFindBondZero, const int&) const; KOKKOS_INLINE_FUNCTION - void calculate_find_bond_item(int, int&) const; + void calculate_find_bond_item(int, int&, int) const; KOKKOS_INLINE_FUNCTION void pack_bond_buffer_item(int, int&, const bool&) const; + template + KOKKOS_INLINE_FUNCTION + void pack_reduced_bond_buffer_item(int, int&, const bool&) const; + KOKKOS_INLINE_FUNCTION void operator()(TagPairReaxFindBondSpeciesZero, const int&) const; @@ -409,6 +414,7 @@ class PairReaxFFKokkos : public PairReaxFF { typename AT::t_f_array f; typename AT::t_int_1d_randomread type; typename AT::t_tagint_1d_randomread tag; + typename AT::t_int_1d_randomread mask; typename AT::t_float_1d_randomread q; typename AT::t_tagint_1d_randomread molecule; @@ -518,8 +524,9 @@ template struct PairReaxKokkosFindBondFunctor { typedef DeviceType device_type; typedef int value_type; + int groupbit; PairReaxFFKokkos c; - PairReaxKokkosFindBondFunctor(PairReaxFFKokkos* c_ptr):c(*c_ptr) {}; + PairReaxKokkosFindBondFunctor(PairReaxFFKokkos* c_ptr, int groupbit):c(*c_ptr),groupbit(groupbit) {}; KOKKOS_INLINE_FUNCTION void join(int &dst, @@ -529,7 +536,7 @@ struct PairReaxKokkosFindBondFunctor { KOKKOS_INLINE_FUNCTION void operator()(const int ii, int &numbonds) const { - c.calculate_find_bond_item(ii,numbonds); + c.calculate_find_bond_item(ii,numbonds,groupbit); } }; @@ -546,6 +553,19 @@ struct PairReaxKokkosPackBondBufferFunctor { } }; +template +struct PairReaxKokkosPackReducedBondBufferFunctor { + typedef DeviceType device_type; + typedef int value_type; + PairReaxFFKokkos c; + PairReaxKokkosPackReducedBondBufferFunctor(PairReaxFFKokkos* c_ptr):c(*c_ptr) {}; + + KOKKOS_INLINE_FUNCTION + void operator()(const int ii, int &j, const bool &final) const { + c.template pack_reduced_bond_buffer_item(ii,j,final); + } +}; + } #endif diff --git a/src/KSPACE/fft3d_wrap.cpp b/src/KSPACE/fft3d_wrap.cpp index 478cf6fc9d..7b00543eea 100644 --- a/src/KSPACE/fft3d_wrap.cpp +++ b/src/KSPACE/fft3d_wrap.cpp @@ -27,30 +27,66 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, int out_klo, int out_khi, int scaled, int permute, int *nbuf, int usecollective) : Pointers(lmp) { + #ifndef FFT_HEFFTE plan = fft_3d_create_plan(comm,nfast,nmid,nslow, in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, scaled,permute,nbuf,usecollective); if (plan == nullptr) error->one(FLERR,"Could not create 3d FFT plan"); + #else + heffte::plan_options options = heffte::default_options(); + options.algorithm = (usecollective == 0) ? + heffte::reshape_algorithm::p2p_plined + : heffte::reshape_algorithm::alltoallv; + options.use_reorder = (permute != 0); + hscale = (scaled == 0) ? heffte::scale::none : heffte::scale::full; + + heffte_plan = std::unique_ptr>( + new heffte::fft3d( + heffte::box3d<>({in_ilo,in_jlo,in_klo}, {in_ihi, in_jhi, in_khi}), + heffte::box3d<>({out_ilo,out_jlo,out_klo}, {out_ihi, out_jhi, out_khi}), + comm, options) + ); + *nbuf = heffte_plan->size_workspace(); + heffte_workspace.resize(heffte_plan->size_workspace()); + #endif } /* ---------------------------------------------------------------------- */ FFT3d::~FFT3d() { + #ifndef FFT_HEFFTE fft_3d_destroy_plan(plan); + #endif } /* ---------------------------------------------------------------------- */ void FFT3d::compute(FFT_SCALAR *in, FFT_SCALAR *out, int flag) { + #ifndef FFT_HEFFTE fft_3d((FFT_DATA *) in,(FFT_DATA *) out,flag,plan); + #else + if (flag == 1) + heffte_plan->forward(reinterpret_cast*>(in), + reinterpret_cast*>(out), + reinterpret_cast*>(heffte_workspace.data()) + ); + else + heffte_plan->backward(reinterpret_cast*>(in), + reinterpret_cast*>(out), + reinterpret_cast*>(heffte_workspace.data()), + hscale + ); + #endif } /* ---------------------------------------------------------------------- */ void FFT3d::timing1d(FFT_SCALAR *in, int nsize, int flag) { + #ifndef FFT_HEFFTE fft_1d_only((FFT_DATA *) in,nsize,flag,plan); + #endif } diff --git a/src/KSPACE/fft3d_wrap.h b/src/KSPACE/fft3d_wrap.h index f72cfd4622..04b828b7de 100644 --- a/src/KSPACE/fft3d_wrap.h +++ b/src/KSPACE/fft3d_wrap.h @@ -17,6 +17,19 @@ #include "fft3d.h" // IWYU pragma: export #include "pointers.h" +#ifdef FFT_HEFFTE +#include "heffte.h" +// select the backend +#if defined(FFT_HEFFTE_FFTW) +using heffte_backend = heffte::backend::fftw; +#elif defined(FFT_HEFFTE_MKL) +using heffte_backend = heffte::backend::mkl; +#else +using heffte_backend = heffte::backend::stock; +#endif + +#endif // FFT_HEFFTE + namespace LAMMPS_NS { class FFT3d : protected Pointers { @@ -30,7 +43,14 @@ class FFT3d : protected Pointers { void timing1d(FFT_SCALAR *, int, int); private: + #ifdef FFT_HEFFTE + // the heFFTe plan supersedes the internal fft_plan_3d + std::unique_ptr> heffte_plan; + std::vector> heffte_workspace; + heffte::scale hscale; + #else struct fft_plan_3d *plan; + #endif }; } // namespace LAMMPS_NS diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index ff8c5eb9c9..2e29b403fd 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -89,6 +89,7 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : ngroups = 0; ngrouptypes = 0; + triclinic = domain->triclinic; // required args @@ -123,8 +124,7 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : // error checks on region and its extent being inside simulation box - region_xlo = region_xhi = region_ylo = region_yhi = - region_zlo = region_zhi = 0.0; + region_xlo = region_xhi = region_ylo = region_yhi = region_zlo = region_zhi = 0.0; if (region) { if (region->bboxflag == 0) error->all(FLERR,"Fix gcmc region does not support a bounding box"); @@ -298,8 +298,7 @@ void FixGCMC::options(int narg, char **arg) } else if (strcmp(arg[iarg],"region") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix gcmc command"); region = domain->get_region_by_id(arg[iarg+1]); - if (!region) - error->all(FLERR,"Region {} for fix gcmc does not exist",arg[iarg+1]); + if (!region) error->all(FLERR,"Region {} for fix gcmc does not exist",arg[iarg+1]); idregion = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"maxangle") == 0) { @@ -464,6 +463,8 @@ int FixGCMC::setmask() void FixGCMC::init() { + triclinic = domain->triclinic; + // set index and check validity of region if (idregion) { @@ -471,19 +472,31 @@ void FixGCMC::init() if (!region) error->all(FLERR, "Region {} for fix gcmc does not exist", idregion); } - triclinic = domain->triclinic; + if (region) { + if (region->bboxflag == 0) + error->all(FLERR,"Fix gcmc region does not support a bounding box"); + if (region->dynamic_check()) + error->all(FLERR,"Fix gcmc region cannot be dynamic"); - if (triclinic) { - if ((region_xlo < domain->boxlo_bound[0]) || (region_xhi > domain->boxhi_bound[0]) || - (region_ylo < domain->boxlo_bound[1]) || (region_yhi > domain->boxhi_bound[1]) || - (region_zlo < domain->boxlo_bound[2]) || (region_zhi > domain->boxhi_bound[2])) { - error->all(FLERR,"Fix gcmc region extends outside simulation box"); + region_xlo = region->extent_xlo; + region_xhi = region->extent_xhi; + region_ylo = region->extent_ylo; + region_yhi = region->extent_yhi; + region_zlo = region->extent_zlo; + region_zhi = region->extent_zhi; + + if (triclinic) { + if ((region_xlo < domain->boxlo_bound[0]) || (region_xhi > domain->boxhi_bound[0]) || + (region_ylo < domain->boxlo_bound[1]) || (region_yhi > domain->boxhi_bound[1]) || + (region_zlo < domain->boxlo_bound[2]) || (region_zhi > domain->boxhi_bound[2])) { + error->all(FLERR,"Fix gcmc region extends outside simulation box"); + } + } else { + if ((region_xlo < domain->boxlo[0]) || (region_xhi > domain->boxhi[0]) || + (region_ylo < domain->boxlo[1]) || (region_yhi > domain->boxhi[1]) || + (region_zlo < domain->boxlo[2]) || (region_zhi > domain->boxhi[2])) + error->all(FLERR,"Fix gcmc region extends outside simulation box"); } - } else { - if ((region_xlo < domain->boxlo[0]) || (region_xhi > domain->boxhi[0]) || - (region_ylo < domain->boxlo[1]) || (region_yhi > domain->boxhi[1]) || - (region_zlo < domain->boxlo[2]) || (region_zhi > domain->boxhi[2])) - error->all(FLERR,"Fix gcmc region extends outside simulation box"); } // set probabilities for MC moves diff --git a/src/MC/fix_widom.cpp b/src/MC/fix_widom.cpp index cc2f1bc94d..7869b213a0 100644 --- a/src/MC/fix_widom.cpp +++ b/src/MC/fix_widom.cpp @@ -73,6 +73,8 @@ FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) : restart_global = 1; time_depend = 1; + triclinic = domain->triclinic; + // required args nevery = utils::inumeric(FLERR,arg[3],false,lmp); @@ -111,18 +113,6 @@ FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) : region_zlo = region->extent_zlo; region_zhi = region->extent_zhi; - if (triclinic) { - if ((region_xlo < domain->boxlo_bound[0]) || (region_xhi > domain->boxhi_bound[0]) || - (region_ylo < domain->boxlo_bound[1]) || (region_yhi > domain->boxhi_bound[1]) || - (region_zlo < domain->boxlo_bound[2]) || (region_zhi > domain->boxhi_bound[2])) - error->all(FLERR,"Fix widom region {} extends outside simulation box", region->id); - } else { - if ((region_xlo < domain->boxlo[0]) || (region_xhi > domain->boxhi[0]) || - (region_ylo < domain->boxlo[1]) || (region_yhi > domain->boxhi[1]) || - (region_zlo < domain->boxlo[2]) || (region_zhi > domain->boxhi[2])) - error->all(FLERR,"Fix widom region {} extends outside simulation box", region->id); - } - // estimate region volume using MC trials double coord[3]; @@ -216,8 +206,7 @@ void FixWidom::options(int narg, char **arg) } else if (strcmp(arg[iarg],"region") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix widom command"); region = domain->get_region_by_id(arg[iarg+1]); - if (!region) - error->all(FLERR,"Region {} for fix widom does not exist",arg[iarg+1]); + if (!region) error->all(FLERR,"Region {} for fix widom does not exist",arg[iarg+1]); idregion = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"charge") == 0) { @@ -292,6 +281,7 @@ int FixWidom::setmask() void FixWidom::init() { + triclinic = domain->triclinic; // set index and check validity of region @@ -300,7 +290,31 @@ void FixWidom::init() if (!region) error->all(FLERR, "Region {} for fix widom does not exist", idregion); } - triclinic = domain->triclinic; + if (region) { + if (region->bboxflag == 0) + error->all(FLERR,"Fix gcmc region does not support a bounding box"); + if (region->dynamic_check()) + error->all(FLERR,"Fix gcmc region cannot be dynamic"); + + region_xlo = region->extent_xlo; + region_xhi = region->extent_xhi; + region_ylo = region->extent_ylo; + region_yhi = region->extent_yhi; + region_zlo = region->extent_zlo; + region_zhi = region->extent_zhi; + + if (triclinic) { + if ((region_xlo < domain->boxlo_bound[0]) || (region_xhi > domain->boxhi_bound[0]) || + (region_ylo < domain->boxlo_bound[1]) || (region_yhi > domain->boxhi_bound[1]) || + (region_zlo < domain->boxlo_bound[2]) || (region_zhi > domain->boxhi_bound[2])) + error->all(FLERR,"Fix widom region {} extends outside simulation box", region->id); + } else { + if ((region_xlo < domain->boxlo[0]) || (region_xhi > domain->boxhi[0]) || + (region_ylo < domain->boxlo[1]) || (region_yhi > domain->boxhi[1]) || + (region_zlo < domain->boxlo[2]) || (region_zhi > domain->boxhi[2])) + error->all(FLERR,"Fix widom region {} extends outside simulation box", region->id); + } + } ave_widom_chemical_potential = 0.0; diff --git a/src/MDI/fix_mdi_qm.cpp b/src/MDI/fix_mdi_qm.cpp index 3ff6b22764..ff2c667f1c 100644 --- a/src/MDI/fix_mdi_qm.cpp +++ b/src/MDI/fix_mdi_qm.cpp @@ -48,6 +48,17 @@ FixMDIQM::FixMDIQM(LAMMPS *lmp, int narg, char **arg) : if (atom->map_style == Atom::MAP_NONE) error->all(FLERR, "Fix mdi/qm requires an atom map be defined"); + // initialize class members + + plugin = 0; + natoms_exists = 0; + celldispl_exists = 0; + elements_exists = 0; + types_exists = 0; + stress_exists = 0; + pe_exists = 0; + keelec_exists = 0; + // confirm LAMMPS is being run as a driver int role; diff --git a/src/MDI/fix_mdi_qmmm.cpp b/src/MDI/fix_mdi_qmmm.cpp index 8e63a34472..958b5ec312 100644 --- a/src/MDI/fix_mdi_qmmm.cpp +++ b/src/MDI/fix_mdi_qmmm.cpp @@ -53,6 +53,18 @@ FixMDIQMMM::FixMDIQMMM(LAMMPS *lmp, int narg, char **arg) : if (atom->map_style == Atom::MAP_NONE) error->all(FLERR, "Fix mdi/qmmm requires an atom map be defined"); + // initialize class members + + plugin = 0; + maxlocal = 0; + natoms_exists = 0; + celldispl_exists = 0; + elements_exists = 0; + types_exists = 0; + stress_exists = 0; + pe_exists = 0; + keelec_exists = 0; + // confirm LAMMPS is being run as a driver int role; diff --git a/src/MDI/mdi_plugin.cpp b/src/MDI/mdi_plugin.cpp index d7805d0cba..92b78b6afb 100644 --- a/src/MDI/mdi_plugin.cpp +++ b/src/MDI/mdi_plugin.cpp @@ -20,6 +20,7 @@ #include "error.h" #include "input.h" +#include "memory.h" #include "modify.h" #include @@ -67,12 +68,12 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp) // do variable substitution in multiple word extra_arg int ncopy = strlen(extra_arg) + 1; - char *copy = (char *) malloc(ncopy); + char *copy = (char *) memory->smalloc(ncopy,"mdi_plugin:copy"); strncpy(copy, extra_arg, ncopy); - char *work = (char *) malloc(ncopy); + char *work = (char *) memory->smalloc(ncopy,"mdi_plugin:work"); int nwork = ncopy; input->substitute(copy, work, ncopy, nwork, 0); - free(work); + memory->sfree(work); extra_arg = copy; iarg += 2; @@ -83,12 +84,12 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp) // do variable substitution in multiple word lammps_command int ncopy = strlen(lammps_command) + 1; - char *copy = (char *) malloc(ncopy); - strncpy(copy, extra_arg, ncopy); - char *work = (char *) malloc(ncopy); + char *copy = (char *) memory->smalloc(ncopy,"mdi_plugin:work"); + strncpy(copy, lammps_command, ncopy); + char *work = (char *) memory->smalloc(ncopy,"mdi_plugin:work"); int nwork = ncopy; input->substitute(copy, work, ncopy, nwork, 0); - free(work); + memory->sfree(work); lammps_command = copy; iarg += 2; @@ -128,8 +129,8 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp) MDI_Launch_plugin(plugin_name, plugin_args, &world, plugin_wrapper, (void *) this); delete[] plugin_args; - delete[] extra_arg; - delete[] lammps_command; + memory->sfree(extra_arg); + memory->sfree(lammps_command); } /* ---------------------------------------------------------------------- diff --git a/src/ML-PACE/compute_pace.cpp b/src/ML-PACE/compute_pace.cpp new file mode 100644 index 0000000000..b96432cfe3 --- /dev/null +++ b/src/ML-PACE/compute_pace.cpp @@ -0,0 +1,479 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS Development team: developers@lammps.org + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "compute_pace.h" +#include "ace-evaluator/ace_evaluator.h" +#include "ace-evaluator/ace_c_basis.h" +#include "ace-evaluator/ace_abstract_basis.h" +#include "ace-evaluator/ace_types.h" +#include +#include + +#include "atom.h" +#include "update.h" +#include "modify.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "force.h" +#include "pair.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +namespace LAMMPS_NS { +struct ACECimpl { + ACECimpl() : basis_set(nullptr), ace(nullptr) {} + ~ACECimpl() + { + delete basis_set; + delete ace; + } + ACECTildeBasisSet *basis_set; + ACECTildeEvaluator *ace; +}; +} + +using namespace LAMMPS_NS; + +enum { SCALAR, VECTOR, ARRAY }; +ComputePACE::ComputePACE(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), cutsq(nullptr), list(nullptr), pace(nullptr), paceall(nullptr), + pace_peratom(nullptr), map(nullptr), cg(nullptr), c_pe(nullptr), c_virial(nullptr) +{ + array_flag = 1; + extarray = 0; + bikflag = 0; + dgradflag = 0; + + int ntypes = atom->ntypes; + int nargmin = 4; + + acecimpl = new ACECimpl; + if (narg < nargmin) error->all(FLERR,"Illegal compute pace command"); + + bikflag = utils::inumeric(FLERR, arg[4], false, lmp); + dgradflag = utils::inumeric(FLERR, arg[5], false, lmp); + if (dgradflag && !bikflag) + error->all(FLERR,"Illegal compute pace command: dgradflag=1 requires bikflag=1"); + + memory->create(map,ntypes+1,"pace:map"); + + //read in file with CG coefficients or c_tilde coefficients + + auto potential_file_name = utils::get_potential_file_path(arg[3]); + delete acecimpl->basis_set; + acecimpl->basis_set = new ACECTildeBasisSet(potential_file_name); + cutmax = acecimpl->basis_set->cutoffmax; + + //# of rank 1, rank > 1 functions + + int n_r1, n_rp = 0; + n_r1 = acecimpl->basis_set->total_basis_size_rank1[0]; + n_rp = acecimpl->basis_set->total_basis_size[0]; + + int ncoeff = n_r1 + n_rp; + nvalues = ncoeff; + + ndims_force = 3; + ndims_virial = 6; + bik_rows = 1; + yoffset = nvalues; + zoffset = 2*nvalues; + natoms = atom->natoms; + if (bikflag) bik_rows = natoms; + dgrad_rows = ndims_force*natoms; + size_array_rows = bik_rows+dgrad_rows + ndims_virial; + if (dgradflag) { + size_array_rows = bik_rows + 3*natoms*natoms + 1; + size_array_cols = nvalues + 3; + if (comm->me == 0) + error->warning(FLERR,"dgradflag=1 creates a N^2 array, beware of large systems."); + } else size_array_cols = nvalues*atom->ntypes + 1; + lastcol = size_array_cols-1; + + ndims_peratom = ndims_force; + size_peratom = ndims_peratom*nvalues*atom->ntypes; + + nmax = 0; +} + +/* ---------------------------------------------------------------------- */ + +ComputePACE::~ComputePACE() +{ + delete acecimpl; + memory->destroy(pace); + memory->destroy(paceall); + memory->destroy(cutsq); + memory->destroy(pace_peratom); + memory->destroy(map); +} + +/* ---------------------------------------------------------------------- */ + +void ComputePACE::init() +{ + if (force->pair == nullptr) + error->all(FLERR,"Compute pace requires a pair style be defined"); + + if (cutmax > force->pair->cutforce) + error->all(FLERR,"Compute pace cutoff is longer than pairwise cutoff"); + + // need an occasional full neighbor list + neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_OCCASIONAL); + + int count = 0; + for (int i = 0; i < modify->ncompute; i++) + if (strcmp(modify->compute[i]->style,"pace") == 0) count++; + if (count > 1 && comm->me == 0) + error->warning(FLERR,"More than one compute pace"); + + // allocate memory for global array + memory->create(pace,size_array_rows,size_array_cols, "pace:pace"); + memory->create(paceall,size_array_rows,size_array_cols, "pace:paceall"); + array = paceall; + + // find compute for reference energy + + std::string id_pe = std::string("thermo_pe"); + int ipe = modify->find_compute(id_pe); + if (ipe == -1) + error->all(FLERR,"compute thermo_pe does not exist."); + c_pe = modify->compute[ipe]; + + // add compute for reference virial tensor + + std::string id_virial = std::string("pace_press"); + std::string pcmd = id_virial + " all pressure NULL virial"; + modify->add_compute(pcmd); + + int ivirial = modify->find_compute(id_virial); + if (ivirial == -1) + error->all(FLERR,"compute pace_press does not exist."); + c_virial = modify->compute[ivirial]; +} + +/* ---------------------------------------------------------------------- */ + +void ComputePACE::init_list(int /*id*/, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +void ComputePACE::compute_array() +{ + int ntotal = atom->nlocal + atom->nghost; + invoked_array = update->ntimestep; + + // grow pace_peratom array if necessary + + if (atom->nmax > nmax) { + memory->destroy(pace_peratom); + nmax = atom->nmax; + memory->create(pace_peratom,nmax,size_peratom,"pace:pace_peratom"); + } + + // clear global array + + for (int irow = 0; irow < size_array_rows; irow++){ + for (int icoeff = 0; icoeff < size_array_cols; icoeff++){ + pace[irow][icoeff] = 0.0; + } + } + + // clear local peratom array + + for (int i = 0; i < ntotal; i++){ + for (int icoeff = 0; icoeff < size_peratom; icoeff++) { + pace_peratom[i][icoeff] = 0.0; + } + } + + // invoke full neighbor list (will copy or build if necessary) + + neighbor->build_one(list); + + const int inum = list->inum; + const int* const ilist = list->ilist; + const int* const numneigh = list->numneigh; + int** const firstneigh = list->firstneigh; + int * const type = atom->type; + + //determine the maximum number of neighbours + int max_jnum = -1; + int nei = 0; + int jtmp =0; + for (int iitmp = 0; iitmp < list->inum; iitmp++) { + int itmp = ilist[iitmp]; + jtmp = numneigh[itmp]; + nei = nei + jtmp; + if (jtmp > max_jnum){ + max_jnum = jtmp; + } + } + + // compute pace derivatives for each atom in group + // use full neighbor list to count atoms less than cutoff + + const int* const mask = atom->mask; + const int ntypes = atom->ntypes; + + for (int ii = 0; ii < inum; ii++) { + int irow = 0; + if (bikflag) irow = atom->tag[ilist[ii] & NEIGHMASK]-1; + const int i = ilist[ii]; + if (mask[i] & groupbit) { + const int itype = type[i]; + const int* const jlist = firstneigh[i]; + const int jnum = numneigh[i]; + const int typeoffset_local = ndims_peratom*nvalues*(itype-1); + const int typeoffset_global = nvalues*(itype-1); + + delete acecimpl->ace; + acecimpl->ace = new ACECTildeEvaluator(*acecimpl->basis_set); + acecimpl->ace->compute_projections = true; + acecimpl->ace->compute_b_grad = true; + int n_r1, n_rp = 0; + n_r1 = acecimpl->basis_set->total_basis_size_rank1[0]; + n_rp = acecimpl->basis_set->total_basis_size[0]; + + int ncoeff = n_r1 + n_rp; + acecimpl->ace->element_type_mapping.init(ntypes+1); + for (int ik = 1; ik <= ntypes; ik++) { + for(int mu = 0; mu < acecimpl->basis_set->nelements; mu++){ + if (mu != -1) { + if (mu == ik - 1) { + map[ik] = mu; + acecimpl->ace->element_type_mapping(ik) = mu; + } + } + } + } + + if (dgradflag) { + + // dBi/dRi tags + + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 0][0] = atom->tag[i]-1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 0][1] = atom->tag[i]-1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 0][2] = 0; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 1][0] = atom->tag[i]-1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 1][1] = atom->tag[i]-1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 1][2] = 1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 2][0] = atom->tag[i]-1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 2][1] = atom->tag[i]-1; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 2][2] = 2; + + // dBi/dRj tags + + for (int j=0; jtag[i]-1) + 0][0] = atom->tag[i]-1; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 0][1] = j; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 0][2] = 0; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 1][0] = atom->tag[i]-1; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 1][1] = j; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 1][2] = 1; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 2][0] = atom->tag[i]-1; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 2][1] = j; + pace[bik_rows + ((j)*3*natoms) + 3*(atom->tag[i]-1) + 2][2] = 2; + } + } + + // resize the neighbor cache after setting the basis + acecimpl->ace->resize_neighbours_cache(max_jnum); + acecimpl->ace->compute_atom(i, atom->x, atom->type, list->numneigh[i], list->firstneigh[i]); + Array1D Bs = acecimpl->ace->projections; + + for (int jj = 0; jj < jnum; jj++) { + const int j = jlist[jj]; + //replace mapping of jj to j + if (!dgradflag) { + double *pacedi = pace_peratom[i]+typeoffset_local; + double *pacedj = pace_peratom[j]+typeoffset_local; + + //force array in (func_ind,neighbour_ind,xyz_ind) format + // dimension: (n_descriptors,max_jnum,3) + //example to access entries for neighbour jj after running compute_atom for atom i: + for (int func_ind =0; func_ind < n_r1 + n_rp; func_ind++){ + DOUBLE_TYPE fx_dB = acecimpl->ace->neighbours_dB(func_ind,jj,0); + DOUBLE_TYPE fy_dB = acecimpl->ace->neighbours_dB(func_ind,jj,1); + DOUBLE_TYPE fz_dB = acecimpl->ace->neighbours_dB(func_ind,jj,2); + pacedi[func_ind] += fx_dB; + pacedi[func_ind+yoffset] += fy_dB; + pacedi[func_ind+zoffset] += fz_dB; + pacedj[func_ind] -= fx_dB; + pacedj[func_ind+yoffset] -= fy_dB; + pacedj[func_ind+zoffset] -= fz_dB; + } + } else { + for (int iicoeff = 0; iicoeff < ncoeff; iicoeff++) { + + // add to pace array for this proc + // dBi/dRj + DOUBLE_TYPE fx_dB = acecimpl->ace->neighbours_dB(iicoeff,jj,0); + DOUBLE_TYPE fy_dB = acecimpl->ace->neighbours_dB(iicoeff,jj,1); + DOUBLE_TYPE fz_dB = acecimpl->ace->neighbours_dB(iicoeff,jj,2); + pace[bik_rows + ((atom->tag[j]-1)*3*natoms) + 3*(atom->tag[i]-1) + 0][iicoeff+3] -= fx_dB; + pace[bik_rows + ((atom->tag[j]-1)*3*natoms) + 3*(atom->tag[i]-1) + 1][iicoeff+3] -= fy_dB; + pace[bik_rows + ((atom->tag[j]-1)*3*natoms) + 3*(atom->tag[i]-1) + 2][iicoeff+3] -= fz_dB; + + // dBi/dRi + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 0][iicoeff+3] += fx_dB; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 1][iicoeff+3] += fy_dB; + pace[bik_rows + ((atom->tag[i]-1)*3*natoms) + 3*(atom->tag[i]-1) + 2][iicoeff+3] += fz_dB; + } + } + } // loop over jj inside + if (!dgradflag) { + + int k = typeoffset_global; + + for (int icoeff = 0; icoeff < ncoeff; icoeff++){ + pace[irow][k++] += Bs(icoeff); + } + } else { + int k = 3; + for (int icoeff = 0; icoeff < ncoeff; icoeff++){ + pace[irow][k++] += Bs(icoeff); + } + } + } //group bit + } // for ii loop + // accumulate force contributions to global array + if (!dgradflag){ + for (int itype = 0; itype < atom->ntypes; itype++) { + const int typeoffset_local = ndims_peratom*nvalues*itype; + const int typeoffset_global = nvalues*itype; + for (int icoeff = 0; icoeff < nvalues; icoeff++) { + for (int i = 0; i < ntotal; i++) { + double *pacedi = pace_peratom[i]+typeoffset_local; + int iglobal = atom->tag[i]; + int irow = 3*(iglobal-1)+1; + pace[irow++][icoeff+typeoffset_global] += pacedi[icoeff]; + pace[irow++][icoeff+typeoffset_global] += pacedi[icoeff+yoffset]; + pace[irow][icoeff+typeoffset_global] += pacedi[icoeff+zoffset]; + } + } + } + } + + if (!dgradflag) { + // accumulate forces to global array + for (int i = 0; i < atom->nlocal; i++) { + int iglobal = atom->tag[i]; + int irow = 3*(iglobal-1)+1; + pace[irow++][lastcol] = atom->f[i][0]; + pace[irow++][lastcol] = atom->f[i][1]; + pace[irow][lastcol] = atom->f[i][2]; + } + } else { + + // for dgradflag=1, put forces at first 3 columns of bik rows + + for (int i=0; inlocal; i++) { + int iglobal = atom->tag[i]; + pace[iglobal-1][0+0] = atom->f[i][0]; + pace[iglobal-1][0+1] = atom->f[i][1]; + pace[iglobal-1][0+2] = atom->f[i][2]; + } + } + + dbdotr_compute(); + + // sum up over all processes + MPI_Allreduce(&pace[0][0],&paceall[0][0],size_array_rows*size_array_cols,MPI_DOUBLE,MPI_SUM,world); + + // assign energy to last column + + if (!dgradflag) { + for (int i = 0; i < bik_rows; i++) paceall[i][lastcol] = 0; + int irow = 0; + double reference_energy = c_pe->compute_scalar(); + paceall[irow][lastcol] = reference_energy; + } else { + + // assign reference energy right after the dgrad rows, first column + + int irow = bik_rows + 3*natoms*natoms; + double reference_energy = c_pe->compute_scalar(); + paceall[irow][0] = reference_energy; + } + + // assign virial stress to last column + // switch to Voigt notation + + if (!dgradflag) { + c_virial->compute_vector(); + int irow = 3*natoms+bik_rows; + paceall[irow++][lastcol] = c_virial->vector[0]; + paceall[irow++][lastcol] = c_virial->vector[1]; + paceall[irow++][lastcol] = c_virial->vector[2]; + paceall[irow++][lastcol] = c_virial->vector[5]; + paceall[irow++][lastcol] = c_virial->vector[4]; + paceall[irow++][lastcol] = c_virial->vector[3]; + } +} + +/* ---------------------------------------------------------------------- + compute global virial contributions via summing r_i.dB^j/dr_i over + own & ghost atoms +------------------------------------------------------------------------- */ +void ComputePACE::dbdotr_compute() +{ + + if (dgradflag) return; + + double **x = atom->x; + int irow0 = bik_rows+ndims_force*natoms; + + // sum over ace contributions to forces + // on all particles including ghosts + + int nall = atom->nlocal + atom->nghost; + for (int i = 0; i < nall; i++) + for (int itype = 0; itype < atom->ntypes; itype++) { + const int typeoffset_local = ndims_peratom*nvalues*itype; + const int typeoffset_global = nvalues*itype; + double *pacedi = pace_peratom[i]+typeoffset_local; + for (int icoeff = 0; icoeff < nvalues; icoeff++) { + double dbdx = pacedi[icoeff]; + double dbdy = pacedi[icoeff+yoffset]; + double dbdz = pacedi[icoeff+zoffset]; + int irow = irow0; + pace[irow++][icoeff+typeoffset_global] += dbdx*x[i][0]; + pace[irow++][icoeff+typeoffset_global] += dbdy*x[i][1]; + pace[irow++][icoeff+typeoffset_global] += dbdz*x[i][2]; + pace[irow++][icoeff+typeoffset_global] += dbdz*x[i][1]; + pace[irow++][icoeff+typeoffset_global] += dbdz*x[i][0]; + pace[irow++][icoeff+typeoffset_global] += dbdy*x[i][0]; + } + } +} + +/* ---------------------------------------------------------------------- + memory usage +------------------------------------------------------------------------- */ + +double ComputePACE::memory_usage() +{ + + double bytes = (double)size_array_rows*size_array_cols*sizeof(double); // pace + bytes += (double)size_array_rows*size_array_cols*sizeof(double); // paceall + bytes += (double)nmax*size_peratom * sizeof(double); // pace_peratom + int n = atom->ntypes+1; + bytes += (double)n*sizeof(int); // map + + return bytes; +} diff --git a/src/ML-PACE/compute_pace.h b/src/ML-PACE/compute_pace.h new file mode 100644 index 0000000000..496c8a16d3 --- /dev/null +++ b/src/ML-PACE/compute_pace.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS Development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(pace,ComputePACE); +// clang-format on +#else + +#ifndef LMP_COMPUTE_PACE_H +#define LMP_COMPUTE_PACE_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputePACE : public Compute { + public: + ComputePACE(class LAMMPS *, int, char **); + ~ComputePACE(); + void init(); + void init_list(int, class NeighList *); + void compute_array(); + double memory_usage(); + + private: + int natoms, nmax, size_peratom, lastcol; + int nvalues, yoffset, zoffset; + int ndims_peratom, ndims_force, ndims_virial; + double **cutsq; + class NeighList *list; + double **pace, **paceall; + double **pace_peratom; + int *map; // map types to [0,nelements) + int bikflag, bik_rows, dgradflag, dgrad_rows; + double *cg; + double cutmax; + Compute *c_pe; + Compute *c_virial; + + void dbdotr_compute(); + struct ACECimpl *acecimpl; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/ML-SNAP/compute_sna_atom.cpp b/src/ML-SNAP/compute_sna_atom.cpp index 2de25b09b6..da49b15117 100644 --- a/src/ML-SNAP/compute_sna_atom.cpp +++ b/src/ML-SNAP/compute_sna_atom.cpp @@ -56,7 +56,10 @@ ComputeSNAAtom::ComputeSNAAtom(LAMMPS *lmp, int narg, char **arg) : wselfallflag = 0; switchinnerflag = 0; nelements = 1; - + nnn = 12; + wmode = 0; + delta = 1.e-3; + nearest_neighbors_mode = false; // process required arguments memory->create(radelem, ntypes + 1, "sna/atom:radelem"); // offset by 1 to match up with types @@ -114,6 +117,22 @@ ComputeSNAAtom::ComputeSNAAtom(LAMMPS *lmp, int narg, char **arg) : if (iarg + 2 > narg) error->all(FLERR, "Illegal compute {} command", style); quadraticflag = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); iarg += 2; + } else if (strcmp(arg[iarg],"nnn") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Illegal compute {} command", style); + nnn = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + nearest_neighbors_mode = true; + if (nnn <= 0) error->all(FLERR, "Illegal compute compute {} command", style); + iarg += 2; + } else if (strcmp(arg[iarg],"wmode") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Illegal compute {} command", style); + wmode = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + if (wmode < 0) error->all(FLERR, "Illegal compute compute {} command", style); + iarg += 2; + } else if (strcmp(arg[iarg],"delta") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Illegal compute {} command", style); + delta = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + if (delta < 1.0e-3) error->all(FLERR, "Illegal compute compute {} command", style); + iarg += 2; } else if (strcmp(arg[iarg], "chem") == 0) { if (iarg + 2 > narg) error->all(FLERR, "Illegal compute {} command", style); chemflag = 1; @@ -183,6 +202,7 @@ ComputeSNAAtom::ComputeSNAAtom(LAMMPS *lmp, int narg, char **arg) : nmax = 0; sna = nullptr; + } /* ---------------------------------------------------------------------- */ @@ -209,7 +229,7 @@ void ComputeSNAAtom::init() { if (force->pair == nullptr) error->all(FLERR,"Compute sna/atom requires a pair style be defined"); - + rcutsq = force->pair->cutforce * force->pair->cutforce; if (cutmax > force->pair->cutforce) error->all(FLERR,"Compute sna/atom cutoff is longer than pairwise cutoff"); @@ -275,63 +295,163 @@ void ComputeSNAAtom::compute_peratom() const int* const jlist = firstneigh[i]; const int jnum = numneigh[i]; - // ensure rij, inside, and typej are of size jnum - snaptr->grow_rij(jnum); + // ############################################################################## // + // ##### Start of section for computing bispectrum on nnn nearest neighbors ##### // + // ############################################################################## // + if (nearest_neighbors_mode) { + // ##### 1) : consider full neighbor list in rlist + memory->create(distsq, jnum, "snann/atom:distsq"); + memory->create(rlist, jnum, 3, "snann/atom:rlist"); - // rij[][3] = displacements between atom I and those neighbors - // inside = indices of neighbors of I within cutoff - // typej = types of neighbors of I within cutoff + int ncount = 0; + for (int jj = 0; jj < jnum; jj++) { + int j = jlist[jj]; + j &= NEIGHMASK; - int ninside = 0; - for (int jj = 0; jj < jnum; jj++) { - int j = jlist[jj]; - j &= NEIGHMASK; + const double delx = xtmp - x[j][0]; + const double dely = ytmp - x[j][1]; + const double delz = ztmp - x[j][2]; + const double rsq = delx * delx + dely * dely + delz * delz; - const double delx = xtmp - x[j][0]; - const double dely = ytmp - x[j][1]; - const double delz = ztmp - x[j][2]; - const double rsq = delx*delx + dely*dely + delz*delz; - int jtype = type[j]; - int jelem = 0; - if (chemflag) - jelem = map[jtype]; - if (rsq < cutsq[itype][jtype] && rsq>1e-20) { - snaptr->rij[ninside][0] = delx; - snaptr->rij[ninside][1] = dely; - snaptr->rij[ninside][2] = delz; - snaptr->inside[ninside] = j; - snaptr->wj[ninside] = wjelem[jtype]; - snaptr->rcutij[ninside] = (radi+radelem[jtype])*rcutfac; - if (switchinnerflag) { - snaptr->sinnerij[ninside] = 0.5*(sinnerelem[itype]+sinnerelem[jtype]); - snaptr->dinnerij[ninside] = 0.5*(dinnerelem[itype]+dinnerelem[jtype]); + if (rsq < rcutsq) { + distsq[ncount] = rsq; + rlist[ncount][0] = delx; + rlist[ncount][1] = dely; + rlist[ncount][2] = delz; + ncount++; } - if (chemflag) snaptr->element[ninside] = jelem; - ninside++; } + + // ##### 2) : compute optimal cutoff such that sum weights S_target = nnn + double S_target=1.*nnn; + double rc_start=0.1; + double rc_max=sqrt(rcutsq); + double tol=1.e-8; + double * sol_dich = dichotomie(S_target, rc_start, rc_max, tol, distsq, ncount, wmode, delta); + memory->destroy(distsq); + + // ##### 3) : assign that optimal cutoff radius to bispectrum context using rcsol + double rcsol = (sol_dich[0]+sol_dich[1])/2.; + memory->destroy(sol_dich); + snaptr->grow_rij(ncount); + + int ninside = 0; + for (int jj = 0; jj < ncount; jj++) { + int j = jlist[jj]; + j &= NEIGHMASK; + + const double rsq = rlist[jj][0]*rlist[jj][0]+rlist[jj][1]*rlist[jj][1]+rlist[jj][2]*rlist[jj][2]; + int jtype = type[j]; + int jelem = 0; + if (chemflag) + jelem = map[jtype]; + + if (rsq < rcsol*rcsol) { + snaptr->rij[ninside][0] = rlist[jj][0];//rijmax; + snaptr->rij[ninside][1] = rlist[jj][1];//rijmax; + snaptr->rij[ninside][2] = rlist[jj][2];//rijmax; + snaptr->inside[ninside] = j; + snaptr->wj[ninside] = 1.; + snaptr->rcutij[ninside] = rcsol; + + if (switchinnerflag) { + snaptr->sinnerij[ninside] = 0.5*(sinnerelem[itype]+sinnerelem[jtype]); + snaptr->dinnerij[ninside] = 0.5*(dinnerelem[itype]+dinnerelem[jtype]); + } + if (chemflag) snaptr->element[ninside] = jelem; + ninside++; + } + } + + memory->destroy(rlist); + + // ############################################################################ // + // ##### End of section for computing bispectrum on nnn nearest neighbors ##### // + // ############################################################################ // + snaptr->compute_ui(ninside, ielem); + snaptr->compute_zi(); + snaptr->compute_bi(ielem); + + for (int icoeff = 0; icoeff < ncoeff; icoeff++) + sna[i][icoeff] = snaptr->blist[icoeff]; + if (quadraticflag) { + int ncount = ncoeff; + for (int icoeff = 0; icoeff < ncoeff; icoeff++) { + double bi = snaptr->blist[icoeff]; + + // diagonal element of quadratic matrix + + sna[i][ncount++] = 0.5*bi*bi; + + // upper-triangular elements of quadratic matrix + + for (int jcoeff = icoeff+1; jcoeff < ncoeff; jcoeff++) + sna[i][ncount++] = bi*snaptr->blist[jcoeff]; + } + } + + } else { + // ensure rij, inside, and typej are of size jnum + + snaptr->grow_rij(jnum); + + // rij[][3] = displacements between atom I and those neighbors + // inside = indices of neighbors of I within cutoff + // typej = types of neighbors of I within cutoff + + int ninside = 0; + for (int jj = 0; jj < jnum; jj++) { + int j = jlist[jj]; + j &= NEIGHMASK; + + const double delx = xtmp - x[j][0]; + const double dely = ytmp - x[j][1]; + const double delz = ztmp - x[j][2]; + const double rsq = delx*delx + dely*dely + delz*delz; + int jtype = type[j]; + int jelem = 0; + if (chemflag) + jelem = map[jtype]; + if (rsq < cutsq[itype][jtype] && rsq>1e-20) { + snaptr->rij[ninside][0] = delx; + snaptr->rij[ninside][1] = dely; + snaptr->rij[ninside][2] = delz; + snaptr->inside[ninside] = j; + snaptr->wj[ninside] = wjelem[jtype]; + snaptr->rcutij[ninside] = (radi+radelem[jtype])*rcutfac; + if (switchinnerflag) { + snaptr->sinnerij[ninside] = 0.5*(sinnerelem[itype]+sinnerelem[jtype]); + snaptr->dinnerij[ninside] = 0.5*(dinnerelem[itype]+dinnerelem[jtype]); + } + if (chemflag) snaptr->element[ninside] = jelem; + ninside++; + } + } + snaptr->compute_ui(ninside, ielem); + snaptr->compute_zi(); + snaptr->compute_bi(ielem); + + for (int icoeff = 0; icoeff < ncoeff; icoeff++) + sna[i][icoeff] = snaptr->blist[icoeff]; + if (quadraticflag) { + int ncount = ncoeff; + for (int icoeff = 0; icoeff < ncoeff; icoeff++) { + double bi = snaptr->blist[icoeff]; + + // diagonal element of quadratic matrix + + sna[i][ncount++] = 0.5*bi*bi; + + // upper-triangular elements of quadratic matrix + + for (int jcoeff = icoeff+1; jcoeff < ncoeff; jcoeff++) + sna[i][ncount++] = bi*snaptr->blist[jcoeff]; + } + } + } - snaptr->compute_ui(ninside, ielem); - snaptr->compute_zi(); - snaptr->compute_bi(ielem); - for (int icoeff = 0; icoeff < ncoeff; icoeff++) - sna[i][icoeff] = snaptr->blist[icoeff]; - if (quadraticflag) { - int ncount = ncoeff; - for (int icoeff = 0; icoeff < ncoeff; icoeff++) { - double bi = snaptr->blist[icoeff]; - - // diagonal element of quadratic matrix - - sna[i][ncount++] = 0.5*bi*bi; - - // upper-triangular elements of quadratic matrix - - for (int jcoeff = icoeff+1; jcoeff < ncoeff; jcoeff++) - sna[i][ncount++] = bi*snaptr->blist[jcoeff]; - } - } } else { for (int icoeff = 0; icoeff < size_peratom_cols; icoeff++) sna[i][icoeff] = 0.0; @@ -352,3 +472,206 @@ double ComputeSNAAtom::memory_usage() return bytes; } +/* ---------------------------------------------------------------------- + select3 routine from Numerical Recipes (slightly modified) + find k smallest values in array of length n + sort auxiliary arrays at same time +------------------------------------------------------------------------- */ + +// Use no-op do while to create single statement + +#define SWAP(a, b) \ + do { \ + tmp = a; \ + (a) = b; \ + (b) = tmp; \ + } while (0) + +#define ISWAP(a, b) \ + do { \ + itmp = a; \ + (a) = b; \ + (b) = itmp; \ + } while (0) + +#define SWAP3(a, b) \ + do { \ + tmp = (a)[0]; \ + (a)[0] = (b)[0]; \ + (b)[0] = tmp; \ + tmp = (a)[1]; \ + (a)[1] = (b)[1]; \ + (b)[1] = tmp; \ + tmp = (a)[2]; \ + (a)[2] = (b)[2]; \ + (b)[2] = tmp; \ + } while (0) + +/* ---------------------------------------------------------------------- */ + +void ComputeSNAAtom::select3(int k, int n, double *arr, int *iarr, double **arr3) +{ + int i, ir, j, l, mid, ia, itmp; + double a, tmp, a3[3]; + + arr--; + iarr--; + arr3--; + l = 1; + ir = n; + for (;;) { + if (ir <= l + 1) { + if (ir == l + 1 && arr[ir] < arr[l]) { + SWAP(arr[l], arr[ir]); + ISWAP(iarr[l], iarr[ir]); + SWAP3(arr3[l], arr3[ir]); + } + return; + } else { + mid = (l + ir) >> 1; + SWAP(arr[mid], arr[l + 1]); + ISWAP(iarr[mid], iarr[l + 1]); + SWAP3(arr3[mid], arr3[l + 1]); + if (arr[l] > arr[ir]) { + SWAP(arr[l], arr[ir]); + ISWAP(iarr[l], iarr[ir]); + SWAP3(arr3[l], arr3[ir]); + } + if (arr[l + 1] > arr[ir]) { + SWAP(arr[l + 1], arr[ir]); + ISWAP(iarr[l + 1], iarr[ir]); + SWAP3(arr3[l + 1], arr3[ir]); + } + if (arr[l] > arr[l + 1]) { + SWAP(arr[l], arr[l + 1]); + ISWAP(iarr[l], iarr[l + 1]); + SWAP3(arr3[l], arr3[l + 1]); + } + i = l + 1; + j = ir; + a = arr[l + 1]; + ia = iarr[l + 1]; + a3[0] = arr3[l + 1][0]; + a3[1] = arr3[l + 1][1]; + a3[2] = arr3[l + 1][2]; + for (;;) { + do i++; + while (arr[i] < a); + do j--; + while (arr[j] > a); + if (j < i) break; + SWAP(arr[i], arr[j]); + ISWAP(iarr[i], iarr[j]); + SWAP3(arr3[i], arr3[j]); + } + arr[l + 1] = arr[j]; + arr[j] = a; + iarr[l + 1] = iarr[j]; + iarr[j] = ia; + arr3[l + 1][0] = arr3[j][0]; + arr3[l + 1][1] = arr3[j][1]; + arr3[l + 1][2] = arr3[j][2]; + arr3[j][0] = a3[0]; + arr3[j][1] = a3[1]; + arr3[j][2] = a3[2]; + if (j >= k) ir = j - 1; + if (j <= k) l = i; + } + } +} + +double * ComputeSNAAtom::weights(double * rsq, double rcut, int ncounts) +{ + double * w=nullptr; + memory->destroy(w); + memory->create(w, ncounts, "snann:gauss_weights"); + double rloc=0.; + for (int i=0; i rcut){ + w[i]=0.; + } else { + w[i]=1.; + } + } + return w; +} + +double * ComputeSNAAtom::tanh_weights(double * rsq, double rcut, double delta, int ncounts) +{ + double * w=nullptr; + memory->destroy(w); + memory->create(w, ncounts, "snann:gauss_weights"); + double rloc=0.; + + for (int i=0; idestroy(www); + } else if (weightmode == 1) { + double * www = tanh_weights(rsq, rcut, delta, ncounts); + S_sol = sum_weights(rsq, www, ncounts); + memory->destroy(www); + } + double err = S_sol - S_target; + return err; +} + +double * ComputeSNAAtom::dichotomie(double S_target, double a, double b, double e, double * rsq, int ncounts, int weightmode, double delta) +{ + + double d=b-a; + double * sol = nullptr; + memory->destroy(sol); + memory->create(sol, 2, "snann:sol"); + double m=0.; + + int cnt=0; + do + { + m = ( a + b ) / 2.; + d = fabs( b - a ); + double f_ra = get_target_rcut(S_target, rsq, a, ncounts, weightmode, delta); + double f_rm = get_target_rcut(S_target, rsq, m, ncounts, weightmode, delta); + if (f_rm == 0.) + { + sol[0]=m; + sol[1]=m; + return sol; + } + else if (f_rm*f_ra > 0.) + { + a = m; + } + else + { + b = m; + } + cnt+=1; + } while ( d > e ); + sol[0]=a; + sol[1]=b; + return sol; +} diff --git a/src/ML-SNAP/compute_sna_atom.h b/src/ML-SNAP/compute_sna_atom.h index 29a84c8dcf..2283865431 100644 --- a/src/ML-SNAP/compute_sna_atom.h +++ b/src/ML-SNAP/compute_sna_atom.h @@ -11,6 +11,10 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Paul Lafourcade (CEA-DAM-DIF, Arpajon, France) +------------------------------------------------------------------------- */ + #ifdef COMPUTE_CLASS // clang-format off ComputeStyle(sna/atom,ComputeSNAAtom); @@ -32,10 +36,25 @@ class ComputeSNAAtom : public Compute { void init_list(int, class NeighList *) override; void compute_peratom() override; double memory_usage() override; + double rcutsq; + + void select3(int, int, double *, int *, double **); + double * weights(double *, double, int); + double * tanh_weights(double *, double, double, int); + double sum_weights(double *, double *, int); + double get_target_rcut(double, double *, double, int, int, double); + double * dichotomie(double, double, double, double, double *, int, int, double); private: int nmax; int ncoeff; + int nnn; + int wmode; + double delta; + bool nearest_neighbors_mode; + double *distsq; + double **rlist; + int *nearest; double **cutsq; class NeighList *list; double **sna; diff --git a/src/MOLECULE/fix_cmap.cpp b/src/MOLECULE/fix_cmap.cpp index f74c05ef06..cb4cb8cadc 100644 --- a/src/MOLECULE/fix_cmap.cpp +++ b/src/MOLECULE/fix_cmap.cpp @@ -39,6 +39,7 @@ #include "memory.h" #include "potential_file_reader.h" #include "respa.h" +#include "text_file_reader.h" #include "update.h" #include @@ -49,15 +50,14 @@ using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; -#define MAXLINE 256 -#define LISTDELTA 10000 -#define LB_FACTOR 1.5 +static constexpr int LISTDELTA = 10000; +static constexpr double LB_FACTOR = 1.5; -#define CMAPMAX 6 // max # of CMAP terms stored by one atom -#define CMAPDIM 24 // grid map dimension is 24 x 24 -#define CMAPXMIN -360.0 -#define CMAPXMIN2 -180.0 -#define CMAPDX 15.0 // 360/CMAPDIM +static constexpr int CMAPMAX = 6; // max # of CMAP terms stored by one atom +static constexpr int CMAPDIM = 24; // grid map dimension is 24 x 24 +static constexpr double CMAPXMIN = -360.0; +static constexpr double CMAPXMIN2 = -180.0; +static constexpr double CMAPDX = 15.0; // 360/CMAPDIM /* ---------------------------------------------------------------------- */ @@ -86,17 +86,15 @@ FixCMAP::FixCMAP(LAMMPS *lmp, int narg, char **arg) : wd_section = 1; respa_level_support = 1; ilevel_respa = 0; - - MPI_Comm_rank(world,&me); - MPI_Comm_size(world,&nprocs); + eflag_caller = 1; // allocate memory for CMAP data memory->create(g_axis,CMAPDIM,"cmap:g_axis"); - memory->create(cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:grid"); - memory->create(d1cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d1grid"); - memory->create(d2cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d2grid"); - memory->create(d12cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d12grid"); + memory->create(cmapgrid,CMAPMAX,CMAPDIM,CMAPDIM,"cmap:grid"); + memory->create(d1cmapgrid,CMAPMAX,CMAPDIM,CMAPDIM,"cmap:d1grid"); + memory->create(d2cmapgrid,CMAPMAX,CMAPDIM,CMAPDIM,"cmap:d2grid"); + memory->create(d12cmapgrid,CMAPMAX,CMAPDIM,CMAPDIM,"cmap:d12grid"); // read and setup CMAP data @@ -184,10 +182,6 @@ void FixCMAP::init() for (i = 0; i < 6; i++) set_map_derivatives(cmapgrid[i],d1cmapgrid[i],d2cmapgrid[i],d12cmapgrid[i]); - // define newton_bond here in case restart file was read (not data file) - - newton_bond = force->newton_bond; - if (utils::strmatch(update->integrate_style,"^respa")) { ilevel_respa = (dynamic_cast(update->integrate))->nlevels-1; if (respa_level >= 0) ilevel_respa = MIN(respa_level,ilevel_respa); @@ -238,6 +232,8 @@ void FixCMAP::min_setup(int vflag) void FixCMAP::pre_neighbor() { int i,m,atom1,atom2,atom3,atom4,atom5; + const int me = comm->me; + const int nprocs = comm->nprocs; // guesstimate initial length of local crossterm list // if ncmap was not set (due to read_restart, no read_data), @@ -637,15 +633,22 @@ void FixCMAP::read_grid_map(char *cmapfile) { if (comm->me == 0) { try { - memset(&cmapgrid[0][0][0], 0, 6*CMAPDIM*CMAPDIM*sizeof(double)); + ncrosstermtypes = 0; + memset(&cmapgrid[0][0][0], 0, CMAPMAX*CMAPDIM*CMAPDIM*sizeof(double)); + utils::logmesg(lmp, "Reading CMAP parameters from: {}\n", cmapfile); PotentialFileReader reader(lmp, cmapfile, "cmap grid"); - // there are six maps in this order. + // there may be up to six maps. + // the charmm36.cmap file has in this order. // alanine, alanine-proline, proline, proline-proline, glycine, glycine-proline. - // read as one big blob of numbers while ignoring comments - - reader.next_dvector(&cmapgrid[0][0][0],6*CMAPDIM*CMAPDIM); + // custom CMAP files created by charmm-gui may have fewer entries + // read one map at a time as a blob of numbers while ignoring comments + // and stop reading when whe have reached EOF. + for (ncrosstermtypes = 0; ncrosstermtypes < CMAPMAX; ++ncrosstermtypes) + reader.next_dvector(&cmapgrid[ncrosstermtypes][0][0],CMAPDIM*CMAPDIM); + } catch (EOFException &) { + utils::logmesg(lmp, " Read in CMAP data for {} crossterm types\n", ncrosstermtypes); } catch (std::exception &e) { error->one(FLERR,"Error reading CMAP potential file: {}", e.what()); } @@ -934,10 +937,6 @@ void FixCMAP::read_data_header(char *line) } catch (std::exception &e) { error->all(FLERR,"Invalid read data header line for fix cmap: {}", e.what()); } - - // not set in constructor because this fix could be defined before newton command - - newton_bond = force->newton_bond; } /* ---------------------------------------------------------------------- @@ -957,10 +956,10 @@ void FixCMAP::read_data_section(char * /*keyword*/, int /*n*/, char *buf, // loop over lines of CMAP crossterms // tokenize the line into values - // add crossterm to one of my atoms, depending on newton_bond + // add crossterm to one of my atoms for (const auto &line : lines) { - ValueTokenizer values(line); + ValueTokenizer values(utils::trim_comment(line)); try { values.skip(); itype = values.next_int(); diff --git a/src/MOLECULE/fix_cmap.h b/src/MOLECULE/fix_cmap.h index fce76aa540..1c6aba95e0 100644 --- a/src/MOLECULE/fix_cmap.h +++ b/src/MOLECULE/fix_cmap.h @@ -65,8 +65,7 @@ class FixCMAP : public Fix { double memory_usage() override; private: - int nprocs, me; - int newton_bond, eflag_caller; + int eflag_caller; int ctype, ilevel_respa; int ncrosstermtypes, crossterm_per_atom, maxcrossterm; int ncrosstermlist; diff --git a/src/Makefile b/src/Makefile index 196641d67d..b9f1bcbdef 100644 --- a/src/Makefile +++ b/src/Makefile @@ -474,7 +474,7 @@ tar: @cd STUBS; $(MAKE) @echo "Created $(ROOT)_src.tar.gz" -check: check-whitespace check-permissions check-homepage check-errordocs check-version +check: check-whitespace check-permissions check-homepage check-errordocs check-docs check-version check-whitespace: $(PYTHON) ../tools/coding_standard/whitespace.py .. @@ -500,8 +500,12 @@ check-errordocs: fix-errordocs: $(PYTHON) ../tools/coding_standard/errordocs.py .. -f +check-docs: + $(MAKE) $(MFLAGS) -C ../doc anchor_check style_check package_check role_check + check-version: - $(PYTHON) ../tools/coding_standard/versiontags.py .. + $(PYTHON) ../tools/coding_standard/versiontags.py .. || echo + format-src: clang-format -i --verbose --style=file *.cpp *.h */*.cpp */*.h diff --git a/src/OPENMP/npair_full_bin_ghost_omp.cpp b/src/OPENMP/npair_bin_ghost_omp.cpp similarity index 58% rename from src/OPENMP/npair_full_bin_ghost_omp.cpp rename to src/OPENMP/npair_bin_ghost_omp.cpp index 0825d61b49..93dd7b1110 100644 --- a/src/OPENMP/npair_full_bin_ghost_omp.cpp +++ b/src/OPENMP/npair_bin_ghost_omp.cpp @@ -12,30 +12,41 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "omp_compat.h" -#include "npair_full_bin_ghost_omp.h" +#include "npair_bin_ghost_omp.h" #include "npair_omp.h" -#include "neigh_list.h" +#include "omp_compat.h" + #include "atom.h" #include "atom_vec.h" -#include "molecule.h" #include "domain.h" -#include "my_page.h" #include "error.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairFullBinGhostOmp::NPairFullBinGhostOmp(LAMMPS *lmp) : NPair(lmp) {} +template +NPairBinGhostOmp::NPairBinGhostOmp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - include neighbors of ghost atoms, but no "special neighbors" for ghosts - every neighbor pair appears in list of both atoms i and j + Full: + binned neighbor list construction for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + include neighbors of ghost atoms, but no "special neighbors" for ghosts + owned and ghost atoms check own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if i owned and j ghost (also stored by proc owning j) + pair stored once if i,j are both ghost and i < j ------------------------------------------------------------------------- */ -void NPairFullBinGhostOmp::build(NeighList *list) +template +void NPairBinGhostOmp::build(NeighList *list) { const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; @@ -48,10 +59,10 @@ void NPairFullBinGhostOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nall); - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; + int i, j, k, n, itype, jtype, ibin, which, imol, iatom; tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int xbin, ybin, zbin, xbin2, ybin2, zbin2; int *neighptr; double **x = atom->x; @@ -93,43 +104,56 @@ void NPairFullBinGhostOmp::build(NeighList *list) // loop over all atoms in surrounding bins in stencil including self // when i is a ghost atom, must check if stencil bin is out of bounds - // skip i = j // no molecular test when i = ghost atom if (i < nlocal) { ibin = atom2bin[i]; for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; + for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { + if (HALF) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + // stores ghost/ghost pairs only once + if (j <= i) continue; + } else { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); + which = find_special(special[i], nspecial[i], tag[j]); else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; } } } } else { - ibin = coord2bin(x[i],xbin,ybin,zbin); + ibin = coord2bin(x[i], xbin, ybin, zbin); for (k = 0; k < nstencil; k++) { xbin2 = xbin + stencilxyz[k][0]; ybin2 = ybin + stencilxyz[k][1]; @@ -137,16 +161,20 @@ void NPairFullBinGhostOmp::build(NeighList *list) if (xbin2 < 0 || xbin2 >= mbinx || ybin2 < 0 || ybin2 >= mbiny || zbin2 < 0 || zbin2 >= mbinz) continue; - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; + for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { + if (HALF) { + if (j <= i) continue; + } else { + if (i == j) continue; + } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; } @@ -157,10 +185,14 @@ void NPairFullBinGhostOmp::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } NPAIR_OMP_CLOSE; list->inum = nlocal; list->gnum = nall - nlocal; } + +namespace LAMMPS_NS { +template class NPairBinGhostOmp<0>; +template class NPairBinGhostOmp<1>; +} diff --git a/src/OPENMP/npair_full_bin_ghost_omp.h b/src/OPENMP/npair_bin_ghost_omp.h similarity index 67% rename from src/OPENMP/npair_full_bin_ghost_omp.h rename to src/OPENMP/npair_bin_ghost_omp.h index 6de134dcf8..df18886e91 100644 --- a/src/OPENMP/npair_full_bin_ghost_omp.h +++ b/src/OPENMP/npair_bin_ghost_omp.h @@ -13,23 +13,29 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairBinGhostOmp<0> NPairFullBinGhostOmp; NPairStyle(full/bin/ghost/omp, NPairFullBinGhostOmp, - NP_FULL | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI); + NP_FULL | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinGhostOmp<1> NPairHalfBinNewtoffGhostOmp; +NPairStyle(half/bin/newtoff/ghost/omp, + NPairHalfBinNewtoffGhostOmp, + NP_HALF | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_FULL_BIN_GHOST_OMP_H -#define LMP_NPAIR_FULL_BIN_GHOST_OMP_H +#ifndef LMP_NPAIR_BIN_GHOST_OMP_H +#define LMP_NPAIR_BIN_GHOST_OMP_H #include "npair.h" namespace LAMMPS_NS { -class NPairFullBinGhostOmp : public NPair { +template +class NPairBinGhostOmp : public NPair { public: - NPairFullBinGhostOmp(class LAMMPS *); + NPairBinGhostOmp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/OPENMP/npair_bin_omp.cpp b/src/OPENMP/npair_bin_omp.cpp new file mode 100644 index 0000000000..5b2189dec2 --- /dev/null +++ b/src/OPENMP/npair_bin_omp.cpp @@ -0,0 +1,277 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_bin_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairBinOmp::NPairBinOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairBinOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; + const double delta = 0.01 * force->angstrom; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i, j, jh, k, n, itype, jtype, ibin, bin_start, which, imol, iatom; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr; + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (!ATOMONLY) { + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + } + + // loop over all atoms in surrounding bins in stencil including self + // skip i = j + + ibin = atom2bin[i]; + + for (k = 0; k < nstencil; k++) { + bin_start = binhead[ibin + stencil[k]]; + if (HALF && NEWTON && (!TRI)) { + if (k == 0) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = bin_start; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // for triclinic, bin stencil is full in all 3 dims + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil, except for i's bin + + if (k == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (ATOMONLY) { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) + jh = jh ^ mask_history; + neighptr[n++] = jh; + } + } else { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol] ->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } + } else { + if (ATOMONLY) { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + } + } + + ilist[i] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage.vgot(n); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; + if (!HALF) list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairBinOmp<0,1,0,0,0>; +template class NPairBinOmp<1,0,0,0,0>; +template class NPairBinOmp<1,1,0,0,0>; +template class NPairBinOmp<1,1,1,0,0>; +template class NPairBinOmp<0,1,0,1,0>; +template class NPairBinOmp<1,0,0,1,0>; +template class NPairBinOmp<1,1,0,1,0>; +template class NPairBinOmp<1,1,1,1,0>; +template class NPairBinOmp<0,1,0,0,1>; +template class NPairBinOmp<1,0,0,0,1>; +template class NPairBinOmp<1,1,0,0,1>; +template class NPairBinOmp<1,1,1,0,1>; +template class NPairBinOmp<0,1,0,1,1>; +template class NPairBinOmp<1,0,0,1,1>; +template class NPairBinOmp<1,1,0,1,1>; +template class NPairBinOmp<1,1,1,1,1>; +} diff --git a/src/OPENMP/npair_bin_omp.h b/src/OPENMP/npair_bin_omp.h new file mode 100644 index 0000000000..dfe5429ff4 --- /dev/null +++ b/src/OPENMP/npair_bin_omp.h @@ -0,0 +1,119 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairBinOmp<0, 1, 0, 0, 0> NPairFullBinOmp; +NPairStyle(full/bin/omp, + NPairFullBinOmp, + NP_FULL | NP_BIN | NP_OMP | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 0, 0, 0, 0> NPairHalfBinNewtoffOmp; +NPairStyle(half/bin/newtoff/omp, + NPairHalfBinNewtoffOmp, + NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 1, 0, 0, 0> NPairHalfBinNewtonOmp; +NPairStyle(half/bin/newton/omp, + NPairHalfBinNewtonOmp, + NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBinOmp<1, 1, 1, 0, 0> NPairHalfBinNewtonTriOmp; +NPairStyle(half/bin/newton/tri/omp, + NPairHalfBinNewtonTriOmp, + NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairBinOmp<0, 1, 0, 1, 0> NPairFullSizeBinOmp; +NPairStyle(full/size/bin/omp, + NPairFullSizeBinOmp, + NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 0, 0, 1, 0> NPairHalfSizeBinNewtoffOmp; +NPairStyle(half/size/bin/newtoff/omp, + NPairHalfSizeBinNewtoffOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 1, 0, 1, 0> NPairHalfSizeBinNewtonOmp; +NPairStyle(half/size/bin/newton/omp, + NPairHalfSizeBinNewtonOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBinOmp<1, 1, 1, 1, 0> NPairHalfSizeBinNewtonTriOmp; +NPairStyle(half/size/bin/newton/tri/omp, + NPairHalfSizeBinNewtonTriOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairBinOmp<0, 1, 0, 0, 1> NPairFullBinAtomonlyOmp; +NPairStyle(full/bin/atomonly/omp, + NPairFullBinAtomonlyOmp, + NP_FULL | NP_BIN | NP_OMP | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 0, 0, 0, 1> NPairHalfBinNewtoffAtomonlyOmp; +NPairStyle(half/bin/newtoff/atomonly/omp, + NPairHalfBinNewtoffAtomonlyOmp, + NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 1, 0, 0, 1> NPairHalfBinNewtonAtomonlyOmp; +NPairStyle(half/bin/newton/atomonly/omp, + NPairHalfBinNewtonAtomonlyOmp, + NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBinOmp<1, 1, 1, 0, 1> NPairHalfBinNewtonTriAtomonlyOmp; +NPairStyle(half/bin/newton/tri/atomonly/omp, + NPairHalfBinNewtonTriAtomonlyOmp, + NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI); + +typedef NPairBinOmp<0, 1, 0, 1, 1> NPairFullSizeBinAtomonlyOmp; +NPairStyle(full/size/bin/atomonly/omp, + NPairFullSizeBinAtomonlyOmp, + NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 0, 0, 1, 1> NPairHalfSizeBinNewtoffAtomonlyOmp; +NPairStyle(half/size/bin/newtoff/atomonly/omp, + NPairHalfSizeBinNewtoffAtomonlyOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinOmp<1, 1, 0, 1, 1> NPairHalfSizeBinNewtonAtomonlyOmp; +NPairStyle(half/size/bin/newton/atomonly/omp, + NPairHalfSizeBinNewtonAtomonlyOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBinOmp<1, 1, 1, 1, 1> NPairHalfSizeBinNewtonTriAtomonlyOmp; +NPairStyle(half/size/bin/newton/tri/atomonly/omp, + NPairHalfSizeBinNewtonTriAtomonlyOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_BIN_OMP_H +#define LMP_NPAIR_BIN_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairBinOmp : public NPair { + public: + NPairBinOmp(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/OPENMP/npair_full_bin_atomonly_omp.cpp b/src/OPENMP/npair_full_bin_atomonly_omp.cpp deleted file mode 100644 index 0a37cca287..0000000000 --- a/src/OPENMP/npair_full_bin_atomonly_omp.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_full_bin_atomonly_omp.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullBinAtomonlyOmp::NPairFullBinAtomonlyOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullBinAtomonlyOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} diff --git a/src/OPENMP/npair_full_bin_atomonly_omp.h b/src/OPENMP/npair_full_bin_atomonly_omp.h deleted file mode 100644 index 50b1aa753c..0000000000 --- a/src/OPENMP/npair_full_bin_atomonly_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/bin/atomonly/omp, - NPairFullBinAtomonlyOmp, - NP_FULL | NP_BIN | NP_ATOMONLY | NP_OMP | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_BIN_ATOMONLY_OMP_H -#define LMP_NPAIR_FULL_BIN_ATOMONLY_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullBinAtomonlyOmp : public NPair { - public: - NPairFullBinAtomonlyOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_full_bin_omp.cpp b/src/OPENMP/npair_full_bin_omp.cpp deleted file mode 100644 index 65af519850..0000000000 --- a/src/OPENMP/npair_full_bin_omp.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_full_bin_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullBinOmp::NPairFullBinOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullBinOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} diff --git a/src/OPENMP/npair_full_bin_omp.h b/src/OPENMP/npair_full_bin_omp.h deleted file mode 100644 index 333025a1fb..0000000000 --- a/src/OPENMP/npair_full_bin_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/bin/omp, - NPairFullBinOmp, - NP_FULL | NP_BIN | NP_OMP | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_BIN_OMP_H -#define LMP_NPAIR_FULL_BIN_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullBinOmp : public NPair { - public: - NPairFullBinOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_full_multi_old_omp.h b/src/OPENMP/npair_full_multi_old_omp.h deleted file mode 100644 index 5d9f4c2f88..0000000000 --- a/src/OPENMP/npair_full_multi_old_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/multi/old/omp, - NPairFullMultiOldOmp, - NP_FULL | NP_MULTI_OLD | NP_OMP | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_MULTI_OLD_OMP_H -#define LMP_NPAIR_FULL_MULTI_OLD_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullMultiOldOmp : public NPair { - public: - NPairFullMultiOldOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_full_multi_omp.cpp b/src/OPENMP/npair_full_multi_omp.cpp deleted file mode 100644 index 1e39838381..0000000000 --- a/src/OPENMP/npair_full_multi_omp.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_full_multi_omp.h" -#include "npair_omp.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullMultiOmp::NPairFullMultiOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - multi stencil is icollection-jcollection dependent - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullMultiOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - // loop over each atom, storing neighbors - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - // use full stencil for all collection combinations - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (i == j) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} diff --git a/src/OPENMP/npair_full_multi_omp.h b/src/OPENMP/npair_full_multi_omp.h deleted file mode 100644 index 0d71bf7bc6..0000000000 --- a/src/OPENMP/npair_full_multi_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/multi/omp, - NPairFullMultiOmp, - NP_FULL | NP_MULTI | NP_OMP | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_MULTI_OMP_H -#define LMP_NPAIR_FULL_MULTI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullMultiOmp : public NPair { - public: - NPairFullMultiOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_full_nsq_ghost_omp.cpp b/src/OPENMP/npair_full_nsq_ghost_omp.cpp deleted file mode 100644 index c1270d9fdc..0000000000 --- a/src/OPENMP/npair_full_nsq_ghost_omp.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_full_nsq_ghost_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullNsqGhostOmp::NPairFullNsqGhostOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 search for all neighbors - include neighbors of ghost atoms, but no "special neighbors" for ghosts - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullNsqGhostOmp::build(NeighList *list) -{ - const int nlocal = atom->nlocal; - const int nall = nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nall); - - int i,j,n,itype,jtype,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms, owned and ghost - // skip i = j - // no molecular test when i = ghost atom - - if (i < nlocal) { - for (j = 0; j < nall; j++) { - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } else { - for (j = 0; j < nall; j++) { - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->gnum = nall - nlocal; -} diff --git a/src/OPENMP/npair_full_nsq_ghost_omp.h b/src/OPENMP/npair_full_nsq_ghost_omp.h deleted file mode 100644 index 448354d4ba..0000000000 --- a/src/OPENMP/npair_full_nsq_ghost_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/nsq/ghost/omp, - NPairFullNsqGhostOmp, - NP_FULL | NP_NSQ | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_NSQ_GHOST_OMP_H -#define LMP_NPAIR_FULL_NSQ_GHOST_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullNsqGhostOmp : public NPair { - public: - NPairFullNsqGhostOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_full_nsq_omp.cpp b/src/OPENMP/npair_full_nsq_omp.cpp deleted file mode 100644 index 695cb1bc48..0000000000 --- a/src/OPENMP/npair_full_nsq_omp.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_full_nsq_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "group.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullNsqOmp::NPairFullNsqOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 search for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullNsqOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,n,itype,jtype,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int nall = atom->nlocal + atom->nghost; - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms, owned and ghost - // skip i = j - - for (j = 0; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} diff --git a/src/OPENMP/npair_full_nsq_omp.h b/src/OPENMP/npair_full_nsq_omp.h deleted file mode 100644 index 53e913a18c..0000000000 --- a/src/OPENMP/npair_full_nsq_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/nsq/omp, - NPairFullNsqOmp, - NP_FULL | NP_NSQ | NP_OMP | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_NSQ_OMP_H -#define LMP_NPAIR_FULL_NSQ_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullNsqOmp : public NPair { - public: - NPairFullNsqOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_bin_atomonly_newton_omp.cpp b/src/OPENMP/npair_half_bin_atomonly_newton_omp.cpp deleted file mode 100644 index 1bc1199628..0000000000 --- a/src/OPENMP/npair_half_bin_atomonly_newton_omp.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_bin_atomonly_newton_omp.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinAtomonlyNewtonOmp::NPairHalfBinAtomonlyNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinAtomonlyNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_bin_atomonly_newton_omp.h b/src/OPENMP/npair_half_bin_atomonly_newton_omp.h deleted file mode 100644 index dcec3aeee2..0000000000 --- a/src/OPENMP/npair_half_bin_atomonly_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/atomonly/newton/omp, - NPairHalfBinAtomonlyNewtonOmp, - NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_ATOMONLY_NEWTON_OMP_H -#define LMP_NPAIR_HALF_BIN_ATOMONLY_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinAtomonlyNewtonOmp : public NPair { - public: - NPairHalfBinAtomonlyNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_bin_newtoff_ghost_omp.cpp b/src/OPENMP/npair_half_bin_newtoff_ghost_omp.cpp deleted file mode 100644 index e10d181a8c..0000000000 --- a/src/OPENMP/npair_half_bin_newtoff_ghost_omp.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_bin_newtoff_ghost_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtoffGhostOmp::NPairHalfBinNewtoffGhostOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - include neighbors of ghost atoms, but no "special neighbors" for ghosts - owned and ghost atoms check own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if i owned and j ghost (also stored by proc owning j) - pair stored once if i,j are both ghost and i < j -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtoffGhostOmp::build(NeighList *list) -{ - const int nlocal = atom->nlocal; - const int nall = nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nall); - - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; - tagint tagprev; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // when i is a ghost atom, must check if stencil bin is out of bounds - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs with owned atom only, on both procs - // stores ghost/ghost pairs only once - // no molecular test when i = ghost atom - - if (i < nlocal) { - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - } else { - ibin = coord2bin(x[i],xbin,ybin,zbin); - for (k = 0; k < nstencil; k++) { - xbin2 = xbin + stencilxyz[k][0]; - ybin2 = ybin + stencilxyz[k][1]; - zbin2 = zbin + stencilxyz[k][2]; - if (xbin2 < 0 || xbin2 >= mbinx || - ybin2 < 0 || ybin2 >= mbiny || - zbin2 < 0 || zbin2 >= mbinz) continue; - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->gnum = nall - atom->nlocal; -} diff --git a/src/OPENMP/npair_half_bin_newtoff_ghost_omp.h b/src/OPENMP/npair_half_bin_newtoff_ghost_omp.h deleted file mode 100644 index 0258320f88..0000000000 --- a/src/OPENMP/npair_half_bin_newtoff_ghost_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newtoff/ghost/omp, - NPairHalfBinNewtoffGhostOmp, - NP_HALF | NP_BIN | NP_NEWTOFF | NP_GHOST | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_OMP_H -#define LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewtoffGhostOmp : public NPair { - public: - NPairHalfBinNewtoffGhostOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_bin_newtoff_omp.cpp b/src/OPENMP/npair_half_bin_newtoff_omp.cpp deleted file mode 100644 index 9d32cc7e2b..0000000000 --- a/src/OPENMP/npair_half_bin_newtoff_omp.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_bin_newtoff_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtoffOmp::NPairHalfBinNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_bin_newtoff_omp.h b/src/OPENMP/npair_half_bin_newtoff_omp.h deleted file mode 100644 index e5d3034667..0000000000 --- a/src/OPENMP/npair_half_bin_newtoff_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newtoff/omp, - NPairHalfBinNewtoffOmp, - NP_HALF | NP_BIN | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_BIN_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewtoffOmp : public NPair { - public: - NPairHalfBinNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_bin_newton_omp.cpp b/src/OPENMP/npair_half_bin_newton_omp.cpp deleted file mode 100644 index d2da12962c..0000000000 --- a/src/OPENMP/npair_half_bin_newton_omp.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_bin_newton_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtonOmp::NPairHalfBinNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - // OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - // OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_bin_newton_omp.h b/src/OPENMP/npair_half_bin_newton_omp.h deleted file mode 100644 index 68064cdf45..0000000000 --- a/src/OPENMP/npair_half_bin_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newton/omp, - NPairHalfBinNewtonOmp, - NP_HALF | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTON_OMP_H -#define LMP_NPAIR_HALF_BIN_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewtonOmp : public NPair { - public: - NPairHalfBinNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_bin_newton_tri_omp.cpp b/src/OPENMP/npair_half_bin_newton_tri_omp.cpp deleted file mode 100644 index 47524474ed..0000000000 --- a/src/OPENMP/npair_half_bin_newton_tri_omp.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_bin_newton_tri_omp.h" -#include "npair_omp.h" -#include "omp_compat.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtonTriOmp::NPairHalfBinNewtonTriOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtonTriOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const double delta = 0.01 * force->angstrom; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_bin_newton_tri_omp.h b/src/OPENMP/npair_half_bin_newton_tri_omp.h deleted file mode 100644 index 90d5af5db1..0000000000 --- a/src/OPENMP/npair_half_bin_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newton/tri/omp, - NPairHalfBinNewtonTriOmp, - NP_HALF | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_BIN_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewtonTriOmp : public NPair { - public: - NPairHalfBinNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_multi_newtoff_omp.cpp b/src/OPENMP/npair_half_multi_newtoff_omp.cpp deleted file mode 100644 index 1b65653f76..0000000000 --- a/src/OPENMP/npair_half_multi_newtoff_omp.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_multi_newtoff_omp.h" -#include "npair_omp.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiNewtoffOmp::NPairHalfMultiNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfMultiNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - // loop over each atom, storing neighbors - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - // use full stencil for all collection combinations - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_multi_newtoff_omp.h b/src/OPENMP/npair_half_multi_newtoff_omp.h deleted file mode 100644 index 658f41f926..0000000000 --- a/src/OPENMP/npair_half_multi_newtoff_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/newtoff/omp, - NPairHalfMultiNewtoffOmp, - NP_HALF | NP_MULTI | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_MULTI_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiNewtoffOmp : public NPair { - public: - NPairHalfMultiNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_multi_newton_omp.cpp b/src/OPENMP/npair_half_multi_newton_omp.cpp deleted file mode 100644 index 8add1d3703..0000000000 --- a/src/OPENMP/npair_half_multi_newton_omp.cpp +++ /dev/null @@ -1,205 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_multi_newton_omp.h" -#include "npair_omp.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiNewtonOmp::NPairHalfMultiNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - // loop over each atom, storing neighbors - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // if same size: uses half stencil so check central bin - if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ - - if (icollection == jcollection) js = bins[i]; - else js = binhead_multi[jcollection][jbin]; - - // if same collection, - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - // if different collections, - // if j is owned atom, store it if j > i - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = js; j >= 0; j = bins[j]) { - if ((icollection != jcollection) && (j < i)) continue; - - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - // for all collections, loop over all atoms in other bins in stencil, store every pair - // stencil is empty if i larger than j - // stencil is half if i same size as j - // stencil is full if i smaller than j - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_multi_newton_omp.h b/src/OPENMP/npair_half_multi_newton_omp.h deleted file mode 100644 index 44bee84653..0000000000 --- a/src/OPENMP/npair_half_multi_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/newton/omp, - NPairHalfMultiNewtonOmp, - NP_HALF | NP_MULTI | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_OMP_H -#define LMP_NPAIR_HALF_MULTI_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiNewtonOmp : public NPair { - public: - NPairHalfMultiNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_multi_newton_tri_omp.cpp b/src/OPENMP/npair_half_multi_newton_tri_omp.cpp deleted file mode 100644 index e26bea990f..0000000000 --- a/src/OPENMP/npair_half_multi_newton_tri_omp.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_newton_tri_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "neighbor.h" -#include "npair_omp.h" -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiNewtonTriOmp::NPairHalfMultiNewtonTriOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiNewtonTriOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const double delta = 0.01 * force->angstrom; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,jbin,icollection,jcollection,which,ns,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in bins in stencil - // for triclinic: - // stencil is empty if i larger than j - // stencil is full if i smaller than j - // stencil is full if i same size as j - // for i smaller than j: - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - // if same size (same collection), exclude half of interactions - - if (cutcollectionsq[icollection][icollection] == - cutcollectionsq[jcollection][jcollection]) { - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_multi_newton_tri_omp.h b/src/OPENMP/npair_half_multi_newton_tri_omp.h deleted file mode 100644 index 21731f4f0b..0000000000 --- a/src/OPENMP/npair_half_multi_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/newton/tri/omp, - NPairHalfMultiNewtonTriOmp, - NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_MULTI_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiNewtonTriOmp : public NPair { - public: - NPairHalfMultiNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_multi_old_newtoff_omp.cpp b/src/OPENMP/npair_half_multi_old_newtoff_omp.cpp deleted file mode 100644 index 4447b4414e..0000000000 --- a/src/OPENMP/npair_half_multi_old_newtoff_omp.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_multi_old_newtoff_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiOldNewtoffOmp::NPairHalfMultiOldNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - multi-type stencil is itype dependent and is distance checked - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfMultiOldNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // skip if i,j neighbor cutoff is less than bin distance - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_multi_old_newtoff_omp.h b/src/OPENMP/npair_half_multi_old_newtoff_omp.h deleted file mode 100644 index 26484d6c5b..0000000000 --- a/src/OPENMP/npair_half_multi_old_newtoff_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/old/newtoff/omp, - NPairHalfMultiOldNewtoffOmp, - NP_HALF | NP_MULTI_OLD | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_MULTI_OLD_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiOldNewtoffOmp : public NPair { - public: - NPairHalfMultiOldNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_multi_old_newton_omp.cpp b/src/OPENMP/npair_half_multi_old_newton_omp.cpp deleted file mode 100644 index 29c551f17d..0000000000 --- a/src/OPENMP/npair_half_multi_old_newton_omp.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_multi_old_newton_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiOldNewtonOmp::NPairHalfMultiOldNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiOldNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - // loop over all atoms in other bins in stencil, store every pair - // skip if i,j neighbor cutoff is less than bin distance - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_multi_old_newton_omp.h b/src/OPENMP/npair_half_multi_old_newton_omp.h deleted file mode 100644 index 8182b49bd7..0000000000 --- a/src/OPENMP/npair_half_multi_old_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/old/newton/omp, - NPairHalfMultiOldNewtonOmp, - NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTON_OMP_H -#define LMP_NPAIR_HALF_MULTI_OLD_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiOldNewtonOmp : public NPair { - public: - NPairHalfMultiOldNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_multi_old_newton_tri_omp.cpp b/src/OPENMP/npair_half_multi_old_newton_tri_omp.cpp deleted file mode 100644 index 38f645abad..0000000000 --- a/src/OPENMP/npair_half_multi_old_newton_tri_omp.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_multi_old_newton_tri_omp.h" -#include "npair_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiOldNewtonTriOmp::NPairHalfMultiOldNewtonTriOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiOldNewtonTriOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const double delta = 0.01 * force->angstrom; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_multi_old_newton_tri_omp.h b/src/OPENMP/npair_half_multi_old_newton_tri_omp.h deleted file mode 100644 index 5efb007dc1..0000000000 --- a/src/OPENMP/npair_half_multi_old_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/old/newton/tri/omp, - NPairHalfMultiOldNewtonTriOmp, - NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_MULTI_OLD_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiOldNewtonTriOmp : public NPair { - public: - NPairHalfMultiOldNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_nsq_newtoff_ghost_omp.cpp b/src/OPENMP/npair_half_nsq_newtoff_ghost_omp.cpp deleted file mode 100644 index 54de8b9607..0000000000 --- a/src/OPENMP/npair_half_nsq_newtoff_ghost_omp.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_nsq_newtoff_ghost_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "group.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfNsqNewtoffGhostOmp::NPairHalfNsqNewtoffGhostOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - include neighbors of ghost atoms, but no "special neighbors" for ghosts - pair stored once if i,j are both owned and i < j - pair stored by me if i owned and j ghost (also stored by proc owning j) - pair stored once if i,j are both ghost and i < j -------------------------------------------------------------------------- */ - -void NPairHalfNsqNewtoffGhostOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int nall = nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nall); - - int i,j,n,itype,jtype,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs with owned atom only, on both procs - // stores ghost/ghost pairs only once - // no molecular test when i = ghost atom - - if (i < nlocal) { - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - } else { - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = atom->nlocal; - list->gnum = nall - atom->nlocal; -} diff --git a/src/OPENMP/npair_half_nsq_newtoff_omp.cpp b/src/OPENMP/npair_half_nsq_newtoff_omp.cpp deleted file mode 100644 index 54a90d9f2b..0000000000 --- a/src/OPENMP/npair_half_nsq_newtoff_omp.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_nsq_newtoff_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "group.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfNsqNewtoffOmp::NPairHalfNsqNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfNsqNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int nall = atom->nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,n,itype,jtype,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // only store pair if i < j - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_nsq_newtoff_omp.h b/src/OPENMP/npair_half_nsq_newtoff_omp.h deleted file mode 100644 index 47a03750f7..0000000000 --- a/src/OPENMP/npair_half_nsq_newtoff_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/nsq/newtoff/omp, - NPairHalfNsqNewtoffOmp, - NP_HALF | NP_NSQ | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_NSQ_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfNsqNewtoffOmp : public NPair { - public: - NPairHalfNsqNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_nsq_newton_omp.cpp b/src/OPENMP/npair_half_nsq_newton_omp.cpp deleted file mode 100644 index 42cf63278a..0000000000 --- a/src/OPENMP/npair_half_nsq_newton_omp.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_nsq_newton_omp.h" -#include "npair_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "group.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfNsqNewtonOmp::NPairHalfNsqNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - every pair stored exactly once by some processor - decision on ghost atoms based on itag,jtag tests -------------------------------------------------------------------------- */ - -void NPairHalfNsqNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,n,itype,jtype,which,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int nall = atom->nlocal + atom->nghost; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // use itag/jtap comparision to eliminate half the interactions - // itag = jtag is possible for long cutoffs that include images of self - // for triclinic, must use delta to eliminate half the I/J interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_nsq_newton_omp.h b/src/OPENMP/npair_half_nsq_newton_omp.h deleted file mode 100644 index 00e975d389..0000000000 --- a/src/OPENMP/npair_half_nsq_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/nsq/newton/omp, - NPairHalfNsqNewtonOmp, - NP_HALF | NP_NSQ | NP_NEWTON | NP_OMP | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_NSQ_NEWTON_OMP_H -#define LMP_NPAIR_HALF_NSQ_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfNsqNewtonOmp : public NPair { - public: - NPairHalfNsqNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_respa_bin_newtoff_omp.cpp b/src/OPENMP/npair_half_respa_bin_newtoff_omp.cpp deleted file mode 100644 index e1d4ee59b1..0000000000 --- a/src/OPENMP/npair_half_respa_bin_newtoff_omp.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_respa_bin_newtoff_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaBinNewtoffOmp::NPairHalfRespaBinNewtoffOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and surrounding bins in non-Newton stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfRespaBinNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; - - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = list->ipage_inner[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = list->ipage_middle + tid; - ipage_middle->reset(); - } - - int which = 0; - int minchange = 0; - - for (i = ifrom; i < ito; i++) { - - n = n_inner = 0; - neighptr = ipage.vget(); - neighptr_inner = ipage_inner.vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - ibin = atom2bin[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) - neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[i] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage.vgot(n_inner); - if (ipage_inner.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[i] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->inum_inner = nlocal; - if (respamiddle) list->inum_middle = nlocal; -} diff --git a/src/OPENMP/npair_half_respa_bin_newtoff_omp.h b/src/OPENMP/npair_half_respa_bin_newtoff_omp.h deleted file mode 100644 index 8ad6209d21..0000000000 --- a/src/OPENMP/npair_half_respa_bin_newtoff_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/respa/bin/newtoff/omp, - NPairHalfRespaBinNewtoffOmp, - NP_HALF | NP_RESPA | NP_BIN | NP_NEWTOFF | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfRespaBinNewtoffOmp : public NPair { - public: - NPairHalfRespaBinNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_respa_bin_newton_omp.cpp b/src/OPENMP/npair_half_respa_bin_newton_omp.cpp deleted file mode 100644 index ce8a103170..0000000000 --- a/src/OPENMP/npair_half_respa_bin_newton_omp.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_respa_bin_newton_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaBinNewtonOmp::NPairHalfRespaBinNewtonOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfRespaBinNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; - - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = list->ipage_inner[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = list->ipage_middle + tid; - ipage_middle->reset(); - } - - int which = 0; - int minchange = 0; - - for (i = ifrom; i < ito; i++) { - - n = n_inner = 0; - neighptr = ipage.vget(); - neighptr_inner = ipage_inner.vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) - neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[i] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage.vgot(n_inner); - if (ipage_inner.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[i] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->inum_inner = nlocal; - if (respamiddle) list->inum_middle = nlocal; -} diff --git a/src/OPENMP/npair_half_respa_bin_newton_tri_omp.h b/src/OPENMP/npair_half_respa_bin_newton_tri_omp.h deleted file mode 100644 index df45372960..0000000000 --- a/src/OPENMP/npair_half_respa_bin_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/respa/bin/newton/tri/omp, - NPairHalfRespaBinNewtonTriOmp, - NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfRespaBinNewtonTriOmp : public NPair { - public: - NPairHalfRespaBinNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_respa_nsq_newtoff_omp.cpp b/src/OPENMP/npair_half_respa_nsq_newtoff_omp.cpp deleted file mode 100644 index 428ca778e8..0000000000 --- a/src/OPENMP/npair_half_respa_nsq_newtoff_omp.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "omp_compat.h" -#include "npair_half_respa_nsq_newtoff_omp.h" -#include "npair_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "group.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaNsqNewtoffOmp::NPairHalfRespaNsqNewtoffOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - pair added if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfRespaNsqNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - - NPAIR_OMP_INIT; - - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,n,itype,jtype,n_inner,n_middle,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int nall = atom->nlocal + atom->nghost; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = list->ipage_inner[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = list->ipage_middle + tid; - ipage_middle->reset(); - } - - int which = 0; - int minchange = 0; - - for (i = ifrom; i < ito; i++) { - - n = n_inner = 0; - neighptr = ipage.vget(); - neighptr_inner = ipage_inner.vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[i] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage.vgot(n_inner); - if (ipage_inner.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[i] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; - list->inum_inner = nlocal; - if (respamiddle) list->inum_middle = nlocal; -} diff --git a/src/OPENMP/npair_half_respa_nsq_newtoff_omp.h b/src/OPENMP/npair_half_respa_nsq_newtoff_omp.h deleted file mode 100644 index abd28fd51b..0000000000 --- a/src/OPENMP/npair_half_respa_nsq_newtoff_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/respa/nsq/newtoff/omp, - NPairHalfRespaNsqNewtoffOmp, - NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTOFF | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfRespaNsqNewtoffOmp : public NPair { - public: - NPairHalfRespaNsqNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp b/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp deleted file mode 100644 index 478e28a5f4..0000000000 --- a/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_bin_newtoff_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeBinNewtoffOmp::NPairHalfSizeBinNewtoffOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and surrounding bins in non-Newton stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeBinNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,ibin,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - ibin = atom2bin[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_bin_newtoff_omp.h b/src/OPENMP/npair_half_size_bin_newtoff_omp.h deleted file mode 100644 index a91836b152..0000000000 --- a/src/OPENMP/npair_half_size_bin_newtoff_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/bin/newtoff/omp, - NPairHalfSizeBinNewtoffOmp, - NP_HALF | NP_SIZE | NP_BIN | NP_NEWTOFF | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeBinNewtoffOmp : public NPair { - public: - NPairHalfSizeBinNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_bin_newton_omp.cpp b/src/OPENMP/npair_half_size_bin_newton_omp.cpp deleted file mode 100644 index dba392781e..0000000000 --- a/src/OPENMP/npair_half_size_bin_newton_omp.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_bin_newton_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeBinNewtonOmp::NPairHalfSizeBinNewtonOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeBinNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,ibin,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_bin_newton_omp.h b/src/OPENMP/npair_half_size_bin_newton_omp.h deleted file mode 100644 index efc554bb3c..0000000000 --- a/src/OPENMP/npair_half_size_bin_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/bin/newton/omp, - NPairHalfSizeBinNewtonOmp, - NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_OMP_H -#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeBinNewtonOmp : public NPair { - public: - NPairHalfSizeBinNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp deleted file mode 100644 index 7fcf07e9c8..0000000000 --- a/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_bin_newton_tri_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeBinNewtonTriOmp::NPairHalfSizeBinNewtonTriOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - const double delta = 0.01 * force->angstrom; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,ibin,which,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_bin_newton_tri_omp.h b/src/OPENMP/npair_half_size_bin_newton_tri_omp.h deleted file mode 100644 index 65b46395ca..0000000000 --- a/src/OPENMP/npair_half_size_bin_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/bin/newton/tri/omp, - NPairHalfSizeBinNewtonTriOmp, - NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeBinNewtonTriOmp : public NPair { - public: - NPairHalfSizeBinNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp b/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp deleted file mode 100644 index ba0dfc16be..0000000000 --- a/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_newtoff_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiNewtoffOmp::NPairHalfSizeMultiNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with partial Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; - int which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - int js; - - // loop over each atom, storing neighbors - - int *collection = neighbor->collection; - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - // use full stencil for all collection combinations - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_multi_newtoff_omp.h b/src/OPENMP/npair_half_size_multi_newtoff_omp.h deleted file mode 100644 index 2e58d9ea38..0000000000 --- a/src/OPENMP/npair_half_size_multi_newtoff_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/newtoff/omp, - NPairHalfSizeMultiNewtoffOmp, - NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_SIZE_MULTI_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiNewtoffOmp : public NPair { - public: - NPairHalfSizeMultiNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_multi_newton_omp.cpp b/src/OPENMP/npair_half_size_multi_newton_omp.cpp deleted file mode 100644 index 4bc17f911c..0000000000 --- a/src/OPENMP/npair_half_size_multi_newton_omp.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_newton_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiNewtonOmp::NPairHalfSizeMultiNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with full Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; - int which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - int js; - - // loop over each atom, storing neighbors - - int *collection = neighbor->collection; - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // if same size: uses half stencil so check central bin - if(cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ - - if(icollection == jcollection) js = bins[i]; - else js = binhead_multi[jcollection][jbin]; - - // if same collection, - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - // if different collections, - // if j is owned atom, store it if j > i - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = js; j >= 0; j = bins[j]) { - if(icollection != jcollection && j < i) continue; - - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - // for all collections, loop over all atoms in other bins in stencil, store every pair - // stencil is empty if i larger than j - // stencil is half if i same size as j - // stencil is full if i smaller than j - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - j = j ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_multi_newton_omp.h b/src/OPENMP/npair_half_size_multi_newton_omp.h deleted file mode 100644 index 99f9174913..0000000000 --- a/src/OPENMP/npair_half_size_multi_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/newton/omp, - NPairHalfSizeMultiNewtonOmp, - NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_OMP_H -#define LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiNewtonOmp : public NPair { - public: - NPairHalfSizeMultiNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp deleted file mode 100644 index 4765c918b7..0000000000 --- a/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_newton_tri_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiNewtonTriOmp::NPairHalfSizeMultiNewtonTriOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with Newton's 3rd law for triclinic - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - const double delta = 0.01 * force->angstrom; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; - int which,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - - int *collection = neighbor->collection; - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in bins in stencil - // stencil is empty if i larger than j - // stencil is half if i same size as j - // stencil is full if i smaller than j - // if half: pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - // if same size (same collection), exclude half of interactions - - if (cutcollectionsq[icollection][icollection] == - cutcollectionsq[jcollection][jcollection]) { - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_multi_newton_tri_omp.h b/src/OPENMP/npair_half_size_multi_newton_tri_omp.h deleted file mode 100644 index d4f6eacc27..0000000000 --- a/src/OPENMP/npair_half_size_multi_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/newton/tri/omp, - NPairHalfSizeMultiNewtonTriOmp, - NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiNewtonTriOmp : public NPair { - public: - NPairHalfSizeMultiNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp b/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp deleted file mode 100644 index e4169482bc..0000000000 --- a/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_old_newtoff_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiOldNewtoffOmp::NPairHalfSizeMultiOldNewtoffOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - multi-type stencil is itype dependent and is distance checked - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // skip if i,j neighbor cutoff is less than bin distance - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_multi_old_newtoff_omp.h b/src/OPENMP/npair_half_size_multi_old_newtoff_omp.h deleted file mode 100644 index 05eb0a5269..0000000000 --- a/src/OPENMP/npair_half_size_multi_old_newtoff_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/old/newtoff/omp, - NPairHalfSizeMultiOldNewtoffOmp, - NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTOFF | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiOldNewtoffOmp : public NPair { - public: - NPairHalfSizeMultiOldNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp b/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp deleted file mode 100644 index 7d6a3de871..0000000000 --- a/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_old_newton_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiOldNewtonOmp::NPairHalfSizeMultiOldNewtonOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - // loop over all atoms in other bins in stencil, store every pair - // skip if i,j neighbor cutoff is less than bin distance - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_multi_old_newton_omp.h b/src/OPENMP/npair_half_size_multi_old_newton_omp.h deleted file mode 100644 index 70ae082dbb..0000000000 --- a/src/OPENMP/npair_half_size_multi_old_newton_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/old/newton/omp, - NPairHalfSizeMultiOldNewtonOmp, - NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTON | NP_OMP | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_OMP_H -#define LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiOldNewtonOmp : public NPair { - public: - NPairHalfSizeMultiOldNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp deleted file mode 100644 index 1c6d025fab..0000000000 --- a/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_old_newton_tri_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiOldNewtonTriOmp::NPairHalfSizeMultiOldNewtonTriOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - const double delta = 0.01 * force->angstrom; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.h b/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.h deleted file mode 100644 index 3c1765b668..0000000000 --- a/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/old/newton/tri/omp, - NPairHalfSizeMultiOldNewtonTriOmp, - NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTON | NP_TRI | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_TRI_OMP_H -#define LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_TRI_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiOldNewtonTriOmp : public NPair { - public: - NPairHalfSizeMultiOldNewtonTriOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp b/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp deleted file mode 100644 index 2982586a18..0000000000 --- a/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_nsq_newtoff_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "group.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeNsqNewtoffOmp::NPairHalfSizeNsqNewtoffOmp(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - pair added to list if atoms i and j are both owned and i < j - pair added if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - - NPAIR_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,n,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int nall = atom->nlocal + atom->nghost; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_nsq_newtoff_omp.h b/src/OPENMP/npair_half_size_nsq_newtoff_omp.h deleted file mode 100644 index 93f038eed4..0000000000 --- a/src/OPENMP/npair_half_size_nsq_newtoff_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/nsq/newtoff/omp, - NPairHalfSizeNsqNewtoffOmp, - NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTOFF | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_OMP_H -#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeNsqNewtoffOmp : public NPair { - public: - NPairHalfSizeNsqNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_half_size_nsq_newton_omp.cpp b/src/OPENMP/npair_half_size_nsq_newton_omp.cpp deleted file mode 100644 index 0628478c0b..0000000000 --- a/src/OPENMP/npair_half_size_nsq_newton_omp.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_nsq_newton_omp.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "group.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeNsqNewtonOmp::NPairHalfSizeNsqNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests -------------------------------------------------------------------------- */ - -void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - const int molecular = atom->molecular; - const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; - const int history = list->history; - const int mask_history = 1 << HISTBITS; - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - NPAIR_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(nlocal); - - int i,j,jh,n,which,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - - int nall = atom->nlocal + atom->nghost; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // use itag/jtap comparision to eliminate half the interactions - // itag = jtag is possible for long cutoffs that include images of self - // for triclinic, must use delta to eliminate half the I/J interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - ilist[i] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - } - NPAIR_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/OPENMP/npair_half_size_nsq_newton_omp.h b/src/OPENMP/npair_half_size_nsq_newton_omp.h deleted file mode 100644 index 9a7e912007..0000000000 --- a/src/OPENMP/npair_half_size_nsq_newton_omp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/nsq/newton/omp, - NPairHalfSizeNsqNewtonOmp, - NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTON | NP_OMP | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_OMP_H -#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeNsqNewtonOmp : public NPair { - public: - NPairHalfSizeNsqNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_halffull_newtoff_omp.cpp b/src/OPENMP/npair_halffull_newtoff_omp.cpp deleted file mode 100644 index 379ae149f8..0000000000 --- a/src/OPENMP/npair_halffull_newtoff_omp.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_halffull_newtoff_omp.h" - -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullNewtoffOmp::NPairHalffullNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullNewtoffOmp::build(NeighList *list) -{ - const int inum_full = list->listfull->inum; - - NPAIR_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(inum_full); - - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over atoms in full list - - for (ii = ifrom; ii < ito; ii++) { - - n = 0; - neighptr = ipage.vget(); - - // loop over parent full list - - i = ilist_full[ii]; - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j > i) neighptr[n++] = joriginal; - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = inum_full; -} diff --git a/src/OPENMP/npair_halffull_newtoff_omp.h b/src/OPENMP/npair_halffull_newtoff_omp.h deleted file mode 100644 index f0ff24dcf9..0000000000 --- a/src/OPENMP/npair_halffull_newtoff_omp.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/newtoff/omp, - NPairHalffullNewtoffOmp, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI |NP_OMP); - -NPairStyle(halffull/newtoff/skip/omp, - NPairHalffullNewtoffOmp, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_SKIP | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_NEWTOFF_OMP_H -#define LMP_NPAIR_HALFFULL_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullNewtoffOmp : public NPair { - public: - NPairHalffullNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_halffull_newton_omp.cpp b/src/OPENMP/npair_halffull_newton_omp.cpp deleted file mode 100644 index e833ab3095..0000000000 --- a/src/OPENMP/npair_halffull_newton_omp.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_halffull_newton_omp.h" - -#include "atom.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullNewtonOmp::NPairHalffullNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - if j is ghost, only store if j coords are "above and to the right" of i - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullNewtonOmp::build(NeighList *list) -{ - const int inum_full = list->listfull->inum; - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(inum_full); - - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - double xtmp,ytmp,ztmp; - - double **x = atom->x; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over parent full list - - for (ii = ifrom; ii < ito; ii++) { - - n = 0; - neighptr = ipage.vget(); - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over full neighbor list - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - - if (j < nlocal) { - if (i > j) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - neighptr[n++] = joriginal; - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = inum_full; -} diff --git a/src/OPENMP/npair_halffull_newton_omp.h b/src/OPENMP/npair_halffull_newton_omp.h deleted file mode 100644 index 3ce9fd9ebe..0000000000 --- a/src/OPENMP/npair_halffull_newton_omp.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/newton/omp, - NPairHalffullNewtonOmp, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI| NP_OMP); - -NPairStyle(halffull/newton/skip/omp, - NPairHalffullNewtonOmp, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI | NP_SKIP | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_NEWTON_OMP_H -#define LMP_NPAIR_HALFFULL_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullNewtonOmp : public NPair { - public: - NPairHalffullNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_halffull_omp.cpp b/src/OPENMP/npair_halffull_omp.cpp new file mode 100644 index 0000000000..bc646accbc --- /dev/null +++ b/src/OPENMP/npair_halffull_omp.cpp @@ -0,0 +1,165 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_halffull_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" + +#include "atom.h" +#include "error.h" +#include "force.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairHalffullOmp::NPairHalffullOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build half list from full list + pair stored once if i,j are both owned and i < j + works if full list is a skip list + + Newtoff: + pair stored by me if j is ghost (also stored by proc owning j) + works for owned (non-ghost) list, also for ghost list + if ghost, also store neighbors of ghost atoms & set inum,gnum correctly + Newton: + if j is ghost, only store if j coords are "above and to the right" of i + use i < j < nlocal to eliminate half the local/local interactions + Newton + Triclinic: + must use delta to eliminate half the local/ghost interactions + cannot use I/J exact coord comparision as for orthog + b/c transforming orthog -> lambda -> orthog for ghost atoms + with an added PBC offset can shift all 3 coords by epsilon +------------------------------------------------------------------------- */ + +template +void NPairHalffullOmp::build(NeighList *list) +{ + const int inum_full = list->listfull->inum; + const double delta = 0.01 * force->angstrom; + + NPAIR_OMP_INIT; + +#if defined(_OPENMP) +#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) +#endif + NPAIR_OMP_SETUP(inum_full); + + int i, j, ii, jj, n, jnum, joriginal; + int *neighptr, *jlist; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + + double **x = atom->x; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + double cutsq_custom = cutoff_custom * cutoff_custom; + + // loop over atoms in full list + + for (ii = ifrom; ii < ito; ii++) { + + n = 0; + neighptr = ipage.vget(); + + // loop over parent full list + + i = ilist_full[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + + if (NEWTON) { + if (j < nlocal) { + if (i > j) continue; + } else if (TRI) { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; + } else { + if (j > i) { + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; + } + } + } + + ilist[ii] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage.vgot(n); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + NPAIR_OMP_CLOSE; + list->inum = inum_full; +} + +namespace LAMMPS_NS { +template class NPairHalffullOmp<0,0,0>; +template class NPairHalffullOmp<1,0,0>; +template class NPairHalffullOmp<1,1,0>; +template class NPairHalffullOmp<0,0,1>; +template class NPairHalffullOmp<1,0,1>; +template class NPairHalffullOmp<1,1,1>; +} diff --git a/src/OPENMP/npair_halffull_omp.h b/src/OPENMP/npair_halffull_omp.h new file mode 100644 index 0000000000..5c0c943566 --- /dev/null +++ b/src/OPENMP/npair_halffull_omp.h @@ -0,0 +1,131 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairHalffullOmp<0, 0, 0> NPairHalffullNewtoffOmp; +NPairStyle(halffull/newtoff/omp, + NPairHalffullNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 0> NPairHalffullNewtoffOmp; +NPairStyle(halffull/newtoff/skip/omp, + NPairHalffullNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 0> NPairHalffullNewtoffOmp; +NPairStyle(halffull/newtoff/ghost/omp, + NPairHalffullNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 0> NPairHalffullNewtoffOmp; +NPairStyle(halffull/newtoff/skip/ghost/omp, + NPairHalffullNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_OMP); + +typedef NPairHalffullOmp<1, 0, 0> NPairHalffullNewtonOmp; +NPairStyle(halffull/newton/omp, + NPairHalffullNewtonOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_OMP); + +typedef NPairHalffullOmp<1, 1, 0> NPairHalffullNewtonTriOmp; +NPairStyle(halffull/newton/tri/omp, + NPairHalffullNewtonTriOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_OMP); + +typedef NPairHalffullOmp<1, 0, 0> NPairHalffullNewtonOmp; +NPairStyle(halffull/newton/skip/omp, + NPairHalffullNewtonOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_SKIP | NP_OMP); + +typedef NPairHalffullOmp<1, 1, 0> NPairHalffullNewtonTriOmp; +NPairStyle(halffull/newton/tri/skip/omp, + NPairHalffullNewtonTriOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_SKIP | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 1> NPairHalffullTrimNewtoffOmp; +NPairStyle(halffull/trim/newtoff/omp, + NPairHalffullTrimNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 1> NPairHalffullTrimNewtoffOmp; +NPairStyle(halffull/trim/newtoff/skip/omp, + NPairHalffullTrimNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 1> NPairHalffullTrimNewtoffOmp; +NPairStyle(halffull/trim/newtoff/ghost/omp, + NPairHalffullTrimNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<0, 0, 1> NPairHalffullTrimNewtoffOmp; +NPairStyle(halffull/trim/newtoff/skip/ghost/omp, + NPairHalffullTrimNewtoffOmp, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<1, 0, 1> NPairHalffullTrimNewtonOmp; +NPairStyle(halffull/trim/newton/omp, + NPairHalffullTrimNewtonOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<1, 1, 1> NPairHalffullTrimNewtonTriOmp; +NPairStyle(halffull/trim/newton/tri/omp, + NPairHalffullTrimNewtonTriOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<1, 0, 1> NPairHalffullTrimNewtonOmp; +NPairStyle(halffull/trim/newton/skip/omp, + NPairHalffullTrimNewtonOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_SKIP | NP_TRIM | NP_OMP); + +typedef NPairHalffullOmp<1, 1, 1> NPairHalffullTrimNewtonTriOmp; +NPairStyle(halffull/trim/newton/tri/skip/omp, + NPairHalffullTrimNewtonTriOmp, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_SKIP | NP_TRIM | NP_OMP); +// clang-format on +#else + +#ifndef LMP_NPAIR_HALFFULL_OMP_H +#define LMP_NPAIR_HALFFULL_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairHalffullOmp : public NPair { + public: + NPairHalffullOmp(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/OPENMP/npair_halffull_trim_newtoff_omp.cpp b/src/OPENMP/npair_halffull_trim_newtoff_omp.cpp deleted file mode 100644 index d0c5c1ab86..0000000000 --- a/src/OPENMP/npair_halffull_trim_newtoff_omp.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_halffull_trim_newtoff_omp.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullTrimNewtoffOmp::NPairHalffullTrimNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list and trim to shorter cutoff - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullTrimNewtoffOmp::build(NeighList *list) -{ - const int inum_full = list->listfull->inum; - - NPAIR_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(inum_full); - - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - double xtmp,ytmp,ztmp; - double delx,dely,delz,rsq; - - double **x = atom->x; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over atoms in full list - - for (ii = ifrom; ii < ito; ii++) { - - n = 0; - neighptr = ipage.vget(); - - // loop over parent full list - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - - // trim to shorter cutoff - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq > cutsq_custom) continue; - - if (j > i) neighptr[n++] = joriginal; - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = inum_full; -} diff --git a/src/OPENMP/npair_halffull_trim_newtoff_omp.h b/src/OPENMP/npair_halffull_trim_newtoff_omp.h deleted file mode 100644 index c86c132b69..0000000000 --- a/src/OPENMP/npair_halffull_trim_newtoff_omp.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/trim/newtoff/omp, - NPairHalffullTrimNewtoffOmp, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); - -NPairStyle(halffull/trim/newtoff/skip/omp, - NPairHalffullTrimNewtoffOmp, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_TRIM_NEWTOFF_OMP_H -#define LMP_NPAIR_HALFFULL_TRIM_NEWTOFF_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullTrimNewtoffOmp : public NPair { - public: - NPairHalffullTrimNewtoffOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_halffull_trim_newton_omp.cpp b/src/OPENMP/npair_halffull_trim_newton_omp.cpp deleted file mode 100644 index bd9d553eb9..0000000000 --- a/src/OPENMP/npair_halffull_trim_newton_omp.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_halffull_trim_newton_omp.h" - -#include "atom.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "my_page.h" -#include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullTrimNewtonOmp::NPairHalffullTrimNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list and trim to shorter cutoff - pair stored once if i,j are both owned and i < j - if j is ghost, only store if j coords are "above and to the right" of i - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullTrimNewtonOmp::build(NeighList *list) -{ - const int inum_full = list->listfull->inum; - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - NPAIR_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) -#endif - NPAIR_OMP_SETUP(inum_full); - - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - double xtmp,ytmp,ztmp; - double delx,dely,delz,rsq; - - double **x = atom->x; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over parent full list - - for (ii = ifrom; ii < ito; ii++) { - - n = 0; - neighptr = ipage.vget(); - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over full neighbor list - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - - if (j < nlocal) { - if (i > j) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - // trim to shorter cutoff - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NPAIR_OMP_CLOSE; - list->inum = inum_full; -} diff --git a/src/OPENMP/npair_halffull_trim_newton_omp.h b/src/OPENMP/npair_halffull_trim_newton_omp.h deleted file mode 100644 index c6950dfa45..0000000000 --- a/src/OPENMP/npair_halffull_trim_newton_omp.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/trim/newton/omp, - NPairHalffullTrimNewtonOmp, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI| NP_TRIM | NP_OMP); - -NPairStyle(halffull/trim/newton/skip/omp, - NPairHalffullTrimNewtonOmp, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_OMP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_TRIM_NEWTON_OMP_H -#define LMP_NPAIR_HALFFULL_TRIM_NEWTON_OMP_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullTrimNewtonOmp : public NPair { - public: - NPairHalffullTrimNewtonOmp(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/OPENMP/npair_multi_old_omp.cpp b/src/OPENMP/npair_multi_old_omp.cpp new file mode 100644 index 0000000000..d45f2d1f5f --- /dev/null +++ b/src/OPENMP/npair_multi_old_omp.cpp @@ -0,0 +1,262 @@ +/* ---------------------------------------------------------------------- + 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 "npair_multi_old_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairMultiOldOmp::NPairMultiOldOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multi/old-type stencil is itype dependent and is distance checked + Full: + binned neighbor list construction for all neighbors + multi-type stencil is itype dependent and is distance checked + every neighbor pair appears in list of both atoms i and j + Half + newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + multi-type stencil is itype dependent and is distance checked + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + multi-type stencil is itype dependent and is distance checked + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairMultiOldOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; + const double delta = 0.01 * force->angstrom; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i, j, jh, k, n, itype, jtype, ibin, bin_start, which, ns, imol, iatom; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr, *s; + double *cutnsq, *distsq; + + // loop over each atom, storing neighbors + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + ibin = atom2bin[i]; + s = stencil_multi_old[itype]; + distsq = distsq_multi_old[itype]; + cutnsq = cutneighsq[itype]; + ns = nstencil_multi_old[itype]; + for (k = 0; k < ns; k++) { + bin_start = binhead[ibin+s[k]]; + if (k == 0) { + if (HALF && NEWTON && (!TRI)) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = bin_start; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // for triclinic, bin stencil is full in all 3 dims + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (k == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (cutnsq[jtype] < distsq[k]) continue; + + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + } + + ilist[i] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage.vgot(n); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairMultiOldOmp<0,1,0,0>; +template class NPairMultiOldOmp<1,0,0,0>; +template class NPairMultiOldOmp<1,1,0,0>; +template class NPairMultiOldOmp<1,1,1,0>; +template class NPairMultiOldOmp<0,1,0,1>; +template class NPairMultiOldOmp<1,0,0,1>; +template class NPairMultiOldOmp<1,1,0,1>; +template class NPairMultiOldOmp<1,1,1,1>; +} diff --git a/src/OPENMP/npair_multi_old_omp.h b/src/OPENMP/npair_multi_old_omp.h new file mode 100644 index 0000000000..4251c6ed48 --- /dev/null +++ b/src/OPENMP/npair_multi_old_omp.h @@ -0,0 +1,77 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairMultiOldOmp<0, 1, 0, 0> NPairFullMultiOldOmp; +NPairStyle(full/multi/old/omp, + NPairFullMultiOldOmp, + NP_FULL | NP_MULTI_OLD | NP_OMP | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOldOmp<1, 0, 0, 0> NPairHalfMultiOldNewtoffOmp; +NPairStyle(half/multi/old/newtoff/omp, + NPairHalfMultiOldNewtoffOmp, + NP_HALF | NP_MULTI_OLD | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOldOmp<1, 1, 0, 0> NPairHalfMultiOldNewtonOmp; +NPairStyle(half/multi/old/newton/omp, + NPairHalfMultiOldNewtonOmp, + NP_HALF | NP_MULTI_OLD | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOldOmp<1, 1, 1, 0> NPairHalfMultiOldNewtonTriOmp; +NPairStyle(half/multi/old/newton/tri/omp, + NPairHalfMultiOldNewtonTriOmp, + NP_HALF | NP_MULTI_OLD | NP_OMP | NP_NEWTON | NP_TRI); + +typedef NPairMultiOldOmp<0, 1, 0, 1> NPairFullSizeMultiOldOmp; +NPairStyle(full/size/multi/old/omp, + NPairFullSizeMultiOldOmp, + NP_FULL | NP_SIZE | NP_MULTI_OLD | NP_OMP | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOldOmp<1, 0, 0, 1> NPairHalfSizeMultiOldNewtoffOmp; +NPairStyle(half/size/multi/old/newtoff/omp, + NPairHalfSizeMultiOldNewtoffOmp, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOldOmp<1, 1, 0, 1> NPairHalfSizeMultiOldNewtonOmp; +NPairStyle(half/size/multi/old/newton/omp, + NPairHalfSizeMultiOldNewtonOmp, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOldOmp<1, 1, 1, 1> NPairHalfSizeMultiOldNewtonTriOmp; +NPairStyle(half/size/multi/old/newton/tri/omp, + NPairHalfSizeMultiOldNewtonTriOmp, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_OMP | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_MULTI_OLD_OMP_H +#define LMP_NPAIR_MULTI_OLD_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairMultiOldOmp : public NPair { + public: + NPairMultiOldOmp(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/OPENMP/npair_multi_omp.cpp b/src/OPENMP/npair_multi_omp.cpp new file mode 100644 index 0000000000..3f8604572c --- /dev/null +++ b/src/OPENMP/npair_multi_omp.cpp @@ -0,0 +1,304 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_multi_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairMultiOmp::NPairMultiOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multi stencil is icollection-jcollection dependent + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairMultiOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; + const double delta = 0.01 * force->angstrom; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i, j, jh, js, k, n, itype, jtype, ibin, jbin, icollection, jcollection, which, ns, imol, iatom; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr, *s; + + int *collection = neighbor->collection; + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itag = tag[i]; + itype = type[i]; + icollection = collection[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (!ATOMONLY) { + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + } + + ibin = atom2bin[i]; + + // loop through stencils for all collections + + for (jcollection = 0; jcollection < ncollections; jcollection++) { + + // Use own bin for same collection + if (icollection == jcollection) jbin = ibin; + else jbin = coord2bin(x[i], jcollection); + + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; + + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + + // For half-newton-ortho, first check self bin (k == 0, always half) + // if checking its own binlist, skip all before i in linked list + if (HALF && NEWTON && !TRI) + if ((k == 0) && (icollection == jcollection)) js = bins[i]; + + for (j = js; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list, only uses full stencils + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off, only uses full stencils + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic, only uses full stencils + // If different sizes -> full stencil (accept all, one-way search) + // If same size -> half stencil, exclude half of interactions + // stencil is empty if i larger than j + // stencil is full if i smaller than j + // stencil is full if i same size as j + // for i smaller than j: + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + + if (flag_same_multi[icollection][jcollection]) { + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } + } else { + // Half neighbor list, newton on, orthonormal, uses a mix of stencils + // If different sizes -> full stencil (accept all, one-way search) + // If same size -> half stencil (first includes a self bin search) + if (k == 0 && flag_same_multi[icollection][jcollection]) { + // if same collection, + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the right" of i + + // if different collections, + // if j is owned atom, store it if j > i + // if j is ghost, only store if j coords are "above and to the right" of i + + if ((icollection != jcollection) && (j < i)) continue; + + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (ATOMONLY) { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < (radsum * radsum)) + jh = jh ^ mask_history; + neighptr[n++] = jh; + } + } else { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < (radsum * radsum)) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } + } else { + if (ATOMONLY) { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + } + } + } + + ilist[i] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage.vgot(n); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairMultiOmp<0,1,0,0,0>; +template class NPairMultiOmp<1,0,0,0,0>; +template class NPairMultiOmp<1,1,0,0,0>; +template class NPairMultiOmp<1,1,1,0,0>; +template class NPairMultiOmp<0,1,0,1,0>; +template class NPairMultiOmp<1,0,0,1,0>; +template class NPairMultiOmp<1,1,0,1,0>; +template class NPairMultiOmp<1,1,1,1,0>; +template class NPairMultiOmp<0,1,0,0,1>; +template class NPairMultiOmp<1,0,0,0,1>; +template class NPairMultiOmp<1,1,0,0,1>; +template class NPairMultiOmp<1,1,1,0,1>; +template class NPairMultiOmp<0,1,0,1,1>; +template class NPairMultiOmp<1,0,0,1,1>; +template class NPairMultiOmp<1,1,0,1,1>; +template class NPairMultiOmp<1,1,1,1,1>; +} diff --git a/src/OPENMP/npair_multi_omp.h b/src/OPENMP/npair_multi_omp.h new file mode 100644 index 0000000000..bcb01c87cf --- /dev/null +++ b/src/OPENMP/npair_multi_omp.h @@ -0,0 +1,115 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairMultiOmp<0, 1, 0, 0, 0> NPairFullMultiOmp; +NPairStyle(full/multi/omp, + NPairFullMultiOmp, + NP_FULL | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 0, 0, 0, 0> NPairHalfMultiNewtoffOmp; +NPairStyle(half/multi/newtoff/omp, + NPairHalfMultiNewtoffOmp, + NP_HALF | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 1, 0, 0, 0> NPairHalfMultiNewtonOmp; +NPairStyle(half/multi/newton/omp, + NPairHalfMultiNewtonOmp, + NP_HALF | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOmp<1, 1, 1, 0, 0> NPairHalfMultiNewtonTriOmp; +NPairStyle(half/multi/newton/tri/omp, + NPairHalfMultiNewtonTriOmp, + NP_HALF | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_TRI); + +typedef NPairMultiOmp<0, 1, 0, 1, 0> NPairFullSizeMultiOmp; +NPairStyle(full/size/multi/omp, + NPairFullSizeMultiOmp, + NP_FULL | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 0, 0, 1, 0> NPairHalfSizeMultiNewtoffOmp; +NPairStyle(half/size/multi/newtoff/omp, + NPairHalfSizeMultiNewtoffOmp, + NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 1, 0, 1, 0> NPairHalfSizeMultiNewtonOmp; +NPairStyle(half/size/multi/newton/omp, + NPairHalfSizeMultiNewtonOmp, + NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOmp<1, 1, 1, 1, 0> NPairHalfSizeMultiNewtonTriOmp; +NPairStyle(half/size/multi/newton/tri/omp, + NPairHalfSizeMultiNewtonTriOmp, + NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_TRI); + +typedef NPairMultiOmp<0, 1, 0, 0, 1> NPairFullMultiAtomonlyOmp; +NPairStyle(full/multi/atomonly/omp, + NPairFullMultiAtomonlyOmp, + NP_FULL | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 0, 0, 0, 1> NPairHalfMultiAtomonlyNewtoffOmp; +NPairStyle(half/multi/atomonly/newtoff/omp, + NPairHalfMultiAtomonlyNewtoffOmp, + NP_HALF | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 1, 0, 0, 1> NPairHalfMultiAtomonlyNewtonOmp; +NPairStyle(half/multi/atomonly/newton/omp, + NPairHalfMultiAtomonlyNewtonOmp, + NP_HALF | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOmp<1, 1, 1, 0, 1> NPairHalfMultiAtomonlyNewtonTriOmp; +NPairStyle(half/multi/atomonly/newton/tri/omp, + NPairHalfMultiAtomonlyNewtonTriOmp, + NP_HALF | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_TRI); + +typedef NPairMultiOmp<0, 1, 0, 1, 1> NPairFullSizeMultiAtomonlyOmp; +NPairStyle(full/size/multi/atomonly/omp, + NPairFullSizeMultiAtomonlyOmp, + NP_FULL | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 0, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewtoffOmp; +NPairStyle(half/size/multi/atomonly/newtoff/omp, + NPairHalfSizeMultiAtomonlyNewtoffOmp, + NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOmp<1, 1, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewtonOmp; +NPairStyle(half/size/multi/atomonly/newton/omp, + NPairHalfSizeMultiAtomonlyNewtonOmp, + NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOmp<1, 1, 1, 1, 1> NPairHalfSizeMultiAtomonlyNewtonTriOmp; +NPairStyle(half/size/multi/atomonly/newton/tri/omp, + NPairHalfSizeMultiAtomonlyNewtonTriOmp, + NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_MULTI_OMP_H +#define LMP_NPAIR_MULTI_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairMultiOmp : public NPair { + public: + NPairMultiOmp(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/OPENMP/npair_full_multi_old_omp.cpp b/src/OPENMP/npair_nsq_ghost_omp.cpp similarity index 61% rename from src/OPENMP/npair_full_multi_old_omp.cpp rename to src/OPENMP/npair_nsq_ghost_omp.cpp index f0ed6360ab..a270fbb84d 100644 --- a/src/OPENMP/npair_full_multi_old_omp.cpp +++ b/src/OPENMP/npair_nsq_ghost_omp.cpp @@ -1,3 +1,4 @@ +// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -11,32 +12,44 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "npair_full_multi_old_omp.h" + +#include "npair_nsq_ghost_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" + #include "atom.h" -#include "atom_vec.h" #include "domain.h" #include "error.h" +#include "atom_vec.h" #include "molecule.h" #include "my_page.h" #include "neigh_list.h" -#include "npair_omp.h" -#include "omp_compat.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairFullMultiOldOmp::NPairFullMultiOldOmp(LAMMPS *lmp) : NPair(lmp) {} +template +NPairNsqGhostOmp::NPairNsqGhostOmp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - multi-type stencil is itype dependent and is distance checked - every neighbor pair appears in list of both atoms i and j + Full: + N^2 search for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + include neighbors of ghost atoms, but no "special neighbors" for ghosts + pair stored once if i,j are both owned and i < j + pair stored by me if i owned and j ghost (also stored by proc owning j) + pair stored once if i,j are both ghost and i < j ------------------------------------------------------------------------- */ -void NPairFullMultiOldOmp::build(NeighList *list) +template +void NPairNsqGhostOmp::build(NeighList *list) { - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int nlocal = atom->nlocal; + const int nall = nlocal + atom->nghost; const int molecular = atom->molecular; const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; @@ -44,15 +57,12 @@ void NPairFullMultiOldOmp::build(NeighList *list) #if defined(_OPENMP) #pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) #endif - NPAIR_OMP_SETUP(nlocal); + NPAIR_OMP_SETUP(nall); - int i, j, k, n, itype, jtype, ibin, which, ns, imol, iatom; + int i, j, jstart, n, itype, jtype, which, imol, iatom; tagint tagprev; double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr, *s; - double *cutsq, *distsq; - - // loop over each atom, storing neighbors + int *neighptr; double **x = atom->x; int *type = atom->type; @@ -74,6 +84,8 @@ void NPairFullMultiOldOmp::build(NeighList *list) MyPage &ipage = list->ipage[tid]; ipage.reset(); + // loop over owned & ghost atoms, storing neighbors + for (i = ifrom; i < ito; i++) { n = 0; @@ -89,28 +101,32 @@ void NPairFullMultiOldOmp::build(NeighList *list) tagprev = tag[i] - iatom - 1; } - // loop over all atoms in other bins in stencil, including self - // skip if i,j neighbor cutoff is less than bin distance - // skip i = j + // loop over all atoms, owned and ghost + // Full: + // skip i = j + // Half: + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs with owned atom only, on both procs + // stores ghost/ghost pairs only once + // no molecular test when i = ghost atom + + if (HALF) jstart = i + 1; + else jstart = 0; + + if (i < nlocal) { + for (j = jstart; j < nall; j++) { + if (!HALF) { + if (i == j) continue; + } - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin + s[k]]; j >= 0; j = bins[j]) { jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - if (i == j) continue; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx * delx + dely * dely + delz * delz; - if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { if (!moltemplate) @@ -130,6 +146,26 @@ void NPairFullMultiOldOmp::build(NeighList *list) neighptr[n++] = j; } } + } else { + for (j = jstart; j < nall; j++) { + if (!HALF) { + if (i == j) continue; + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (HALF) { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } else { + if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; + } + } } ilist[i] = i; @@ -140,5 +176,10 @@ void NPairFullMultiOldOmp::build(NeighList *list) } NPAIR_OMP_CLOSE; list->inum = nlocal; - list->gnum = 0; + list->gnum = nall - nlocal; +} + +namespace LAMMPS_NS { +template class NPairNsqGhostOmp<0>; +template class NPairNsqGhostOmp<1>; } diff --git a/src/OPENMP/npair_half_nsq_newtoff_ghost_omp.h b/src/OPENMP/npair_nsq_ghost_omp.h similarity index 64% rename from src/OPENMP/npair_half_nsq_newtoff_ghost_omp.h rename to src/OPENMP/npair_nsq_ghost_omp.h index 4df15104c3..1d33758bac 100644 --- a/src/OPENMP/npair_half_nsq_newtoff_ghost_omp.h +++ b/src/OPENMP/npair_nsq_ghost_omp.h @@ -13,23 +13,29 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairNsqGhostOmp<0> NPairFullNsqGhostOmp; +NPairStyle(full/nsq/ghost/omp, + NPairFullNsqGhostOmp, + NP_FULL | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_OMP | NP_ORTHO | NP_TRI); + +typedef NPairNsqGhostOmp<1> NPairHalfNsqNewtoffGhostOmp; NPairStyle(half/nsq/newtoff/ghost/omp, NPairHalfNsqNewtoffGhostOmp, - NP_HALF | NP_NSQ | NP_NEWTOFF | NP_GHOST | NP_OMP | - NP_ORTHO | NP_TRI); + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_GHOST | NP_OMP | NP_ORTHO | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_OMP_H -#define LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_OMP_H +#ifndef LMP_NPAIR_NSQ_GHOST_OMP_H +#define LMP_NPAIR_NSQ_GHOST_OMP_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfNsqNewtoffGhostOmp : public NPair { +template +class NPairNsqGhostOmp : public NPair { public: - NPairHalfNsqNewtoffGhostOmp(class LAMMPS *); + NPairNsqGhostOmp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/OPENMP/npair_nsq_omp.cpp b/src/OPENMP/npair_nsq_omp.cpp new file mode 100644 index 0000000000..c482fc8f2d --- /dev/null +++ b/src/OPENMP/npair_nsq_omp.cpp @@ -0,0 +1,238 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_nsq_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairNsqOmp::NPairNsqOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + N^2 search for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + Newton: + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + every pair stored exactly once by some processor + decision on ghost atoms based on itag,jtag tests + Half + Newton + Tri: + use itag/jtap comparision to eliminate half the interactions + for triclinic, must use delta to eliminate half the I/J interactions + cannot use I/J exact coord comparision as for orthog + b/c transforming orthog -> lambda -> orthog for ghost atoms + with an added PBC offset can shift all 3 coords by epsilon +------------------------------------------------------------------------- */ + +template +void NPairNsqOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; + const double delta = 0.01 * force->angstrom; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i, j, jh, jstart, n, itype, jtype, which, imol, iatom; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr; + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int nall = atom->nlocal + atom->nghost; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // Full: loop over all atoms, owned and ghost, skip i = j + // Half: loop over remaining atoms, owned and ghost + // Newtoff: only store pair if i < j + // Newton: itag = jtag is possible for long cutoffs that include images of self + + if (!HALF) jstart = 0; + else jstart = i + 1; + + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + + if (!HALF) { + // Full neighbor list + if (i == j) continue; + } else if (NEWTON) { + // Half neighbor list, newton on + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else if (TRI) { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + + ilist[i] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage.vgot(n); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairNsqOmp<0,1,0,0>; +template class NPairNsqOmp<1,0,0,0>; +template class NPairNsqOmp<1,1,0,0>; +template class NPairNsqOmp<1,1,1,0>; +template class NPairNsqOmp<0,1,0,1>; +template class NPairNsqOmp<1,0,0,1>; +template class NPairNsqOmp<1,1,0,1>; +template class NPairNsqOmp<1,1,1,1>; +} diff --git a/src/OPENMP/npair_nsq_omp.h b/src/OPENMP/npair_nsq_omp.h new file mode 100644 index 0000000000..b7479b6e17 --- /dev/null +++ b/src/OPENMP/npair_nsq_omp.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off + +typedef NPairNsqOmp<0, 1, 0, 0> NPairFullNsqOmp; +NPairStyle(full/nsq/omp, + NPairFullNsqOmp, + NP_FULL | NP_NSQ | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsqOmp<1, 0, 0, 0> NPairHalfNsqNewtoffOmp; +NPairStyle(half/nsq/newtoff/omp, + NPairHalfNsqNewtoffOmp, + NP_HALF | NP_NSQ | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsqOmp<1, 1, 0, 0> NPairHalfNsqNewtonOmp; +NPairStyle(half/nsq/newton/omp, + NPairHalfNsqNewtonOmp, + NP_HALF | NP_NSQ | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairNsqOmp<1, 1, 1, 0> NPairHalfNsqNewtonTriOmp; +NPairStyle(half/nsq/newton/tri/omp, + NPairHalfNsqNewtonTriOmp, + NP_HALF | NP_NSQ | NP_OMP | NP_NEWTON | NP_TRI); + +typedef NPairNsqOmp<0, 1, 0, 1> NPairFullSizeNsqOmp; +NPairStyle(full/size/nsq/omp, + NPairFullSizeNsqOmp, + NP_FULL | NP_SIZE | NP_NSQ | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsqOmp<1, 0, 0, 1> NPairHalfSizeNsqNewtoffOmp; +NPairStyle(half/size/nsq/newtoff/omp, + NPairHalfSizeNsqNewtoffOmp, + NP_HALF | NP_SIZE | NP_NSQ | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsqOmp<1, 1, 0, 1> NPairHalfSizeNsqNewtonOmp; +NPairStyle(half/size/nsq/newton/omp, + NPairHalfSizeNsqNewtonOmp, + NP_HALF | NP_SIZE | NP_NSQ | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairNsqOmp<1, 1, 1, 1> NPairHalfSizeNsqNewtonTriOmp; +NPairStyle(half/size/nsq/newton/tri/omp, + NPairHalfSizeNsqNewtonTriOmp, + NP_HALF | NP_SIZE | NP_NSQ | NP_OMP | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_NSQ_OMP_H +#define LMP_NPAIR_NSQ_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairNsqOmp : public NPair { + public: + NPairNsqOmp(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/OPENMP/npair_half_respa_bin_newton_tri_omp.cpp b/src/OPENMP/npair_respa_bin_omp.cpp similarity index 51% rename from src/OPENMP/npair_half_respa_bin_newton_tri_omp.cpp rename to src/OPENMP/npair_respa_bin_omp.cpp index 78b3abdd66..c958167ba0 100644 --- a/src/OPENMP/npair_half_respa_bin_newton_tri_omp.cpp +++ b/src/OPENMP/npair_respa_bin_omp.cpp @@ -12,9 +12,9 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "omp_compat.h" -#include "npair_half_respa_bin_newton_tri_omp.h" +#include "npair_respa_bin_omp.h" #include "npair_omp.h" +#include "omp_compat.h" #include "atom.h" #include "atom_vec.h" @@ -29,17 +29,25 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairHalfRespaBinNewtonTriOmp::NPairHalfRespaBinNewtonTriOmp(LAMMPS *lmp) : +template +NPairRespaBinOmp::NPairRespaBinOmp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- multiple respa lists - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor + Newtoff + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and surrounding bins in non-Newton stencil + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Newton + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -void NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) +template +void NPairRespaBinOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; const int molecular = atom->molecular; @@ -55,10 +63,10 @@ void NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; + int i, j, k, n, itype, jtype, ibin, bin_start, n_inner, n_middle, imol, iatom; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int *neighptr, *neighptr_inner, *neighptr_middle; double **x = atom->x; int *type = atom->type; @@ -80,7 +88,7 @@ void NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) int *numneigh_inner = list->numneigh_inner; int **firstneigh_inner = list->firstneigh_inner; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; + int *ilist_middle, *numneigh_middle, **firstneigh_middle; if (respamiddle) { ilist_middle = list->ilist_middle; numneigh_middle = list->numneigh_middle; @@ -117,75 +125,112 @@ void NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; + ibin = atom2bin[i]; if (moltemplate) { imol = molindex[i]; iatom = molatom[i]; tagprev = tag[i] - iatom - 1; } - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + bin_start = binhead[ibin + stencil[k]]; + if (NEWTON && (!TRI)) { + if (k == 0) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; + for (j = bin_start; j >= 0; j = bins[j]) { + if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // for triclinic, bin stencil is full in all 3 dims + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; } else { - if (x[j][0] < xtmp) continue; + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (k == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } } } } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); + which = find_special(special[i], nspecial[i], tag[j]); else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + else if ((minchange = domain->minimum_image_check(delx, dely, delz))) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; + if (which == 0) + neighptr_inner[n_inner++] = j; + else if (minchange) + neighptr_inner[n_inner++] = j; else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); } if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; + if (which == 0) + neighptr_middle[n_middle++] = j; + else if (minchange) + neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = j ^ (which << SBBITS); } @@ -197,23 +242,20 @@ void NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); ilist_inner[i] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; - ipage_inner.vgot(n_inner); - if (ipage_inner.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + ipage.vgot(n_inner); + if (ipage_inner.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); if (respamiddle) { ilist_middle[i] = i; firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_middle->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } } NPAIR_OMP_CLOSE; @@ -221,3 +263,9 @@ void NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) list->inum_inner = nlocal; if (respamiddle) list->inum_middle = nlocal; } + +namespace LAMMPS_NS { +template class NPairRespaBinOmp<0,0>; +template class NPairRespaBinOmp<1,0>; +template class NPairRespaBinOmp<1,1>; +} diff --git a/src/OPENMP/npair_half_respa_bin_newton_omp.h b/src/OPENMP/npair_respa_bin_omp.h similarity index 55% rename from src/OPENMP/npair_half_respa_bin_newton_omp.h rename to src/OPENMP/npair_respa_bin_omp.h index 695d0ce627..23daacbb8f 100644 --- a/src/OPENMP/npair_half_respa_bin_newton_omp.h +++ b/src/OPENMP/npair_respa_bin_omp.h @@ -13,22 +13,34 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairRespaBinOmp<0, 0> NPairHalfRespaBinNewtoffOmp; +NPairStyle(half/respa/bin/newtoff, + NPairHalfRespaBinNewtoffOmp, + NP_HALF | NP_RESPA | NP_BIN | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairRespaBinOmp<1, 0> NPairHalfRespaBinNewtonOmp; NPairStyle(half/respa/bin/newton/omp, NPairHalfRespaBinNewtonOmp, - NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO); + NP_HALF | NP_RESPA | NP_BIN | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairRespaBinOmp<1, 1> NPairHalfRespaBinNewtonTriOmp; +NPairStyle(half/respa/bin/newton/tri/omp, + NPairHalfRespaBinNewtonTriOmp, + NP_HALF | NP_RESPA | NP_BIN | NP_OMP | NP_NEWTON | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_OMP_H -#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_OMP_H +#ifndef LMP_NPAIR_RESPA_BIN_OMP_H +#define LMP_NPAIR_RESPA_BIN_OMP_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfRespaBinNewtonOmp : public NPair { +template +class NPairRespaBinOmp : public NPair { public: - NPairHalfRespaBinNewtonOmp(class LAMMPS *); + NPairRespaBinOmp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/OPENMP/npair_half_respa_nsq_newton_omp.cpp b/src/OPENMP/npair_respa_nsq_omp.cpp similarity index 55% rename from src/OPENMP/npair_half_respa_nsq_newton_omp.cpp rename to src/OPENMP/npair_respa_nsq_omp.cpp index a9745edc64..6815b21544 100644 --- a/src/OPENMP/npair_half_respa_nsq_newton_omp.cpp +++ b/src/OPENMP/npair_respa_nsq_omp.cpp @@ -12,9 +12,9 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "omp_compat.h" -#include "npair_half_respa_nsq_newton_omp.h" +#include "npair_respa_nsq_omp.h" #include "npair_omp.h" +#include "omp_compat.h" #include "atom.h" #include "atom_vec.h" @@ -30,24 +30,38 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairHalfRespaNsqNewtonOmp::NPairHalfRespaNsqNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} +template +NPairRespaNsqOmp::NPairRespaNsqOmp(LAMMPS *lmp) : + NPair(lmp) {} /* ---------------------------------------------------------------------- multiple respa lists - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests + Newtoff + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + pair added if j is ghost (also stored by proc owning j) + Newton + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests + use itag/jtag comparision to eliminate half the interactions + itag = jtag is possible for long cutoffs that include images of self + Newton + Triclinic: + for triclinic, must use delta to eliminate half the I/J interactions + cannot use I/J exact coord comparision as for orthog + b/c transforming orthog -> lambda -> orthog for ghost atoms + with an added PBC offset can shift all 3 coords by epsilon ------------------------------------------------------------------------- */ -void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) +template +void NPairRespaNsqOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; const int molecular = atom->molecular; const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; NPAIR_OMP_INIT; @@ -58,10 +72,10 @@ void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,n,itype,jtype,n_inner,n_middle,imol,iatom; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; + int i, j, n, itype, jtype, n_inner, n_middle, imol, iatom; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int *neighptr, *neighptr_inner, *neighptr_middle; double **x = atom->x; int *type = atom->type; @@ -85,7 +99,7 @@ void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) int *numneigh_inner = list->numneigh_inner; int **firstneigh_inner = list->firstneigh_inner; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; + int *ilist_middle, *numneigh_middle, **firstneigh_middle; if (respamiddle) { ilist_middle = list->ilist_middle; numneigh_middle = list->numneigh_middle; @@ -117,8 +131,8 @@ void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) neighptr_middle = ipage_middle->vget(); } - itag = tag[i]; itype = type[i]; + itag = tag[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; @@ -129,72 +143,75 @@ void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) } // loop over remaining atoms, owned and ghost - // use itag/jtap comparision to eliminate half the interactions - // itag = jtag is possible for long cutoffs that include images of self - // for triclinic, must use delta to eliminate half the I/J interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - for (j = i+1; j < nall; j++) { + for (j = i + 1; j < nall; j++) { if (includegroup && !(mask[j] & bitmask)) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; + if (NEWTON) { + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else if (TRI) { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } } } } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); + which = find_special(special[i], nspecial[i], tag[j]); else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + else if ((minchange = domain->minimum_image_check(delx, dely, delz))) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); + if (which == 0) + neighptr_inner[n_inner++] = j; + else if (minchange) + neighptr_inner[n_inner++] = j; + else if (which > 0) + neighptr_inner[n_inner++] = j ^ (which << SBBITS); } - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; + if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (which == 0) + neighptr_middle[n_middle++] = j; + else if (minchange) + neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = j ^ (which << SBBITS); } @@ -205,23 +222,20 @@ void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); ilist_inner[i] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; ipage.vgot(n_inner); - if (ipage_inner.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_inner.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); if (respamiddle) { ilist_middle[i] = i; firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_middle->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } } NPAIR_OMP_CLOSE; @@ -229,3 +243,9 @@ void NPairHalfRespaNsqNewtonOmp::build(NeighList *list) list->inum_inner = nlocal; if (respamiddle) list->inum_middle = nlocal; } + +namespace LAMMPS_NS { +template class NPairRespaNsqOmp<0,0>; +template class NPairRespaNsqOmp<1,0>; +template class NPairRespaNsqOmp<1,1>; +} diff --git a/src/OPENMP/npair_half_respa_nsq_newton_omp.h b/src/OPENMP/npair_respa_nsq_omp.h similarity index 55% rename from src/OPENMP/npair_half_respa_nsq_newton_omp.h rename to src/OPENMP/npair_respa_nsq_omp.h index d949ef7e93..810931674c 100644 --- a/src/OPENMP/npair_half_respa_nsq_newton_omp.h +++ b/src/OPENMP/npair_respa_nsq_omp.h @@ -13,23 +13,34 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairRespaNsqOmp<0,0> NPairHalfRespaNsqNewtoffOmp; +NPairStyle(half/respa/nsq/newtoff/omp, + NPairHalfRespaNsqNewtoff, + NP_HALF | NP_RESPA | NP_NSQ | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairRespaNsqOmp<1,0> NPairHalfRespaNsqNewtonOmp; NPairStyle(half/respa/nsq/newton/omp, NPairHalfRespaNsqNewtonOmp, - NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_OMP | - NP_ORTHO | NP_TRI); + NP_HALF | NP_RESPA | NP_NSQ | NP_OMP | NP_NEWTON | NP_ORTHO); + +typedef NPairRespaNsqOmp<1,1> NPairHalfRespaNsqNewtonTriOmp; +NPairStyle(half/respa/nsq/newton/tri/omp, + NPairHalfRespaNsqNewtonTriOmp, + NP_HALF | NP_RESPA | NP_NSQ | NP_OMP | NP_NEWTON | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_OMP_H -#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_OMP_H +#ifndef LMP_NPAIR_RESPA_NSQ_OMP_H +#define LMP_NPAIR_RESPA_NSQ_OMP_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfRespaNsqNewtonOmp : public NPair { +template +class NPairRespaNsqOmp : public NPair { public: - NPairHalfRespaNsqNewtonOmp(class LAMMPS *); + NPairRespaNsqOmp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/OPENMP/npair_skip_omp.h b/src/OPENMP/npair_skip_omp.h index ce61968c17..937304ad3f 100644 --- a/src/OPENMP/npair_skip_omp.h +++ b/src/OPENMP/npair_skip_omp.h @@ -16,6 +16,7 @@ #ifdef NPAIR_CLASS // clang-format off + NPairStyle(skip/omp, NPairSkip, NP_SKIP | NP_HALF | NP_FULL | @@ -50,6 +51,41 @@ NPairStyle(skip/ghost/omp, NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP | NP_GHOST); + +NPairStyle(skip/trim/omp, + NPairSkipTrim, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + +NPairStyle(skip/trim/half/respa/omp, + NPairSkipTrimRespa, + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + +NPairStyle(skip/trim/half/size/omp, + NPairSkipTrimSize, + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + +NPairStyle(skip/trim/size/off2on/omp, + NPairSkipTrimSizeOff2on, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + +NPairStyle(skip/trim/size/off2on/oneside/omp, + NPairSkipTrimSizeOff2onOneside, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); + +NPairStyle(skip/trim/ghost/omp, + NPairSkipTrim, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP | NP_GHOST); // clang-format off #endif diff --git a/src/OPENMP/npair_skip_trim_omp.h b/src/OPENMP/npair_skip_trim_omp.h deleted file mode 100644 index aba6f50e17..0000000000 --- a/src/OPENMP/npair_skip_trim_omp.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -// There is no benefit from multi-threading for skip lists, so we -// just forward the requests to the corresponding non-omp versions. - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim/omp, - NPairSkipTrim, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); - -NPairStyle(skip/trim/half/respa/omp, - NPairSkipTrimRespa, - NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); - -NPairStyle(skip/trim/half/size/omp, - NPairSkipTrimSize, - NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); - -NPairStyle(skip/trim/size/off2on/omp, - NPairSkipTrimSizeOff2on, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); - -NPairStyle(skip/trim/size/off2on/oneside/omp, - NPairSkipTrimSizeOff2onOneside, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP); - -NPairStyle(skip/trim/ghost/omp, - NPairSkipTrim, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_OMP | NP_GHOST); -// clang-format off -#endif - diff --git a/src/OPENMP/npair_trim_omp.cpp b/src/OPENMP/npair_trim_omp.cpp index d7ac0ddb40..0840c1a5f2 100644 --- a/src/OPENMP/npair_trim_omp.cpp +++ b/src/OPENMP/npair_trim_omp.cpp @@ -13,14 +13,13 @@ ------------------------------------------------------------------------- */ #include "npair_trim_omp.h" +#include "npair_omp.h" +#include "omp_compat.h" #include "atom.h" #include "error.h" #include "my_page.h" #include "neigh_list.h" -#include "npair_omp.h" - -#include "omp_compat.h" using namespace LAMMPS_NS; @@ -43,10 +42,9 @@ void NPairTrimOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(inum_copy); - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - double xtmp,ytmp,ztmp; - double delx,dely,delz,rsq; + int i, j, ii, jj, n, jnum, joriginal; + int *neighptr, *jlist; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; double **x = atom->x; @@ -100,8 +98,7 @@ void NPairTrimOmp::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } NPAIR_OMP_CLOSE; list->inum = inum_copy; diff --git a/src/PYTHON/python_impl.cpp b/src/PYTHON/python_impl.cpp index 57f8ea1cf0..0db468d701 100644 --- a/src/PYTHON/python_impl.cpp +++ b/src/PYTHON/python_impl.cpp @@ -17,6 +17,7 @@ #include "python_impl.h" +#include "comm.h" #include "error.h" #include "input.h" #include "memory.h" @@ -29,22 +30,33 @@ #ifdef MLIAP_PYTHON #include "mliap_model_python.h" +#if defined(__PYX_EXTERN_C) && !defined(CYTHON_EXTERN_C) +#undef __PYX_EXTERN_C +#endif #include "mliap_unified.h" // The above should somehow really be included in the next file. // We could get around this with cython --capi-reexport-cincludes // However, that exposes -too many- headers. #include "mliap_model_python_couple.h" +#if defined(__PYX_EXTERN_C) && !defined(CYTHON_EXTERN_C) +#undef __PYX_EXTERN_C +#endif #include "mliap_unified_couple.h" #ifdef LMP_KOKKOS #include "mliap_model_python_kokkos.h" +#if defined(__PYX_EXTERN_C) && !defined(CYTHON_EXTERN_C) +#undef __PYX_EXTERN_C +#endif #include "mliap_unified_kokkos.h" // The above should somehow really be included in the next file. // We could get around this with cython --capi-reexport-cincludes // However, that exposes -too many- headers. #include "mliap_model_python_couple_kokkos.h" +#if defined(__PYX_EXTERN_C) && !defined(CYTHON_EXTERN_C) +#undef __PYX_EXTERN_C +#endif #include "mliap_unified_couple_kokkos.h" - #endif #endif @@ -61,46 +73,58 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp) nfunc = 0; pfuncs = nullptr; -#if PY_MAJOR_VERSION >= 3 -#ifndef Py_LIMITED_API +#if PY_MAJOR_VERSION >= 3 && !defined(Py_LIMITED_API) // check for PYTHONUNBUFFERED environment variable const char *PYTHONUNBUFFERED = getenv("PYTHONUNBUFFERED"); + // Force the stdout and stderr streams to be unbuffered. + bool unbuffered = PYTHONUNBUFFERED != nullptr && strcmp(PYTHONUNBUFFERED, "1") == 0; - if (PYTHONUNBUFFERED != nullptr && strcmp(PYTHONUNBUFFERED, "1") == 0) { - // Python Global configuration variable - // Force the stdout and stderr streams to be unbuffered. - Py_UnbufferedStdioFlag = 1; - } +#if (PY_VERSION_HEX >= 0x030800f0) + PyConfig config; + PyConfig_InitPythonConfig(&config); + config.buffered_stdio = !unbuffered; +#else + // Python Global configuration variable + Py_UnbufferedStdioFlag = unbuffered; #endif #endif #ifdef MLIAP_PYTHON - // Inform python intialization scheme of the mliappy module. - // This -must- happen before python is initialized. - int err = PyImport_AppendInittab("mliap_model_python_couple", PyInit_mliap_model_python_couple); - if (err) error->all(FLERR, "Could not register MLIAPPY embedded python module."); + // cannot register mliappy module a second time + if (!Py_IsInitialized()) { + // Inform python intialization scheme of the mliappy module. + // This -must- happen before python is initialized. + int err = PyImport_AppendInittab("mliap_model_python_couple", PyInit_mliap_model_python_couple); + if (err) error->all(FLERR, "Could not register MLIAPPY embedded python module."); + + err = PyImport_AppendInittab("mliap_unified_couple", PyInit_mliap_unified_couple); + if (err) error->all(FLERR, "Could not register MLIAPPY unified embedded python module."); - err = PyImport_AppendInittab("mliap_unified_couple", PyInit_mliap_unified_couple); - if (err) error->all(FLERR, "Could not register MLIAPPY unified embedded python module."); #ifdef LMP_KOKKOS - // Inform python intialization scheme of the mliappy module. - // This -must- happen before python is initialized. - err = PyImport_AppendInittab("mliap_model_python_couple_kokkos", PyInit_mliap_model_python_couple_kokkos); - if (err) error->all(FLERR, "Could not register MLIAPPY embedded python module."); - - err = PyImport_AppendInittab("mliap_unified_couple_kokkos", PyInit_mliap_unified_couple_kokkos); - if (err) error->all(FLERR, "Could not register MLIAPPY unified embedded python module."); + // Inform python intialization scheme of the mliappy module. + // This -must- happen before python is initialized. + err = PyImport_AppendInittab("mliap_model_python_couple_kokkos", + PyInit_mliap_model_python_couple_kokkos); + if (err) error->all(FLERR, "Could not register MLIAPPY embedded python KOKKOS module."); + err = PyImport_AppendInittab("mliap_unified_couple_kokkos", PyInit_mliap_unified_couple_kokkos); + if (err) error->all(FLERR, "Could not register MLIAPPY unified embedded python KOKKOS module."); #endif + } #endif +#if PY_VERSION_HEX >= 0x030800f0 && !defined(Py_LIMITED_API) + Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); +#else Py_Initialize(); +#endif // only needed for Python 2.x and Python 3 < 3.7 // With Python 3.7 this function is now called by Py_Initialize() // Deprecated since version 3.9, will be removed in version 3.11 -#if PY_MAJOR_VERSION < 3 || PY_MINOR_VERSION < 7 - if (!PyEval_ThreadsInitialized()) { PyEval_InitThreads(); } +#if PY_VERSION_HEX < 0x030700f0 + if (!PyEval_ThreadsInitialized()) PyEval_InitThreads(); #endif PyUtils::GIL lock; diff --git a/src/REAXFF/compute_reaxff_atom.cpp b/src/REAXFF/compute_reaxff_atom.cpp new file mode 100644 index 0000000000..1834de0b4b --- /dev/null +++ b/src/REAXFF/compute_reaxff_atom.cpp @@ -0,0 +1,254 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Richard Berger (LANL) +------------------------------------------------------------------------- */ + +#include "compute_reaxff_atom.h" +#include "atom.h" +#include "molecule.h" +#include "update.h" +#include "force.h" +#include "memory.h" +#include "error.h" +#include "neigh_list.h" + +#include "pair_reaxff.h" +#include "reaxff_api.h" + +using namespace LAMMPS_NS; +using namespace ReaxFF; + +/* ---------------------------------------------------------------------- */ + +ComputeReaxFFAtom::ComputeReaxFFAtom(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), neighid(nullptr), abo(nullptr), bondcount(nullptr), reaxff(nullptr) +{ + if (atom->tag_consecutive() == 0) + error->all(FLERR, "Atom IDs must be consecutive for compute reaxff/atom"); + + peratom_flag = 1; + + // initialize output + + nlocal = -1; + nbonds = 0; + prev_nbonds = -1; + + size_peratom_cols = 3; + + size_local_rows = 0; + size_local_cols = 3; + + invoked_bonds = -1; + + store_bonds = false; + nsub = 0; + + int iarg = 3; + while (iarg narg) utils::missing_cmd_args(FLERR, "compute reaxff/atom pair", error); + ++iarg; + + if (isdigit(arg[iarg][0])) { + nsub = utils::inumeric(FLERR, arg[iarg], false, lmp); + ++iarg; + if (nsub > 0) continue; + } + error->all(FLERR, "Illegal compute reaxff/atom command"); + } else if (strcmp(arg[iarg], "bonds") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "compute reaxff/atom bonds", error); + store_bonds = utils::logical(FLERR, arg[iarg+1], false, lmp); + iarg += 2; + } else error->all(FLERR,"Illegal compute reaxff/atom command"); + } + + local_flag = store_bonds; +} + +/* ---------------------------------------------------------------------- */ + +ComputeReaxFFAtom::~ComputeReaxFFAtom() +{ + memory->destroy(array_local); + memory->destroy(array_atom); + memory->destroy(abo); + memory->destroy(neighid); + memory->destroy(bondcount); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeReaxFFAtom::init() +{ + if (lmp->suffix_enable) { + if (lmp->suffix) + reaxff = dynamic_cast(force->pair_match(fmt::format("^reax../{}", lmp->suffix), 0, nsub)); + if (!reaxff && lmp->suffix2) + reaxff = dynamic_cast(force->pair_match(fmt::format("^reax../{}", lmp->suffix2), 0, nsub)); + } + + if (!reaxff) reaxff = dynamic_cast(force->pair_match("^reax..", 0, nsub)); + + if (!reaxff) error->all(FLERR,"Cannot use compute reaxff/atom without " + "pair_style reaxff or reaxff/omp"); + + if (reaxff->kokkosable && !kokkosable) + error->all(FLERR,"Cannot use compute reaxff/atom with pair_style reaxff/kk. Use reaxff/atom/kk."); +} + +/* ---------------------------------------------------------------------- */ + +int ComputeReaxFFAtom::FindBond() +{ + int *ilist, i, ii, inum; + int j, pj, nj; + tagint jtag; + double bo_tmp,bo_cut; + + inum = reaxff->list->inum; + ilist = reaxff->list->ilist; + bond_data *bo_ij; + bo_cut = reaxff->api->control->bg_cut; + + tagint *tag = atom->tag; + int * mask = atom->mask; + int numbonds = 0; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (mask[i] & groupbit) { + nj = 0; + + for (pj = Start_Index(i, reaxff->api->lists); pj < End_Index(i, reaxff->api->lists); ++pj) { + bo_ij = &(reaxff->api->lists->select.bond_list[pj]); + j = bo_ij->nbr; + if (mask[j] & groupbit) { + jtag = tag[j]; + bo_tmp = bo_ij->bo_data.BO; + + if (bo_tmp > bo_cut) { + if (store_bonds) { + neighid[i][nj] = jtag; + abo[i][nj] = bo_tmp; + } + nj++; + } + } + } + bondcount[i] = nj; + numbonds += nj; + } + } + return numbonds; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeReaxFFAtom::compute_bonds() +{ + invoked_bonds = update->ntimestep; + + if (atom->nlocal > nlocal) { + memory->destroy(abo); + memory->destroy(neighid); + memory->destroy(bondcount); + memory->destroy(array_atom); + nlocal = atom->nlocal; + if (store_bonds) { + memory->create(abo, nlocal, MAXREAXBOND, "reaxff/atom:abo"); + memory->create(neighid, nlocal, MAXREAXBOND, "reaxff/atom:neighid"); + } + memory->create(bondcount, nlocal, "reaxff/atom:bondcount"); + memory->create(array_atom, nlocal, 3, "reaxff/atom:array_atom"); + } + + for (int i = 0; i < nlocal; i++) { + bondcount[i] = 0; + for (int j = 0; store_bonds && j < MAXREAXBOND; j++) { + neighid[i][j] = 0; + abo[i][j] = 0.0; + } + } + + nbonds = FindBond(); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeReaxFFAtom::compute_local() +{ + invoked_local = update->ntimestep; + + if (invoked_bonds < update->ntimestep) + compute_bonds(); + + if (nbonds > prev_nbonds) { + // grow array_local + memory->destroy(array_local); + memory->create(array_local, nbonds, 3, "reaxff/atom:array_local"); + prev_nbonds = nbonds; + } + + size_local_rows = nbonds; + auto tag = atom->tag; + + int b = 0; + + for (int i = 0; i < nlocal; ++i) { + const int numbonds = bondcount[i]; + + for (int k = 0; k < numbonds; k++) { + auto bond = array_local[b++]; + bond[0] = tag[i]; + bond[1] = neighid[i][k]; + bond[2] = abo[i][k]; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputeReaxFFAtom::compute_peratom() +{ + invoked_peratom = update->ntimestep; + + if (invoked_bonds < update->ntimestep) { + compute_bonds(); + } + + for (int i = 0; i < nlocal; ++i) { + auto ptr = array_atom[i]; + ptr[0] = reaxff->api->workspace->total_bond_order[i]; + ptr[1] = reaxff->api->workspace->nlp[i]; + ptr[2] = bondcount[i]; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local data +------------------------------------------------------------------------- */ + +double ComputeReaxFFAtom::memory_usage() +{ + double bytes = (double)(nlocal*3) * sizeof(double); + bytes += (double)(nlocal) * sizeof(int); + if (store_bonds) { + bytes += (double)(2*nlocal*MAXREAXBOND) * sizeof(double); + bytes += (double)(nbonds*3) * sizeof(double); + } + return bytes; +} diff --git a/src/REAXFF/compute_reaxff_atom.h b/src/REAXFF/compute_reaxff_atom.h new file mode 100644 index 0000000000..1f9aaec1ae --- /dev/null +++ b/src/REAXFF/compute_reaxff_atom.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Richard Berger (LANL) +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(reaxff/atom,ComputeReaxFFAtom); +// clang-format on +#else + +#ifndef LMP_COMPUTE_REAXFF_ATOM_H +#define LMP_COMPUTE_REAXFF_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeReaxFFAtom : public Compute { + public: + ComputeReaxFFAtom(class LAMMPS *, int, char **); + ~ComputeReaxFFAtom() override; + void init() override; + void compute_local() override; + void compute_peratom() override; + virtual void compute_bonds(); + double memory_usage() override; + + protected: + bigint invoked_bonds; // last timestep on which compute_bonds() was invoked + int nlocal; + int nbonds; + int prev_nbonds; + int nsub; + bool store_bonds; + + tagint **neighid; + double **abo; + int *bondcount; + class PairReaxFF *reaxff; + + private: + int FindBond(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/REAXFF/fix_reaxff.cpp b/src/REAXFF/fix_reaxff.cpp index 06941cd8a0..bec16b5d04 100644 --- a/src/REAXFF/fix_reaxff.cpp +++ b/src/REAXFF/fix_reaxff.cpp @@ -19,7 +19,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. ------------------------------------------------------------------------- */ #include "fix_reaxff.h" diff --git a/src/REAXFF/reaxff_allocate.cpp b/src/REAXFF/reaxff_allocate.cpp index ce56668a01..06ebc20f30 100644 --- a/src/REAXFF/reaxff_allocate.cpp +++ b/src/REAXFF/reaxff_allocate.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_control.cpp b/src/REAXFF/reaxff_control.cpp index d914765f45..99e498b428 100644 --- a/src/REAXFF/reaxff_control.cpp +++ b/src/REAXFF/reaxff_control.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_ffield.cpp b/src/REAXFF/reaxff_ffield.cpp index d5761eb343..6ca8dc6256 100644 --- a/src/REAXFF/reaxff_ffield.cpp +++ b/src/REAXFF/reaxff_ffield.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38, 245-259 (2012). This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -30,6 +30,7 @@ #include "error.h" #include "memory.h" #include "text_file_reader.h" +#include "tokenizer.h" #include "utils.h" #include @@ -40,6 +41,8 @@ using LAMMPS_NS::utils::open_potential; using LAMMPS_NS::utils::getsyserror; using LAMMPS_NS::utils::uppercase; +using LAMMPS_NS::EOFException; +using LAMMPS_NS::ValueTokenizer; namespace ReaxFF { @@ -538,17 +541,20 @@ namespace ReaxFF { } } - // next line is number of hydrogen bond parameters - - values = reader.next_values(0); - n = values.next_int(); - ++lineno; + // next line is number of hydrogen bond parameters. that block may be missing for (i = 0; i < ntypes; ++i) for (j = 0; j < ntypes; ++j) for (k = 0; k < ntypes; ++k) hbp[i][j][k].r0_hb = -1.0; + auto thisline = reader.next_line(); + if (!thisline) throw EOFException("ReaxFF parameter file has no hydrogen bond parameters"); + + values = ValueTokenizer(thisline); + n = values.next_int(); + ++lineno; + for (i = 0; i < n; ++i) { values = reader.next_values(0); ++lineno; @@ -570,6 +576,8 @@ namespace ReaxFF { } memory->destroy(tor_flag); + } catch (EOFException &e) { + error->warning(FLERR, e.what()); } catch (std::exception &e) { error->one(FLERR,e.what()); } diff --git a/src/REAXFF/reaxff_forces.cpp b/src/REAXFF/reaxff_forces.cpp index a4edfeee5c..274799c30c 100644 --- a/src/REAXFF/reaxff_forces.cpp +++ b/src/REAXFF/reaxff_forces.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_hydrogen_bonds.cpp b/src/REAXFF/reaxff_hydrogen_bonds.cpp index 6a56675f19..0389db7832 100644 --- a/src/REAXFF/reaxff_hydrogen_bonds.cpp +++ b/src/REAXFF/reaxff_hydrogen_bonds.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_list.cpp b/src/REAXFF/reaxff_list.cpp index 0ff0852a04..2989f717d6 100644 --- a/src/REAXFF/reaxff_list.cpp +++ b/src/REAXFF/reaxff_list.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_lookup.cpp b/src/REAXFF/reaxff_lookup.cpp index c0e7bf2c54..d9ee471caf 100644 --- a/src/REAXFF/reaxff_lookup.cpp +++ b/src/REAXFF/reaxff_lookup.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_multi_body.cpp b/src/REAXFF/reaxff_multi_body.cpp index 2390b54474..855d82623f 100644 --- a/src/REAXFF/reaxff_multi_body.cpp +++ b/src/REAXFF/reaxff_multi_body.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_nonbonded.cpp b/src/REAXFF/reaxff_nonbonded.cpp index 75cbd79b29..e0a8d092b2 100644 --- a/src/REAXFF/reaxff_nonbonded.cpp +++ b/src/REAXFF/reaxff_nonbonded.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_reset_tools.cpp b/src/REAXFF/reaxff_reset_tools.cpp index bebb2e2cfc..9de917e142 100644 --- a/src/REAXFF/reaxff_reset_tools.cpp +++ b/src/REAXFF/reaxff_reset_tools.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_tool_box.cpp b/src/REAXFF/reaxff_tool_box.cpp index 22ef299b41..aa6f831e95 100644 --- a/src/REAXFF/reaxff_tool_box.cpp +++ b/src/REAXFF/reaxff_tool_box.cpp @@ -10,7 +10,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_torsion_angles.cpp b/src/REAXFF/reaxff_torsion_angles.cpp index e9b6bc618d..29233a56dc 100644 --- a/src/REAXFF/reaxff_torsion_angles.cpp +++ b/src/REAXFF/reaxff_torsion_angles.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/REAXFF/reaxff_valence_angles.cpp b/src/REAXFF/reaxff_valence_angles.cpp index ac3e2dbd1e..b46f09d23a 100644 --- a/src/REAXFF/reaxff_valence_angles.cpp +++ b/src/REAXFF/reaxff_valence_angles.cpp @@ -11,7 +11,7 @@ Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and - Algorithmic Techniques", Parallel Computing, in press. + Algorithmic Techniques", Parallel Computing, 38 (4-5), 245-259. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/RIGID/fix_rigid_nh_small.cpp b/src/RIGID/fix_rigid_nh_small.cpp index 952dc29032..3ee11e28d2 100644 --- a/src/RIGID/fix_rigid_nh_small.cpp +++ b/src/RIGID/fix_rigid_nh_small.cpp @@ -219,7 +219,6 @@ void FixRigidNHSmall::init() } } - int icompute; if (tcomputeflag) { temperature = modify->get_compute_by_id(id_temp); if (!temperature) diff --git a/src/YAFF/angle_mm3.cpp b/src/YAFF/angle_mm3.cpp index c75a0d8308..af199f6fe9 100644 --- a/src/YAFF/angle_mm3.cpp +++ b/src/YAFF/angle_mm3.cpp @@ -36,7 +36,10 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -AngleMM3::AngleMM3(LAMMPS *lmp) : Angle(lmp) {} +AngleMM3::AngleMM3(LAMMPS *lmp) : Angle(lmp) +{ + born_matrix_enable = 1; +} /* ---------------------------------------------------------------------- */ @@ -284,3 +287,43 @@ double AngleMM3::single(int type, int i1, int i2, int i3) return energy; } + +/* ---------------------------------------------------------------------- */ + +void AngleMM3::born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) +{ + double **x = atom->x; + + double delx1 = x[i1][0] - x[i2][0]; + double dely1 = x[i1][1] - x[i2][1]; + double delz1 = x[i1][2] - x[i2][2]; + domain->minimum_image(delx1,dely1,delz1); + double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); + + double delx2 = x[i3][0] - x[i2][0]; + double dely2 = x[i3][1] - x[i2][1]; + double delz2 = x[i3][2] - x[i2][2]; + domain->minimum_image(delx2,dely2,delz2); + double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); + + double c = delx1*delx2 + dely1*dely2 + delz1*delz2; + c /= r1*r2; + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + double theta = acos(c); + + double s = sqrt(1.0 - c*c); + if (s < SMALL) s = SMALL; + s = 1.0/s; + + double dtheta = theta - theta0[type]; + double dtheta2 = dtheta*dtheta; + double dtheta3 = dtheta2*dtheta; + double dtheta4 = dtheta3*dtheta; + double dtheta5 = dtheta4*dtheta; + double df = 2.0 * dtheta - 2.406423 * dtheta2 + 0.735348 * dtheta3 - 0.65832 * dtheta4 + 1.42254 * dtheta5; + double d2f = 2.0 - 4.812846 * dtheta + 2.206044 * dtheta2 - 2.63328 * dtheta3 + 7.1127 * dtheta4; + + du = -k2[type] * df / s; + du2 = k2[type] * (d2f - df * c / s) / (s * s) ; +} diff --git a/src/YAFF/angle_mm3.h b/src/YAFF/angle_mm3.h index 95009a9cf6..22f5bd746c 100644 --- a/src/YAFF/angle_mm3.h +++ b/src/YAFF/angle_mm3.h @@ -35,6 +35,7 @@ class AngleMM3 : public Angle { void read_restart(FILE *) override; void write_data(FILE *) override; double single(int, int, int, int) override; + void born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) override; protected: double *theta0, *k2; diff --git a/src/YAFF/bond_mm3.cpp b/src/YAFF/bond_mm3.cpp index a5ef6fb8bc..31ce2dad3e 100644 --- a/src/YAFF/bond_mm3.cpp +++ b/src/YAFF/bond_mm3.cpp @@ -31,7 +31,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -BondMM3::BondMM3(LAMMPS *lmp) : Bond(lmp) {} +BondMM3::BondMM3(LAMMPS *lmp) : Bond(lmp) +{ + born_matrix_enable = 1; +} /* ---------------------------------------------------------------------- */ @@ -219,3 +222,19 @@ double BondMM3::single(int type, double rsq, else fforce = 0.0; return k2[type]*dr2*(1.0+K3*dr+K4*dr2); } + +/* ---------------------------------------------------------------------- */ + +void BondMM3::born_matrix(int type, double rsq, int /*i*/, int /*j*/, double &du, double &du2) +{ + double r = sqrt(rsq); + double dr = r - r0[type]; + double dr2 = dr * dr; + double dr3 = dr2 * dr; + + double K3 = -2.55 * k2[type] /force->angstrom; + double K4 = 7.0 * k2[type] * 2.55 * 2.55 / (12.0 * force->angstrom * force->angstrom); + + du = 2.0 * k2[type] * dr + 3.0 * K3 * dr2 + 4.0 * K4 * dr3; + du2 = 2.0 * k2[type] + 6.0 * K3 * dr + 12.0 * K4 * dr2; +} diff --git a/src/YAFF/bond_mm3.h b/src/YAFF/bond_mm3.h index 302c4052d0..ea89ac826d 100644 --- a/src/YAFF/bond_mm3.h +++ b/src/YAFF/bond_mm3.h @@ -35,6 +35,7 @@ class BondMM3 : public Bond { void read_restart(FILE *) override; void write_data(FILE *) override; double single(int, double, int, int, double &) override; + void born_matrix(int, double, int, int, double &, double &) override; protected: double *r0, *k2; diff --git a/src/compute_pair.cpp b/src/compute_pair.cpp index 2788b632d2..e789adbc89 100644 --- a/src/compute_pair.cpp +++ b/src/compute_pair.cpp @@ -30,7 +30,7 @@ enum { EPAIR, EVDWL, ECOUL }; ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), pstyle(nullptr), pair(nullptr), one(nullptr) { - if (narg < 4) error->all(FLERR, "Illegal compute pair command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute pair", error); scalar_flag = 1; extscalar = 1; @@ -63,7 +63,7 @@ ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg], "ecoul") == 0) evalue = ECOUL; else - error->all(FLERR, "Illegal compute pair command"); + error->all(FLERR, "Unknown compute pair keyword {}", arg[iarg]); ++iarg; } @@ -75,7 +75,7 @@ ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) : pair = force->pair_match(pstyle, 1, nsub); } - if (!pair) error->all(FLERR, "Unrecognized pair style in compute pair command"); + if (!pair) error->all(FLERR, "Unrecognized pair style {} in compute pair command", pstyle); npair = pair->nextra; if (npair) { @@ -104,7 +104,7 @@ void ComputePair::init() // recheck for pair style in case it has been deleted pair = force->pair_match(pstyle, 1, nsub); - if (!pair) error->all(FLERR, "Unrecognized pair style in compute pair command"); + if (!pair) error->all(FLERR, "Unrecognized pair style {} in compute pair command", pstyle); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_balance.cpp b/src/fix_balance.cpp index 7174765f52..23a56c0a9d 100644 --- a/src/fix_balance.cpp +++ b/src/fix_balance.cpp @@ -83,7 +83,7 @@ FixBalance::FixBalance(LAMMPS *lmp, int narg, char **arg) : // error checks if (lbstyle == SHIFT) { - int blen = bstr.size(); + const int blen = bstr.size(); for (int i = 0; i < blen; i++) { if (bstr[i] != 'x' && bstr[i] != 'y' && bstr[i] != 'z') error->all(FLERR,"Fix balance shift string is invalid"); diff --git a/src/fix_halt.cpp b/src/fix_halt.cpp index fcfefe102d..b34c79867f 100644 --- a/src/fix_halt.cpp +++ b/src/fix_halt.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -31,49 +30,49 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{BONDMAX,TLIMIT,DISKFREE,VARIABLE}; -enum{LT,LE,GT,GE,EQ,NEQ,XOR}; -enum{HARD,SOFT,CONTINUE}; -enum{NOMSG=0,YESMSG=1}; +enum { BONDMAX, TLIMIT, DISKFREE, VARIABLE }; +enum { LT, LE, GT, GE, EQ, NEQ, XOR }; +enum { HARD, SOFT, CONTINUE }; +enum { NOMSG = 0, YESMSG = 1 }; /* ---------------------------------------------------------------------- */ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), idvar(nullptr), dlimit_path(nullptr) + Fix(lmp, narg, arg), idvar(nullptr), dlimit_path(nullptr) { - if (narg < 7) error->all(FLERR,"Illegal fix halt command"); - nevery = utils::inumeric(FLERR,arg[3],false,lmp); - if (nevery <= 0) error->all(FLERR,"Illegal fix halt command"); + if (narg < 7) utils::missing_cmd_args(FLERR, "fix halt", error); + nevery = utils::inumeric(FLERR, arg[3], false, lmp); + if (nevery <= 0) error->all(FLERR, "Illegal fix halt command: nevery must be > 0"); // comparison args idvar = nullptr; int iarg = 4; - if (strcmp(arg[iarg],"tlimit") == 0) { + if (strcmp(arg[iarg], "tlimit") == 0) { attribute = TLIMIT; - } else if (strcmp(arg[iarg],"diskfree") == 0) { + } else if (strcmp(arg[iarg], "diskfree") == 0) { attribute = DISKFREE; dlimit_path = utils::strdup("."); - } else if (strcmp(arg[iarg],"bondmax") == 0) { + } else if (strcmp(arg[iarg], "bondmax") == 0) { attribute = BONDMAX; } else { - ArgInfo argi(arg[iarg],ArgInfo::VARIABLE); + ArgInfo argi(arg[iarg], ArgInfo::VARIABLE); - if ((argi.get_type() == ArgInfo::UNKNOWN) - || (argi.get_type() == ArgInfo::NONE) - || (argi.get_dim() != 0)) - error->all(FLERR,"Invalid fix halt attribute"); + if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_type() == ArgInfo::NONE) || + (argi.get_dim() != 0)) + error->all(FLERR, "Invalid fix halt attribute {}", arg[iarg]); attribute = VARIABLE; idvar = argi.copy_name(); ivar = input->variable->find(idvar); - if (ivar < 0) error->all(FLERR,"Could not find fix halt variable name"); + if (ivar < 0) error->all(FLERR, "Could not find fix halt variable name"); if (input->variable->equalstyle(ivar) == 0) - error->all(FLERR,"Fix halt variable is not equal-style variable"); + error->all(FLERR, "Fix halt variable is not equal-style variable"); } + // clang-format off ++iarg; if (strcmp(arg[iarg],"<") == 0) operation = LT; else if (strcmp(arg[iarg],"<=") == 0) operation = LE; @@ -85,7 +84,7 @@ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) : else error->all(FLERR,"Invalid fix halt operator"); ++iarg; - value = utils::numeric(FLERR,arg[iarg],false,lmp); + value = utils::numeric(FLERR, arg[iarg], false, lmp); // parse optional args @@ -93,38 +92,40 @@ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) : msgflag = YESMSG; ++iarg; while (iarg < narg) { - if (strcmp(arg[iarg],"error") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix halt command"); - if (strcmp(arg[iarg+1],"hard") == 0) eflag = HARD; - else if (strcmp(arg[iarg+1],"soft") == 0) eflag = SOFT; - else if (strcmp(arg[iarg+1],"continue") == 0) eflag = CONTINUE; - else error->all(FLERR,"Illegal fix halt command"); + if (strcmp(arg[iarg], "error") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix halt error", error); + if (strcmp(arg[iarg + 1], "hard") == 0) eflag = HARD; + else if (strcmp(arg[iarg + 1], "soft") == 0) eflag = SOFT; + else if (strcmp(arg[iarg + 1], "continue") == 0) eflag = CONTINUE; + else error->all(FLERR, "Unknown fix halt error condition {}", arg[iarg]); iarg += 2; - } else if (strcmp(arg[iarg],"message") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix halt command"); - msgflag = utils::logical(FLERR,arg[iarg+1],false,lmp); + } else if (strcmp(arg[iarg], "message") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix halt message", error); + msgflag = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"path") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix halt command"); + } else if (strcmp(arg[iarg], "path") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix halt error", error); ++iarg; delete[] dlimit_path; // strip off outer quotes, if present - int len = strlen(arg[iarg])+1; - if ( ((arg[iarg][0] == '"') || (arg[iarg][0] == '\'')) - && (arg[iarg][0] == arg[iarg][len-2])) { - arg[iarg][len-2] = '\0'; - dlimit_path = utils::strdup(arg[iarg]+1); - } else dlimit_path = utils::strdup(arg[iarg]); + int len = strlen(arg[iarg]) + 1; + if (((arg[iarg][0] == '"') || (arg[iarg][0] == '\'')) && + (arg[iarg][0] == arg[iarg][len - 2])) { + arg[iarg][len - 2] = '\0'; + dlimit_path = utils::strdup(arg[iarg] + 1); + } else + dlimit_path = utils::strdup(arg[iarg]); ++iarg; - } else error->all(FLERR,"Illegal fix halt command"); + } else error->all(FLERR, "Unknown fix halt keyword {}", arg[iarg]); } + // clang-format on // add nfirst to all computes that store invocation times // since don't know a priori which are invoked via variables by this fix // once in end_of_step() can set timestep for ones actually invoked if (attribute == VARIABLE) { - const bigint nfirst = (update->ntimestep/nevery)*nevery + nevery; + const bigint nfirst = (update->ntimestep / nevery) * nevery + nevery; modify->addstep_compute_all(nfirst); } } @@ -133,8 +134,8 @@ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) : FixHalt::~FixHalt() { - delete [] idvar; - delete [] dlimit_path; + delete[] idvar; + delete[] dlimit_path; } /* ---------------------------------------------------------------------- */ @@ -156,22 +157,22 @@ void FixHalt::init() if (attribute == VARIABLE) { ivar = input->variable->find(idvar); - if (ivar < 0) error->all(FLERR,"Could not find fix halt variable name"); + if (ivar < 0) error->all(FLERR, "Could not find fix halt variable {}", idvar); if (input->variable->equalstyle(ivar) == 0) - error->all(FLERR,"Fix halt variable is not equal-style variable"); + error->all(FLERR, "Fix halt variable {} is not equal-style variable", idvar); } // settings used by TLIMIT - nextstep = (update->ntimestep/nevery)*nevery + nevery; + nextstep = (update->ntimestep / nevery) * nevery + nevery; thisstep = -1; tratio = 0.5; // check if disk limit is supported if (attribute == DISKFREE) { - if (diskfree() < 0.0) - error->all(FLERR,"Disk limit not supported by OS or illegal path"); + if (!dlimit_path || platform::disk_free(dlimit_path) < 0.0) + error->all(FLERR, "Disk limit not supported by OS or illegal path"); } } @@ -196,7 +197,7 @@ void FixHalt::end_of_step() if (update->ntimestep != nextstep) return; attvalue = tlimit(); } else if (attribute == DISKFREE) { - attvalue = diskfree(); + attvalue = platform::disk_free(dlimit_path) / 1048576.0; // MBytes } else if (attribute == BONDMAX) { attvalue = bondmax(); } else { @@ -205,6 +206,10 @@ void FixHalt::end_of_step() modify->addstep_compute(update->ntimestep + nevery); } + // ensure that the attribute is *exactly* the same on all ranks + + MPI_Bcast(&attvalue, 1, MPI_DOUBLE, 0, world); + // check if halt is triggered, else just return if (operation == LT) { @@ -220,21 +225,19 @@ void FixHalt::end_of_step() } else if (operation == NEQ) { if (attvalue == value) return; } else if (operation == XOR) { - if ((attvalue == 0.0 && value == 0.0) || - (attvalue != 0.0 && value != 0.0)) return; + if ((attvalue == 0.0 && value == 0.0) || (attvalue != 0.0 && value != 0.0)) return; } // hard halt -> exit LAMMPS // soft/continue halt -> trigger timer to break from run loop // print message with ID of fix halt in case multiple instances - std::string message = fmt::format("Fix halt condition for fix-id {} met on " - "step {} with value {}", + std::string message = fmt::format("Fix halt condition for fix-id {} met on step {} with value {}", id, update->ntimestep, attvalue); if (eflag == HARD) { - error->all(FLERR,message); - } else if (eflag == SOFT || eflag == CONTINUE) { - if (comm->me == 0 && msgflag == YESMSG) error->message(FLERR,message); + error->all(FLERR, message); + } else if ((eflag == SOFT) || (eflag == CONTINUE)) { + if ((comm->me == 0) && (msgflag == YESMSG)) error->message(FLERR, message); timer->force_timeout(); } } @@ -260,8 +263,8 @@ double FixHalt::bondmax() int **bondlist = neighbor->bondlist; int nbondlist = neighbor->nbondlist; - int i1,i2; - double delx,dely,delz,rsq; + int i1, i2; + double delx, dely, delz, rsq; double maxone = 0.0; for (int n = 0; n < nbondlist; n++) { @@ -272,12 +275,12 @@ double FixHalt::bondmax() dely = x[i1][1] - x[i2][1]; delz = x[i1][2] - x[i2][2]; - rsq = delx*delx + dely*dely + delz*delz; - maxone = MAX(rsq,maxone); + rsq = delx * delx + dely * dely + delz * delz; + maxone = MAX(rsq, maxone); } double maxall; - MPI_Allreduce(&maxone,&maxall,1,MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&maxone, &maxall, 1, MPI_DOUBLE, MPI_MAX, world); return sqrt(maxall); } @@ -291,48 +294,15 @@ double FixHalt::bondmax() double FixHalt::tlimit() { double cpu = timer->elapsed(Timer::TOTAL); - MPI_Bcast(&cpu,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cpu, 1, MPI_DOUBLE, 0, world); if (cpu < value) { bigint elapsed = update->ntimestep - update->firststep; - bigint final = update->firststep + - static_cast (tratio*value/cpu * elapsed); - nextstep = (final/nevery)*nevery + nevery; + bigint final = update->firststep + static_cast(tratio * value / cpu * elapsed); + nextstep = (final / nevery) * nevery + nevery; if (nextstep == update->ntimestep) nextstep += nevery; tratio = 1.0; } return cpu; } - -/* ---------------------------------------------------------------------- - determine available disk space, if supported. Return -1 if not. -------------------------------------------------------------------------- */ -#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) -#include -#endif -double FixHalt::diskfree() -{ -#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct statvfs fs; - double disk_free = -1.0; - - if (dlimit_path) { - disk_free = 1.0e100; - int rv = statvfs(dlimit_path,&fs); - if (rv == 0) { -#if defined(__linux__) - disk_free = fs.f_bavail*fs.f_bsize/1048576.0; -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) - disk_free = fs.f_bavail*fs.f_frsize/1048576.0; -#endif - } else - disk_free = -1.0; - - MPI_Bcast(&disk_free,1,MPI_DOUBLE,0,world); - } - return disk_free; -#else - return -1.0; -#endif -} diff --git a/src/fix_temp_berendsen.h b/src/fix_temp_berendsen.h index 78ece2af22..f137830508 100644 --- a/src/fix_temp_berendsen.h +++ b/src/fix_temp_berendsen.h @@ -38,7 +38,7 @@ class FixTempBerendsen : public Fix { void restart(char *buf) override; void *extract(const char *, int &) override; - private: + protected: int which; double t_start, t_stop, t_period, t_target; double energy; diff --git a/src/grid2d.cpp b/src/grid2d.cpp index 74fd105ec0..d39b7b4a78 100644 --- a/src/grid2d.cpp +++ b/src/grid2d.cpp @@ -114,7 +114,7 @@ Grid2d::Grid2d(LAMMPS *lmp, MPI_Comm gcomm, int gnx, int gny, int ixlo, int ixhi // additional intialization // other constructor invokes this from setup_grid() - initialize(); + Grid2d::initialize(); } /* ---------------------------------------------------------------------- */ @@ -522,7 +522,7 @@ void Grid2d::ghost_grid() // also ensure no other procs use ghost cells beyond +y limit if (yextra) { - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { if (comm->myloc[1] == comm->procgrid[1]-1) inyhi = outyhi = ny - 1; } else { if (comm->mysplit[1][1] == 1.0) inyhi = outyhi = ny - 1; @@ -553,15 +553,13 @@ void Grid2d::ghost_grid() void Grid2d::extract_comm_info() { - layout = comm->layout; - // for non TILED layout: // proc xyz lohi = my 4 neighbor procs in this MPI_Comm // these proc IDs can be overridden by caller using set_proc_neighs() // xyz split = copy of 1d vectors in Comm // grid2proc = copy of 3d array in Comm - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { procxlo = comm->procneigh[0][0]; procxhi = comm->procneigh[0][1]; procylo = comm->procneigh[1][0]; @@ -585,7 +583,7 @@ void Grid2d::extract_comm_info() // RCBinfo.cut = this proc's inlo in that dim // Allgather creates the tree of dims and cuts - if (layout == Comm::LAYOUT_TILED) { + if (comm->layout == Comm::LAYOUT_TILED) { rcbinfo = (RCBinfo *) memory->smalloc(nprocs*sizeof(RCBinfo),"grid3d:rcbinfo"); RCBinfo rcbone; @@ -615,7 +613,7 @@ void Grid2d::extract_comm_info() void Grid2d::setup_comm(int &nbuf1, int &nbuf2) { - if (layout != Comm::LAYOUT_TILED) setup_comm_brick(nbuf1,nbuf2); + if (comm->layout != Comm::LAYOUT_TILED) setup_comm_brick(nbuf1,nbuf2); else setup_comm_tiled(nbuf1,nbuf2); } @@ -1039,7 +1037,7 @@ void Grid2d::setup_comm_tiled(int &nbuf1, int &nbuf2) int Grid2d::ghost_adjacent() { - if (layout != Comm::LAYOUT_TILED) return ghost_adjacent_brick(); + if (comm->layout != Comm::LAYOUT_TILED) return ghost_adjacent_brick(); return ghost_adjacent_tiled(); } @@ -1085,7 +1083,7 @@ int Grid2d::ghost_adjacent_tiled() void Grid2d::forward_comm(int caller, void *ptr, int which, int nper, int nbyte, void *buf1, void *buf2, MPI_Datatype datatype) { - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { if (caller == KSPACE) forward_comm_brick((KSpace *) ptr,which,nper,nbyte, buf1,buf2,datatype); @@ -1190,7 +1188,7 @@ forward_comm_tiled(T *ptr, int which, int nper, int nbyte, void Grid2d::reverse_comm(int caller, void *ptr, int which, int nper, int nbyte, void *buf1, void *buf2, MPI_Datatype datatype) { - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { if (caller == KSPACE) reverse_comm_brick((KSpace *) ptr,which,nper,nbyte, buf1,buf2,datatype); @@ -1314,10 +1312,6 @@ void Grid2d::setup_remap(Grid2d *old, int &nremap_buf1, int &nremap_buf2) deallocate_remap(); - // set layout to current Comm layout - - layout = comm->layout; - // overlaps of my old decomp owned box with all owned boxes in new decomp // noverlap_old = # of overlaps, including self // overlap_old = vector of overlap info in Overlap data struct @@ -1654,7 +1648,7 @@ int Grid2d::compute_overlap(int ghostflag, int *box, int *pbc, Overlap *&overlap // test obox against appropriate layout - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { // find comm->procgrid indices in each dim for box bounds diff --git a/src/grid2d.h b/src/grid2d.h index 43316baad8..8316f840be 100644 --- a/src/grid2d.h +++ b/src/grid2d.h @@ -55,7 +55,6 @@ class Grid2d : protected Pointers { protected: int me, nprocs; - int layout; // not TILED or TILED, same as Comm class MPI_Comm gridcomm; // communicator for this class // usually world, but MSM calls with subset diff --git a/src/grid3d.cpp b/src/grid3d.cpp index c6cff3f317..6ca8f7895c 100644 --- a/src/grid3d.cpp +++ b/src/grid3d.cpp @@ -123,7 +123,7 @@ Grid3d::Grid3d(LAMMPS *lmp, MPI_Comm gcomm, int gnx, int gny, int gnz, // additional intialization // other constructor invokes this from setup_grid() - initialize(); + Grid3d::initialize(); } /* ---------------------------------------------------------------------- */ @@ -577,7 +577,7 @@ void Grid3d::ghost_grid() // also ensure no other procs use ghost cells beyond +z limit if (zextra) { - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { if (comm->myloc[2] == comm->procgrid[2]-1) inzhi = outzhi = nz - 1; } else { if (comm->mysplit[2][1] == 1.0) inzhi = outzhi = nz - 1; @@ -613,15 +613,13 @@ void Grid3d::ghost_grid() void Grid3d::extract_comm_info() { - layout = comm->layout; - // for non TILED layout: // proc xyz lohi = my 6 neighbor procs in this MPI_Comm // these proc IDs can be overridden by caller using set_proc_neighs() // xyz split = copy of 1d vectors in Comm // grid2proc = copy of 3d array in Comm - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { procxlo = comm->procneigh[0][0]; procxhi = comm->procneigh[0][1]; procylo = comm->procneigh[1][0]; @@ -649,7 +647,7 @@ void Grid3d::extract_comm_info() // RCBinfo.cut = this proc's inlo in that dim // Allgather creates the tree of dims and cuts - if (layout == Comm::LAYOUT_TILED) { + if (comm->layout == Comm::LAYOUT_TILED) { rcbinfo = (RCBinfo *) memory->smalloc(nprocs*sizeof(RCBinfo),"grid3d:rcbinfo"); RCBinfo rcbone; @@ -680,7 +678,7 @@ void Grid3d::extract_comm_info() void Grid3d::setup_comm(int &nbuf1, int &nbuf2) { - if (layout != Comm::LAYOUT_TILED) setup_comm_brick(nbuf1,nbuf2); + if (comm->layout != Comm::LAYOUT_TILED) setup_comm_brick(nbuf1,nbuf2); else setup_comm_tiled(nbuf1,nbuf2); } @@ -1207,7 +1205,7 @@ void Grid3d::setup_comm_tiled(int &nbuf1, int &nbuf2) int Grid3d::ghost_adjacent() { - if (layout != Comm::LAYOUT_TILED) return ghost_adjacent_brick(); + if (comm->layout != Comm::LAYOUT_TILED) return ghost_adjacent_brick(); return ghost_adjacent_tiled(); } @@ -1255,7 +1253,7 @@ int Grid3d::ghost_adjacent_tiled() void Grid3d::forward_comm(int caller, void *ptr, int which, int nper, int nbyte, void *buf1, void *buf2, MPI_Datatype datatype) { - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { if (caller == KSPACE) forward_comm_brick((KSpace *) ptr,which,nper,nbyte, buf1,buf2,datatype); @@ -1360,7 +1358,7 @@ forward_comm_tiled(T *ptr, int which, int nper, int nbyte, void Grid3d::reverse_comm(int caller, void *ptr, int which, int nper, int nbyte, void *buf1, void *buf2, MPI_Datatype datatype) { - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { if (caller == KSPACE) reverse_comm_brick((KSpace *) ptr,which,nper,nbyte, buf1,buf2,datatype); @@ -1484,10 +1482,6 @@ void Grid3d::setup_remap(Grid3d *old, int &nremap_buf1, int &nremap_buf2) deallocate_remap(); - // set layout to current Comm layout - - layout = comm->layout; - // overlaps of my old decomp owned box with all owned boxes in new decomp // noverlap_old = # of overlaps, including self // overlap_old = vector of overlap info in Overlap data struct @@ -1829,7 +1823,7 @@ int Grid3d::compute_overlap(int ghostflag, int *box, int *pbc, Overlap *&overlap return noverlap_list; } - if (layout != Comm::LAYOUT_TILED) { + if (comm->layout != Comm::LAYOUT_TILED) { // find comm->procgrid indices in each dim for box bounds diff --git a/src/grid3d.h b/src/grid3d.h index e4a8e276f5..6a15c2c942 100644 --- a/src/grid3d.h +++ b/src/grid3d.h @@ -57,7 +57,6 @@ class Grid3d : protected Pointers { protected: int me, nprocs; - int layout; // not TILED or TILED, same as Comm class MPI_Comm gridcomm; // communicator for this class // usually world, but MSM calls with subset diff --git a/src/library.cpp b/src/library.cpp index 1acdfc4787..a629df7b8c 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -709,7 +709,7 @@ void lammps_commands_string(void *handle, const char *str) break; } - lmp->input->one(cmd.c_str()); + lmp->input->one(cmd); } } } diff --git a/src/neighbor.cpp b/src/neighbor.cpp index ad509dce7b..c6c959a894 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1791,16 +1791,17 @@ void Neighbor::print_pairwise_info() out += fmt::format(", trim from ({})",rq->copylist+1); else out += fmt::format(", copy from ({})",rq->copylist+1); - } else if (rq->halffull) + } else if (rq->halffull) { if (rq->trim) out += fmt::format(", half/full trim from ({})",rq->halffulllist+1); else out += fmt::format(", half/full from ({})",rq->halffulllist+1); - else if (rq->skip) + } else if (rq->skip) { if (rq->trim) out += fmt::format(", skip trim from ({})",rq->skiplist+1); else out += fmt::format(", skip from ({})",rq->skiplist+1); + } out += "\n"; // list of neigh list attributes @@ -2015,6 +2016,7 @@ int Neighbor::choose_stencil(NeighRequest *rq) // require match of these request flags and mask bits // (!A != !B) is effectively a logical xor + if (!rq->intel != !(mask & NS_INTEL)) continue; if (!rq->ghost != !(mask & NS_GHOST)) continue; if (!rq->ssa != !(mask & NS_SSA)) continue; diff --git a/src/neighbor.h b/src/neighbor.h index ed99ae0af1..4807e90393 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -301,8 +301,9 @@ namespace NeighConst { NS_ORTHO = 1 << 6, NS_TRI = 1 << 7, NS_GHOST = 1 << 8, - NS_SSA = 1 << 9, - NS_MULTI_OLD = 1 << 10 + NS_INTEL = 1 << 9, + NS_SSA = 1 << 10, + NS_MULTI_OLD = 1 << 11 }; enum { diff --git a/src/npair.cpp b/src/npair.cpp index c1615411c0..9af7767912 100644 --- a/src/npair.cpp +++ b/src/npair.cpp @@ -174,6 +174,9 @@ void NPair::copy_stencil_info() nstencil_multi = ns->nstencil_multi; stencil_multi = ns->stencil_multi; + + flag_half_multi = ns->flag_half_multi; + flag_same_multi = ns->flag_same_multi; } /* ---------------------------------------------------------------------- diff --git a/src/npair.h b/src/npair.h index 3eeb1d48f4..4abc7aabef 100644 --- a/src/npair.h +++ b/src/npair.h @@ -96,6 +96,8 @@ class NPair : protected Pointers { int *nstencil_multi_old; int **stencil_multi_old; double **distsq_multi_old; + bool **flag_half_multi; + bool **flag_same_multi; int **nstencil_multi; int ***stencil_multi; diff --git a/src/npair_bin.cpp b/src/npair_bin.cpp new file mode 100644 index 0000000000..d3d3415bc0 --- /dev/null +++ b/src/npair_bin.cpp @@ -0,0 +1,270 @@ +/* ---------------------------------------------------------------------- + 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 "npair_bin.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairBin::NPairBin(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairBin::build(NeighList *list) +{ + int i, j, jh, k, n, itype, jtype, ibin, bin_start, which, imol, iatom, moltemplate; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum,cut,cutsq; + int *neighptr; + + const double delta = 0.01 * force->angstrom; + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (!ATOMONLY) { + if (molecular == Atom::TEMPLATE) + moltemplate = 1; + else + moltemplate = 0; + } + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (!ATOMONLY) { + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + } + + ibin = atom2bin[i]; + + for (k = 0; k < nstencil; k++) { + bin_start = binhead[ibin + stencil[k]]; + if (HALF && NEWTON && (!TRI)) { + if (k == 0) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = bin_start; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // for triclinic, bin stencil is full in all 3 dims + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil, except for i's bin + + if (k == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (ATOMONLY) { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < (radsum * radsum)) + jh = jh ^ mask_history; + neighptr[n++] = jh; + } + } else { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < (radsum * radsum)) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } + } else { + if (ATOMONLY) { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + if (!HALF) list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairBin<0,1,0,0,0>; +template class NPairBin<1,0,0,0,0>; +template class NPairBin<1,1,0,0,0>; +template class NPairBin<1,1,1,0,0>; +template class NPairBin<0,1,0,1,0>; +template class NPairBin<1,0,0,1,0>; +template class NPairBin<1,1,0,1,0>; +template class NPairBin<1,1,1,1,0>; +template class NPairBin<0,1,0,0,1>; +template class NPairBin<1,0,0,0,1>; +template class NPairBin<1,1,0,0,1>; +template class NPairBin<1,1,1,0,1>; +template class NPairBin<0,1,0,1,1>; +template class NPairBin<1,0,0,1,1>; +template class NPairBin<1,1,0,1,1>; +template class NPairBin<1,1,1,1,1>; +} diff --git a/src/npair_bin.h b/src/npair_bin.h new file mode 100644 index 0000000000..94b7c7077e --- /dev/null +++ b/src/npair_bin.h @@ -0,0 +1,119 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairBin<0, 1, 0, 0, 0> NPairFullBin; +NPairStyle(full/bin, + NPairFullBin, + NP_FULL | NP_BIN | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 0, 0, 0, 0> NPairHalfBinNewtoff; +NPairStyle(half/bin/newtoff, + NPairHalfBinNewtoff, + NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 1, 0, 0, 0> NPairHalfBinNewton; +NPairStyle(half/bin/newton, + NPairHalfBinNewton, + NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBin<1, 1, 1, 0, 0> NPairHalfBinNewtonTri; +NPairStyle(half/bin/newton/tri, + NPairHalfBinNewtonTri, + NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairBin<0, 1, 0, 1, 0> NPairFullSizeBin; +NPairStyle(full/size/bin, + NPairFullSizeBin, + NP_FULL | NP_SIZE | NP_BIN | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 0, 0, 1, 0> NPairHalfSizeBinNewtoff; +NPairStyle(half/size/bin/newtoff, + NPairHalfSizeBinNewtoff, + NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 1, 0, 1, 0> NPairHalfSizeBinNewton; +NPairStyle(half/size/bin/newton, + NPairHalfSizeBinNewton, + NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBin<1, 1, 1, 1, 0> NPairHalfSizeBinNewtonTri; +NPairStyle(half/size/bin/newton/tri, + NPairHalfSizeBinNewtonTri, + NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairBin<0, 1, 0, 0, 1> NPairFullBinAtomonly; +NPairStyle(full/bin/atomonly, + NPairFullBinAtomonly, + NP_FULL | NP_BIN | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 0, 0, 0, 1> NPairHalfBinAtomonlyNewtoff; +NPairStyle(half/bin/atomonly/newtoff, + NPairHalfBinAtomonlyNewtoff, + NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 1, 0, 0, 1> NPairHalfBinAtomonlyNewton; +NPairStyle(half/bin/atomonly/newton, + NPairHalfBinAtomonlyNewton, + NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBin<1, 1, 1, 0, 1> NPairHalfBinAtomonlyNewtonTri; +NPairStyle(half/bin/atomonly/newton/tri, + NPairHalfBinAtomonlyNewtonTri, + NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_TRI); + +typedef NPairBin<0, 1, 0, 1, 1> NPairFullSizeBinAtomonly; +NPairStyle(full/size/bin/atomonly, + NPairFullSizeBinAtomonly, + NP_FULL | NP_SIZE | NP_BIN | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 0, 0, 1, 1> NPairHalfSizeBinAtomonlyNewtoff; +NPairStyle(half/size/bin/atomonly/newtoff, + NPairHalfSizeBinAtomonlyNewtoff, + NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 1, 0, 1, 1> NPairHalfSizeBinAtomonlyNewton; +NPairStyle(half/size/bin/atomonly/newton, + NPairHalfSizeBinAtomonlyNewton, + NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBin<1, 1, 1, 1, 1> NPairHalfSizeBinAtomonlyNewtonTri; +NPairStyle(half/size/bin/atomonly/newton/tri, + NPairHalfSizeBinAtomonlyNewtonTri, + NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_BIN_H +#define LMP_NPAIR_BIN_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairBin : public NPair { + public: + NPairBin(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/npair_full_bin_ghost.cpp b/src/npair_bin_ghost.cpp similarity index 51% rename from src/npair_full_bin_ghost.cpp rename to src/npair_bin_ghost.cpp index fc2f325c48..8403bc8f3d 100644 --- a/src/npair_full_bin_ghost.cpp +++ b/src/npair_bin_ghost.cpp @@ -12,33 +12,46 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "npair_full_bin_ghost.h" -#include "neigh_list.h" +#include "npair_bin_ghost.h" + #include "atom.h" #include "atom_vec.h" -#include "molecule.h" #include "domain.h" -#include "my_page.h" #include "error.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" +#include "neighbor.h" using namespace LAMMPS_NS; +using namespace NeighConst; /* ---------------------------------------------------------------------- */ -NPairFullBinGhost::NPairFullBinGhost(LAMMPS *lmp) : NPair(lmp) {} +template +NPairBinGhost::NPairBinGhost(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - include neighbors of ghost atoms, but no "special neighbors" for ghosts - every neighbor pair appears in list of both atoms i and j + Full: + binned neighbor list construction for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + include neighbors of ghost atoms, but no "special neighbors" for ghosts + owned and ghost atoms check own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if i owned and j ghost (also stored by proc owning j) + pair stored once if i,j are both ghost and i < j ------------------------------------------------------------------------- */ -void NPairFullBinGhost::build(NeighList *list) +template +void NPairBinGhost::build(NeighList *list) { - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + int i, j, k, n, itype, jtype, ibin, bin_start, which, imol, iatom, moltemplate; tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int xbin, ybin, zbin, xbin2, ybin2, zbin2; int *neighptr; double **x = atom->x; @@ -50,12 +63,15 @@ void NPairFullBinGhost::build(NeighList *list) int **nspecial = atom->nspecial; int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; + if (includegroup) nlocal = atom->nfirst; int *molindex = atom->molindex; int *molatom = atom->molatom; Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; + if (molecular == Atom::TEMPLATE) + moltemplate = 1; + else + moltemplate = 0; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -66,7 +82,6 @@ void NPairFullBinGhost::build(NeighList *list) ipage->reset(); // loop over owned & ghost atoms, storing neighbors - for (i = 0; i < nall; i++) { n = 0; neighptr = ipage->vget(); @@ -81,45 +96,58 @@ void NPairFullBinGhost::build(NeighList *list) tagprev = tag[i] - iatom - 1; } - // loop over all atoms in surrounding bins in stencil including self - // when i is a ghost atom, must check if stencil bin is out of bounds - // skip i = j - // no molecular test when i = ghost atom - if (i < nlocal) { ibin = atom2bin[i]; + + // loop over all atoms in surrounding bins in stencil including self + // when i is a ghost atom, must check if stencil bin is out of bounds + // no molecular test when i = ghost atom for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; + bin_start = binhead[ibin + stencil[k]]; + for (j = bin_start; j >= 0; j = bins[j]) { + if (HALF) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + // stores ghost/ghost pairs only once + if (j <= i) continue; + } else { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); + which = find_special(special[i], nspecial[i], tag[j]); else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; } } } - } else { - ibin = coord2bin(x[i],xbin,ybin,zbin); + ibin = coord2bin(x[i], xbin, ybin, zbin); for (k = 0; k < nstencil; k++) { xbin2 = xbin + stencilxyz[k][0]; ybin2 = ybin + stencilxyz[k][1]; @@ -127,16 +155,20 @@ void NPairFullBinGhost::build(NeighList *list) if (xbin2 < 0 || xbin2 >= mbinx || ybin2 < 0 || ybin2 >= mbiny || zbin2 < 0 || zbin2 >= mbinz) continue; - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; + for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { + if (HALF) { + if (j <= i) continue; + } else { + if (i == j) continue; + } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; } @@ -147,10 +179,14 @@ void NPairFullBinGhost::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } list->inum = atom->nlocal; list->gnum = inum - atom->nlocal; } + +namespace LAMMPS_NS { +template class NPairBinGhost<0>; +template class NPairBinGhost<1>; +} diff --git a/src/npair_half_bin_newtoff_ghost.h b/src/npair_bin_ghost.h similarity index 66% rename from src/npair_half_bin_newtoff_ghost.h rename to src/npair_bin_ghost.h index c581ba86fe..f6cbcf2851 100644 --- a/src/npair_half_bin_newtoff_ghost.h +++ b/src/npair_bin_ghost.h @@ -13,22 +13,29 @@ #ifdef NPAIR_CLASS // clang-format off -NPairStyle(half/bin/newtoff/ghost, - NPairHalfBinNewtoffGhost, +typedef NPairBinGhost<0> NPairFullBinGhost; +NPairStyle(full/bin/ghost, + NPairFullBinGhost, + NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); + +typedef NPairBinGhost<1> NPairHalfBinGhostNewtoff; +NPairStyle(half/bin/ghost/newtoff, + NPairHalfBinGhostNewtoff, NP_HALF | NP_BIN | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_H -#define LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_H +#ifndef LMP_NPAIR_BIN_GHOST_H +#define LMP_NPAIR_BIN_GHOST_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfBinNewtoffGhost : public NPair { +template +class NPairBinGhost : public NPair { public: - NPairHalfBinNewtoffGhost(class LAMMPS *); + NPairBinGhost(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_full_bin.cpp b/src/npair_full_bin.cpp deleted file mode 100644 index 47e0943221..0000000000 --- a/src/npair_full_bin.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_full_bin.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullBin::NPairFullBin(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullBin::build(NeighList *list) -{ - int i, j, k, n, itype, jtype, ibin, which, imol, iatom, moltemplate; - tagint tagprev; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) - moltemplate = 1; - else - moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; - - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) { - which = find_special(special[i], nspecial[i], tag[j]); - } else if (imol >= 0) { - const auto mol = onemols[imol]; - which = find_special(mol->special[iatom], mol->nspecial[iatom], tag[j] - tagprev); - } else { - which = 0; - } - if (which == 0) - neighptr[n++] = j; - else if (domain->minimum_image_check(delx, dely, delz)) - neighptr[n++] = j; - else if (which > 0) - neighptr[n++] = j ^ (which << SBBITS); - } else - neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} diff --git a/src/npair_full_bin.h b/src/npair_full_bin.h deleted file mode 100644 index 7ee37c8ec5..0000000000 --- a/src/npair_full_bin.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/bin, - NPairFullBin, - NP_FULL | NP_BIN | NP_MOLONLY | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_BIN_H -#define LMP_NPAIR_FULL_BIN_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullBin : public NPair { - public: - NPairFullBin(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_full_bin_atomonly.cpp b/src/npair_full_bin_atomonly.cpp deleted file mode 100644 index 825b25fe56..0000000000 --- a/src/npair_full_bin_atomonly.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_full_bin_atomonly.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullBinAtomonly::NPairFullBinAtomonly(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullBinAtomonly::build(NeighList *list) -{ - int i, j, k, n, itype, jtype, ibin; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { - if (i == j) continue; - - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} diff --git a/src/npair_full_bin_atomonly.h b/src/npair_full_bin_atomonly.h deleted file mode 100644 index b30d0433e0..0000000000 --- a/src/npair_full_bin_atomonly.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/bin/atomonly, - NPairFullBinAtomonly, - NP_FULL | NP_BIN | NP_ATOMONLY | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_BIN_ATOMONLY_H -#define LMP_NPAIR_FULL_BIN_ATOMONLY_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullBinAtomonly : public NPair { - public: - NPairFullBinAtomonly(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_full_bin_ghost.h b/src/npair_full_bin_ghost.h deleted file mode 100644 index 7fedb1e0c5..0000000000 --- a/src/npair_full_bin_ghost.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/bin/ghost, - NPairFullBinGhost, - NP_FULL | NP_BIN | NP_GHOST | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_BIN_GHOST_H -#define LMP_NPAIR_FULL_BIN_GHOST_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullBinGhost : public NPair { - public: - NPairFullBinGhost(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_full_multi.cpp b/src/npair_full_multi.cpp deleted file mode 100644 index 5df1c5b200..0000000000 --- a/src/npair_full_multi.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_full_multi.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullMulti::NPairFullMulti(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - multi stencil is icollection-jcollection dependent - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullMulti::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - // use full stencil for all collection combinations - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (i == j) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} diff --git a/src/npair_full_multi.h b/src/npair_full_multi.h deleted file mode 100644 index c3c707a91d..0000000000 --- a/src/npair_full_multi.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/multi, - NPairFullMulti, - NP_FULL | NP_MULTI | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_MULTI_H -#define LMP_NPAIR_FULL_MULTI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullMulti : public NPair { - public: - NPairFullMulti(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_full_multi_old.cpp b/src/npair_full_multi_old.cpp deleted file mode 100644 index 2d529627f2..0000000000 --- a/src/npair_full_multi_old.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_full_multi_old.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullMultiOld::NPairFullMultiOld(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - multi-type stencil is itype dependent and is distance checked - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullMultiOld::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil, including self - // skip if i,j neighbor cutoff is less than bin distance - // skip i = j - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - if (i == j) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} diff --git a/src/npair_full_nsq.cpp b/src/npair_full_nsq.cpp deleted file mode 100644 index c4ae539622..0000000000 --- a/src/npair_full_nsq.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_full_nsq.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "group.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullNsq::NPairFullNsq(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 search for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullNsq::build(NeighList *list) -{ - int i, j, n, itype, jtype, which, bitmask, imol, iatom, moltemplate; - tagint tagprev; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) - moltemplate = 1; - else - moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms, owned and ghost - // skip i = j - - for (j = 0; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) { - which = find_special(special[i], nspecial[i], tag[j]); - } else if (imol >= 0) { - const auto mol = onemols[imol]; - which = find_special(mol->special[iatom], mol->nspecial[iatom], tag[j] - tagprev); - } else { - which = 0; - } - - if (which == 0) - neighptr[n++] = j; - else if (domain->minimum_image_check(delx, dely, delz)) - neighptr[n++] = j; - else if (which > 0) - neighptr[n++] = j ^ (which << SBBITS); - } else - neighptr[n++] = j; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} diff --git a/src/npair_full_nsq.h b/src/npair_full_nsq.h deleted file mode 100644 index 0f6665826d..0000000000 --- a/src/npair_full_nsq.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/nsq, - NPairFullNsq, - NP_FULL | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_NSQ_H -#define LMP_NPAIR_FULL_NSQ_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullNsq : public NPair { - public: - NPairFullNsq(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_full_nsq_ghost.cpp b/src/npair_full_nsq_ghost.cpp deleted file mode 100644 index 1ea118bc85..0000000000 --- a/src/npair_full_nsq_ghost.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_full_nsq_ghost.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairFullNsqGhost::NPairFullNsqGhost(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 search for all neighbors - include neighbors of ghost atoms, but no "special neighbors" for ghosts - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void NPairFullNsqGhost::build(NeighList *list) -{ - int i,j,n,itype,jtype,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = 0; i < nall; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms, owned and ghost - // skip i = j - // no molecular test when i = ghost atom - - if (i < nlocal) { - for (j = 0; j < nall; j++) { - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } else { - for (j = 0; j < nall; j++) { - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = atom->nlocal; - list->gnum = inum - atom->nlocal; -} diff --git a/src/npair_full_nsq_ghost.h b/src/npair_full_nsq_ghost.h deleted file mode 100644 index 0e26d8c5df..0000000000 --- a/src/npair_full_nsq_ghost.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(full/nsq/ghost, - NPairFullNsqGhost, - NP_FULL | NP_NSQ | NP_GHOST | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_FULL_NSQ_GHOST_H -#define LMP_NPAIR_FULL_NSQ_GHOST_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairFullNsqGhost : public NPair { - public: - NPairFullNsqGhost(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_bin_atomonly_newton.cpp b/src/npair_half_bin_atomonly_newton.cpp deleted file mode 100644 index 316d7731fc..0000000000 --- a/src/npair_half_bin_atomonly_newton.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_half_bin_atomonly_newton.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinAtomonlyNewton::NPairHalfBinAtomonlyNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinAtomonlyNewton::build(NeighList *list) -{ - int i, j, k, n, itype, jtype, ibin; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_bin_newtoff.cpp b/src/npair_half_bin_newtoff.cpp deleted file mode 100644 index 09d3e2a682..0000000000 --- a/src/npair_half_bin_newtoff.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_half_bin_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtoff::NPairHalfBinNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtoff::build(NeighList *list) -{ - int i, j, k, n, itype, jtype, ibin, which, imol, iatom, moltemplate; - tagint tagprev; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) - moltemplate = 1; - else - moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i], nspecial[i], tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], - tag[j] - tagprev); - else - which = 0; - if (which == 0) - neighptr[n++] = j; - else if (domain->minimum_image_check(delx, dely, delz)) - neighptr[n++] = j; - else if (which > 0) - neighptr[n++] = j ^ (which << SBBITS); - // OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else - neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - list->inum = inum; -} diff --git a/src/npair_half_bin_newtoff.h b/src/npair_half_bin_newtoff.h deleted file mode 100644 index ce551b1b95..0000000000 --- a/src/npair_half_bin_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newtoff, - NPairHalfBinNewtoff, - NP_HALF | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_H -#define LMP_NPAIR_HALF_BIN_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewtoff : public NPair { - public: - NPairHalfBinNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_bin_newtoff_ghost.cpp b/src/npair_half_bin_newtoff_ghost.cpp deleted file mode 100644 index 6672e8fd5b..0000000000 --- a/src/npair_half_bin_newtoff_ghost.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_bin_newtoff_ghost.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtoffGhost::NPairHalfBinNewtoffGhost(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - include neighbors of ghost atoms, but no "special neighbors" for ghosts - owned and ghost atoms check own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if i owned and j ghost (also stored by proc owning j) - pair stored once if i,j are both ghost and i < j -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtoffGhost::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nall; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // when i is a ghost atom, must check if stencil bin is out of bounds - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs with owned atom only, on both procs - // stores ghost/ghost pairs only once - // no molecular test when i = ghost atom - - if (i < nlocal) { - ibin = atom2bin[i]; - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - } else { - ibin = coord2bin(x[i],xbin,ybin,zbin); - for (k = 0; k < nstencil; k++) { - xbin2 = xbin + stencilxyz[k][0]; - ybin2 = ybin + stencilxyz[k][1]; - zbin2 = zbin + stencilxyz[k][2]; - if (xbin2 < 0 || xbin2 >= mbinx || - ybin2 < 0 || ybin2 >= mbiny || - zbin2 < 0 || zbin2 >= mbinz) continue; - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = atom->nlocal; - list->gnum = inum - atom->nlocal; -} diff --git a/src/npair_half_bin_newton.cpp b/src/npair_half_bin_newton.cpp deleted file mode 100644 index 201b1d2e27..0000000000 --- a/src/npair_half_bin_newton.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_bin_newton.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewton::NPairHalfBinNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinNewton::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - // OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - // OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_bin_newton.h b/src/npair_half_bin_newton.h deleted file mode 100644 index bbb4f825a0..0000000000 --- a/src/npair_half_bin_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newton, - NPairHalfBinNewton, - NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTON_H -#define LMP_NPAIR_HALF_BIN_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewton : public NPair { - public: - NPairHalfBinNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_bin_newton_tri.cpp b/src/npair_half_bin_newton_tri.cpp deleted file mode 100644 index d261363b0e..0000000000 --- a/src/npair_half_bin_newton_tri.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_bin_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfBinNewtonTri::NPairHalfBinNewtonTri(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfBinNewtonTri::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - const double delta = 0.01 * force->angstrom; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_bin_newton_tri.h b/src/npair_half_bin_newton_tri.h deleted file mode 100644 index fbc3703f64..0000000000 --- a/src/npair_half_bin_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/bin/newton/tri, - NPairHalfBinNewtonTri, - NP_HALF | NP_BIN | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_BIN_NEWTON_TRI_H -#define LMP_NPAIR_HALF_BIN_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfBinNewtonTri : public NPair { - public: - NPairHalfBinNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_multi_newtoff.cpp b/src/npair_half_multi_newtoff.cpp deleted file mode 100644 index 5cacd8015d..0000000000 --- a/src/npair_half_multi_newtoff.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiNewtoff::NPairHalfMultiNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfMultiNewtoff::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - // use full stencil for all collection combinations - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_multi_newtoff.h b/src/npair_half_multi_newtoff.h deleted file mode 100644 index cfb3ba9e60..0000000000 --- a/src/npair_half_multi_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/newtoff, - NPairHalfMultiNewtoff, - NP_HALF | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_NEWTOFF_H -#define LMP_NPAIR_HALF_MULTI_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiNewtoff : public NPair { - public: - NPairHalfMultiNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_multi_newton.cpp b/src/npair_half_multi_newton.cpp deleted file mode 100644 index dad42ffb7f..0000000000 --- a/src/npair_half_multi_newton.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiNewton::NPairHalfMultiNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiNewton::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // if same size: uses half stencil so check central bin - if(cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ - - if (icollection == jcollection) js = bins[i]; - else js = binhead_multi[jcollection][jbin]; - - // if same collection, - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - // if different collections, - // if j is owned atom, store it if j > i - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = js; j >= 0; j = bins[j]) { - if((icollection != jcollection) && (j < i)) continue; - - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - // for all collections, loop over all atoms in other bins in stencil, store every pair - // stencil is empty if i larger than j - // stencil is half if i same size as j - // stencil is full if i smaller than j - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_multi_newton_tri.cpp b/src/npair_half_multi_newton_tri.cpp deleted file mode 100644 index 24300f6929..0000000000 --- a/src/npair_half_multi_newton_tri.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" -#include "neighbor.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiNewtonTri::NPairHalfMultiNewtonTri(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiNewtonTri::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,jbin,icollection,jcollection,which,ns,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - int js; - - const double delta = 0.01 * force->angstrom; - - int *collection = neighbor->collection; - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in bins in stencil - // for triclinic: - // stencil is empty if i larger than j - // stencil is full if i smaller than j - // stencil is full if i same size as j - // for i smaller than j: - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - // if same size (same collection), exclude half of interactions - - if (cutcollectionsq[icollection][icollection] == - cutcollectionsq[jcollection][jcollection]) { - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_multi_newton_tri.h b/src/npair_half_multi_newton_tri.h deleted file mode 100644 index a26087465f..0000000000 --- a/src/npair_half_multi_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/newton/tri, - NPairHalfMultiNewtonTri, - NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_TRI_H -#define LMP_NPAIR_HALF_MULTI_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiNewtonTri : public NPair { - public: - NPairHalfMultiNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_multi_old_newtoff.cpp b/src/npair_half_multi_old_newtoff.cpp deleted file mode 100644 index 69c9543838..0000000000 --- a/src/npair_half_multi_old_newtoff.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_old_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiOldNewtoff::NPairHalfMultiOldNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - multi-type stencil is itype dependent and is distance checked - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfMultiOldNewtoff::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // skip if i,j neighbor cutoff is less than bin distance - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_multi_old_newtoff.h b/src/npair_half_multi_old_newtoff.h deleted file mode 100644 index d81d2d685a..0000000000 --- a/src/npair_half_multi_old_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/old/newtoff, - NPairHalfMultiOldNewtoff, - NP_HALF | NP_MULTI_OLD | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTOFF_H -#define LMP_NPAIR_HALF_MULTI_OLD_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiOldNewtoff : public NPair { - public: - NPairHalfMultiOldNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_multi_old_newton.cpp b/src/npair_half_multi_old_newton.cpp deleted file mode 100644 index e9556d50ff..0000000000 --- a/src/npair_half_multi_old_newton.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_old_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiOldNewton::NPairHalfMultiOldNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiOldNewton::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - // loop over all atoms in other bins in stencil, store every pair - // skip if i,j neighbor cutoff is less than bin distance - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_multi_old_newton.h b/src/npair_half_multi_old_newton.h deleted file mode 100644 index 1b8bff5080..0000000000 --- a/src/npair_half_multi_old_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/old/newton, - NPairHalfMultiOldNewton, - NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTON_H -#define LMP_NPAIR_HALF_MULTI_OLD_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiOldNewton : public NPair { - public: - NPairHalfMultiOldNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_multi_old_newton_tri.cpp b/src/npair_half_multi_old_newton_tri.cpp deleted file mode 100644 index ce3149ebf5..0000000000 --- a/src/npair_half_multi_old_newton_tri.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_multi_old_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfMultiOldNewtonTri::NPairHalfMultiOldNewtonTri(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfMultiOldNewtonTri::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - const double delta = 0.01 * force->angstrom; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_multi_old_newton_tri.h b/src/npair_half_multi_old_newton_tri.h deleted file mode 100644 index bb15724074..0000000000 --- a/src/npair_half_multi_old_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/multi/old/newton/tri, - NPairHalfMultiOldNewtonTri, - NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTON_TRI_H -#define LMP_NPAIR_HALF_MULTI_OLD_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfMultiOldNewtonTri : public NPair { - public: - NPairHalfMultiOldNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_nsq_newtoff.cpp b/src/npair_half_nsq_newtoff.cpp deleted file mode 100644 index 8cc79b7013..0000000000 --- a/src/npair_half_nsq_newtoff.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_half_nsq_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "group.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfNsqNewtoff::NPairHalfNsqNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfNsqNewtoff::build(NeighList *list) -{ - int i, j, n, itype, jtype, which, bitmask, imol, iatom, moltemplate; - tagint tagprev; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) - moltemplate = 1; - else - moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // only store pair if i < j - - for (j = i + 1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i], nspecial[i], tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], - tag[j] - tagprev); - else - which = 0; - if (which == 0) - neighptr[n++] = j; - else if (domain->minimum_image_check(delx, dely, delz)) - neighptr[n++] = j; - else if (which > 0) - neighptr[n++] = j ^ (which << SBBITS); - } else - neighptr[n++] = j; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - list->inum = inum; -} diff --git a/src/npair_half_nsq_newtoff.h b/src/npair_half_nsq_newtoff.h deleted file mode 100644 index 157d9c3835..0000000000 --- a/src/npair_half_nsq_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/nsq/newtoff, - NPairHalfNsqNewtoff, - NP_HALF | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_H -#define LMP_NPAIR_HALF_NSQ_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfNsqNewtoff : public NPair { - public: - NPairHalfNsqNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_nsq_newton.cpp b/src/npair_half_nsq_newton.cpp deleted file mode 100644 index 4d5afbdd3e..0000000000 --- a/src/npair_half_nsq_newton.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_nsq_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "group.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfNsqNewton::NPairHalfNsqNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - every pair stored exactly once by some processor - decision on ghost atoms based on itag,jtag tests -------------------------------------------------------------------------- */ - -void NPairHalfNsqNewton::build(NeighList *list) -{ - int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // use itag/jtap comparision to eliminate half the interactions - // itag = jtag is possible for long cutoffs that include images of self - // for triclinic, must use delta to eliminate half the I/J interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_nsq_newton.h b/src/npair_half_nsq_newton.h deleted file mode 100644 index 8f6952ff01..0000000000 --- a/src/npair_half_nsq_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/nsq/newton, - NPairHalfNsqNewton, - NP_HALF | NP_NSQ | NP_NEWTON | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_NSQ_NEWTON_H -#define LMP_NPAIR_HALF_NSQ_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfNsqNewton : public NPair { - public: - NPairHalfNsqNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_respa_bin_newtoff.cpp b/src/npair_half_respa_bin_newtoff.cpp deleted file mode 100644 index 11d9e916e7..0000000000 --- a/src/npair_half_respa_bin_newtoff.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_respa_bin_newtoff.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaBinNewtoff::NPairHalfRespaBinNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and surrounding bins in non-Newton stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfRespaBinNewtoff::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - MyPage *ipage_inner = list->ipage_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - ipage_middle = list->ipage_middle; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - for (i = 0; i < nlocal; i++) { - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - ibin = atom2bin[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) - neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - } - - ilist[inum] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - inum++; - } - - list->inum = inum; - list->inum_inner = inum; - if (respamiddle) list->inum_middle = inum; -} diff --git a/src/npair_half_respa_bin_newton.cpp b/src/npair_half_respa_bin_newton.cpp deleted file mode 100644 index 6f829660bd..0000000000 --- a/src/npair_half_respa_bin_newton.cpp +++ /dev/null @@ -1,233 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_respa_bin_newton.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaBinNewton::NPairHalfRespaBinNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfRespaBinNewton::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - MyPage *ipage_inner = list->ipage_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - ipage_middle = list->ipage_middle; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - for (i = 0; i < nlocal; i++) { - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) - neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - } - - ilist[inum] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - inum++; - } - - list->inum = inum; - list->inum_inner = inum; - if (respamiddle) list->inum_middle = inum; -} diff --git a/src/npair_half_respa_bin_newton.h b/src/npair_half_respa_bin_newton.h deleted file mode 100644 index 2cd68446a8..0000000000 --- a/src/npair_half_respa_bin_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/respa/bin/newton, - NPairHalfRespaBinNewton, - NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_H -#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfRespaBinNewton : public NPair { - public: - NPairHalfRespaBinNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_respa_bin_newton_tri.cpp b/src/npair_half_respa_bin_newton_tri.cpp deleted file mode 100644 index 4cd4ead0fa..0000000000 --- a/src/npair_half_respa_bin_newton_tri.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_respa_bin_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaBinNewtonTri::NPairHalfRespaBinNewtonTri(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfRespaBinNewtonTri::build(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - const double delta = 0.01 * force->angstrom; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - MyPage *ipage_inner = list->ipage_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - ipage_middle = list->ipage_middle; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - for (i = 0; i < nlocal; i++) { - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) - neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - } - - ilist[inum] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - inum++; - } - - list->inum = inum; - list->inum_inner = inum; - if (respamiddle) list->inum_middle = inum; -} diff --git a/src/npair_half_respa_bin_newton_tri.h b/src/npair_half_respa_bin_newton_tri.h deleted file mode 100644 index 68289c2d37..0000000000 --- a/src/npair_half_respa_bin_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/respa/bin/newton/tri, - NPairHalfRespaBinNewtonTri, - NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_H -#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfRespaBinNewtonTri : public NPair { - public: - NPairHalfRespaBinNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_respa_nsq_newtoff.cpp b/src/npair_half_respa_nsq_newtoff.cpp deleted file mode 100644 index 7bbd9dbece..0000000000 --- a/src/npair_half_respa_nsq_newtoff.cpp +++ /dev/null @@ -1,182 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_respa_nsq_newtoff.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "group.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfRespaNsqNewtoff::NPairHalfRespaNsqNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - multiple respa lists - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - pair added if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfRespaNsqNewtoff::build(NeighList *list) -{ - int i,j,n,itype,jtype,n_inner,n_middle,bitmask,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - MyPage *ipage_inner = list->ipage_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - ipage_middle = list->ipage_middle; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - for (i = 0; i < nlocal; i++) { - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - - if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); - } - - if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; - else if (which > 0) - neighptr_middle[n_middle++] = j ^ (which << SBBITS); - } - } - } - - ilist[inum] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - inum++; - } - - list->inum = inum; - list->inum_inner = inum; - if (respamiddle) list->inum_middle = inum; -} diff --git a/src/npair_half_respa_nsq_newton.h b/src/npair_half_respa_nsq_newton.h deleted file mode 100644 index 4a5ae23aef..0000000000 --- a/src/npair_half_respa_nsq_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/respa/nsq/newton, - NPairHalfRespaNsqNewton, - NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_H -#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfRespaNsqNewton : public NPair { - public: - NPairHalfRespaNsqNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_bin_newtoff.cpp b/src/npair_half_size_bin_newtoff.cpp deleted file mode 100644 index b4842337ca..0000000000 --- a/src/npair_half_size_bin_newtoff.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_bin_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeBinNewtoff::NPairHalfSizeBinNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and surrounding bins in non-Newton stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeBinNewtoff::build(NeighList *list) -{ - int i,j,jh,k,n,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - ibin = atom2bin[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_bin_newtoff.h b/src/npair_half_size_bin_newtoff.h deleted file mode 100644 index ac68f699ca..0000000000 --- a/src/npair_half_size_bin_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/bin/newtoff, - NPairHalfSizeBinNewtoff, - NP_HALF | NP_SIZE | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_H -#define LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeBinNewtoff : public NPair { - public: - NPairHalfSizeBinNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_bin_newton.cpp b/src/npair_half_size_bin_newton.cpp deleted file mode 100644 index 11ac30ed30..0000000000 --- a/src/npair_half_size_bin_newton.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_bin_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeBinNewton::NPairHalfSizeBinNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeBinNewton::build(NeighList *list) -{ - int i,j,jh,k,n,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_bin_newton_tri.cpp b/src/npair_half_size_bin_newton_tri.cpp deleted file mode 100644 index 0d1a0a7329..0000000000 --- a/src/npair_half_size_bin_newton_tri.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_bin_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeBinNewtonTri::NPairHalfSizeBinNewtonTri(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeBinNewtonTri::build(NeighList *list) -{ - int i,j,jh,k,n,ibin,which,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - const double delta = 0.01 * force->angstrom; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_bin_newton_tri.h b/src/npair_half_size_bin_newton_tri.h deleted file mode 100644 index ad35b7ac36..0000000000 --- a/src/npair_half_size_bin_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/bin/newton/tri, - NPairHalfSizeBinNewtonTri, - NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_H -#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeBinNewtonTri : public NPair { - public: - NPairHalfSizeBinNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_multi_newtoff.cpp b/src/npair_half_size_multi_newtoff.cpp deleted file mode 100644 index 0c22a49ed0..0000000000 --- a/src/npair_half_size_multi_newtoff.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -es 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 "npair_half_size_multi_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiNewtoff::NPairHalfSizeMultiNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with partial Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiNewtoff::build(NeighList *list) -{ - int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; - int which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - int js; - - int *collection = neighbor->collection; - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - // use full stencil for all collection combinations - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_multi_newtoff.h b/src/npair_half_size_multi_newtoff.h deleted file mode 100644 index 89ca0eae4e..0000000000 --- a/src/npair_half_size_multi_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/newtoff, - NPairHalfSizeMultiNewtoff, - NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_NEWTOFF_H -#define LMP_NPAIR_HALF_SIZE_MULTI_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiNewtoff : public NPair { - public: - NPairHalfSizeMultiNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_multi_newton.cpp b/src/npair_half_size_multi_newton.cpp deleted file mode 100644 index ff9df7e2cf..0000000000 --- a/src/npair_half_size_multi_newton.cpp +++ /dev/null @@ -1,213 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiNewton::NPairHalfSizeMultiNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with full Newton's 3rd law - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiNewton::build(NeighList *list) -{ - int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; - int which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - - int *collection = neighbor->collection; - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // if same size: uses half stencil so check central bin - if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ - - if (icollection == jcollection) js = bins[i]; - else js = binhead_multi[jcollection][jbin]; - - // if same collection, - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - // if different collections, - // if j is owned atom, store it if j > i - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = js; j >= 0; j = bins[j]) { - if ((icollection != jcollection) && (j < i)) continue; - - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - // for all collections, loop over all atoms in other bins in stencil, store every pair - // stencil is empty if i larger than j - // stencil is half if i same size as j - // stencil is full if i smaller than j - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_multi_newton.h b/src/npair_half_size_multi_newton.h deleted file mode 100644 index 2f892e37ee..0000000000 --- a/src/npair_half_size_multi_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/newton, - NPairHalfSizeMultiNewton, - NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_H -#define LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiNewton : public NPair { - public: - NPairHalfSizeMultiNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_multi_newton_tri.cpp b/src/npair_half_size_multi_newton_tri.cpp deleted file mode 100644 index aa0d8e3f42..0000000000 --- a/src/npair_half_size_multi_newton_tri.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiNewtonTri::NPairHalfSizeMultiNewtonTri(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with Newton's 3rd law for triclinic - multi stencil is icollection-jcollection dependent - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiNewtonTri::build(NeighList *list) -{ - int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; - int which,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - - const double delta = 0.01 * force->angstrom; - - int *collection = neighbor->collection; - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - itype = type[i]; - icollection = collection[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - ibin = atom2bin[i]; - - // loop through stencils for all collections - - for (jcollection = 0; jcollection < ncollections; jcollection++) { - - // if same collection use own bin - - if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); - - // loop over all atoms in bins in stencil - // stencil is empty if i larger than j - // stencil is half if i same size as j - // stencil is full if i smaller than j - // if half: pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; - - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - - // if same size (same collection), exclude half of interactions - - if (cutcollectionsq[icollection][icollection] == - cutcollectionsq[jcollection][jcollection]) { - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_multi_newton_tri.h b/src/npair_half_size_multi_newton_tri.h deleted file mode 100644 index 70563147dc..0000000000 --- a/src/npair_half_size_multi_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/newton/tri, - NPairHalfSizeMultiNewtonTri, - NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_TRI_H -#define LMP_NPAIR_HALF_SIZE_MULTI_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiNewtonTri : public NPair { - public: - NPairHalfSizeMultiNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_multi_old_newtoff.cpp b/src/npair_half_size_multi_old_newtoff.cpp deleted file mode 100644 index 158ddc0f10..0000000000 --- a/src/npair_half_size_multi_old_newtoff.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_old_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiOldNewtoff::NPairHalfSizeMultiOldNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - multi-type stencil is itype dependent and is distance checked - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiOldNewtoff::build(NeighList *list) -{ - int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // skip if i,j neighbor cutoff is less than bin distance - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_multi_old_newtoff.h b/src/npair_half_size_multi_old_newtoff.h deleted file mode 100644 index 051d5d47de..0000000000 --- a/src/npair_half_size_multi_old_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/old/newtoff, - NPairHalfSizeMultiOldNewtoff, - NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTOFF_H -#define LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiOldNewtoff : public NPair { - public: - NPairHalfSizeMultiOldNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_multi_old_newton.cpp b/src/npair_half_size_multi_old_newton.cpp deleted file mode 100644 index cbb75f568d..0000000000 --- a/src/npair_half_size_multi_old_newton.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_old_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiOldNewton::NPairHalfSizeMultiOldNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiOldNewton::build(NeighList *list) -{ - int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - double *cutsq,*distsq; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - // loop over all atoms in other bins in stencil, store every pair - // skip if i,j neighbor cutoff is less than bin distance - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - j = j ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_multi_old_newton.h b/src/npair_half_size_multi_old_newton.h deleted file mode 100644 index 082e752e80..0000000000 --- a/src/npair_half_size_multi_old_newton.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/old/newton, - NPairHalfSizeMultiOldNewton, - NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTON | NP_ORTHO); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_H -#define LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiOldNewton : public NPair { - public: - NPairHalfSizeMultiOldNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_multi_old_newton_tri.cpp b/src/npair_half_size_multi_old_newton_tri.cpp deleted file mode 100644 index 848a19aa39..0000000000 --- a/src/npair_half_size_multi_old_newton_tri.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_multi_old_newton_tri.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeMultiOldNewtonTri::NPairHalfSizeMultiOldNewtonTri(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void NPairHalfSizeMultiOldNewtonTri::build(NeighList *list) -{ - int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutdistsq; - int *neighptr,*s; - double *cutsq,*distsq; - - const double delta = 0.01 * force->angstrom; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in bins in stencil - // for triclinic, bin stencil is full in all 3 dims - // must use itag/jtag to eliminate half the I/J interactions - // cannot use I/J exact coord comparision - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - ibin = atom2bin[i]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi_old[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - - if (j <= i) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutdistsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_half_size_multi_old_newton_tri.h b/src/npair_half_size_multi_old_newton_tri.h deleted file mode 100644 index 354832e07d..0000000000 --- a/src/npair_half_size_multi_old_newton_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/multi/old/newton/tri, - NPairHalfSizeMultiOldNewtonTri, - NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTON | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_TRI_H -#define LMP_NPAIR_HALF_SIZE_MULTI_OLD_NEWTON_TRI_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeMultiOldNewtonTri : public NPair { - public: - NPairHalfSizeMultiOldNewtonTri(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_nsq_newtoff.cpp b/src/npair_half_size_nsq_newtoff.cpp deleted file mode 100644 index acbb4cf7dd..0000000000 --- a/src/npair_half_size_nsq_newtoff.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_half_size_nsq_newtoff.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "group.h" -#include "molecule.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeNsqNewtoff::NPairHalfSizeNsqNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - pair added if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void NPairHalfSizeNsqNewtoff::build(NeighList *list) -{ - int i, j, jh, n, bitmask, which, imol, iatom, moltemplate; - tagint tagprev; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - double radi, radsum, cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *tag = atom->tag; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) - moltemplate = 1; - else - moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - - for (j = i + 1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (exclude && exclusion(i, j, type[i], type[j], mask, molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - radsum = radi + radius[j]; - cutsq = (radsum + skin) * (radsum + skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum * radsum) jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i], nspecial[i], tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], - tag[j] - tagprev); - else - which = 0; - if (which == 0) - neighptr[n++] = jh; - else if (domain->minimum_image_check(delx, dely, delz)) - neighptr[n++] = jh; - else if (which > 0) - neighptr[n++] = jh ^ (which << SBBITS); - } else - neighptr[n++] = jh; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - list->inum = inum; -} diff --git a/src/npair_half_size_nsq_newtoff.h b/src/npair_half_size_nsq_newtoff.h deleted file mode 100644 index d84d7d62dd..0000000000 --- a/src/npair_half_size_nsq_newtoff.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(half/size/nsq/newtoff, - NPairHalfSizeNsqNewtoff, - NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_H -#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalfSizeNsqNewtoff : public NPair { - public: - NPairHalfSizeNsqNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_half_size_nsq_newton.cpp b/src/npair_half_size_nsq_newton.cpp deleted file mode 100644 index ce0c7f9562..0000000000 --- a/src/npair_half_size_nsq_newton.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_half_size_nsq_newton.h" - -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "molecule.h" -#include "group.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalfSizeNsqNewton::NPairHalfSizeNsqNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - size particles - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests -------------------------------------------------------------------------- */ - -void NPairHalfSizeNsqNewton::build(NeighList *list) -{ - int i,j,jh,n,bitmask,which,imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - tagint **special = atom->special; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - if (molecular == Atom::TEMPLATE) moltemplate = 1; - else moltemplate = 0; - - int history = list->history; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int mask_history = 1 << HISTBITS; - - int inum = 0; - ipage->reset(); - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - - itag = tag[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // use itag/jtap comparision to eliminate half the interactions - // itag = jtag is possible for long cutoffs that include images of self - // for triclinic, must use delta to eliminate half the I/J interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - } - - if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - jh = j; - if (history && rsq < radsum*radsum) - jh = jh ^ mask_history; - - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = jh; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = jh; - else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); - } else neighptr[n++] = jh; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_halffull.cpp b/src/npair_halffull.cpp new file mode 100644 index 0000000000..b3d8d4f50e --- /dev/null +++ b/src/npair_halffull.cpp @@ -0,0 +1,160 @@ +/* ---------------------------------------------------------------------- + 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 "npair_halffull.h" + +#include "atom.h" +#include "error.h" +#include "force.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairHalffull::NPairHalffull(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build half list from full list + pair stored once if i,j are both owned and i < j + works if full list is a skip list + + Newtoff: + pair stored by me if j is ghost (also stored by proc owning j) + works for owned (non-ghost) list, also for ghost list + if ghost, also store neighbors of ghost atoms & set inum,gnum correctly + Newton: + if j is ghost, only store if j coords are "above and to the right" of i + use i < j < nlocal to eliminate half the local/local interactions + Newton + Triclinic: + must use delta to eliminate half the local/ghost interactions + cannot use I/J exact coord comparision as for orthog + b/c transforming orthog -> lambda -> orthog for ghost atoms + with an added PBC offset can shift all 3 coords by epsilon +------------------------------------------------------------------------- */ + +template +void NPairHalffull::build(NeighList *list) +{ + int i, j, ii, jj, n, jnum, joriginal; + int *neighptr, *jlist; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + + const double delta = 0.01 * force->angstrom; + + double **x = atom->x; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + int inum_full = list->listfull->inum; + if (!NEWTON) + if (list->ghost) inum_full += list->listfull->gnum; + + int inum = 0; + ipage->reset(); + + double cutsq_custom = cutoff_custom * cutoff_custom; + + // loop over atoms in full list + + for (ii = 0; ii < inum_full; ii++) { + n = 0; + neighptr = ipage->vget(); + + // loop over parent full list + + i = ilist_full[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + + if (NEWTON) { + if (j < nlocal) { + if (i > j) continue; + } else if (TRI) { + if (fabs(x[j][2]-ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1]-ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq > cutsq_custom) continue; + } + + neighptr[n++] = joriginal; + } else { + if (j > i) { + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq > cutsq_custom) continue; + } + + neighptr[n++] = joriginal; + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + list->inum = inum; + if (!NEWTON) + if (list->ghost) list->gnum = list->listfull->gnum; +} + +namespace LAMMPS_NS { +template class NPairHalffull<0,0,0>; +template class NPairHalffull<1,0,0>; +template class NPairHalffull<1,1,0>; +template class NPairHalffull<0,0,1>; +template class NPairHalffull<1,0,1>; +template class NPairHalffull<1,1,1>; +} diff --git a/src/npair_halffull.h b/src/npair_halffull.h new file mode 100644 index 0000000000..41d2e37dc4 --- /dev/null +++ b/src/npair_halffull.h @@ -0,0 +1,131 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairHalffull<0, 0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI); + +typedef NPairHalffull<0, 0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff/skip, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP); + +typedef NPairHalffull<0, 0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff/ghost, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST); + +typedef NPairHalffull<0, 0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff/skip/ghost, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST); + +typedef NPairHalffull<1, 0, 0> NPairHalffullNewton; +NPairStyle(halffull/newton, + NPairHalffullNewton, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO); + +typedef NPairHalffull<1, 1, 0> NPairHalffullNewtonTri; +NPairStyle(halffull/newton/tri, + NPairHalffullNewtonTri, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI); + +typedef NPairHalffull<1, 0, 0> NPairHalffullNewton; +NPairStyle(halffull/newton/skip, + NPairHalffullNewton, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_SKIP); + +typedef NPairHalffull<1, 1, 0> NPairHalffullNewtonTri; +NPairStyle(halffull/newton/skip/tri, + NPairHalffullNewtonTri, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_SKIP); + +typedef NPairHalffull<0, 0, 1> NPairHalffullTrimNewtoff; +NPairStyle(halffull/trim/newtoff, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_TRIM); + +typedef NPairHalffull<0, 0, 1> NPairHalffullTrimNewtoff; +NPairStyle(halffull/trim/newtoff/skip, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM); + +typedef NPairHalffull<0, 0, 1> NPairHalffullTrimNewtoff; +NPairStyle(halffull/trim/newtoff/ghost, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM); + +typedef NPairHalffull<0, 0, 1> NPairHalffullTrimNewtoff; +NPairStyle(halffull/trim/newtoff/skip/ghost, + NPairHalffullTrimNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_TRIM); + +typedef NPairHalffull<1, 0, 1> NPairHalffullTrimNewton; +NPairStyle(halffull/trim/newton, + NPairHalffullTrimNewton, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_TRIM); + +typedef NPairHalffull<1, 1, 1> NPairHalffullTrimNewtonTri; +NPairStyle(halffull/trim/newton/tri, + NPairHalffullTrimNewtonTri, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_TRIM); + +typedef NPairHalffull<1, 0, 1> NPairHalffullTrimNewton; +NPairStyle(halffull/trim/newton/skip, + NPairHalffullTrimNewton, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_SKIP | NP_TRIM); + +typedef NPairHalffull<1, 1, 1> NPairHalffullTrimNewtonTri; +NPairStyle(halffull/trim/newton/tri/skip, + NPairHalffullTrimNewtonTri, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_TRI | NP_SKIP | NP_TRIM); +// clang-format on +#else + +#ifndef LMP_NPAIR_HALFFULL_H +#define LMP_NPAIR_HALFFULL_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairHalffull : public NPair { + public: + NPairHalffull(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/npair_halffull_newtoff.cpp b/src/npair_halffull_newtoff.cpp deleted file mode 100644 index a5f0e1624a..0000000000 --- a/src/npair_halffull_newtoff.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_halffull_newtoff.h" - -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullNewtoff::NPairHalffullNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) - works if full list is a skip list - works for owned (non-ghost) list, also for ghost list - if ghost, also store neighbors of ghost atoms & set inum,gnum correctly -------------------------------------------------------------------------- */ - -void NPairHalffullNewtoff::build(NeighList *list) -{ - int i, j, ii, jj, n, jnum, joriginal; - int *neighptr, *jlist; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - if (list->ghost) inum_full += list->listfull->gnum; - - int inum = 0; - ipage->reset(); - - // loop over atoms in full list - - for (ii = 0; ii < inum_full; ii++) { - n = 0; - neighptr = ipage->vget(); - - // loop over parent full list - - i = ilist_full[ii]; - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j > i) neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - if (list->ghost) list->gnum = list->listfull->gnum; -} diff --git a/src/npair_halffull_newtoff.h b/src/npair_halffull_newtoff.h deleted file mode 100644 index d2b42f2370..0000000000 --- a/src/npair_halffull_newtoff.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/newtoff, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI); - -NPairStyle(halffull/newtoff/skip, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_SKIP); - -NPairStyle(halffull/newtoff/ghost, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_GHOST); - -NPairStyle(halffull/newtoff/skip/ghost, - NPairHalffullNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_NEWTOFF_H -#define LMP_NPAIR_HALFFULL_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullNewtoff : public NPair { - public: - NPairHalffullNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_halffull_newton.cpp b/src/npair_halffull_newton.cpp deleted file mode 100644 index 12320c46f3..0000000000 --- a/src/npair_halffull_newton.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_halffull_newton.h" - -#include "atom.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullNewton::NPairHalffullNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - if j is ghost, only store if j coords are "above and to the right" of i - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullNewton::build(NeighList *list) -{ - int i, j, ii, jj, n, jnum, joriginal; - int *neighptr, *jlist; - double xtmp, ytmp, ztmp; - - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - double **x = atom->x; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - - int inum = 0; - ipage->reset(); - - // loop over parent full list - - for (ii = 0; ii < inum_full; ii++) { - n = 0; - neighptr = ipage->vget(); - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over full neighbor list - // use i < j < nlocal to eliminate half the local/local interactions - // for triclinic, must use delta to eliminate half the local/ghost interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - - if (j < nlocal) { - if (i > j) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - list->inum = inum; -} diff --git a/src/npair_halffull_newton.h b/src/npair_halffull_newton.h deleted file mode 100644 index 3a9462f8b4..0000000000 --- a/src/npair_halffull_newton.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/newton, - NPairHalffullNewton, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI); - -NPairStyle(halffull/newton/skip, - NPairHalffullNewton, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI | NP_SKIP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_NEWTON_H -#define LMP_NPAIR_HALFFULL_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullNewton : public NPair { - public: - NPairHalffullNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_halffull_trim_newtoff.cpp b/src/npair_halffull_trim_newtoff.cpp deleted file mode 100644 index db97bf185a..0000000000 --- a/src/npair_halffull_trim_newtoff.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_halffull_trim_newtoff.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullTrimNewtoff::NPairHalffullTrimNewtoff(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) - works if full list is a skip list - works for owned (non-ghost) list, also for ghost list - if ghost, also store neighbors of ghost atoms & set inum,gnum correctly -------------------------------------------------------------------------- */ - -void NPairHalffullTrimNewtoff::build(NeighList *list) -{ - int i, j, ii, jj, n, jnum, joriginal; - int *neighptr, *jlist; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - - double **x = atom->x; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - if (list->ghost) inum_full += list->listfull->gnum; - - int inum = 0; - ipage->reset(); - - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over atoms in full list - - for (ii = 0; ii < inum_full; ii++) { - n = 0; - neighptr = ipage->vget(); - - // loop over parent full list - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j > i) { - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - if (list->ghost) list->gnum = list->listfull->gnum; -} diff --git a/src/npair_halffull_trim_newtoff.h b/src/npair_halffull_trim_newtoff.h deleted file mode 100644 index ca7726c837..0000000000 --- a/src/npair_halffull_trim_newtoff.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/trim/newtoff, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM); - -NPairStyle(halffull/trim/newtoff/skip, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP); - -NPairStyle(halffull/trim/newtoff/ghost, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST); - -NPairStyle(halffull/trim/newtoff/skip/ghost, - NPairHalffullTrimNewtoff, - NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | - NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP | NP_GHOST); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_TRIM_NEWTOFF_H -#define LMP_NPAIR_HALFFULL_TRIM_NEWTOFF_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullTrimNewtoff : public NPair { - public: - NPairHalffullTrimNewtoff(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_halffull_trim_newton.cpp b/src/npair_halffull_trim_newton.cpp deleted file mode 100644 index 56cef00b25..0000000000 --- a/src/npair_halffull_trim_newton.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_halffull_trim_newton.h" - -#include "atom.h" -#include "domain.h" -#include "error.h" -#include "force.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairHalffullTrimNewton::NPairHalffullTrimNewton(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - if j is ghost, only store if j coords are "above and to the right" of i - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullTrimNewton::build(NeighList *list) -{ - int i, j, ii, jj, n, jnum, joriginal; - int *neighptr, *jlist; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - - const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; - - double **x = atom->x; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - - int inum = 0; - ipage->reset(); - - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over parent full list - - for (ii = 0; ii < inum_full; ii++) { - n = 0; - neighptr = ipage->vget(); - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over full neighbor list - // use i < j < nlocal to eliminate half the local/local interactions - // for triclinic, must use delta to eliminate half the local/ghost interactions - // cannot use I/J exact coord comparision as for orthog - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift all 3 coords by epsilon - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - - if (j < nlocal) { - if (i > j) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; - } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - list->inum = inum; -} diff --git a/src/npair_halffull_trim_newton.h b/src/npair_halffull_trim_newton.h deleted file mode 100644 index 5eb5aa3cd3..0000000000 --- a/src/npair_halffull_trim_newton.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(halffull/trim/newton, - NPairHalffullTrimNewton, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI | NP_TRIM); - -NPairStyle(halffull/trim/newton/skip, - NPairHalffullTrimNewton, - NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP); -// clang-format on -#else - -#ifndef LMP_NPAIR_HALFFULL_TRIM_NEWTON_H -#define LMP_NPAIR_HALFFULL_TRIM_NEWTON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullTrimNewton : public NPair { - public: - NPairHalffullTrimNewton(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_multi.cpp b/src/npair_multi.cpp new file mode 100644 index 0000000000..b5f813c0a8 --- /dev/null +++ b/src/npair_multi.cpp @@ -0,0 +1,301 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_multi.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairMulti::NPairMulti(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multi stencil is icollection-jcollection dependent + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairMulti::build(NeighList *list) +{ + int i, j, jh, js, k, n, itype, jtype, ibin, jbin, icollection, jcollection, which, ns, imol, iatom, moltemplate; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr, *s; + + const double delta = 0.01 * force->angstrom; + + int *collection = neighbor->collection; + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (!ATOMONLY) { + if (molecular == Atom::TEMPLATE) + moltemplate = 1; + else + moltemplate = 0; + } + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + + itag = tag[i]; + itype = type[i]; + icollection = collection[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (!ATOMONLY) { + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + } + + ibin = atom2bin[i]; + + // loop through stencils for all collections + + for (jcollection = 0; jcollection < ncollections; jcollection++) { + + // Use own bin for same collection + if (icollection == jcollection) jbin = ibin; + else jbin = coord2bin(x[i], jcollection); + + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; + + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + + // For half-newton-ortho, first check self bin (k == 0, always half) + // if checking its own binlist, skip all before i in linked list + if (HALF && NEWTON && !TRI) + if ((k == 0) && (icollection == jcollection)) js = bins[i]; + + for (j = js; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list, only uses full stencils + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off, only uses full stencils + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic, only uses full stencils + // If different sizes -> full stencil (accept all, one-way search) + // If same size -> half stencil, exclude half of interactions + // stencil is empty if i larger than j + // stencil is full if i smaller than j + // stencil is full if i same size as j + // for i smaller than j: + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + + if (flag_same_multi[icollection][jcollection]) { + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } + } else { + // Half neighbor list, newton on, orthonormal, uses a mix of stencils + // If different sizes -> full stencil (accept all, one-way search) + // If same size -> half stencil (first includes a self bin search) + if (k == 0 && flag_same_multi[icollection][jcollection]) { + // if same collection, + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the right" of i + + // if different collections, + // if j is owned atom, store it if j > i + // if j is ghost, only store if j coords are "above and to the right" of i + + if ((icollection != jcollection) && (j < i)) continue; + + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (ATOMONLY) { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < (radsum * radsum)) + jh = jh ^ mask_history; + neighptr[n++] = jh; + } + } else { + if (rsq <= cutsq) { + jh = j; + if (history && rsq < (radsum * radsum)) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } + } else { + if (ATOMONLY) { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairMulti<0,1,0,0,0>; +template class NPairMulti<1,0,0,0,0>; +template class NPairMulti<1,1,0,0,0>; +template class NPairMulti<1,1,1,0,0>; +template class NPairMulti<0,1,0,1,0>; +template class NPairMulti<1,0,0,1,0>; +template class NPairMulti<1,1,0,1,0>; +template class NPairMulti<1,1,1,1,0>; +template class NPairMulti<0,1,0,0,1>; +template class NPairMulti<1,0,0,0,1>; +template class NPairMulti<1,1,0,0,1>; +template class NPairMulti<1,1,1,0,1>; +template class NPairMulti<0,1,0,1,1>; +template class NPairMulti<1,0,0,1,1>; +template class NPairMulti<1,1,0,1,1>; +template class NPairMulti<1,1,1,1,1>; +} diff --git a/src/npair_multi.h b/src/npair_multi.h new file mode 100644 index 0000000000..a82352f840 --- /dev/null +++ b/src/npair_multi.h @@ -0,0 +1,119 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairMulti<0, 1, 0, 0, 0> NPairFullMulti; +NPairStyle(full/multi, + NPairFullMulti, + NP_FULL | NP_MULTI | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 0, 0, 0, 0> NPairHalfMultiNewtoff; +NPairStyle(half/multi/newtoff, + NPairHalfMultiNewtoff, + NP_HALF | NP_MULTI | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 1, 0, 0, 0> NPairHalfMultiNewton; +NPairStyle(half/multi/newton, + NPairHalfMultiNewton, + NP_HALF | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairMulti<1, 1, 1, 0, 0> NPairHalfMultiNewtonTri; +NPairStyle(half/multi/newton/tri, + NPairHalfMultiNewtonTri, + NP_HALF | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairMulti<0, 1, 0, 1, 0> NPairFullSizeMulti; +NPairStyle(full/size/multi, + NPairFullSizeMulti, + NP_FULL | NP_SIZE | NP_MULTI | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 0, 0, 1, 0> NPairHalfSizeMultiNewtoff; +NPairStyle(half/size/multi/newtoff, + NPairHalfSizeMultiNewtoff, + NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 1, 0, 1, 0> NPairHalfSizeMultiNewton; +NPairStyle(half/size/multi/newton, + NPairHalfSizeMultiNewton, + NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairMulti<1, 1, 1, 1, 0> NPairHalfSizeMultiNewtonTri; +NPairStyle(half/size/multi/newton/tri, + NPairHalfSizeMultiNewtonTri, + NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairMulti<0, 1, 0, 0, 1> NPairFullMultiAtomonly; +NPairStyle(full/multi/atomonly, + NPairFullMultiAtomonly, + NP_FULL | NP_MULTI | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 0, 0, 0, 1> NPairHalfMultiAtomonlyNewtoff; +NPairStyle(half/multi/atomonly/newtoff, + NPairHalfMultiAtomonlyNewtoff, + NP_HALF | NP_MULTI | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 1, 0, 0, 1> NPairHalfMultiAtomonlyNewton; +NPairStyle(half/multi/atomonly/newton, + NPairHalfMultiAtomonlyNewton, + NP_HALF | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairMulti<1, 1, 1, 0, 1> NPairHalfMultiAtomonlyNewtonTri; +NPairStyle(half/multi/atomonly/newton/tri, + NPairHalfMultiAtomonlyNewtonTri, + NP_HALF | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_TRI); + +typedef NPairMulti<0, 1, 0, 1, 1> NPairFullSizeMultiAtomonly; +NPairStyle(full/size/multi/atomonly, + NPairFullSizeMultiAtomonly, + NP_FULL | NP_SIZE | NP_MULTI | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 0, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewtoff; +NPairStyle(half/size/multi/atomonly/newtoff, + NPairHalfSizeMultiAtomonlyNewtoff, + NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 1, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewton; +NPairStyle(half/size/multi/atomonly/newton, + NPairHalfSizeMultiAtomonlyNewton, + NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairMulti<1, 1, 1, 1, 1> NPairHalfSizeMultiAtomonlyNewtonTri; +NPairStyle(half/size/multi/atomonly/newton/tri, + NPairHalfSizeMultiAtomonlyNewtonTri, + NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_MULTI_H +#define LMP_NPAIR_MULTI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairMulti : public NPair { + public: + NPairMulti(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/npair_multi_old.cpp b/src/npair_multi_old.cpp new file mode 100644 index 0000000000..a4ca1e7361 --- /dev/null +++ b/src/npair_multi_old.cpp @@ -0,0 +1,255 @@ +// clang-format off +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_multi_old.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairMultiOld::NPairMultiOld(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multi/old-type stencil is itype dependent and is distance checked + Full: + binned neighbor list construction for all neighbors + multi-type stencil is itype dependent and is distance checked + every neighbor pair appears in list of both atoms i and j + Half + newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + multi-type stencil is itype dependent and is distance checked + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + multi-type stencil is itype dependent and is distance checked + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairMultiOld::build(NeighList *list) +{ + int i, j, jh, k, n, itype, jtype, ibin, bin_start, which, ns, imol, iatom, moltemplate; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr, *s; + double *cutnsq, *distsq; + + const double delta = 0.01 * force->angstrom; + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) + moltemplate = 1; + else + moltemplate = 0; + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + ibin = atom2bin[i]; + s = stencil_multi_old[itype]; + distsq = distsq_multi_old[itype]; + cutnsq = cutneighsq[itype]; + ns = nstencil_multi_old[itype]; + for (k = 0; k < ns; k++) { + bin_start = binhead[ibin + s[k]]; + if (HALF && NEWTON && (!TRI)) { + if (k == 0) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = bin_start; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // for triclinic, bin stencil is full in all 3 dims + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (k == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (cutnsq[jtype] < distsq[k]) continue; + + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) + jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairMultiOld<0,1,0,0>; +template class NPairMultiOld<1,0,0,0>; +template class NPairMultiOld<1,1,0,0>; +template class NPairMultiOld<1,1,1,0>; +template class NPairMultiOld<0,1,0,1>; +template class NPairMultiOld<1,0,0,1>; +template class NPairMultiOld<1,1,0,1>; +template class NPairMultiOld<1,1,1,1>; +} diff --git a/src/npair_multi_old.h b/src/npair_multi_old.h new file mode 100644 index 0000000000..f01844ed57 --- /dev/null +++ b/src/npair_multi_old.h @@ -0,0 +1,77 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairMultiOld<0, 1, 0, 0> NPairFullMultiOld; +NPairStyle(full/multi/old, + NPairFullMultiOld, + NP_FULL | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 0, 0, 0> NPairHalfMultiOldNewtoff; +NPairStyle(half/multi/old/newtoff, + NPairHalfMultiOldNewtoff, + NP_HALF | NP_MULTI_OLD | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 1, 0, 0> NPairHalfMultiOldNewton; +NPairStyle(half/multi/old/newton, + NPairHalfMultiOldNewton, + NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOld<1, 1, 1, 0> NPairHalfMultiOldNewtonTri; +NPairStyle(half/multi/old/newton/tri, + NPairHalfMultiOldNewtonTri, + NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_TRI); + +typedef NPairMultiOld<0, 1, 0, 1> NPairFullSizeMultiOld; +NPairStyle(full/size/multi/old, + NPairFullSizeMultiOld, + NP_FULL | NP_SIZE | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 0, 0, 1> NPairHalfSizeMultiOldNewtoff; +NPairStyle(half/size/multi/old/newtoff, + NPairHalfSizeMultiOldNewtoff, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 1, 0, 1> NPairHalfSizeMultiOldNewton; +NPairStyle(half/size/multi/old/newton, + NPairHalfSizeMultiOldNewton, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOld<1, 1, 1, 1> NPairHalfSizeMultiOldNewtonTri; +NPairStyle(half/size/multi/old/newton/tri, + NPairHalfSizeMultiOldNewtonTri, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_MULTI_OLD_H +#define LMP_NPAIR_MULTI_OLD_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairMultiOld : public NPair { + public: + NPairMultiOld(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/npair_nsq.cpp b/src/npair_nsq.cpp new file mode 100644 index 0000000000..c2f43d9cb0 --- /dev/null +++ b/src/npair_nsq.cpp @@ -0,0 +1,230 @@ +/* ---------------------------------------------------------------------- + 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 "npair_nsq.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairNsq::NPairNsq(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + N^2 search for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Half + Newton: + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + every pair stored exactly once by some processor + decision on ghost atoms based on itag, jtag tests + Half + Newton + Tri: + use itag/jtap comparision to eliminate half the interactions + for triclinic, must use delta to eliminate half the I/J interactions + cannot use I/J exact coord comparision as for orthog + b/c transforming orthog -> lambda -> orthog for ghost atoms + with an added PBC offset can shift all 3 coords by epsilon +------------------------------------------------------------------------- */ + +template +void NPairNsq::build(NeighList *list) +{ + int i, j, jh, jstart, n, itype, jtype, which, bitmask, imol, iatom, moltemplate; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq; + int *neighptr; + + const double delta = 0.01 * force->angstrom; + + double **x = atom->x; + double *radius = atom->radius; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) + moltemplate = 1; + else + moltemplate = 0; + + int history = list->history; + int mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // Full: loop over all atoms, owned and ghost, skip i = j + // Half: loop over remaining atoms, owned and ghost + // Newtoff: only store pair if i < j + // Newton: itag = jtag is possible for long cutoffs that include images of self + + if (!HALF) jstart = 0; + else jstart = i + 1; + + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + + if (!HALF) { + // Full neighbor list + if (i == j) continue; + } else if (NEWTON) { + // Half neighbor list, newton on + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else if (TRI) { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) jh = jh ^ mask_history; + + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = jh; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = jh; + else if (which > 0) + neighptr[n++] = jh ^ (which << SBBITS); + } else + neighptr[n++] = jh; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if (domain->minimum_image_check(delx, dely, delz)) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + if (!HALF) list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairNsq<0,1,0,0>; +template class NPairNsq<1,0,0,0>; +template class NPairNsq<1,1,0,0>; +template class NPairNsq<1,1,1,0>; +template class NPairNsq<0,1,0,1>; +template class NPairNsq<1,0,0,1>; +template class NPairNsq<1,1,0,1>; +template class NPairNsq<1,1,1,1>; +} diff --git a/src/npair_nsq.h b/src/npair_nsq.h new file mode 100644 index 0000000000..7c4a22e1a7 --- /dev/null +++ b/src/npair_nsq.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairNsq<0, 1, 0, 0> NPairFullNsq; +NPairStyle(full/nsq, + NPairFullNsq, + NP_FULL | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 0, 0, 0> NPairHalfNsqNewtoff; +NPairStyle(half/nsq/newtoff, + NPairHalfNsqNewtoff, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 1, 0, 0> NPairHalfNsqNewton; +NPairStyle(half/nsq/newton, + NPairHalfNsqNewton, + NP_HALF | NP_NSQ | NP_NEWTON | NP_ORTHO); + +typedef NPairNsq<1, 1, 1, 0> NPairHalfNsqNewtonTri; +NPairStyle(half/nsq/newton/tri, + NPairHalfNsqNewtonTri, + NP_HALF | NP_NSQ | NP_NEWTON | NP_TRI); + +typedef NPairNsq<0, 1, 0, 1> NPairFullSizeNsq; +NPairStyle(full/size/nsq, + NPairFullSizeNsq, + NP_FULL | NP_SIZE | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 0, 0, 1> NPairHalfSizeNsqNewtoff; +NPairStyle(half/size/nsq/newtoff, + NPairHalfSizeNsqNewtoff, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 1, 0, 1> NPairHalfSizeNsqNewton; +NPairStyle(half/size/nsq/newton, + NPairHalfSizeNsqNewton, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTON | NP_ORTHO); + +typedef NPairNsq<1, 1, 1, 1> NPairHalfSizeNsqNewtonTri; +NPairStyle(half/size/nsq/newton/tri, + NPairHalfSizeNsqNewtonTri, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_NSQ_H +#define LMP_NPAIR_NSQ_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairNsq : public NPair { + public: + NPairNsq(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/npair_half_nsq_newtoff_ghost.cpp b/src/npair_nsq_ghost.cpp similarity index 65% rename from src/npair_half_nsq_newtoff_ghost.cpp rename to src/npair_nsq_ghost.cpp index cef9d5203c..47009deff7 100644 --- a/src/npair_half_nsq_newtoff_ghost.cpp +++ b/src/npair_nsq_ghost.cpp @@ -12,33 +12,42 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "npair_half_nsq_newtoff_ghost.h" +#include "npair_nsq_ghost.h" #include "neigh_list.h" #include "atom.h" #include "atom_vec.h" #include "group.h" #include "molecule.h" +#include "neighbor.h" #include "domain.h" #include "my_page.h" #include "error.h" using namespace LAMMPS_NS; +using namespace NeighConst; /* ---------------------------------------------------------------------- */ -NPairHalfNsqNewtoffGhost::NPairHalfNsqNewtoffGhost(LAMMPS *lmp) : NPair(lmp) {} +template +NPairNsqGhost::NPairNsqGhost(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - include neighbors of ghost atoms, but no "special neighbors" for ghosts - pair stored once if i,j are both owned and i < j - pair stored by me if i owned and j ghost (also stored by proc owning j) - pair stored once if i,j are both ghost and i < j + Full: + N^2 search for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + include neighbors of ghost atoms, but no "special neighbors" for ghosts + pair stored once if i,j are both owned and i < j + pair stored by me if i owned and j ghost (also stored by proc owning j) + pair stored once if i,j are both ghost and i < j ------------------------------------------------------------------------- */ -void NPairHalfNsqNewtoffGhost::build(NeighList *list) +template +void NPairNsqGhost::build(NeighList *list) { - int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + int i,j,jstart,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; int *neighptr; @@ -72,7 +81,6 @@ void NPairHalfNsqNewtoffGhost::build(NeighList *list) ipage->reset(); // loop over owned & ghost atoms, storing neighbors - for (i = 0; i < nall; i++) { n = 0; neighptr = ipage->vget(); @@ -87,23 +95,33 @@ void NPairHalfNsqNewtoffGhost::build(NeighList *list) tagprev = tag[i] - iatom - 1; } - // loop over remaining atoms, owned and ghost - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs with owned atom only, on both procs - // stores ghost/ghost pairs only once + // loop over all atoms, owned and ghost + // Full: + // skip i = j + // Half: + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs with owned atom only, on both procs + // stores ghost/ghost pairs only once // no molecular test when i = ghost atom + if (HALF) jstart = i + 1; + else jstart = 0; + if (i < nlocal) { - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; // JTC: missing in original full version + if (!HALF) { + if (i == j) continue; + } + jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { @@ -121,19 +139,26 @@ void NPairHalfNsqNewtoffGhost::build(NeighList *list) } else neighptr[n++] = j; } } - } else { - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; // JTC: missing in original full version + if (!HALF) { + if (i == j) continue; + } + jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + if (HALF) { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } else { + if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; + } } } @@ -148,3 +173,8 @@ void NPairHalfNsqNewtoffGhost::build(NeighList *list) list->inum = atom->nlocal; list->gnum = inum - atom->nlocal; } + +namespace LAMMPS_NS { +template class NPairNsqGhost<0>; +template class NPairNsqGhost<1>; +} diff --git a/src/npair_half_nsq_newtoff_ghost.h b/src/npair_nsq_ghost.h similarity index 71% rename from src/npair_half_nsq_newtoff_ghost.h rename to src/npair_nsq_ghost.h index 86f3f9e36f..516f0bd929 100644 --- a/src/npair_half_nsq_newtoff_ghost.h +++ b/src/npair_nsq_ghost.h @@ -13,22 +13,29 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairNsqGhost<0> NPairFullNsqGhost; +NPairStyle(full/nsq/ghost, + NPairFullNsqGhost, + NP_FULL | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); + +typedef NPairNsqGhost<1> NPairHalfNsqNewtoffGhost; NPairStyle(half/nsq/newtoff/ghost, NPairHalfNsqNewtoffGhost, NP_HALF | NP_NSQ | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_H -#define LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_H +#ifndef LMP_NPAIR_NSQ_GHOST_H +#define LMP_NPAIR_NSQ_GHOST_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfNsqNewtoffGhost : public NPair { +template +class NPairNsqGhost : public NPair { public: - NPairHalfNsqNewtoffGhost(class LAMMPS *); + NPairNsqGhost(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_respa_bin.cpp b/src/npair_respa_bin.cpp new file mode 100644 index 0000000000..f2fb9f7486 --- /dev/null +++ b/src/npair_respa_bin.cpp @@ -0,0 +1,261 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_respa_bin.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairRespaBin::NPairRespaBin(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + Newtoff + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and surrounding bins in non-Newton stencil + pair stored once if i,j are both owned and i < j + pair stored by me if j is ghost (also stored by proc owning j) + Newton + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairRespaBin::build(NeighList *list) +{ + int i, j, k, n, itype, jtype, ibin, bin_start, n_inner, n_middle, imol, iatom, moltemplate; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int *neighptr, *neighptr_inner, *neighptr_middle; + + const double delta = 0.01 * force->angstrom; + + double **x = atom->x; + int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) + moltemplate = 1; + else + moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_inner = list->ilist_inner; + int *numneigh_inner = list->numneigh_inner; + int **firstneigh_inner = list->firstneigh_inner; + MyPage *ipage_inner = list->ipage_inner; + + int *ilist_middle, *numneigh_middle, **firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + ilist_middle = list->ilist_middle; + numneigh_middle = list->numneigh_middle; + firstneigh_middle = list->firstneigh_middle; + ipage_middle = list->ipage_middle; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; i++) { + n = n_inner = 0; + neighptr = ipage->vget(); + neighptr_inner = ipage_inner->vget(); + if (respamiddle) { + n_middle = 0; + neighptr_middle = ipage_middle->vget(); + } + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + ibin = atom2bin[i]; + + for (k = 0; k < nstencil; k++) { + bin_start = binhead[ibin+stencil[k]]; + if (NEWTON && (!TRI)) { + if (k == 0) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = bin_start; j >= 0; j = bins[j]) { + if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // for triclinic, bin stencil is full in all 3 dims + // must use itag/jtag to eliminate half the I/J interactions + // cannot use I/J exact coord comparision + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift all 3 coords by epsilon + if (j <= i) continue; + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (k == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i], nspecial[i], tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) + neighptr[n++] = j; + else if ((minchange = domain->minimum_image_check(delx, dely, delz))) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; + + if (rsq < cut_inner_sq) { + if (which == 0) + neighptr_inner[n_inner++] = j; + else if (minchange) + neighptr_inner[n_inner++] = j; + else if (which > 0) + neighptr_inner[n_inner++] = j ^ (which << SBBITS); + } + + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (which == 0) + neighptr_middle[n_middle++] = j; + else if (minchange) + neighptr_middle[n_middle++] = j; + else if (which > 0) + neighptr_middle[n_middle++] = j ^ (which << SBBITS); + } + } + } + } + + ilist[inum] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + + ilist_inner[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = i; + firstneigh_middle[i] = neighptr_middle; + numneigh_middle[i] = n_middle; + ipage_middle->vgot(n_middle); + if (ipage_middle->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); + } + + inum++; + } + + list->inum = inum; + list->inum_inner = inum; + if (respamiddle) list->inum_middle = inum; +} + +namespace LAMMPS_NS { +template class NPairRespaBin<0,0>; +template class NPairRespaBin<1,0>; +template class NPairRespaBin<1,1>; +} diff --git a/src/npair_half_respa_bin_newtoff.h b/src/npair_respa_bin.h similarity index 62% rename from src/npair_half_respa_bin_newtoff.h rename to src/npair_respa_bin.h index a6d8b10de0..d721275eb4 100644 --- a/src/npair_half_respa_bin_newtoff.h +++ b/src/npair_respa_bin.h @@ -13,22 +13,34 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairRespaBin<0, 0> NPairHalfRespaBinNewtoff; NPairStyle(half/respa/bin/newtoff, NPairHalfRespaBinNewtoff, NP_HALF | NP_RESPA | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairRespaBin<1, 0> NPairHalfRespaBinNewton; +NPairStyle(half/respa/bin/newton, + NPairHalfRespaBinNewton, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_ORTHO); + +typedef NPairRespaBin<1, 1> NPairHalfRespaBinNewtonTri; +NPairStyle(half/respa/bin/newton/tri, + NPairHalfRespaBinNewtonTri, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_H -#define LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_H +#ifndef LMP_NPAIR_RESPA_BIN_H +#define LMP_NPAIR_RESPA_BIN_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfRespaBinNewtoff : public NPair { +template +class NPairRespaBin : public NPair { public: - NPairHalfRespaBinNewtoff(class LAMMPS *); + NPairRespaBin(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_half_respa_nsq_newton.cpp b/src/npair_respa_nsq.cpp similarity index 56% rename from src/npair_half_respa_nsq_newton.cpp rename to src/npair_respa_nsq.cpp index ae56d62fb5..9ca166a491 100644 --- a/src/npair_half_respa_nsq_newton.cpp +++ b/src/npair_respa_nsq.cpp @@ -12,7 +12,7 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "npair_half_respa_nsq_newton.h" +#include "npair_respa_nsq.h" #include "atom.h" #include "atom_vec.h" @@ -28,26 +28,39 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairHalfRespaNsqNewton::NPairHalfRespaNsqNewton(LAMMPS *lmp) : NPair(lmp) {} +template +NPairRespaNsq::NPairRespaNsq(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- multiple respa lists - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests + Newtoff + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + pair added if j is ghost (also stored by proc owning j) + Newton + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests + use itag/jtag comparision to eliminate half the interactions + itag = jtag is possible for long cutoffs that include images of self + Newton + Triclinic: + for triclinic, must use delta to eliminate half the I/J interactions + cannot use I/J exact coord comparision as for orthog + b/c transforming orthog -> lambda -> orthog for ghost atoms + with an added PBC offset can shift all 3 coords by epsilon + ------------------------------------------------------------------------- */ -void NPairHalfRespaNsqNewton::build(NeighList *list) +template +void NPairRespaNsq::build(NeighList *list) { - int i,j,n,itype,jtype,n_inner,n_middle,bitmask; - int imol,iatom,moltemplate; - tagint itag,jtag,tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; + int i, j, n, itype, jtype, n_inner, n_middle, bitmask, imol, iatom, moltemplate; + tagint itag, jtag, tagprev; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int *neighptr, *neighptr_inner, *neighptr_middle; const double delta = 0.01 * force->angstrom; - const int triclinic = domain->triclinic; double **x = atom->x; int *type = atom->type; @@ -79,7 +92,7 @@ void NPairHalfRespaNsqNewton::build(NeighList *list) int **firstneigh_inner = list->firstneigh_inner; MyPage *ipage_inner = list->ipage_inner; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; + int *ilist_middle, *numneigh_middle, **firstneigh_middle; MyPage *ipage_middle; int respamiddle = list->respamiddle; if (respamiddle) { @@ -105,8 +118,8 @@ void NPairHalfRespaNsqNewton::build(NeighList *list) neighptr_middle = ipage_middle->vget(); } - itag = tag[i]; itype = type[i]; + itag = tag[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; @@ -124,65 +137,74 @@ void NPairHalfRespaNsqNewton::build(NeighList *list) // b/c transforming orthog -> lambda -> orthog for ghost atoms // with an added PBC offset can shift all 3 coords by epsilon - for (j = i+1; j < nall; j++) { + for (j = i + 1; j < nall; j++) { if (includegroup && !(mask[j] & bitmask)) continue; - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else if (triclinic) { - if (fabs(x[j][2]-ztmp) > delta) { - if (x[j][2] < ztmp) continue; - } else if (fabs(x[j][1]-ytmp) > delta) { - if (x[j][1] < ytmp) continue; + if (NEWTON) { + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else if (TRI) { + if (fabs(x[j][2] - ztmp) > delta) { + if (x[j][2] < ztmp) continue; + } else if (fabs(x[j][1] - ytmp) > delta) { + if (x[j][1] < ytmp) continue; + } else { + if (x[j][0] < xtmp) continue; + } } else { - if (x[j][0] < xtmp) continue; - } - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } } } } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq <= cutneighsq[itype][jtype]) { if (molecular != Atom::ATOMIC) { if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); + which = find_special(special[i], nspecial[i], tag[j]); else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if ((minchange = domain->minimum_image_check(delx,dely,delz))) + which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], + tag[j] - tagprev); + else + which = 0; + if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + else if ((minchange = domain->minimum_image_check(delx, dely, delz))) + neighptr[n++] = j; + else if (which > 0) + neighptr[n++] = j ^ (which << SBBITS); + } else + neighptr[n++] = j; if (rsq < cut_inner_sq) { - if (which == 0) neighptr_inner[n_inner++] = j; - else if (minchange) neighptr_inner[n_inner++] = j; - else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); + if (which == 0) + neighptr_inner[n_inner++] = j; + else if (minchange) + neighptr_inner[n_inner++] = j; + else if (which > 0) + neighptr_inner[n_inner++] = j ^ (which << SBBITS); } - if (respamiddle && - rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { - if (which == 0) neighptr_middle[n_middle++] = j; - else if (minchange) neighptr_middle[n_middle++] = j; + if (respamiddle && (rsq < cut_middle_sq) && (rsq > cut_middle_inside_sq)) { + if (which == 0) + neighptr_middle[n_middle++] = j; + else if (minchange) + neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = j ^ (which << SBBITS); } @@ -193,23 +215,20 @@ void NPairHalfRespaNsqNewton::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_inner->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); if (respamiddle) { ilist_middle[inum] = i; firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; ipage_middle->vgot(n_middle); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_middle->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } inum++; @@ -219,3 +238,9 @@ void NPairHalfRespaNsqNewton::build(NeighList *list) list->inum_inner = inum; if (respamiddle) list->inum_middle = inum; } + +namespace LAMMPS_NS { +template class NPairRespaNsq<0,0>; +template class NPairRespaNsq<1,0>; +template class NPairRespaNsq<1,1>; +} diff --git a/src/npair_half_respa_nsq_newtoff.h b/src/npair_respa_nsq.h similarity index 62% rename from src/npair_half_respa_nsq_newtoff.h rename to src/npair_respa_nsq.h index e0f3ae8380..83bed2e8f2 100644 --- a/src/npair_half_respa_nsq_newtoff.h +++ b/src/npair_respa_nsq.h @@ -13,22 +13,34 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairRespaNsq<0,0> NPairHalfRespaNsqNewtoff; NPairStyle(half/respa/nsq/newtoff, NPairHalfRespaNsqNewtoff, NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairRespaNsq<1,0> NPairHalfRespaNsqNewton; +NPairStyle(half/respa/nsq/newton, + NPairHalfRespaNsqNewton, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_ORTHO); + +typedef NPairRespaNsq<1,1> NPairHalfRespaNsqNewtonTri; +NPairStyle(half/respa/nsq/newton/tri, + NPairHalfRespaNsqNewtonTri, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_TRI); // clang-format on #else -#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_H -#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_H +#ifndef LMP_NPAIR_RESPA_NSQ_H +#define LMP_NPAIR_RESPA_NSQ_H #include "npair.h" namespace LAMMPS_NS { -class NPairHalfRespaNsqNewtoff : public NPair { +template +class NPairRespaNsq : public NPair { public: - NPairHalfRespaNsqNewtoff(class LAMMPS *); + NPairRespaNsq(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_skip.cpp b/src/npair_skip.cpp index d9d4fa491f..6afb43bc16 100644 --- a/src/npair_skip.cpp +++ b/src/npair_skip.cpp @@ -22,7 +22,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairSkip::NPairSkip(LAMMPS *lmp) : NPair(lmp) {} +template +NPairSkipTemp::NPairSkipTemp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- build skip list for subset of types from parent list @@ -32,7 +33,8 @@ NPairSkip::NPairSkip(LAMMPS *lmp) : NPair(lmp) {} if ghost, also store neighbors of ghost atoms & set inum,gnum correctly ------------------------------------------------------------------------- */ -void NPairSkip::build(NeighList *list) +template +void NPairSkipTemp::build(NeighList *list) { int i, j, ii, jj, n, itype, jnum, joriginal; int *neighptr, *jlist; @@ -57,6 +59,11 @@ void NPairSkip::build(NeighList *list) int inum = 0; ipage->reset(); + double **x = atom->x; + double xtmp, ytmp, ztmp; + double delx, dely, delz, rsq; + double cutsq_custom = cutoff_custom * cutoff_custom; + // loop over atoms in other list // skip I atom entirely if iskip is set for type[I] // skip I,J pair if ijskip is set for type[I],type[J] @@ -66,6 +73,12 @@ void NPairSkip::build(NeighList *list) itype = type[i]; if (iskip[itype]) continue; + if (TRIM) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + } + n = 0; neighptr = ipage->vget(); @@ -78,6 +91,15 @@ void NPairSkip::build(NeighList *list) joriginal = jlist[jj]; j = joriginal & NEIGHMASK; if (ijskip[itype][type[j]]) continue; + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; } @@ -100,3 +122,8 @@ void NPairSkip::build(NeighList *list) list->gnum = inum - num; } } + +namespace LAMMPS_NS { +template class NPairSkipTemp<0>; +template class NPairSkipTemp<1>; +} diff --git a/src/npair_skip.h b/src/npair_skip.h index 4e85174730..cb0d201555 100644 --- a/src/npair_skip.h +++ b/src/npair_skip.h @@ -13,17 +13,46 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairSkipTemp<0> NPairSkip; NPairStyle(skip, NPairSkip, NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); +typedef NPairSkipTemp<0> NPairSkip; NPairStyle(skip/ghost, NPairSkip, NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_GHOST); + +typedef NPairSkipTemp<0> NPairSkipSize; +NPairStyle(skip/half/size, + NPairSkipSize, + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairSkipTemp<1> NPairSkipTrim; +NPairStyle(skip/trim, + NPairSkipTrim, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); + +typedef NPairSkipTemp<1> NPairSkipTrim; +NPairStyle(skip/ghost/trim, + NPairSkipTrim, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM); + +typedef NPairSkipTemp<1> NPairSkipTrimSize; +NPairStyle(skip/trim/half/size, + NPairSkipTrimSize, + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); + // clang-format on #else @@ -34,9 +63,10 @@ NPairStyle(skip/ghost, namespace LAMMPS_NS { -class NPairSkip : public NPair { +template +class NPairSkipTemp : public NPair { public: - NPairSkip(class LAMMPS *); + NPairSkipTemp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_skip_respa.cpp b/src/npair_skip_respa.cpp index 022c0d5f60..4c3dda91eb 100644 --- a/src/npair_skip_respa.cpp +++ b/src/npair_skip_respa.cpp @@ -23,7 +23,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairSkipRespa::NPairSkipRespa(LAMMPS *lmp) : NPair(lmp) {} +template +NPairSkipRespaTemp::NPairSkipRespaTemp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- build skip list for subset of types from parent list @@ -31,10 +32,11 @@ NPairSkipRespa::NPairSkipRespa(LAMMPS *lmp) : NPair(lmp) {} this is for respa lists, copy the inner/middle values from parent ------------------------------------------------------------------------- */ -void NPairSkipRespa::build(NeighList *list) +template +void NPairSkipRespaTemp::build(NeighList *list) { - int i,j,ii,jj,n,itype,jnum,joriginal,n_inner,n_middle; - int *neighptr,*jlist,*neighptr_inner,*neighptr_middle; + int i, j, ii, jj, n, itype, jnum, joriginal, n_inner, n_middle; + int *neighptr, *jlist, *neighptr_inner, *neighptr_middle; int *type = atom->type; @@ -58,9 +60,9 @@ void NPairSkipRespa::build(NeighList *list) int *numneigh_inner_skip = list->listskip->numneigh_inner; int **firstneigh_inner_skip = list->listskip->firstneigh_inner; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; + int *ilist_middle, *numneigh_middle, **firstneigh_middle; MyPage *ipage_middle; - int *numneigh_middle_skip,**firstneigh_middle_skip; + int *numneigh_middle_skip, **firstneigh_middle_skip; int respamiddle = list->respamiddle; if (respamiddle) { ilist_middle = list->ilist_middle; @@ -76,6 +78,11 @@ void NPairSkipRespa::build(NeighList *list) ipage_inner->reset(); if (respamiddle) ipage_middle->reset(); + double **x = atom->x; + double xtmp, ytmp, ztmp; + double delx, dely, delz, rsq; + double cutsq_custom = cutoff_custom * cutoff_custom; + // loop over atoms in other list // skip I atom entirely if iskip is set for type[I] // skip I,J pair if ijskip is set for type[I],type[J] @@ -85,6 +92,12 @@ void NPairSkipRespa::build(NeighList *list) itype = type[i]; if (iskip[itype]) continue; + if (TRIM) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + } + n = n_inner = 0; neighptr = ipage->vget(); neighptr_inner = ipage_inner->vget(); @@ -102,6 +115,15 @@ void NPairSkipRespa::build(NeighList *list) joriginal = jlist[jj]; j = joriginal & NEIGHMASK; if (ijskip[itype][type[j]]) continue; + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; } @@ -114,6 +136,15 @@ void NPairSkipRespa::build(NeighList *list) joriginal = jlist[jj]; j = joriginal & NEIGHMASK; if (ijskip[itype][type[j]]) continue; + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + neighptr_inner[n_inner++] = joriginal; } @@ -127,6 +158,15 @@ void NPairSkipRespa::build(NeighList *list) joriginal = jlist[jj]; j = joriginal & NEIGHMASK; if (ijskip[itype][type[j]]) continue; + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + neighptr_middle[n_middle++] = joriginal; } } @@ -135,23 +175,20 @@ void NPairSkipRespa::build(NeighList *list) firstneigh[i] = neighptr; numneigh[i] = n; ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); ilist_inner[inum] = i; firstneigh_inner[i] = neighptr_inner; numneigh_inner[i] = n_inner; ipage_inner->vgot(n); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_inner->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); if (respamiddle) { ilist_middle[inum] = i; firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; ipage_middle->vgot(n); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage_middle->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } inum++; @@ -161,3 +198,8 @@ void NPairSkipRespa::build(NeighList *list) list->inum_inner = inum; if (respamiddle) list->inum_middle = inum; } + +namespace LAMMPS_NS { +template class NPairSkipRespaTemp<0>; +template class NPairSkipRespaTemp<1>; +} diff --git a/src/npair_skip_respa.h b/src/npair_skip_respa.h index 822fcc290b..af25e84faf 100644 --- a/src/npair_skip_respa.h +++ b/src/npair_skip_respa.h @@ -13,11 +13,20 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairSkipRespaTemp<0> NPairSkipRespa; NPairStyle(skip/half/respa, NPairSkipRespa, NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairSkipRespaTemp<1> NPairSkipTrimRespa; +NPairStyle(skip/trim/half/respa, + NPairSkipTrimRespa, + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); + // clang-format on #else @@ -28,9 +37,10 @@ NPairStyle(skip/half/respa, namespace LAMMPS_NS { -class NPairSkipRespa : public NPair { +template +class NPairSkipRespaTemp : public NPair { public: - NPairSkipRespa(class LAMMPS *); + NPairSkipRespaTemp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_skip_size.cpp b/src/npair_skip_size.cpp deleted file mode 100644 index 22883b4e60..0000000000 --- a/src/npair_skip_size.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_skip_size.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipSize::NPairSkipSize(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip -------------------------------------------------------------------------- */ - -void NPairSkipSize::build(NeighList *list) -{ - int i, j, ii, jj, n, itype, jnum, joriginal; - int *neighptr, *jlist; - - int *type = atom->type; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - int inum = 0; - ipage->reset(); - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - n = 0; - neighptr = ipage->vget(); - - // loop over parent non-skip size list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_skip_size.h b/src/npair_skip_size.h deleted file mode 100644 index 9c2f23447b..0000000000 --- a/src/npair_skip_size.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/half/size, - NPairSkipSize, - NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_SIZE_H -#define LMP_NPAIR_SKIP_SIZE_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairSkipSize : public NPair { - public: - NPairSkipSize(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_skip_size_off2on.cpp b/src/npair_skip_size_off2on.cpp index f1b6d2f4fb..89e633b238 100644 --- a/src/npair_skip_size_off2on.cpp +++ b/src/npair_skip_size_off2on.cpp @@ -22,7 +22,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairSkipSizeOff2on::NPairSkipSizeOff2on(LAMMPS *lmp) : NPair(lmp) {} +template +NPairSkipSizeOff2onTemp::NPairSkipSizeOff2onTemp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- build skip list for subset of types from parent list @@ -30,7 +31,8 @@ NPairSkipSizeOff2on::NPairSkipSizeOff2on(LAMMPS *lmp) : NPair(lmp) {} parent non-skip list used newton off, this skip list is newton on ------------------------------------------------------------------------- */ -void NPairSkipSizeOff2on::build(NeighList *list) +template +void NPairSkipSizeOff2onTemp::build(NeighList *list) { int i, j, ii, jj, n, itype, jnum, joriginal; tagint itag, jtag; @@ -56,6 +58,11 @@ void NPairSkipSizeOff2on::build(NeighList *list) int inum = 0; ipage->reset(); + double **x = atom->x; + double xtmp, ytmp, ztmp; + double delx, dely, delz, rsq; + double cutsq_custom = cutoff_custom * cutoff_custom; + // loop over atoms in other list // skip I atom entirely if iskip is set for type[I] // skip I,J pair if ijskip is set for type[I],type[J] @@ -66,6 +73,12 @@ void NPairSkipSizeOff2on::build(NeighList *list) if (iskip[itype]) continue; itag = tag[i]; + if (TRIM) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + } + n = 0; neighptr = ipage->vget(); @@ -84,6 +97,14 @@ void NPairSkipSizeOff2on::build(NeighList *list) jtag = tag[j]; if (j >= nlocal && jtag < itag) continue; + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; } @@ -95,3 +116,8 @@ void NPairSkipSizeOff2on::build(NeighList *list) } list->inum = inum; } + +namespace LAMMPS_NS { +template class NPairSkipSizeOff2onTemp<0>; +template class NPairSkipSizeOff2onTemp<1>; +} diff --git a/src/npair_skip_size_off2on.h b/src/npair_skip_size_off2on.h index faed76f6c3..b86100ae20 100644 --- a/src/npair_skip_size_off2on.h +++ b/src/npair_skip_size_off2on.h @@ -13,11 +13,19 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairSkipSizeOff2onTemp<0> NPairSkipSizeOff2on; NPairStyle(skip/size/off2on, NPairSkipSizeOff2on, NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairSkipSizeOff2onTemp<1> NPairSkipTrimSizeOff2on; +NPairStyle(skip/trim/size/off2on, + NPairSkipTrimSizeOff2on, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); // clang-format on #else @@ -28,9 +36,10 @@ NPairStyle(skip/size/off2on, namespace LAMMPS_NS { -class NPairSkipSizeOff2on : public NPair { +template +class NPairSkipSizeOff2onTemp : public NPair { public: - NPairSkipSizeOff2on(class LAMMPS *); + NPairSkipSizeOff2onTemp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_skip_size_off2on_oneside.cpp b/src/npair_skip_size_off2on_oneside.cpp index 3300ef1526..7682b90d95 100644 --- a/src/npair_skip_size_off2on_oneside.cpp +++ b/src/npair_skip_size_off2on_oneside.cpp @@ -24,7 +24,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairSkipSizeOff2onOneside::NPairSkipSizeOff2onOneside(LAMMPS *lmp) : +template +NPairSkipSizeOff2onOnesideTemp::NPairSkipSizeOff2onOnesideTemp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- @@ -34,10 +35,11 @@ NPairSkipSizeOff2onOneside::NPairSkipSizeOff2onOneside(LAMMPS *lmp) : this skip list is newton on and onesided ------------------------------------------------------------------------- */ -void NPairSkipSizeOff2onOneside::build(NeighList *list) +template +void NPairSkipSizeOff2onOnesideTemp::build(NeighList *list) { - int i,j,ii,jj,itype,jnum,joriginal,flip,tmp; - int *surf,*jlist; + int i, j, ii, jj, itype, jnum, joriginal, flip, tmp; + int *surf, *jlist; int *type = atom->type; int nlocal = atom->nlocal; @@ -61,6 +63,11 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) int inum = 0; ipage->reset(); + double **x = atom->x; + double xtmp, ytmp, ztmp; + double delx, dely, delz, rsq; + double cutsq_custom = cutoff_custom * cutoff_custom; + // two loops over parent list required, one to count, one to store // because onesided constraint means pair I,J may be stored with I or J // so don't know in advance how much space to alloc for each atom's neighs @@ -76,6 +83,12 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) itype = type[i]; if (iskip[itype]) continue; + if (TRIM) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + } + // loop over parent non-skip size list jlist = firstneigh_skip[i]; @@ -86,6 +99,14 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) j = joriginal & NEIGHMASK; if (ijskip[itype][type[j]]) continue; + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + // flip I,J if necessary to satisfy onesided constraint // do not keep if I is now ghost @@ -107,8 +128,7 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) for (i = 0; i < nlocal; i++) { if (numneigh[i] == 0) continue; firstneigh[i] = ipage->get(numneigh[i]); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } // second loop over atoms in other list to store neighbors @@ -122,6 +142,12 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) itype = type[i]; if (iskip[itype]) continue; + if (TRIM) { + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + } + // loop over parent non-skip size list and optionally its history info jlist = firstneigh_skip[i]; @@ -132,6 +158,14 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) j = joriginal & NEIGHMASK; if (ijskip[itype][type[j]]) continue; + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq_custom) continue; + } + // flip I,J if necessary to satisfy onesided constraint // do not keep if I is now ghost @@ -158,3 +192,8 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) list->inum = inum; } + +namespace LAMMPS_NS { +template class NPairSkipSizeOff2onOnesideTemp<0>; +template class NPairSkipSizeOff2onOnesideTemp<1>; +} diff --git a/src/npair_skip_size_off2on_oneside.h b/src/npair_skip_size_off2on_oneside.h index 48eccf7faf..a5259ef04b 100644 --- a/src/npair_skip_size_off2on_oneside.h +++ b/src/npair_skip_size_off2on_oneside.h @@ -13,11 +13,19 @@ #ifdef NPAIR_CLASS // clang-format off +typedef NPairSkipSizeOff2onOnesideTemp<0> NPairSkipSizeOff2onOneside; NPairStyle(skip/size/off2on/oneside, NPairSkipSizeOff2onOneside, NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairSkipSizeOff2onOnesideTemp<1> NPairSkipTrimSizeOff2onOneside; +NPairStyle(skip/trim/size/off2on/oneside, + NPairSkipTrimSizeOff2onOneside, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI | NP_TRIM); // clang-format on #else @@ -28,9 +36,10 @@ NPairStyle(skip/size/off2on/oneside, namespace LAMMPS_NS { -class NPairSkipSizeOff2onOneside : public NPair { +template +class NPairSkipSizeOff2onOnesideTemp : public NPair { public: - NPairSkipSizeOff2onOneside(class LAMMPS *); + NPairSkipSizeOff2onOnesideTemp(class LAMMPS *); void build(class NeighList *) override; }; diff --git a/src/npair_skip_trim.cpp b/src/npair_skip_trim.cpp deleted file mode 100644 index a286a7e19e..0000000000 --- a/src/npair_skip_trim.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_skip_trim.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrim::NPairSkipTrim(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - works for half and full lists - works for owned (non-ghost) list, also for ghost list - iskip and ijskip flag which atom types and type pairs to skip - if ghost, also store neighbors of ghost atoms & set inum,gnum correctly -------------------------------------------------------------------------- */ - -void NPairSkipTrim::build(NeighList *list) -{ - int i, j, ii, jj, n, itype, jnum, joriginal; - int *neighptr, *jlist; - - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int num_skip = list->listskip->inum; - if (list->ghost) num_skip += list->listskip->gnum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - int inum = 0; - ipage->reset(); - - double **x = atom->x; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < num_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - n = 0; - neighptr = ipage->vget(); - - // loop over parent non-skip list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - if (list->ghost) { - int num = 0; - for (i = 0; i < inum; i++) - if (ilist[i] < nlocal) - num++; - else - break; - list->inum = num; - list->gnum = inum - num; - } -} diff --git a/src/npair_skip_trim.h b/src/npair_skip_trim.h deleted file mode 100644 index f2a26d654e..0000000000 --- a/src/npair_skip_trim.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim, - NPairSkipTrim, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); - -NPairStyle(skip/ghost/trim, - NPairSkipTrim, - NP_SKIP | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_TRIM_H -#define LMP_NPAIR_SKIP_TRIM_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairSkipTrim : public NPair { - public: - NPairSkipTrim(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_skip_trim_respa.cpp b/src/npair_skip_trim_respa.cpp deleted file mode 100644 index 7dd040ca0a..0000000000 --- a/src/npair_skip_trim_respa.cpp +++ /dev/null @@ -1,193 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_skip_trim_respa.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrimRespa::NPairSkipTrimRespa(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - this is for respa lists, copy the inner/middle values from parent -------------------------------------------------------------------------- */ - -void NPairSkipTrimRespa::build(NeighList *list) -{ - int i,j,ii,jj,n,itype,jnum,joriginal,n_inner,n_middle; - int *neighptr,*jlist,*neighptr_inner,*neighptr_middle; - - int *type = atom->type; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - int *ilist_inner = list->ilist_inner; - int *numneigh_inner = list->numneigh_inner; - int **firstneigh_inner = list->firstneigh_inner; - MyPage *ipage_inner = list->ipage_inner; - int *numneigh_inner_skip = list->listskip->numneigh_inner; - int **firstneigh_inner_skip = list->listskip->firstneigh_inner; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int *numneigh_middle_skip,**firstneigh_middle_skip; - int respamiddle = list->respamiddle; - if (respamiddle) { - ilist_middle = list->ilist_middle; - numneigh_middle = list->numneigh_middle; - firstneigh_middle = list->firstneigh_middle; - ipage_middle = list->ipage_middle; - numneigh_middle_skip = list->listskip->numneigh_middle; - firstneigh_middle_skip = list->listskip->firstneigh_middle; - } - - int inum = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - double **x = atom->x; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - // loop over parent outer rRESPA list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - - // loop over parent inner rRESPA list - - jlist = firstneigh_inner_skip[i]; - jnum = numneigh_inner_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - neighptr_inner[n_inner++] = joriginal; - } - - // loop over parent middle rRESPA list - - if (respamiddle) { - jlist = firstneigh_middle_skip[i]; - jnum = numneigh_middle_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - neighptr_middle[n_middle++] = joriginal; - } - } - - ilist[inum] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - ilist_inner[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - inum++; - } - - list->inum = inum; - list->inum_inner = inum; - if (respamiddle) list->inum_middle = inum; -} diff --git a/src/npair_skip_trim_respa.h b/src/npair_skip_trim_respa.h deleted file mode 100644 index dcfe71c28d..0000000000 --- a/src/npair_skip_trim_respa.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim/half/respa, - NPairSkipTrimRespa, - NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_TRIM_RESPA_H -#define LMP_NPAIR_SKIP_TRIM_RESPA_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairSkipTrimRespa : public NPair { - public: - NPairSkipTrimRespa(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_skip_trim_size.cpp b/src/npair_skip_trim_size.cpp deleted file mode 100644 index fab70a78b5..0000000000 --- a/src/npair_skip_trim_size.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_skip_trim_size.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrimSize::NPairSkipTrimSize(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip -------------------------------------------------------------------------- */ - -void NPairSkipTrimSize::build(NeighList *list) -{ - int i, j, ii, jj, n, itype, jnum, joriginal; - int *neighptr, *jlist; - - int *type = atom->type; - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - int inum = 0; - ipage->reset(); - - double **x = atom->x; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - n = 0; - neighptr = ipage->vget(); - - // loop over parent non-skip size list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/npair_skip_trim_size.h b/src/npair_skip_trim_size.h deleted file mode 100644 index 3b536860ca..0000000000 --- a/src/npair_skip_trim_size.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim/half/size, - NPairSkipTrimSize, - NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_TRIM_SIZE_H -#define LMP_NPAIR_SKIP_TRIM_SIZE_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairSkipTrimSize : public NPair { - public: - NPairSkipTrimSize(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_skip_trim_size_off2on.cpp b/src/npair_skip_trim_size_off2on.cpp deleted file mode 100644 index 3e9a1e5f63..0000000000 --- a/src/npair_skip_trim_size_off2on.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "npair_skip_trim_size_off2on.h" - -#include "atom.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrimSizeOff2on::NPairSkipTrimSizeOff2on(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - parent non-skip list used newton off, this skip list is newton on -------------------------------------------------------------------------- */ - -void NPairSkipTrimSizeOff2on::build(NeighList *list) -{ - int i, j, ii, jj, n, itype, jnum, joriginal; - tagint itag, jtag; - int *neighptr, *jlist; - - tagint *tag = atom->tag; - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - int inum = 0; - ipage->reset(); - - double **x = atom->x; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - double cutsq_custom = cutoff_custom * cutoff_custom; - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - itag = tag[i]; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - n = 0; - neighptr = ipage->vget(); - - // loop over parent non-skip size list and optionally its history info - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - // only keep I,J when J = ghost if Itag < Jtag - - jtag = tag[j]; - if (j >= nlocal && jtag < itag) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); - } - list->inum = inum; -} diff --git a/src/npair_skip_trim_size_off2on.h b/src/npair_skip_trim_size_off2on.h deleted file mode 100644 index 6e52082329..0000000000 --- a/src/npair_skip_trim_size_off2on.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim/size/off2on, - NPairSkipTrimSizeOff2on, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | - NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_TRIM_SIZE_OFF2ON_H -#define LMP_NPAIR_SKIP_TRIM_SIZE_OFF2ON_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairSkipTrimSizeOff2on : public NPair { - public: - NPairSkipTrimSizeOff2on(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_skip_trim_size_off2on_oneside.cpp b/src/npair_skip_trim_size_off2on_oneside.cpp deleted file mode 100644 index 9d43ac8087..0000000000 --- a/src/npair_skip_trim_size_off2on_oneside.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "npair_skip_trim_size_off2on_oneside.h" - -#include "atom.h" -#include "domain.h" -#include "error.h" -#include "my_page.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NPairSkipTrimSizeOff2onOneside::NPairSkipTrimSizeOff2onOneside(LAMMPS *lmp) : - NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - parent non-skip list used newton off and was not onesided, - this skip list is newton on and onesided -------------------------------------------------------------------------- */ - -void NPairSkipTrimSizeOff2onOneside::build(NeighList *list) -{ - int i,j,ii,jj,itype,jnum,joriginal,flip,tmp; - int *surf,*jlist; - - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - if (domain->dimension == 2) surf = atom->line; - else surf = atom->tri; - - int inum = 0; - ipage->reset(); - - double **x = atom->x; - double xtmp, ytmp, ztmp; - double delx, dely, delz, rsq; - double cutsq_custom = cutoff_custom * cutoff_custom; - - // two loops over parent list required, one to count, one to store - // because onesided constraint means pair I,J may be stored with I or J - // so don't know in advance how much space to alloc for each atom's neighs - - // first loop over atoms in other list to count neighbors - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (i = 0; i < nlocal; i++) numneigh[i] = 0; - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over parent non-skip size list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - // flip I,J if necessary to satisfy onesided constraint - // do not keep if I is now ghost - - if (surf[i] >= 0) { - if (j >= nlocal) continue; - tmp = i; - i = j; - j = tmp; - flip = 1; - } else flip = 0; - - numneigh[i]++; - if (flip) i = j; - } - } - - // allocate all per-atom neigh list chunks - - for (i = 0; i < nlocal; i++) { - if (numneigh[i] == 0) continue; - firstneigh[i] = ipage->get(numneigh[i]); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - // second loop over atoms in other list to store neighbors - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (i = 0; i < nlocal; i++) numneigh[i] = 0; - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over parent non-skip size list and optionally its history info - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutsq_custom) continue; - - // flip I,J if necessary to satisfy onesided constraint - // do not keep if I is now ghost - - if (surf[i] >= 0) { - if (j >= nlocal) continue; - tmp = i; - i = j; - j = tmp; - flip = 1; - } else flip = 0; - - // store j in neigh list, not joriginal, like other neigh methods - // OK, b/c there is no special list flagging for surfs - - firstneigh[i][numneigh[i]] = j; - numneigh[i]++; - if (flip) i = j; - } - - // only add atom I to ilist if it has neighbors - - if (numneigh[i]) ilist[inum++] = i; - } - - list->inum = inum; -} diff --git a/src/npair_skip_trim_size_off2on_oneside.h b/src/npair_skip_trim_size_off2on_oneside.h deleted file mode 100644 index 27861123dd..0000000000 --- a/src/npair_skip_trim_size_off2on_oneside.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS -// clang-format off -NPairStyle(skip/trim/size/off2on/oneside, - NPairSkipTrimSizeOff2onOneside, - NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | - NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | - NP_ORTHO | NP_TRI | NP_TRIM); -// clang-format on -#else - -#ifndef LMP_NPAIR_SKIP_TRIM_SIZE_OFF2ON_ONESIDE_H -#define LMP_NPAIR_SKIP_TRIM_SIZE_OFF2ON_ONESIDE_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairSkipTrimSizeOff2onOneside : public NPair { - public: - NPairSkipTrimSizeOff2onOneside(class LAMMPS *); - void build(class NeighList *) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/npair_trim.cpp b/src/npair_trim.cpp index f026466f92..1b25646185 100644 --- a/src/npair_trim.cpp +++ b/src/npair_trim.cpp @@ -12,6 +12,7 @@ ------------------------------------------------------------------------- */ #include "npair_trim.h" + #include "atom.h" #include "error.h" #include "my_page.h" diff --git a/src/nstencil.cpp b/src/nstencil.cpp index 5bbcb1210d..5d2bf5d239 100644 --- a/src/nstencil.cpp +++ b/src/nstencil.cpp @@ -84,6 +84,7 @@ NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp) flag_half_multi = nullptr; flag_skip_multi = nullptr; + flag_same_multi = nullptr; bin_collection_multi = nullptr; maxcollections = 0; @@ -122,6 +123,7 @@ NStencil::~NStencil() memory->destroy(maxstencil_multi); memory->destroy(flag_half_multi); memory->destroy(flag_skip_multi); + memory->destroy(flag_same_multi); memory->destroy(bin_collection_multi); memory->destroy(stencil_sx_multi); @@ -289,6 +291,7 @@ void NStencil::create_setup() memory->destroy(maxstencil_multi); memory->destroy(flag_half_multi); memory->destroy(flag_skip_multi); + memory->destroy(flag_same_multi); memory->destroy(bin_collection_multi); memory->destroy(stencil_sx_multi); memory->destroy(stencil_sy_multi); @@ -307,6 +310,8 @@ void NStencil::create_setup() "neighstencil:flag_half_multi"); memory->create(flag_skip_multi, n, n, "neighstencil:flag_skip_multi"); + memory->create(flag_same_multi, n, n, + "neighstencil:flag_same_multi"); memory->create(bin_collection_multi, n, n, "neighstencil:bin_collection_multi"); diff --git a/src/nstencil.h b/src/nstencil.h index 6ae7f05dfb..dcb5219a3f 100644 --- a/src/nstencil.h +++ b/src/nstencil.h @@ -45,6 +45,7 @@ class NStencil : protected Pointers { // Arrays to store options for multi itype-jtype stencils bool **flag_half_multi; // flag creation of a half stencil for icollection-jcollection bool **flag_skip_multi; // skip creation of icollection-jcollection stencils (for newton on) + bool **flag_same_multi; // flag same size collection (doesn't always correspond to a half, e.g. newton + tri) int **bin_collection_multi; // what collection to use for bin information NStencil(class LAMMPS *); diff --git a/src/nstencil_bin.cpp b/src/nstencil_bin.cpp new file mode 100644 index 0000000000..ccefa16978 --- /dev/null +++ b/src/nstencil_bin.cpp @@ -0,0 +1,76 @@ +/* ---------------------------------------------------------------------- + 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 "nstencil_bin.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NStencilBin::NStencilBin(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +template +void NStencilBin::create() +{ + int i, j, k; + + // For half stencils, only the upper plane is needed + // for triclinic, need to use full stencil in all dims + // not a half stencil in y + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift both coords by epsilon + // thus for an I/J owned/ghost pair, the xy coords + // and bin assignments can be different on I proc vs J proc + + int sy_min = sy; + int sz_min = sz; + if ((!TRI) && HALF && (!DIM_3D)) sy_min = 0; + if ((!TRI) && HALF && DIM_3D) sz_min = 0; + + nstencil = 0; + + // Half and ortho stencils include central bin first + // This preserves the historical order of the neighbor list + // as the old npair classes used to separately parse the central bin first + if (HALF && (!TRI)) stencil[nstencil++] = 0; + + for (k = -sz_min; k <= sz; k++) { + for (j = -sy_min; j <= sy; j++) { + for (i = -sx; i <= sx; i++) { + + // Now only include "upper right" bins for half and ortho stencils + if (HALF && (!DIM_3D) && (!TRI)) + if (j <= 0 && (j != 0 || i <= 0)) continue; + if (HALF && DIM_3D && (!TRI)) + if (k <= 0 && j <= 0 && (j != 0 || i <= 0)) continue; + + if (bin_distance(i, j, k) < cutneighmaxsq) + stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i; + } + } + } +} + +namespace LAMMPS_NS { +template class NStencilBin<0,0,0>; +template class NStencilBin<0,1,0>; +template class NStencilBin<1,0,0>; +template class NStencilBin<1,0,1>; +template class NStencilBin<1,1,0>; +template class NStencilBin<1,1,1>; +} diff --git a/src/nstencil_bin.h b/src/nstencil_bin.h new file mode 100644 index 0000000000..889725dd1a --- /dev/null +++ b/src/nstencil_bin.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS +// clang-format off +typedef NStencilBin<0, 0, 0> NStencilFullBin2d; +NStencilStyle(full/bin/2d, + NStencilFullBin2d, + NS_FULL | NS_BIN | NS_2D | NS_ORTHO | NS_TRI); + +typedef NStencilBin<0, 1, 0> NStencilFullBin3d; +NStencilStyle(full/bin/3d, + NStencilFullBin3d, + NS_FULL | NS_BIN | NS_3D | NS_ORTHO | NS_TRI); + +typedef NStencilBin<1, 0, 0> NStencilHalfBin2d; +NStencilStyle(half/bin/2d, + NStencilHalfBin2d, + NS_HALF | NS_BIN | NS_2D | NS_ORTHO); + +typedef NStencilBin<1, 0, 1> NStencilHalfBin2dTri; +NStencilStyle(half/bin/2d/tri, + NStencilHalfBin2dTri, + NS_HALF | NS_BIN | NS_2D | NS_TRI); + +typedef NStencilBin<1, 1, 0> NStencilHalfBin3d; +NStencilStyle(half/bin/3d, + NStencilHalfBin3d, + NS_HALF | NS_BIN | NS_3D | NS_ORTHO); + +typedef NStencilBin<1, 1, 1> NStencilHalfBin3dTri; +NStencilStyle(half/bin/3d/tri, + NStencilHalfBin3dTri, + NS_HALF | NS_BIN | NS_3D | NS_TRI); +// clang-format on +#else + +#ifndef LMP_NSTENCIL_BIN_H +#define LMP_NSTENCIL_BIN_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +template +class NStencilBin : public NStencil { + public: + NStencilBin(class LAMMPS *); + void create() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/nstencil_full_bin_2d.cpp b/src/nstencil_full_bin_2d.cpp deleted file mode 100644 index cbcdc6e797..0000000000 --- a/src/nstencil_full_bin_2d.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_bin_2d.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullBin2d::NStencilFullBin2d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullBin2d::create() -{ - int i, j; - - nstencil = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i, j, 0) < cutneighmaxsq) stencil[nstencil++] = j * mbinx + i; -} diff --git a/src/nstencil_full_bin_2d.h b/src/nstencil_full_bin_2d.h deleted file mode 100644 index c3cdbb3b9b..0000000000 --- a/src/nstencil_full_bin_2d.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(full/bin/2d, - NStencilFullBin2d, - NS_FULL | NS_BIN | NS_2D | NS_ORTHO | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_FULL_BIN_2D_H -#define LMP_NSTENCIL_FULL_BIN_2D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilFullBin2d : public NStencil { - public: - NStencilFullBin2d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_full_bin_3d.cpp b/src/nstencil_full_bin_3d.cpp deleted file mode 100644 index e305abc764..0000000000 --- a/src/nstencil_full_bin_3d.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_bin_3d.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullBin3d::NStencilFullBin3d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullBin3d::create() -{ - int i, j, k; - - nstencil = 0; - - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i, j, k) < cutneighmaxsq) - stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i; -} diff --git a/src/nstencil_full_bin_3d.h b/src/nstencil_full_bin_3d.h deleted file mode 100644 index 73da08b840..0000000000 --- a/src/nstencil_full_bin_3d.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(full/bin/3d, - NStencilFullBin3d, - NS_FULL | NS_BIN | NS_3D | NS_ORTHO | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_FULL_BIN_3D_H -#define LMP_NSTENCIL_FULL_BIN_3D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilFullBin3d : public NStencil { - public: - NStencilFullBin3d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_full_ghost_bin_2d.cpp b/src/nstencil_full_ghost_bin_2d.cpp deleted file mode 100644 index 0429624cb1..0000000000 --- a/src/nstencil_full_ghost_bin_2d.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_ghost_bin_2d.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullGhostBin2d::NStencilFullGhostBin2d(LAMMPS *lmp) : NStencil(lmp) -{ - xyzflag = 1; -} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullGhostBin2d::create() -{ - int i, j; - - nstencil = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i, j, 0) < cutneighmaxsq) { - stencilxyz[nstencil][0] = i; - stencilxyz[nstencil][1] = j; - stencilxyz[nstencil][2] = 0; - stencil[nstencil++] = j * mbinx + i; - } -} diff --git a/src/nstencil_full_multi_2d.cpp b/src/nstencil_full_multi_2d.cpp deleted file mode 100644 index b49e245d25..0000000000 --- a/src/nstencil_full_multi_2d.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_multi_2d.h" - -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullMulti2d::NStencilFullMulti2d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void NStencilFullMulti2d::set_stencil_properties() -{ - int n = ncollections; - int i, j; - - // Always look up neighbor using full stencil and neighbor's bin - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - flag_half_multi[i][j] = false; - flag_skip_multi[i][j] = false; - bin_collection_multi[i][j] = j; - } - } -} - -/* ---------------------------------------------------------------------- - create stencils based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullMulti2d::create() -{ - int icollection, jcollection, bin_collection, i, j, ns; - int n = ncollections; - double cutsq; - - for (icollection = 0; icollection < n; icollection++) { - for (jcollection = 0; jcollection < n; jcollection++) { - if (flag_skip_multi[icollection][jcollection]) { - nstencil_multi[icollection][jcollection] = 0; - continue; - } - - ns = 0; - - sx = stencil_sx_multi[icollection][jcollection]; - sy = stencil_sy_multi[icollection][jcollection]; - - mbinx = stencil_mbinx_multi[icollection][jcollection]; - mbiny = stencil_mbiny_multi[icollection][jcollection]; - - bin_collection = bin_collection_multi[icollection][jcollection]; - - cutsq = cutcollectionsq[icollection][jcollection]; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, 0, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j * mbinx + i; - - nstencil_multi[icollection][jcollection] = ns; - } - } -} diff --git a/src/nstencil_full_multi_2d.h b/src/nstencil_full_multi_2d.h deleted file mode 100644 index 6b9c98bd89..0000000000 --- a/src/nstencil_full_multi_2d.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(full/multi/2d, - NStencilFullMulti2d, NS_FULL | NS_MULTI | NS_2D | NS_ORTHO | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_FULL_MULTI_2D_H -#define LMP_NSTENCIL_FULL_MULTI_2D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilFullMulti2d : public NStencil { - public: - NStencilFullMulti2d(class LAMMPS *); - void create() override; - - protected: - void set_stencil_properties() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_full_multi_3d.cpp b/src/nstencil_full_multi_3d.cpp deleted file mode 100644 index d2d5faec62..0000000000 --- a/src/nstencil_full_multi_3d.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_multi_3d.h" - -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullMulti3d::NStencilFullMulti3d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void NStencilFullMulti3d::set_stencil_properties() -{ - int n = ncollections; - int i, j; - - // Always look up neighbor using full stencil and neighbor's bin - // Stencil cutoff set by i-j cutoff - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - flag_half_multi[i][j] = true; - flag_skip_multi[i][j] = false; - bin_collection_multi[i][j] = j; - } - } -} - -/* ---------------------------------------------------------------------- - create stencils based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullMulti3d::create() -{ - int icollection, jcollection, bin_collection, i, j, k, ns; - int n = ncollections; - double cutsq; - - for (icollection = 0; icollection < n; icollection++) { - for (jcollection = 0; jcollection < n; jcollection++) { - if (flag_skip_multi[icollection][jcollection]) { - nstencil_multi[icollection][jcollection] = 0; - continue; - } - - ns = 0; - - sx = stencil_sx_multi[icollection][jcollection]; - sy = stencil_sy_multi[icollection][jcollection]; - sz = stencil_sz_multi[icollection][jcollection]; - - mbinx = stencil_mbinx_multi[icollection][jcollection]; - mbiny = stencil_mbiny_multi[icollection][jcollection]; - mbinz = stencil_mbinz_multi[icollection][jcollection]; - - bin_collection = bin_collection_multi[icollection][jcollection]; - - cutsq = cutcollectionsq[icollection][jcollection]; - - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, k, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = k * mbiny * mbinx + j * mbinx + i; - - nstencil_multi[icollection][jcollection] = ns; - } - } -} diff --git a/src/nstencil_full_multi_3d.h b/src/nstencil_full_multi_3d.h deleted file mode 100644 index e4d4691139..0000000000 --- a/src/nstencil_full_multi_3d.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(full/multi/3d, - NStencilFullMulti3d, NS_FULL | NS_MULTI | NS_3D | NS_ORTHO | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_FULL_MULTI_3D_H -#define LMP_NSTENCIL_FULL_MULTI_3D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilFullMulti3d : public NStencil { - public: - NStencilFullMulti3d(class LAMMPS *); - void create() override; - - protected: - void set_stencil_properties() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_full_multi_old_2d.cpp b/src/nstencil_full_multi_old_2d.cpp deleted file mode 100644 index 80d7275279..0000000000 --- a/src/nstencil_full_multi_old_2d.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_multi_old_2d.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullMultiOld2d::NStencilFullMultiOld2d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullMultiOld2d::create() -{ - int i, j, n; - double rsq, typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - n = 0; - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i, j, 0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j * mbinx + i; - } - } - nstencil_multi_old[itype] = n; - } -} diff --git a/src/nstencil_full_multi_old_2d.h b/src/nstencil_full_multi_old_2d.h deleted file mode 100644 index 713a88d549..0000000000 --- a/src/nstencil_full_multi_old_2d.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(full/multi/old/2d, - NStencilFullMultiOld2d, - NS_FULL | NS_MULTI_OLD | NS_2D | NS_ORTHO | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_FULL_MULTI_OLD_2D_H -#define LMP_NSTENCIL_FULL_MULTI_OLD_2D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilFullMultiOld2d : public NStencil { - public: - NStencilFullMultiOld2d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_full_multi_old_3d.cpp b/src/nstencil_full_multi_old_3d.cpp deleted file mode 100644 index c733bc8e88..0000000000 --- a/src/nstencil_full_multi_old_3d.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_full_multi_old_3d.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilFullMultiOld3d::NStencilFullMultiOld3d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilFullMultiOld3d::create() -{ - int i, j, k, n; - double rsq, typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - n = 0; - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i, j, k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k * mbiny * mbinx + j * mbinx + i; - } - } - nstencil_multi_old[itype] = n; - } -} diff --git a/src/nstencil_full_multi_old_3d.h b/src/nstencil_full_multi_old_3d.h deleted file mode 100644 index 9ebaed6154..0000000000 --- a/src/nstencil_full_multi_old_3d.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(full/multi/old/3d, - NStencilFullMultiOld3d, - NS_FULL | NS_MULTI_OLD | NS_3D | NS_ORTHO | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_FULL_MULTI_OLD_3D_H -#define LMP_NSTENCIL_FULL_MULTI_OLD_3D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilFullMultiOld3d : public NStencil { - public: - NStencilFullMultiOld3d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_full_ghost_bin_3d.cpp b/src/nstencil_ghost_bin.cpp similarity index 75% rename from src/nstencil_full_ghost_bin_3d.cpp rename to src/nstencil_ghost_bin.cpp index 866f391b90..81372bedaf 100644 --- a/src/nstencil_full_ghost_bin_3d.cpp +++ b/src/nstencil_ghost_bin.cpp @@ -11,13 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include "nstencil_full_ghost_bin_3d.h" +#include "nstencil_ghost_bin.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NStencilFullGhostBin3d::NStencilFullGhostBin3d(LAMMPS *lmp) : NStencil(lmp) +template +NStencilGhostBin::NStencilGhostBin(LAMMPS *lmp) : NStencil(lmp) { xyzflag = 1; } @@ -26,19 +27,28 @@ NStencilFullGhostBin3d::NStencilFullGhostBin3d(LAMMPS *lmp) : NStencil(lmp) create stencil based on bin geometry and cutoff ------------------------------------------------------------------------- */ -void NStencilFullGhostBin3d::create() +template +void NStencilGhostBin::create() { int i, j, k; nstencil = 0; - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) + for (k = -sz; k <= sz; k++) { + for (j = -sy; j <= sy; j++) { + for (i = -sx; i <= sx; i++) { if (bin_distance(i, j, k) < cutneighmaxsq) { stencilxyz[nstencil][0] = i; stencilxyz[nstencil][1] = j; stencilxyz[nstencil][2] = k; stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i; } + } + } + } +} + +namespace LAMMPS_NS { +template class NStencilGhostBin<0>; +template class NStencilGhostBin<1>; } diff --git a/src/nstencil_full_ghost_bin_2d.h b/src/nstencil_ghost_bin.h similarity index 70% rename from src/nstencil_full_ghost_bin_2d.h rename to src/nstencil_ghost_bin.h index 2907880c92..ed4ae21be9 100644 --- a/src/nstencil_full_ghost_bin_2d.h +++ b/src/nstencil_ghost_bin.h @@ -13,22 +13,29 @@ #ifdef NSTENCIL_CLASS // clang-format off +typedef NStencilGhostBin<0> NStencilFullGhostBin2d; NStencilStyle(full/ghost/bin/2d, NStencilFullGhostBin2d, NS_FULL | NS_GHOST | NS_BIN | NS_2D | NS_ORTHO | NS_TRI); + +typedef NStencilGhostBin<1> NStencilFullGhostBin3d; +NStencilStyle(full/ghost/bin/3d, + NStencilFullGhostBin3d, + NS_FULL | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO | NS_TRI); // clang-format on #else -#ifndef LMP_NSTENCIL_FULL_GHOST_BIN_2D_H -#define LMP_NSTENCIL_FULL_GHOST_BIN_2D_H +#ifndef LMP_NSTENCIL_GHOST_BIN_H +#define LMP_NSTENCIL_GHOST_BIN_H #include "nstencil.h" namespace LAMMPS_NS { -class NStencilFullGhostBin2d : public NStencil { +template +class NStencilGhostBin : public NStencil { public: - NStencilFullGhostBin2d(class LAMMPS *); + NStencilGhostBin(class LAMMPS *); void create() override; }; diff --git a/src/nstencil_half_bin_2d.cpp b/src/nstencil_half_bin_2d.cpp deleted file mode 100644 index c65095a3b0..0000000000 --- a/src/nstencil_half_bin_2d.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_bin_2d.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin2d::NStencilHalfBin2d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfBin2d::create() -{ - int i, j; - - nstencil = 0; - - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) - if (bin_distance(i, j, 0) < cutneighmaxsq) stencil[nstencil++] = j * mbinx + i; -} diff --git a/src/nstencil_half_bin_2d.h b/src/nstencil_half_bin_2d.h deleted file mode 100644 index 506136b41d..0000000000 --- a/src/nstencil_half_bin_2d.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/bin/2d, - NStencilHalfBin2d, - NS_HALF | NS_BIN | NS_2D | NS_ORTHO); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_BIN_2D_H -#define LMP_NSTENCIL_HALF_BIN_2D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin2d : public NStencil { - public: - NStencilHalfBin2d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_bin_2d_tri.cpp b/src/nstencil_half_bin_2d_tri.cpp deleted file mode 100644 index 920918fe09..0000000000 --- a/src/nstencil_half_bin_2d_tri.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_bin_2d_tri.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin2dTri::NStencilHalfBin2dTri(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfBin2dTri::create() -{ - int i, j; - - // for triclinic, need to use full stencil in all dims - // not a half stencil in y - // b/c transforming orthog -> lambda -> orthog for ghost atoms - // with an added PBC offset can shift both coords by epsilon - // thus for an I/J owned/ghost pair, the xy coords - // and bin assignments can be different on I proc vs J proc - - nstencil = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i, j, 0) < cutneighmaxsq) - stencil[nstencil++] = j * mbinx + i; -} diff --git a/src/nstencil_half_bin_2d_tri.h b/src/nstencil_half_bin_2d_tri.h deleted file mode 100644 index 2873b7d92f..0000000000 --- a/src/nstencil_half_bin_2d_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/bin/2d/tri, - NStencilHalfBin2dTri, - NS_HALF | NS_BIN | NS_2D | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_BIN_2D_TRI_H -#define LMP_NSTENCIL_HALF_BIN_2D_TRI_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin2dTri : public NStencil { - public: - NStencilHalfBin2dTri(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_bin_3d.cpp b/src/nstencil_half_bin_3d.cpp deleted file mode 100644 index 90d8e45053..0000000000 --- a/src/nstencil_half_bin_3d.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_bin_3d.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin3d::NStencilHalfBin3d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfBin3d::create() -{ - int i, j, k; - - nstencil = 0; - - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) - if (bin_distance(i, j, k) < cutneighmaxsq) - stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i; -} diff --git a/src/nstencil_half_bin_3d.h b/src/nstencil_half_bin_3d.h deleted file mode 100644 index 2b612a4a0a..0000000000 --- a/src/nstencil_half_bin_3d.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/bin/3d, - NStencilHalfBin3d, - NS_HALF | NS_BIN | NS_3D | NS_ORTHO); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_BIN_3D_H -#define LMP_NSTENCIL_HALF_BIN_3D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin3d : public NStencil { - public: - NStencilHalfBin3d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_bin_3d_tri.h b/src/nstencil_half_bin_3d_tri.h deleted file mode 100644 index ad24ab0a06..0000000000 --- a/src/nstencil_half_bin_3d_tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/bin/3d/tri, - NStencilHalfBin3dTri, - NS_HALF | NS_BIN | NS_3D | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_BIN_3D_TRI_H -#define LMP_NSTENCIL_HALF_BIN_3D_TRI_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin3dTri : public NStencil { - public: - NStencilHalfBin3dTri(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_2d.cpp b/src/nstencil_half_multi_2d.cpp deleted file mode 100644 index 5932ccae64..0000000000 --- a/src/nstencil_half_multi_2d.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_2d.h" - -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMulti2d::NStencilHalfMulti2d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void NStencilHalfMulti2d::set_stencil_properties() -{ - int n = ncollections; - int i, j; - - // Cross collections: use full stencil, looking one way through hierarchy - // smaller -> larger => use full stencil in larger bin - // larger -> smaller => no nstencil required - // If cut offs are same, use half stencil - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - if (cutcollectionsq[i][i] > cutcollectionsq[j][j]) continue; - - flag_skip_multi[i][j] = false; - - if (cutcollectionsq[i][i] == cutcollectionsq[j][j]) { - flag_half_multi[i][j] = true; - bin_collection_multi[i][j] = i; - } else { - flag_half_multi[i][j] = false; - bin_collection_multi[i][j] = j; - } - } - } -} - -/* ---------------------------------------------------------------------- - create stencils based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMulti2d::create() -{ - int icollection, jcollection, bin_collection, i, j, ns; - int n = ncollections; - double cutsq; - - for (icollection = 0; icollection < n; icollection++) { - for (jcollection = 0; jcollection < n; jcollection++) { - if (flag_skip_multi[icollection][jcollection]) { - nstencil_multi[icollection][jcollection] = 0; - continue; - } - - ns = 0; - - sx = stencil_sx_multi[icollection][jcollection]; - sy = stencil_sy_multi[icollection][jcollection]; - - mbinx = stencil_mbinx_multi[icollection][jcollection]; - mbiny = stencil_mbiny_multi[icollection][jcollection]; - - bin_collection = bin_collection_multi[icollection][jcollection]; - - cutsq = cutcollectionsq[icollection][jcollection]; - - if (flag_half_multi[icollection][jcollection]) { - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) { - if (bin_distance_multi(i, j, 0, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j * mbinx + i; - } - } else { - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, 0, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j * mbinx + i; - } - nstencil_multi[icollection][jcollection] = ns; - } - } -} diff --git a/src/nstencil_half_multi_2d.h b/src/nstencil_half_multi_2d.h deleted file mode 100644 index a87f517b5b..0000000000 --- a/src/nstencil_half_multi_2d.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/2d, - NStencilHalfMulti2d, NS_HALF | NS_MULTI | NS_2D | NS_ORTHO); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_2D_H -#define LMP_NSTENCIL_HALF_MULTI_2D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMulti2d : public NStencil { - public: - NStencilHalfMulti2d(class LAMMPS *); - void create() override; - - protected: - void set_stencil_properties() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_2d_tri.cpp b/src/nstencil_half_multi_2d_tri.cpp deleted file mode 100644 index 85bbe94c86..0000000000 --- a/src/nstencil_half_multi_2d_tri.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_2d_tri.h" - -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMulti2dTri::NStencilHalfMulti2dTri(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void NStencilHalfMulti2dTri::set_stencil_properties() -{ - int n = ncollections; - int i, j; - - // Cross collections: use full stencil, looking one way through hierarchy - // smaller -> larger => use full stencil in larger bin - // larger -> smaller => no nstencil required - // If cut offs are same, use half stencil - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - if (cutcollectionsq[i][i] > cutcollectionsq[j][j]) continue; - - flag_skip_multi[i][j] = false; - - if (cutcollectionsq[i][i] == cutcollectionsq[j][j]) { - flag_half_multi[i][j] = true; - bin_collection_multi[i][j] = i; - } else { - flag_half_multi[i][j] = false; - bin_collection_multi[i][j] = j; - } - } - } -} - -/* ---------------------------------------------------------------------- - create stencils based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMulti2dTri::create() -{ - int icollection, jcollection, bin_collection, i, j, ns; - int n = ncollections; - double cutsq; - - for (icollection = 0; icollection < n; icollection++) { - for (jcollection = 0; jcollection < n; jcollection++) { - if (flag_skip_multi[icollection][jcollection]) { - nstencil_multi[icollection][jcollection] = 0; - continue; - } - - ns = 0; - - sx = stencil_sx_multi[icollection][jcollection]; - sy = stencil_sy_multi[icollection][jcollection]; - - mbinx = stencil_mbinx_multi[icollection][jcollection]; - mbiny = stencil_mbiny_multi[icollection][jcollection]; - - bin_collection = bin_collection_multi[icollection][jcollection]; - - cutsq = cutcollectionsq[icollection][jcollection]; - - if (flag_half_multi[icollection][jcollection]) { - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, 0, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j * mbinx + i; - } else { - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, 0, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j * mbinx + i; - } - nstencil_multi[icollection][jcollection] = ns; - } - } -} diff --git a/src/nstencil_half_multi_2d_tri.h b/src/nstencil_half_multi_2d_tri.h deleted file mode 100644 index 6067afbb50..0000000000 --- a/src/nstencil_half_multi_2d_tri.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/2d/tri, - NStencilHalfMulti2dTri, NS_HALF | NS_MULTI | NS_2D | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_2D_TRI_H -#define LMP_NSTENCIL_HALF_MULTI_2D_TRI_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMulti2dTri : public NStencil { - public: - NStencilHalfMulti2dTri(class LAMMPS *); - void create() override; - - protected: - void set_stencil_properties() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_3d.cpp b/src/nstencil_half_multi_3d.cpp deleted file mode 100644 index 8b1a1d85c5..0000000000 --- a/src/nstencil_half_multi_3d.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_3d.h" - -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMulti3d::NStencilHalfMulti3d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void NStencilHalfMulti3d::set_stencil_properties() -{ - int n = ncollections; - int i, j; - - // Cross collections: use full stencil, looking one way through hierarchy - // smaller -> larger => use full stencil in larger bin - // larger -> smaller => no nstencil required - // If cut offs are same, use half stencil - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - if (cutcollectionsq[i][i] > cutcollectionsq[j][j]) continue; - - flag_skip_multi[i][j] = false; - - if (cutcollectionsq[i][i] == cutcollectionsq[j][j]) { - flag_half_multi[i][j] = true; - bin_collection_multi[i][j] = i; - } else { - flag_half_multi[i][j] = false; - bin_collection_multi[i][j] = j; - } - } - } -} - -/* ---------------------------------------------------------------------- - create stencils based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMulti3d::create() -{ - int icollection, jcollection, bin_collection, i, j, k, ns; - int n = ncollections; - double cutsq; - - for (icollection = 0; icollection < n; icollection++) { - for (jcollection = 0; jcollection < n; jcollection++) { - if (flag_skip_multi[icollection][jcollection]) { - nstencil_multi[icollection][jcollection] = 0; - continue; - } - - ns = 0; - - sx = stencil_sx_multi[icollection][jcollection]; - sy = stencil_sy_multi[icollection][jcollection]; - sz = stencil_sz_multi[icollection][jcollection]; - - mbinx = stencil_mbinx_multi[icollection][jcollection]; - mbiny = stencil_mbiny_multi[icollection][jcollection]; - mbinz = stencil_mbinz_multi[icollection][jcollection]; - - bin_collection = bin_collection_multi[icollection][jcollection]; - - cutsq = cutcollectionsq[icollection][jcollection]; - - if (flag_half_multi[icollection][jcollection]) { - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) { - if (bin_distance_multi(i, j, k, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = k * mbiny * mbinx + j * mbinx + i; - } - } else { - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, k, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = k * mbiny * mbinx + j * mbinx + i; - } - nstencil_multi[icollection][jcollection] = ns; - } - } -} diff --git a/src/nstencil_half_multi_3d.h b/src/nstencil_half_multi_3d.h deleted file mode 100644 index c9281cab19..0000000000 --- a/src/nstencil_half_multi_3d.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/3d, - NStencilHalfMulti3d, NS_HALF | NS_MULTI | NS_3D | NS_ORTHO); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_3D_H -#define LMP_NSTENCIL_HALF_MULTI_3D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMulti3d : public NStencil { - public: - NStencilHalfMulti3d(class LAMMPS *); - void create() override; - - protected: - void set_stencil_properties() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_3d_tri.cpp b/src/nstencil_half_multi_3d_tri.cpp deleted file mode 100644 index 9761e15854..0000000000 --- a/src/nstencil_half_multi_3d_tri.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_3d_tri.h" - -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMulti3dTri::NStencilHalfMulti3dTri(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void NStencilHalfMulti3dTri::set_stencil_properties() -{ - int n = ncollections; - int i, j; - - // Cross collections: use full stencil, looking one way through hierarchy - // smaller -> larger => use full stencil in larger bin - // larger -> smaller => no nstencil required - // If cut offs are same, use half stencil - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - if (cutcollectionsq[i][i] > cutcollectionsq[j][j]) continue; - - flag_skip_multi[i][j] = false; - - if (cutcollectionsq[i][i] == cutcollectionsq[j][j]) { - flag_half_multi[i][j] = true; - bin_collection_multi[i][j] = i; - } else { - flag_half_multi[i][j] = false; - bin_collection_multi[i][j] = j; - } - } - } -} - -/* ---------------------------------------------------------------------- - create stencils based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMulti3dTri::create() -{ - int icollection, jcollection, bin_collection, i, j, k, ns; - int n = ncollections; - double cutsq; - - for (icollection = 0; icollection < n; icollection++) { - for (jcollection = 0; jcollection < n; jcollection++) { - if (flag_skip_multi[icollection][jcollection]) { - nstencil_multi[icollection][jcollection] = 0; - continue; - } - - ns = 0; - - sx = stencil_sx_multi[icollection][jcollection]; - sy = stencil_sy_multi[icollection][jcollection]; - sz = stencil_sz_multi[icollection][jcollection]; - - mbinx = stencil_mbinx_multi[icollection][jcollection]; - mbiny = stencil_mbiny_multi[icollection][jcollection]; - mbinz = stencil_mbinz_multi[icollection][jcollection]; - - bin_collection = bin_collection_multi[icollection][jcollection]; - cutsq = cutcollectionsq[icollection][jcollection]; - - if (flag_half_multi[icollection][jcollection]) { - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, k, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = k * mbiny * mbinx + j * mbinx + i; - } else { - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i, j, k, bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = k * mbiny * mbinx + j * mbinx + i; - } - nstencil_multi[icollection][jcollection] = ns; - } - } -} diff --git a/src/nstencil_half_multi_3d_tri.h b/src/nstencil_half_multi_3d_tri.h deleted file mode 100644 index 9a55c10f1d..0000000000 --- a/src/nstencil_half_multi_3d_tri.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/3d/tri, - NStencilHalfMulti3dTri, NS_HALF | NS_MULTI | NS_3D | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_3D_TRI_H -#define LMP_NSTENCIL_HALF_MULTI_3D_TRI_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMulti3dTri : public NStencil { - public: - NStencilHalfMulti3dTri(class LAMMPS *); - void create() override; - - protected: - void set_stencil_properties() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_old_2d.cpp b/src/nstencil_half_multi_old_2d.cpp deleted file mode 100644 index 6bf9e5c5b1..0000000000 --- a/src/nstencil_half_multi_old_2d.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_old_2d.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMultiOld2d::NStencilHalfMultiOld2d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMultiOld2d::create() -{ - int i, j, n; - double rsq, typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - n = 0; - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) { - rsq = bin_distance(i, j, 0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j * mbinx + i; - } - } - nstencil_multi_old[itype] = n; - } -} diff --git a/src/nstencil_half_multi_old_2d.h b/src/nstencil_half_multi_old_2d.h deleted file mode 100644 index a3825bcb71..0000000000 --- a/src/nstencil_half_multi_old_2d.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/old/2d, - NStencilHalfMultiOld2d, NS_HALF | NS_MULTI_OLD | NS_2D | NS_ORTHO); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_OLD_2D_H -#define LMP_NSTENCIL_HALF_MULTI_OLD_2D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMultiOld2d : public NStencil { - public: - NStencilHalfMultiOld2d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_old_2d_tri.cpp b/src/nstencil_half_multi_old_2d_tri.cpp deleted file mode 100644 index 0aeb65bebd..0000000000 --- a/src/nstencil_half_multi_old_2d_tri.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_old_2d_tri.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMultiOld2dTri::NStencilHalfMultiOld2dTri(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMultiOld2dTri::create() -{ - int i, j, n; - double rsq, typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - n = 0; - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i, j, 0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j * mbinx + i; - } - } - nstencil_multi_old[itype] = n; - } -} diff --git a/src/nstencil_half_multi_old_2d_tri.h b/src/nstencil_half_multi_old_2d_tri.h deleted file mode 100644 index a65eb21ff7..0000000000 --- a/src/nstencil_half_multi_old_2d_tri.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/old/2d/tri, - NStencilHalfMultiOld2dTri, NS_HALF | NS_MULTI_OLD | NS_2D | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_OLD_2D_TRI_H -#define LMP_NSTENCIL_HALF_MULTI_OLD_2D_TRI_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMultiOld2dTri : public NStencil { - public: - NStencilHalfMultiOld2dTri(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_old_3d.cpp b/src/nstencil_half_multi_old_3d.cpp deleted file mode 100644 index 99e72610f0..0000000000 --- a/src/nstencil_half_multi_old_3d.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_old_3d.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMultiOld3d::NStencilHalfMultiOld3d(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMultiOld3d::create() -{ - int i, j, k, n; - double rsq, typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - n = 0; - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) { - rsq = bin_distance(i, j, k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k * mbiny * mbinx + j * mbinx + i; - } - } - nstencil_multi_old[itype] = n; - } -} diff --git a/src/nstencil_half_multi_old_3d.h b/src/nstencil_half_multi_old_3d.h deleted file mode 100644 index 3b93d3cd6c..0000000000 --- a/src/nstencil_half_multi_old_3d.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi_old/3d, - NStencilHalfMultiOld3d, NS_HALF | NS_MULTI_OLD | NS_3D | NS_ORTHO); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_OLD_3D_H -#define LMP_NSTENCIL_HALF_MULTI_OLD_3D_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMultiOld3d : public NStencil { - public: - NStencilHalfMultiOld3d(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_half_multi_old_3d_tri.cpp b/src/nstencil_half_multi_old_3d_tri.cpp deleted file mode 100644 index 3717b7836b..0000000000 --- a/src/nstencil_half_multi_old_3d_tri.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "nstencil_half_multi_old_3d_tri.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfMultiOld3dTri::NStencilHalfMultiOld3dTri(LAMMPS *lmp) : NStencil(lmp) {} - -/* ---------------------------------------------------------------------- - create stencil based on bin geometry and cutoff -------------------------------------------------------------------------- */ - -void NStencilHalfMultiOld3dTri::create() -{ - int i, j, k, n; - double rsq, typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi_old[itype]; - distsq = distsq_multi_old[itype]; - n = 0; - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i, j, k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k * mbiny * mbinx + j * mbinx + i; - } - } - nstencil_multi_old[itype] = n; - } -} diff --git a/src/nstencil_half_multi_old_3d_tri.h b/src/nstencil_half_multi_old_3d_tri.h deleted file mode 100644 index 89fc167959..0000000000 --- a/src/nstencil_half_multi_old_3d_tri.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NSTENCIL_CLASS -// clang-format off -NStencilStyle(half/multi/old/3d/tri, - NStencilHalfMultiOld3dTri, NS_HALF | NS_MULTI_OLD | NS_3D | NS_TRI); -// clang-format on -#else - -#ifndef LMP_NSTENCIL_HALF_MULTI_OLD_3D_TRI_H -#define LMP_NSTENCIL_HALF_MULTI_OLD_3D_TRI_H - -#include "nstencil.h" - -namespace LAMMPS_NS { - -class NStencilHalfMultiOld3dTri : public NStencil { - public: - NStencilHalfMultiOld3dTri(class LAMMPS *); - void create() override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/nstencil_multi.cpp b/src/nstencil_multi.cpp new file mode 100644 index 0000000000..693c415876 --- /dev/null +++ b/src/nstencil_multi.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 "nstencil_multi.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NStencilMulti::NStencilMulti(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- */ + +template +void NStencilMulti::set_stencil_properties() +{ + int n = ncollections; + int i, j; + + // FULL + // Always look up neighbor using full stencil and neighbor's bin + // Stencil cutoff set by i-j cutoff + + // HALF + // Cross collections: use full stencil, looking one way through hierarchy + // smaller -> larger => use full stencil in larger bin + // larger -> smaller => no nstencil required + // If cut offs are same, use half stencil + // If triclinic, need full stencil + + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if (HALF) + if (cutcollectionsq[i][i] > cutcollectionsq[j][j]) continue; + + flag_skip_multi[i][j] = false; + flag_half_multi[i][j] = false; + flag_same_multi[i][j] = false; + bin_collection_multi[i][j] = j; + + if (HALF) { + if (cutcollectionsq[i][i] == cutcollectionsq[j][j]) { + if (!TRI) flag_half_multi[i][j] = true; + flag_same_multi[i][j] = true; + bin_collection_multi[i][j] = i; + } + } + } + } +} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +template +void NStencilMulti::create() +{ + int icollection, jcollection, bin_collection, i, j, k, ns, half_flag; + int n = ncollections; + double cutsq; + + for (icollection = 0; icollection < n; icollection++) { + for (jcollection = 0; jcollection < n; jcollection++) { + if (flag_skip_multi[icollection][jcollection]) { + nstencil_multi[icollection][jcollection] = 0; + continue; + } + + ns = 0; + + sx = stencil_sx_multi[icollection][jcollection]; + sy = stencil_sy_multi[icollection][jcollection]; + sz = stencil_sz_multi[icollection][jcollection]; + + mbinx = stencil_mbinx_multi[icollection][jcollection]; + mbiny = stencil_mbiny_multi[icollection][jcollection]; + mbinz = stencil_mbinz_multi[icollection][jcollection]; + + bin_collection = bin_collection_multi[icollection][jcollection]; + cutsq = cutcollectionsq[icollection][jcollection]; + half_flag = flag_half_multi[icollection][jcollection]; + + // Half and ortho stencils include central bin first + // This preserves the historical order of the neighbor list + // as the old npair classes used to separately parse the central bin first + // This !TRI condition (and the one below) are now unnecessary + // since triclinic only uses full stencils - kept the flags for clarity + if (HALF && (!TRI)) + if (half_flag) stencil_multi[icollection][jcollection][ns++] = 0; + + // For half stencils, only the upper plane is needed + int sy_min = sy; + int sz_min = sz; + if (HALF) { + if (half_flag && (!DIM_3D)) sy_min = 0; + if (half_flag && DIM_3D) sz_min = 0; + } + + for (k = -sz_min; k <= sz; k++) { + for (j = -sy_min; j <= sy; j++) { + for (i = -sx; i <= sx; i++) { + // Now only include "upper right" bins for half and ortho stencils + if (HALF && (!TRI)) { + if (half_flag) { + if (DIM_3D) { + if (k <= 0 && j <= 0 && (j != 0 || i <= 0)) continue; + } else { + if (j <= 0 && (j != 0 || i <= 0)) continue; + } + } + } + if (bin_distance_multi(i, j, k, bin_collection) < cutsq) + stencil_multi[icollection][jcollection][ns++] = k * mbiny * mbinx + j * mbinx + i; + } + } + } + + nstencil_multi[icollection][jcollection] = ns; + } + } +} + +namespace LAMMPS_NS { +template class NStencilMulti<0,0,0>; +template class NStencilMulti<0,1,0>; +template class NStencilMulti<1,0,0>; +template class NStencilMulti<1,0,1>; +template class NStencilMulti<1,1,0>; +template class NStencilMulti<1,1,1>; +} diff --git a/src/nstencil_multi.h b/src/nstencil_multi.h new file mode 100644 index 0000000000..33219891c2 --- /dev/null +++ b/src/nstencil_multi.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS +// clang-format off +typedef NStencilMulti<0, 0, 0> NStencilFullMulti2d; +NStencilStyle(full/multi/2d, + NStencilFullMulti2d, + NS_FULL | NS_MULTI | NS_2D | NS_ORTHO | NS_TRI); + +typedef NStencilMulti<0, 1, 0> NStencilFullMulti3d; +NStencilStyle(full/multi/3d, + NStencilFullMulti3d, + NS_FULL | NS_MULTI | NS_3D | NS_ORTHO | NS_TRI); + +typedef NStencilMulti<1, 0, 0> NStencilHalfMulti2d; +NStencilStyle(half/multi/2d, + NStencilHalfMulti2d, + NS_HALF | NS_MULTI | NS_2D | NS_ORTHO); + +typedef NStencilMulti<1, 0, 1> NStencilHalfMulti2dTri; +NStencilStyle(half/multi/2d/tri, + NStencilHalfMulti2dTri, + NS_HALF | NS_MULTI | NS_2D | NS_TRI); + +typedef NStencilMulti<1, 1, 0> NStencilHalfMulti3d; +NStencilStyle(half/multi/3d, + NStencilHalfMulti3d, + NS_HALF | NS_MULTI | NS_3D | NS_ORTHO); + +typedef NStencilMulti<1, 1, 1> NStencilHalfMulti3dTri; +NStencilStyle(half/multi/3d/tri, + NStencilHalfMulti3dTri, + NS_HALF | NS_MULTI | NS_3D | NS_TRI); +// clang-format on +#else + +#ifndef LMP_NSTENCIL_MULTI_H +#define LMP_NSTENCIL_MULTI_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +template +class NStencilMulti : public NStencil { + public: + NStencilMulti(class LAMMPS *); + void create() override; + + protected: + void set_stencil_properties() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/nstencil_multi_old.cpp b/src/nstencil_multi_old.cpp new file mode 100644 index 0000000000..8648e6f73c --- /dev/null +++ b/src/nstencil_multi_old.cpp @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------- + 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 "nstencil_multi_old.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NStencilMultiOld::NStencilMultiOld(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +template +void NStencilMultiOld::create() +{ + int i, j, k, n, itype; + double rsq, typesq; + int *s; + double *distsq; + int ntypes = atom->ntypes; + + // For half stencils, only the upper plane is needed + // for triclinic, need to use full stencil in all dims + // not a half stencil in y + // b/c transforming orthog -> lambda -> orthog for ghost atoms + // with an added PBC offset can shift both coords by epsilon + // thus for an I/J owned/ghost pair, the xy coords + // and bin assignments can be different on I proc vs J proc + + int sy_min = sy; + int sz_min = sz; + if ((!TRI) && HALF && (!DIM_3D)) sy_min = 0; + if ((!TRI) && HALF && DIM_3D) sz_min = 0; + + for (itype = 1; itype <= ntypes; itype++) { + + typesq = cuttypesq[itype]; + s = stencil_multi_old[itype]; + distsq = distsq_multi_old[itype]; + n = 0; + + // Half and ortho stencils include central bin first + // This preserves the historical order of the neighbor list + // as the old npair classes used to separately parse the central bin first + if (HALF && (!TRI)) s[n++] = 0; + + for (k = -sz_min; k <= sz; k++) { + for (j = -sy_min; j <= sy; j++) { + for (i = -sx; i <= sx; i++) { + + // Now only include "upper right" bins for half and ortho stencils + if (HALF && (!DIM_3D) && (!TRI)) + if (j <= 0 && (j != 0 || i <= 0)) continue; + if (HALF && DIM_3D && (!TRI)) + if (k <= 0 && j <= 0 && (j != 0 || i <= 0)) continue; + + rsq = bin_distance(i, j, k); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = k * mbiny * mbinx + j * mbinx + i; + } + } + } + } + nstencil_multi_old[itype] = n; + } +} + +namespace LAMMPS_NS { +template class NStencilMultiOld<0,0,0>; +template class NStencilMultiOld<0,1,0>; +template class NStencilMultiOld<1,0,0>; +template class NStencilMultiOld<1,0,1>; +template class NStencilMultiOld<1,1,0>; +template class NStencilMultiOld<1,1,1>; +} diff --git a/src/nstencil_multi_old.h b/src/nstencil_multi_old.h new file mode 100644 index 0000000000..5d9dfce644 --- /dev/null +++ b/src/nstencil_multi_old.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS +// clang-format off +typedef NStencilMultiOld<0, 0, 0> NStencilFullMultiOld2d; +NStencilStyle(full/multi/old/2d, + NStencilFullMultiOld2d, + NS_FULL | NS_MULTI_OLD | NS_2D | NS_ORTHO | NS_TRI); + +typedef NStencilMultiOld<0, 1, 0> NStencilFullMultiOld3d; +NStencilStyle(full/multi/old/3d, + NStencilFullMultiOld3d, + NS_FULL | NS_MULTI_OLD | NS_3D | NS_ORTHO | NS_TRI); + +typedef NStencilMultiOld<1, 0, 0> NStencilHalfMultiOld2d; +NStencilStyle(half/multi/old/2d, + NStencilHalfMultiOld2d, + NS_HALF | NS_MULTI_OLD | NS_2D | NS_ORTHO); + +typedef NStencilMultiOld<1, 0, 1> NStencilHalfMultiOld2dTri; +NStencilStyle(half/multi/old/2d/tri, + NStencilHalfMultiOld2dTri, + NS_HALF | NS_MULTI_OLD | NS_2D | NS_TRI); + +typedef NStencilMultiOld<1, 1, 0> NStencilHalfMultiOld3d; +NStencilStyle(half/multi/old/3d, + NStencilHalfMultiOld3d, + NS_HALF | NS_MULTI_OLD | NS_3D | NS_ORTHO); + +typedef NStencilMultiOld<1, 1, 1> NStencilHalfMultiOld3dTri; +NStencilStyle(half/multi/old/3d/tri, + NStencilHalfMultiOld3dTri, + NS_HALF | NS_MULTI_OLD | NS_3D | NS_TRI); +// clang-format on +#else + +#ifndef LMP_NSTENCIL_MULTI_OLD_H +#define LMP_NSTENCIL_MULTI_OLD_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +template +class NStencilMultiOld : public NStencil { + public: + NStencilMultiOld(class LAMMPS *); + void create() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/platform.cpp b/src/platform.cpp index 064f142425..b324bd0b5c 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -61,6 +61,13 @@ #include #include #endif + +// for disk_free() +#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) || defined(__NetBSD__) +#include +#endif + //////////////////////////////////////////////////////////////////////// #include @@ -1047,6 +1054,36 @@ bool platform::file_is_readable(const std::string &path) } return false; } +/* ---------------------------------------------------------------------- + determine available disk space, if supported. Return -1 if not. +------------------------------------------------------------------------- */ + +double platform::disk_free(const std::string &path) +{ + double bytes_free = -1.0; + +#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) || defined(__NetBSD__) + struct statvfs fs; + + if (path.size()) { + int rv = statvfs(path.c_str(), &fs); + if (rv == 0) { +#if defined(__linux__) + bytes_free = fs.f_bavail * fs.f_bsize; +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) || defined(__NetBSD__) + bytes_free = fs.f_bavail * fs.f_frsize; +#endif + } + } +#elif defined(_WIN32) + uint64_t is_free = 0; + if (GetDiskFreeSpaceEx(path.c_str(), (PULARGE_INTEGER) &is_free, nullptr, nullptr)) + bytes_free = is_free; +#endif + return bytes_free; +} /* ---------------------------------------------------------------------- check if filename has a known compression extension diff --git a/src/platform.h b/src/platform.h index 036074c900..4328f873dd 100644 --- a/src/platform.h +++ b/src/platform.h @@ -377,6 +377,15 @@ namespace platform { bool file_is_readable(const std::string &path); + /*! Return free disk space in bytes of file system pointed to by path + * + * Returns -1.0 if the path is invalid or free space reporting not supported. + * + * \param path file or folder path in file system + * \return */ + + double disk_free(const std::string &path); + /*! Check if a file name ends in a known extension for a compressed file format * * Currently supported file extensions are: .gz, .bz2, .zst, .xz, .lzma, lz4 diff --git a/src/potential_file_reader.cpp b/src/potential_file_reader.cpp index 2c0b9a6a55..613225a797 100644 --- a/src/potential_file_reader.cpp +++ b/src/potential_file_reader.cpp @@ -144,6 +144,8 @@ void PotentialFileReader::next_dvector(double *list, int n) { try { return reader->next_dvector(list, n); + } catch (EOFException &) { + throw EOFException("EOF reached"); } catch (FileReaderException &e) { error->one(FLERR, e.what()); } diff --git a/src/text_file_reader.cpp b/src/text_file_reader.cpp index 46a5fd33a9..0b8d717687 100644 --- a/src/text_file_reader.cpp +++ b/src/text_file_reader.cpp @@ -189,8 +189,9 @@ void TextFileReader::next_dvector(double *list, int n) char *ptr = next_line(); if (ptr == nullptr) { - // EOF - if (i < n) { + if (i == 0) { // EOF without any records + throw EOFException("EOF reached"); + } else if (i < n) { // EOF with incomplete data throw FileReaderException( fmt::format("Incorrect format in {} file! {}/{} values", filetype, i, n)); } diff --git a/src/utils.cpp b/src/utils.cpp index 992feb34e8..bde6dffca5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -395,7 +395,24 @@ double utils::numeric(const char *file, int line, const std::string &str, bool d lmp->error->all(file, line, msg); } - return atof(buf.c_str()); + double rv = 0; + try { + rv = stod(buf); + } catch (std::invalid_argument const &) { + auto msg = fmt::format("Floating point number {} in input script or data file is invalid", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } catch (std::out_of_range const &) { + auto msg = + fmt::format("Floating point number {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return rv; } /* ---------------------------------------------------------------------- @@ -439,7 +456,17 @@ int utils::inumeric(const char *file, int line, const std::string &str, bool do_ lmp->error->all(file, line, msg); } - return atoi(buf.c_str()); + int rv = 0; + try { + rv = stoi(buf); + } catch (std::out_of_range const &) { + auto msg = fmt::format("Integer {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return rv; } /* ---------------------------------------------------------------------- @@ -484,7 +511,18 @@ bigint utils::bnumeric(const char *file, int line, const std::string &str, bool lmp->error->all(file, line, msg); } - return ATOBIGINT(buf.c_str()); + long long rv = 0; + try { + rv = stoll(buf); + if (rv > MAXBIGINT) throw std::out_of_range("64-bit"); + } catch (std::out_of_range const &) { + auto msg = fmt::format("Integer {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return static_cast(rv); } /* ---------------------------------------------------------------------- @@ -529,7 +567,18 @@ tagint utils::tnumeric(const char *file, int line, const std::string &str, bool lmp->error->all(file, line, msg); } - return ATOTAGINT(buf.c_str()); + long long rv = 0; + try { + rv = stoll(buf); + if (rv > MAXTAGINT) throw std::out_of_range("64-bit"); + } catch (std::out_of_range const &) { + auto msg = fmt::format("Integer {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return static_cast(rv); } /* ---------------------------------------------------------------------- diff --git a/src/version.h b/src/version.h index e2f596d1aa..d1d8472ca6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1,2 @@ #define LAMMPS_VERSION "21 Nov 2023" +#define LAMMPS_UPDATE "Development" diff --git a/tools/lammps-gui/CMakeLists.txt b/tools/lammps-gui/CMakeLists.txt index caae722865..b1469794bb 100644 --- a/tools/lammps-gui/CMakeLists.txt +++ b/tools/lammps-gui/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) -project(lammps-gui VERSION 1.5.10 LANGUAGES CXX) +project(lammps-gui VERSION 1.5.11 LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) diff --git a/tools/lammps-gui/help_index.table b/tools/lammps-gui/help_index.table index 5ce4ae6203..5aa9e13dda 100644 --- a/tools/lammps-gui/help_index.table +++ b/tools/lammps-gui/help_index.table @@ -254,6 +254,7 @@ compute_nbond_atom.html compute nbond/atom compute_omega_chunk.html compute omega/chunk compute_orientorder_atom.html compute orientorder/atom compute_orientorder_atom.html compute orientorder/atom/kk +compute_pace.html compute pace compute_pair_local.html compute pair/local compute_pair.html compute pair compute_pe_atom.html compute pe/atom @@ -267,13 +268,17 @@ compute_property_chunk.html compute property/chunk compute_property_grid.html compute property/grid compute_property_local.html compute property/local compute_ptm_atom.html compute ptm/atom +compute_rattlers_atom.html compute rattlers/atom compute_rdf.html compute rdf +compute_reaxff_atom.html compute reaxff/atom +compute_reaxff_atom.html compute reaxff/atom/kk compute_reduce_chunk.html compute reduce/chunk compute_reduce.html compute reduce compute_reduce.html compute reduce/region compute_rigid_local.html compute rigid/local compute.html compute compute_saed.html compute saed +compute_slcsa_atom.html compute slcsa/atom compute_slice.html compute slice compute_smd_contact_radius.html compute smd/contact/radius compute_smd_damage.html compute smd/damage @@ -484,6 +489,7 @@ fix_drude_transform.html fix drude/transform/inverse fix_dt_reset.html fix dt/reset fix_dt_reset.html fix dt/reset/kk fix_efield.html fix efield +fix_efield.html fix efield/kk fix_efield.html fix efield/tip4p fix_ehex.html fix ehex fix_electrode.html fix electrode/conp @@ -565,6 +571,7 @@ fix_nh.html fix nvt/kk fix_nh.html fix nvt/omp fix_nh_uef.html fix npt/uef fix_nh_uef.html fix nvt/uef +fix_nonaffine_displacement.html fix nonaffine/displacement fix_nph_asphere.html fix nph/asphere fix_nph_asphere.html fix nph/asphere/omp fix_nph_body.html fix nph/body @@ -634,6 +641,7 @@ fix_polarize.html fix polarize/functional fix_pour.html fix pour fix_precession_spin.html fix precession/spin fix_press_berendsen.html fix press/berendsen +fix_press_langevin.html fix press/langevin fix_print.html fix print fix_propel_self.html fix propel/self fix_property_atom.html fix property/atom @@ -703,14 +711,17 @@ fix_spring_chunk.html fix spring/chunk fix_spring_rg.html fix spring/rg fix_spring.html fix spring fix_spring_self.html fix spring/self +fix_spring_self.html fix spring/self/kk fix_srd.html fix srd fix_store_force.html fix store/force fix_store_state.html fix store/state fix_temp_berendsen.html fix temp/berendsen +fix_temp_berendsen.html fix temp/berendsen/kk fix_temp_csvr.html fix temp/csld fix_temp_csvr.html fix temp/csvr fix_temp_rescale_eff.html fix temp/rescale/eff fix_temp_rescale.html fix temp/rescale +fix_temp_rescale.html fix temp/rescale/kk fix_tfmc.html fix tfmc fix_tgnh_drude.html fix tgnpt/drude fix_tgnh_drude.html fix tgnvt/drude @@ -980,6 +991,7 @@ pair_coul_shield.html pair_style coul/shield pair_coul_slater.html pair_style coul/slater pair_coul_slater.html pair_style coul/slater/cut pair_coul_slater.html pair_style coul/slater/long +pair_coul_slater.html pair_style coul/slater/long/gpu pair_coul_tt.html pair_style coul/tt pair_cs.html pair_style born/coul/dsf/cs pair_cs.html pair_style born/coul/long/cs @@ -1073,8 +1085,10 @@ pair_fep_soft.html pair_style lj/class2/coul/cut/soft pair_fep_soft.html pair_style lj/class2/coul/long/soft pair_fep_soft.html pair_style lj/class2/soft pair_fep_soft.html pair_style lj/cut/coul/cut/soft +pair_fep_soft.html pair_style lj/cut/coul/cut/soft/gpu pair_fep_soft.html pair_style lj/cut/coul/cut/soft/omp pair_fep_soft.html pair_style lj/cut/coul/long/soft +pair_fep_soft.html pair_style lj/cut/coul/long/soft/gpu pair_fep_soft.html pair_style lj/cut/coul/long/soft/omp pair_fep_soft.html pair_style lj/cut/soft pair_fep_soft.html pair_style lj/cut/soft/omp @@ -1225,7 +1239,9 @@ pair_meam_sw_spline.html pair_style meam/sw/spline pair_mesocnt.html pair_style mesocnt pair_mesocnt.html pair_style mesocnt/viscous pair_mesodpd.html pair_style edpd +pair_mesodpd.html pair_style edpd/gpu pair_mesodpd.html pair_style mdpd +pair_mesodpd.html pair_style mdpd/gpu pair_mesodpd.html pair_style mdpd/rhosum pair_mesodpd.html pair_style tdpd pair_mgpt.html pair_style mgpt @@ -1245,7 +1261,8 @@ pair_morse.html pair_style morse/smooth/linear/omp pair_multi_lucy.html pair_style multi/lucy pair_multi_lucy_rx.html pair_style multi/lucy/rx pair_multi_lucy_rx.html pair_style multi/lucy/rx/kk -pair_nb3b_harmonic.html pair_style nb3b/harmonic +pair_nb3b.html pair_style nb3b/harmonic +pair_nb3b.html pair_style nb3b/screened pair_nm.html pair_style nm/cut pair_nm.html pair_style nm/cut/coul/cut pair_nm.html pair_style nm/cut/coul/cut/omp @@ -1303,16 +1320,20 @@ pair_smd_triangulated_surface.html pair_style smd/tri_surface pair_smd_ulsph.html pair_style smd/ulsph pair_smtbq.html pair_style smtbq pair_snap.html pair_style snap +pair_snap.html pair_style snap/intel pair_snap.html pair_style snap/kk pair_soft.html pair_style soft pair_soft.html pair_style soft/gpu pair_soft.html pair_style soft/omp pair_sph_heatconduction.html pair_style sph/heatconduction +pair_sph_heatconduction.html pair_style sph/heatconduction/gpu pair_sph_idealgas.html pair_style sph/idealgas pair_sph_lj.html pair_style sph/lj +pair_sph_lj.html pair_style sph/lj/gpu pair_sph_rhosum.html pair_style sph/rhosum pair_sph_taitwater_morris.html pair_style sph/taitwater/morris pair_sph_taitwater.html pair_style sph/taitwater +pair_sph_taitwater.html pair_style sph/taitwater/gpu pair_spica.html pair_style lj/spica pair_spica.html pair_style lj/spica/coul/long pair_spica.html pair_style lj/spica/coul/long/gpu @@ -1384,6 +1405,7 @@ pair_write.html pair_write pair_ylz.html pair_style ylz pair_yukawa_colloid.html pair_style yukawa/colloid pair_yukawa_colloid.html pair_style yukawa/colloid/gpu +pair_yukawa_colloid.html pair_style yukawa/colloid/kk pair_yukawa_colloid.html pair_style yukawa/colloid/omp pair_yukawa.html pair_style yukawa pair_yukawa.html pair_style yukawa/gpu diff --git a/tools/lammps-gui/main.cpp b/tools/lammps-gui/main.cpp index cf09fbb892..d70e9d3e46 100644 --- a/tools/lammps-gui/main.cpp +++ b/tools/lammps-gui/main.cpp @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) LammpsGui w(nullptr, infile); w.show(); - return a.exec(); + return QApplication::exec(); } // Local Variables: diff --git a/tools/lammps-gui/preferences.cpp b/tools/lammps-gui/preferences.cpp index fd01bb5046..27cc106008 100644 --- a/tools/lammps-gui/preferences.cpp +++ b/tools/lammps-gui/preferences.cpp @@ -177,7 +177,7 @@ void Preferences::accept() msg.exec(); const char *path = mystrdup(QCoreApplication::applicationFilePath()); const char *arg0 = mystrdup(QCoreApplication::arguments().at(0)); - execl(path, arg0, (char *)NULL); + execl(path, arg0, (char *)nullptr); } // reformatting settings diff --git a/tools/lammps-gui/stdcapture.cpp b/tools/lammps-gui/stdcapture.cpp index b09aebf053..8be543e70e 100644 --- a/tools/lammps-gui/stdcapture.cpp +++ b/tools/lammps-gui/stdcapture.cpp @@ -38,7 +38,7 @@ StdCapture::StdCapture() : m_oldStdOut(0), m_capturing(false) { // make stdout unbuffered so that we don't need to flush the stream - setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); m_pipe[READ] = 0; m_pipe[WRITE] = 0; @@ -106,7 +106,7 @@ bool StdCapture::EndCapture() std::string StdCapture::GetChunk() { - if (!m_capturing) return std::string(); + if (!m_capturing) return {}; int bytesRead = 0; buf[0] = '\0'; @@ -120,7 +120,7 @@ std::string StdCapture::GetChunk() if (bytesRead > 0) { buf[bytesRead] = '\0'; } - return std::string(buf); + return {buf}; } std::string StdCapture::GetCapture() diff --git a/tools/msi2lmp/src/SearchAndFill.c b/tools/msi2lmp/src/SearchAndFill.c index 7a7a1032ea..35de0c81fe 100644 --- a/tools/msi2lmp/src/SearchAndFill.c +++ b/tools/msi2lmp/src/SearchAndFill.c @@ -93,7 +93,7 @@ void SearchAndFill(struct FrcFieldItem *item) file_pos = ftell(FrcF); if (file_pos < 0) { - fprintf(stderr, "Could not obtain file stream position: ", strerror(errno)); + fprintf(stderr, "Could not obtain file stream position: %s\n", strerror(errno)); exit(2); } @@ -116,7 +116,7 @@ void SearchAndFill(struct FrcFieldItem *item) /* Read lines until keyword is found */ if (fseek(FrcF,file_pos,SEEK_SET) < 0) { - fprintf(stderr, "Resetting file stream failed: ", strerror(errno)); + fprintf(stderr, "Resetting file stream failed: %s\n", strerror(errno)); exit(2); } strcpy(line,"empty"); diff --git a/tools/valgrind/MPICH.supp b/tools/valgrind/MPICH.supp new file mode 100644 index 0000000000..6934cf8fbd --- /dev/null +++ b/tools/valgrind/MPICH.supp @@ -0,0 +1,41 @@ +{ + MPICH_MPI_init1 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + obj:* + ... + fun:psm3_init + ... + fun:MPIDI_OFI_init_local + ... + fun:PMPI_Init + fun:main +} +{ + MPICH_MPI_init2 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:strdup + obj:* + ... + fun:fi_ini + ... + fun:MPIDI_OFI_init_local + ... + fun:PMPI_Init + fun:main +} +{ + MPICH_MPI_init3 + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + obj:* + ... + fun:MPIDI_OFI_init_local + ... + fun:PMPI_Init + fun:main +} diff --git a/tools/valgrind/README b/tools/valgrind/README index 63c440f7b2..e62031da9b 100644 --- a/tools/valgrind/README +++ b/tools/valgrind/README @@ -8,6 +8,7 @@ on running LAMMPS, use a command line like following: valgrind --show-leak-kinds=all --track-origins=yes \ --suppressions=/path/to/lammps/tools/valgrind/OpenMP.supp \ --suppressions=/path/to/lammps/tools/valgrind/OpenMPI.supp \ + --suppressions=/path/to/lammps/tools/valgrind/MPICH.supp \ --suppressions=/path/to/lammps/tools/valgrind/Python3.supp \ --suppressions=/path/to/lammps/tools/valgrind/GTest.supp \ --suppressions=/path/to/lammps/tools/valgrind/FlexiBLAS.supp \ diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index b91a6108d9..7f0a054c40 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -314,7 +314,7 @@ TEST_F(GroupTest, Dynamic) command("group ramp variable grow");); } -constexpr double EPSILON = 1.0e-14; +constexpr double EPSILON = 1.0e-13; TEST_F(GroupTest, VariableFunctions) { diff --git a/unittest/force-styles/tests/mol-pair-coul_slater_long.yaml b/unittest/force-styles/tests/mol-pair-coul_slater_long.yaml index ba11503a2c..51b04f301c 100644 --- a/unittest/force-styles/tests/mol-pair-coul_slater_long.yaml +++ b/unittest/force-styles/tests/mol-pair-coul_slater_long.yaml @@ -1,7 +1,7 @@ --- lammps_version: 23 Jun 2022 date_generated: Thu Jul 7 09:00:39 2022 -epsilon: 2e-13 +epsilon: 1e-12 skip_tests: prerequisites: ! | atom full diff --git a/unittest/force-styles/tests/mol-pair-lj_cut_coul_cut_soft.yaml b/unittest/force-styles/tests/mol-pair-lj_cut_coul_cut_soft.yaml index e242a56029..485730531f 100644 --- a/unittest/force-styles/tests/mol-pair-lj_cut_coul_cut_soft.yaml +++ b/unittest/force-styles/tests/mol-pair-lj_cut_coul_cut_soft.yaml @@ -1,7 +1,7 @@ --- lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:31 2022 -epsilon: 2e-13 +epsilon: 5e-13 skip_tests: prerequisites: ! | atom full diff --git a/unittest/force-styles/tests/mol-pair-lj_cut_coul_long_soft.yaml b/unittest/force-styles/tests/mol-pair-lj_cut_coul_long_soft.yaml index 8eca065092..a1e89e54c0 100644 --- a/unittest/force-styles/tests/mol-pair-lj_cut_coul_long_soft.yaml +++ b/unittest/force-styles/tests/mol-pair-lj_cut_coul_long_soft.yaml @@ -1,7 +1,7 @@ --- lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:17:31 2022 -epsilon: 5e-12 +epsilon: 7.5e-12 skip_tests: prerequisites: ! | atom full diff --git a/unittest/formats/test_input_convert.cpp b/unittest/formats/test_input_convert.cpp index 858275a76f..78a78d08df 100644 --- a/unittest/formats/test_input_convert.cpp +++ b/unittest/formats/test_input_convert.cpp @@ -117,6 +117,17 @@ TEST_F(InputConvertTest, numeric) TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, nullptr, false, lmp);); TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "2.56D+3", false, lmp);); + TEST_FAILURE(".*ERROR: Floating point number.*out of range.*", + utils::numeric(FLERR, "1.0e2000", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating .*", utils::numeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "+-546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating .*", utils::numeric(FLERR, "5.467e--1", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "4.4e++1", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "--5.0460", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "++5.4670", false, lmp);); } TEST_F(InputConvertTest, inumeric) @@ -142,6 +153,13 @@ TEST_F(InputConvertTest, inumeric) TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "0x05", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, nullptr, false, lmp);); + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::inumeric(FLERR, "1263012546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "+-546700", false, lmp);); } TEST_F(InputConvertTest, bnumeric) @@ -167,6 +185,13 @@ TEST_F(InputConvertTest, bnumeric) TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "0x05", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, nullptr, false, lmp);); + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::bnumeric(FLERR, "18446744073709551616123", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "+-546700", false, lmp);); } TEST_F(InputConvertTest, tnumeric) @@ -192,6 +217,17 @@ TEST_F(InputConvertTest, tnumeric) TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "0x05", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, nullptr, false, lmp);); +#if defined(LAMMPS_SMALLBIG) + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::tnumeric(FLERR, "4294967296", false, lmp);); +#endif + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::tnumeric(FLERR, "18446744073709551616123", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "+-546700", false, lmp);); } } // namespace LAMMPS_NS diff --git a/unittest/fortran/wrap_configuration.cpp b/unittest/fortran/wrap_configuration.cpp index 5fb744086e..08974d8a08 100644 --- a/unittest/fortran/wrap_configuration.cpp +++ b/unittest/fortran/wrap_configuration.cpp @@ -234,7 +234,7 @@ TEST_F(LAMMPS_configuration, style_count) { Info info(lmp); for (const auto &c : style_category) - EXPECT_EQ(f_lammps_style_count(c.c_str()), info.get_available_styles(c.c_str()).size()); + EXPECT_EQ(f_lammps_style_count(c.c_str()), info.get_available_styles(c).size()); }; TEST_F(LAMMPS_configuration, style_name) diff --git a/unittest/python/CMakeLists.txt b/unittest/python/CMakeLists.txt index b4ba281d93..f3b851620c 100644 --- a/unittest/python/CMakeLists.txt +++ b/unittest/python/CMakeLists.txt @@ -84,20 +84,26 @@ if(Python_EXECUTABLE) WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) set_tests_properties(PythonCommands PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") - add_test(NAME PythonNumpy - COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-numpy.py -v - WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) - set_tests_properties(PythonNumpy PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") + # randomly failing on macOS with python 3.12 + if(NOT APPLE) + add_test(NAME PythonNumpy + COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-numpy.py -v + WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) + set_tests_properties(PythonNumpy PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") + endif() add_test(NAME PythonCapabilities COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-capabilities.py -v WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) set_tests_properties(PythonCapabilities PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") - add_test(NAME PythonPyLammps - COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-pylammps.py -v - WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) - set_tests_properties(PythonPyLammps PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") + # randomly failing on macOS with python 3.12 + if(NOT APPLE) + add_test(NAME PythonPyLammps + COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-pylammps.py -v + WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) + set_tests_properties(PythonPyLammps PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") + endif() add_test(NAME PythonFormats COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-formats.py -v diff --git a/unittest/utils/test_lepton.cpp b/unittest/utils/test_lepton.cpp index 7b2c86f05f..a9fa6e3543 100644 --- a/unittest/utils/test_lepton.cpp +++ b/unittest/utils/test_lepton.cpp @@ -129,9 +129,9 @@ TEST(LeptonCustomFunction, zbl) */ class ExampleFunction : public Lepton::CustomFunction { - int getNumArguments() const { return 2; } - double evaluate(const double *arguments) const { return 2.0 * arguments[0] * arguments[1]; } - double evaluateDerivative(const double *arguments, const int *derivOrder) const + int getNumArguments() const override { return 2; } + double evaluate(const double *arguments) const override { return 2.0 * arguments[0] * arguments[1]; } + double evaluateDerivative(const double *arguments, const int *derivOrder) const override { if (derivOrder[0] == 1) { if (derivOrder[1] == 0) @@ -142,7 +142,7 @@ class ExampleFunction : public Lepton::CustomFunction { if (derivOrder[1] == 1 && derivOrder[0] == 0) return 2.0 * arguments[0]; return 0.0; } - Lepton::CustomFunction *clone() const { return new ExampleFunction(); } + Lepton::CustomFunction *clone() const override { return new ExampleFunction(); } }; /**