diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 59a937faba..d1617cbb25 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -50,6 +50,7 @@ src/PTM/* @pmla src/QMMM/* @akohlmey src/REACTION/* @jrgissing src/REAXFF/* @hasanmetin @stanmoore1 +src/RHEO/* @jtclemm src/SCAFACOS/* @rhalver src/SNAP/* @athomps src/SPIN/* @julient31 diff --git a/cmake/Modules/LAMMPSUtils.cmake b/cmake/Modules/LAMMPSUtils.cmake index 2ec9d1b706..223577fe31 100644 --- a/cmake/Modules/LAMMPSUtils.cmake +++ b/cmake/Modules/LAMMPSUtils.cmake @@ -32,7 +32,13 @@ function(check_omp_h_include) set(CMAKE_REQUIRED_INCLUDES ${OpenMP_CXX_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LINK_OPTIONS ${OpenMP_CXX_FLAGS}) set(CMAKE_REQUIRED_LIBRARIES ${OpenMP_CXX_LIBRARIES}) - check_include_file_cxx(omp.h _have_omp_h) + # there are all kinds of problems with finding omp.h + # for Clang and derived compilers so we pretend it is there. + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(_have_omp_h TRUE) + else() + check_include_file_cxx(omp.h _have_omp_h) + endif() else() set(_have_omp_h FALSE) endif() diff --git a/cmake/Modules/Packages/RHEO.cmake b/cmake/Modules/Packages/RHEO.cmake index be8c22877b..7639acd8bc 100644 --- a/cmake/Modules/Packages/RHEO.cmake +++ b/cmake/Modules/Packages/RHEO.cmake @@ -1,2 +1,2 @@ -find_package(GSL 2.7 REQUIRED) +find_package(GSL 2.6 REQUIRED) target_link_libraries(lammps PRIVATE GSL::gsl) diff --git a/doc/src/Build_extras.rst b/doc/src/Build_extras.rst index 4802c67420..eae247d66a 100644 --- a/doc/src/Build_extras.rst +++ b/doc/src/Build_extras.rst @@ -639,6 +639,9 @@ They must be specified in uppercase. * - AMD_GFX1100 - GPU - AMD GPU RX7900XTX + * - AMD_GFX1103 + - GPU + - AMD Phoenix APU with Radeon 740M/760M/780M/880M/890M * - INTEL_GEN - GPU - SPIR64-based devices, e.g. Intel GPUs, using JIT diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index 34100871ce..b6aa6e4114 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -414,8 +414,8 @@ Read or write compressed files If this option is enabled, large files can be read or written with compression by ``gzip`` or similar tools by several LAMMPS commands, including :doc:`read_data `, :doc:`rerun `, and -:doc:`dump `. Supported compression tools are currently -``gzip``, ``bzip2``, ``zstd``, and ``lzma``. +:doc:`dump `. Supported compression tools and algorithms are currently +``gzip``, ``bzip2``, ``zstd``, ``xz``, ``lz4``, and ``lzma`` (via xz). .. tabs:: diff --git a/doc/src/Commands_bond.rst b/doc/src/Commands_bond.rst index eec6f7acf1..2664b74076 100644 --- a/doc/src/Commands_bond.rst +++ b/doc/src/Commands_bond.rst @@ -73,7 +73,7 @@ OPT. * :doc:`none ` * :doc:`zero ` - * :doc:`hybrid ` + * :doc:`hybrid (k) ` * * * @@ -101,7 +101,7 @@ OPT. * :doc:`mesocnt ` * :doc:`mm3 ` * :doc:`quartic (o) ` - * :doc:`spica (o) ` + * :doc:`spica (ko) ` * :doc:`table (o) ` .. _dihedral: @@ -119,7 +119,7 @@ OPT. * :doc:`none ` * :doc:`zero ` - * :doc:`hybrid ` + * :doc:`hybrid (k) ` * * * @@ -157,7 +157,7 @@ OPT. * :doc:`none ` * :doc:`zero ` - * :doc:`hybrid ` + * :doc:`hybrid (k) ` * * * diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index a1b2a78fdb..9cf0495c8e 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -195,7 +195,7 @@ OPT. * :doc:`lj/mdf ` * :doc:`lj/relres (o) ` * :doc:`lj/spica (gko) ` - * :doc:`lj/spica/coul/long (go) ` + * :doc:`lj/spica/coul/long (gko) ` * :doc:`lj/spica/coul/msm (o) ` * :doc:`lj/sf/dipole/sf (go) ` * :doc:`lj/smooth (go) ` diff --git a/doc/src/Howto_lammps_gui.rst b/doc/src/Howto_lammps_gui.rst index a91a46ad3c..1283bcfa5a 100644 --- a/doc/src/Howto_lammps_gui.rst +++ b/doc/src/Howto_lammps_gui.rst @@ -1,5 +1,5 @@ -Using the LAMMPS-GUI -==================== +Using LAMMPS-GUI +================ This document describes **LAMMPS-GUI version 1.6**. @@ -16,54 +16,101 @@ to the online LAMMPS documentation for known LAMMPS commands and styles. .. note:: - Pre-compiled, ready-to-use LAMMPS-GUI executables for Linux (Ubuntu - 20.04LTS or later and compatible), macOS (version 11 aka Big Sur or - later), and Windows (version 10 or later) :ref:`are available - ` for download. None-MPI LAMMPS executables of - the same LAMMPS version are included in these packages as well. The - source code for the LAMMPS-GUI is included in the LAMMPS source code + Pre-compiled, ready-to-use LAMMPS-GUI executables for Linux x86\_64 + (Ubuntu 20.04LTS or later and compatible), macOS (version 11 aka Big + Sur or later), and Windows (version 10 or later) :ref:`are available + ` for download. None-MPI LAMMPS executables for + running LAMMPS from the command line and :doc:`some LAMMPS tools ` + are also included. + + The source code for LAMMPS-GUI is included in the LAMMPS source code distribution and can be found in the ``tools/lammps-gui`` folder. It can be compiled alongside LAMMPS when :doc:`compiling with CMake `. LAMMPS-GUI tries to provide an experience similar to what people -traditionally would do to run LAMMPS using a command line window -but just rolled into a single executable: +traditionally would have running LAMMPS using a command line window +and the console LAMMPS executable but just rolled into a single executable: -- editing LAMMPS input files with a text editor +- writing & editing LAMMPS input files with a text editor - run LAMMPS on those input file with selected command line flags - use or extract data from the created files and visualize it with either a molecular visualization program or a plotting program - That procedure is quite effective for people proficient in using the command line, as that allows them to use tools for the individual steps that they are most comfortable with. It is often *required* to adopt this workflow when running LAMMPS simulations on high-performance computing facilities. -The main benefit of using the LAMMPS-GUI application instead is that -many basic tasks can be done directly from the GUI without switching to -a text console window or using external programs, let alone writing -scripts to extract data from the generated output. It also integrates -well with graphical desktop environments. +The main benefit of using LAMMPS-GUI is that many basic tasks can be +done directly from the GUI without switching to a text console window or +using external programs, let alone writing scripts to extract data from +the generated output. It also integrates well with graphical desktop +environments where the `.lmp` filename extension can be registered with +LAMMPS-GUI as the executable to launch when double clicking on such +files. Also, LAMMPS-GUI has support for drag-n-drop, i.e. an input +file can be selected and then moved and dropped on the LAMMPS-GUI +executable, and LAMMPS-GUI will launch and read the file into its +buffer. LAMMPS-GUI thus makes it easier for beginners to get started running simple LAMMPS simulations. It is very suitable for tutorials on LAMMPS since you only need to learn how to use a single program for most tasks -and thus time can be saved and people can focus on learning LAMMPS. It -is also designed to keep the barrier low when you decide to switch to a -full featured, standalone programming editor and more sophisticated -visualization and analysis tools, and run LAMMPS from the command line -or a batch script. +and thus time can be saved and people can focus on learning LAMMPS. +The tutorials at https://lammpstutorials.github.io/ were specifically +updated for use with LAMMPS-GUI. + +Another design goal is to keep the barrier low when replacing part of +the functionality of LAMMPS-GUI with external tools. The following text provides a detailed tour of the features and -functionality of the LAMMPS-GUI. Suggestions for new features and +functionality of LAMMPS-GUI. Suggestions for new features and reports of bugs are always welcome. You can use the :doc:`the same channels as for LAMMPS itself ` for that purpose. ----- +Installing Pre-compiled LAMMPS-GUI Packages +------------------------------------------- + +LAMMPS-GUI is available as pre-compiled binary packages for Linux +x86\_64, macOS 11 and later, and Windows 10 and later. Alternately, it +can be compiled from source. + +Windows 10 and later +^^^^^^^^^^^^^^^^^^^^ + +After downloading the ``LAMMPS-Win10-64bit-GUI-.exe`` installer +package, you need to execute it, and start the installation process. +Since those packages are currently unsigned, you have to enable "Developer Mode" +in the Windows System Settings to run the installer. + +MacOS 11 and later +^^^^^^^^^^^^^^^^^^ + +After downloading the ``LAMMPS-macOS-multiarch-GUI-.dmg`` +installer package, you need to double-click it and then, in the window +that opens, drag the app bundle as indicated into the "Applications" +folder. The follow the instructions in the "README.txt" file to +get access to the other included executables. + +Linux on x86\_64 +^^^^^^^^^^^^^^^^ + +After downloading and unpacking the +``LAMMPS-Linux-x86_64-GUI-.tar.gz`` package. You can switch +into the "LAMMPS_GUI" folder and execute "./lammps-gui" directly. + +Compiling from Source +^^^^^^^^^^^^^^^^^^^^^ + +There also are instructions for :ref:`compiling LAMMPS-GUI from source +code ` available elsewhere in the manual. +Compilation from source *requires* using CMake. + +----- + Starting LAMMPS-GUI ------------------- @@ -88,17 +135,24 @@ window is stored when exiting and restored when starting again. Opening Files ^^^^^^^^^^^^^ -The LAMMPS-GUI application tries to open the first command line argument -as a LAMMPS input script, further arguments are ignored. When no -argument is given, LAMMPS-GUI starts with an empty buffer. Files can -also be opened via the ``File`` menu or by drag-and-drop of a file from -a graphical file manager into the editor window. Only one file can be -edited at a time, so opening a new file with a filled buffer closes that -buffer. If the buffer has unsaved modifications, you are asked to -either cancel the operation, discard the changes, or save them. A -buffer with modifications can be saved any time from the "File" menu, by -the keyboard shortcut `Ctrl-S` (`Command-S` on macOS), or by clicking on -the "Save" button at the very left in the status bar. +The LAMMPS-GUI application can be launched without command line arguments +and then starts with an empty buffer in the *Editor* window. If arguments +are given LAMMPS will use first command line argument as the file name for +the *Editor* buffer and reads its contents into the buffer, if the file +exists. All further arguments are ignored. Files can also be opened via +the ``File`` menu, the `Ctrl-O` (`Command-O` on macOS) keyboard shortcut +or by drag-and-drop of a file from a graphical file manager into the editor +window. If a file extension (e.g. ``.lmp``) has been registered with the +graphical environment to launch LAMMPS-GUI, an existing input file can +be launched with LAMMPS-GUI through double clicking. + +Only one file can be edited at a time, so opening a new file with a +filled buffer closes that buffer. If the buffer has unsaved +modifications, you are asked to either cancel the operation, discard the +changes, or save them. A buffer with modifications can be saved any +time from the "File" menu, by the keyboard shortcut `Ctrl-S` +(`Command-S` on macOS), or by clicking on the "Save" button at the very +left in the status bar. Running LAMMPS ^^^^^^^^^^^^^^ @@ -235,20 +289,30 @@ run number that this chart window corresponds to. Same as for the *Output* window, the chart window is replaced on each new run, but the behavior can be changed in the preferences dialog. +.. versionadded:: 1.6 + + Support for YAML export added + From the ``File`` menu on the top left, it is possible to save an image of the currently displayed plot or export the data in either plain text columns (for use by plotting tools like `gnuplot `_ or `grace -`_), or as CSV data which can -be imported for further processing with Microsoft Excel or `pandas -`_ +`_), as CSV data which can be +imported for further processing with Microsoft Excel `LibreOffice Calc +`_ or with Python via `pandas +`_, or as YAML which can be imported into +Python with `PyYAML `_ or pandas. Thermo output data from successive run commands in the input script is combined into a single data set unless the format, number, or names of output columns are changed with a :doc:`thermo_style ` or a :doc:`thermo_modify ` command, or the current time step is reset with :doc:`reset_timestep `, or if a -:doc:`clear ` command is issued. +:doc:`clear ` command is issued. This is where the YAML export +from the *Charts* window differs from that of the *Output* window: +here you get the compounded data set starting with the last change of +output fields or timestep setting, while the export from the log will +contain *all* YAML output but *segmented* into individual runs. Image Slide Show ---------------- @@ -347,15 +411,16 @@ actual image size, high-quality (SSAO) rendering, anti-aliasing, view style, display of box or axes, zoom factor. The view of the system can be rotated horizontally and vertically. It is also possible to only display the atoms within a group defined in the input script (default is -"all"). After each change, the image is rendered again and the display -updated. The small palette icon on the top left is colored while LAMMPS -is running to render the new image; it is grayed out when LAMMPS is -finished. When there are many atoms to render and high quality images -with anti-aliasing are requested, re-rendering may take several seconds. -From the ``File`` menu of the image window, the current image can be -saved to a file (keyboard shortcut `Ctrl-S`) or copied to the clipboard -(keyboard shortcut `Ctrl-C`) for pasting the image into another -application. +"all"). The image can also be re-centered on the center of mass of the +selected group. After each change, the image is rendered again and the +display updated. The small palette icon on the top left is colored +while LAMMPS is running to render the new image; it is grayed out when +LAMMPS is finished. When there are many atoms to render and high +quality images with anti-aliasing are requested, re-rendering may take +several seconds. From the ``File`` menu of the image window, the +current image can be saved to a file (keyboard shortcut `Ctrl-S`) or +copied to the clipboard (keyboard shortcut `Ctrl-C`) for pasting the +image into another application. .. versionadded:: 1.6 @@ -427,7 +492,7 @@ Context Specific Help |gui-popup1| |gui-popup2| -A unique feature of the LAMMPS-GUI is the option to look up the +A unique feature of LAMMPS-GUI is the option to look up the LAMMPS documentation for the command in the current line. This can be done by either clicking the right mouse button or by using the `Ctrl-?` keyboard shortcut. When using the mouse, there are additional entries in the @@ -435,10 +500,16 @@ context menu that open the corresponding documentation page in the online LAMMPS documentation in a web browser window. When using the keyboard, the first of those entries is chosen. +.. versionadded:: 1.6 + If the word under the cursor is a file, then additionally the context menu has an entry to open the file in a read-only text viewer window. This is a convenient way to view the contents of files that are -referenced in the input. +referenced in the input. The file viewer also supports on-the-fly +decompression based on the file name suffix in a :ref:`similar fashion +as available with LAMMPS `. If the necessary decompression +program is missing or the file cannot be decompressed, the viewer window +will contain a corresponding message. Menu ---- @@ -458,7 +529,7 @@ The ``File`` menu offers the usual options: - ``New`` clears the current buffer and resets the file name to ``*unknown*`` - ``Open`` opens a dialog to select a new file for editing in the *Editor* -- ``View`` opens a dialog to select a file for viewing in a *separate* window (read-only) +- ``View`` opens a dialog to select a file for viewing in a *separate* window (read-only) with support for on-the-fly decompression as explained above. - ``Save`` saves the current file; if the file name is ``*unknown*`` a dialog will open to select a new file name - ``Save As`` opens a dialog to select and new file name (and folder, if @@ -531,12 +602,12 @@ in an ``Image Viewer`` window. The ``View in OVITO`` entry will launch `OVITO `_ with a :doc:`data file ` containing the current state of -the system. This option is only available if the LAMMPS-GUI can find +the system. This option is only available if LAMMPS-GUI can find the OVITO executable in the system path. The ``View in VMD`` entry will launch VMD with a :doc:`data file ` containing the current state of the system. This option -is only available if the LAMMPS-GUI can find the VMD executable in the +is only available if LAMMPS-GUI can find the VMD executable in the system path. View @@ -559,6 +630,9 @@ a minimal description of LAMMPS-GUI. The ``LAMMPS-GUI Howto`` entry will open this documentation page from the online documentation in a web browser window. The ``LAMMPS Manual`` entry will open the main page of the LAMMPS online documentation in a web browser window. +The ``LAMMPS Tutorial`` entry will open the main page of the set of +LAMMPS tutorials authored and maintained by Simon Gravelle at +https://lammpstutorials.github.io/ in a web browser window. ----- @@ -566,8 +640,8 @@ Preferences ----------- The ``Preferences`` dialog allows customization of the behavior and -look of the LAMMPS-GUI application. The settings are grouped and each -group is displayed within a tab. +look of LAMMPS-GUI. The settings are grouped and each group is +displayed within a tab. .. |guiprefs1| image:: JPG/lammps-gui-prefs-general.png :width: 24% @@ -744,12 +818,12 @@ available (On macOS use the Command key instead of Ctrl/Control). - Reformat line - Shift+TAB - Show Completions - * - Ctrl+Shift+Enter + * - Ctrl+Shift+T + - LAMMPS Tutorial + - Ctrl+Shift+Enter - Run File - - - - - - Further editing keybindings `are documented with the Qt documentation `_. In diff --git a/doc/src/Howto_pylammps.rst b/doc/src/Howto_pylammps.rst index bce37d5ac7..5ef3248e1d 100644 --- a/doc/src/Howto_pylammps.rst +++ b/doc/src/Howto_pylammps.rst @@ -6,19 +6,22 @@ PyLammps Tutorial Overview -------- -``PyLammps`` is a Python wrapper class for LAMMPS which can be created -on its own or use an existing lammps Python object. It creates a simpler, +:py:class:`PyLammps ` is a Python wrapper class for +LAMMPS which can be created on its own or use an existing +:py:class:`lammps Python ` object. It creates a simpler, more "pythonic" interface to common LAMMPS functionality, in contrast to -the ``lammps`` wrapper for the C-style LAMMPS library interface which -is written using `Python ctypes `_. The ``lammps`` wrapper -is discussed on the :doc:`Python_head` doc page. +the :py:class:`lammps ` wrapper for the LAMMPS :ref:`C +language library interface API ` which is written using +`Python ctypes `_. The :py:class:`lammps ` +wrapper is discussed on the :doc:`Python_head` doc page. -Unlike the flat ``ctypes`` interface, PyLammps exposes a discoverable -API. It no longer requires knowledge of the underlying C++ code -implementation. Finally, the ``IPyLammps`` wrapper builds on top of -``PyLammps`` and adds some additional features for -`IPython integration `_ into `Jupyter notebooks `_, -e.g. for embedded visualization output from :doc:`dump style image `. +Unlike the flat `ctypes `_ interface, PyLammps exposes a +discoverable API. It no longer requires knowledge of the underlying C++ +code implementation. Finally, the :py:class:`IPyLammps +` wrapper builds on top of :py:class:`PyLammps +` and adds some additional features for `IPython +integration `_ into `Jupyter notebooks `_, e.g. for +embedded visualization output from :doc:`dump style image `. .. _ctypes: https://docs.python.org/3/library/ctypes.html .. _ipython: https://ipython.org/ @@ -30,19 +33,22 @@ Comparison of lammps and PyLammps interfaces lammps.lammps """"""""""""" -* uses ``ctypes`` -* direct memory access to native C++ data +* uses `ctypes `_ +* direct memory access to native C++ data with optional support for NumPy arrays * provides functions to send and receive data to LAMMPS +* interface modeled after the LAMMPS :ref:`C language library interface API ` * requires knowledge of how LAMMPS internally works (C pointers, etc) +* full support for running Python with MPI using `mpi4py `_ lammps.PyLammps """"""""""""""" -* higher-level abstraction built on top of original ctypes interface +* higher-level abstraction built on *top* of original :py:class:`ctypes based interface ` * manipulation of Python objects * communication with LAMMPS is hidden from API user * shorter, more concise Python * better IPython integration, designed for quick prototyping +* designed for serial execution Quick Start ----------- @@ -506,14 +512,26 @@ inside of the IPython notebook. Using PyLammps and mpi4py (Experimental) ---------------------------------------- -PyLammps can be run in parallel using mpi4py. This python package can be installed using +PyLammps can be run in parallel using `mpi4py +`_. This python package can be installed +using .. code-block:: bash pip install mpi4py -The following is a short example which reads in an existing LAMMPS input file and -executes it in parallel. You can find in.melt in the examples/melt folder. +.. warning:: + + Usually, any :py:class:`PyLammps ` command must be + executed by *all* MPI processes. However, evaluations and querying + the system state is only available on MPI rank 0. Using these + functions from other MPI ranks will raise an exception. + +The following is a short example which reads in an existing LAMMPS input +file and executes it in parallel. You can find in.melt in the +examples/melt folder. Please take note that the +:py:meth:`PyLammps.eval() ` is called only from +MPI rank 0. .. code-block:: python @@ -535,10 +553,6 @@ following mpirun command: mpirun -np 4 python melt.py -.. warning:: - - Any command must be executed by all MPI processes. However, evaluations and querying the system state is only available on rank 0. - Feedback and Contributing ------------------------- diff --git a/doc/src/JPG/lammps-gui-image.png b/doc/src/JPG/lammps-gui-image.png index fb3fe609e0..48b9fd1ce3 100644 Binary files a/doc/src/JPG/lammps-gui-image.png and b/doc/src/JPG/lammps-gui-image.png differ diff --git a/doc/src/Tools.rst b/doc/src/Tools.rst index 4505142459..060fd9f89d 100644 --- a/doc/src/Tools.rst +++ b/doc/src/Tools.rst @@ -484,23 +484,22 @@ are in the :doc:`Howto_lammps_gui` tutorial Howto page. Here are a few highlights of LAMMPS-GUI -- Text editor with syntax highlighting customized for LAMMPS -- Text editor features command completion for known commands and styles -- Text editor will switch working directory to folder of file in buffer -- Text editor will remember up to 5 recent files +- Text editor with line numbers and syntax highlighting customized for LAMMPS +- Text editor features command completion and auto-indentation for known commands and styles +- Text editor will switch its working directory to folder of file in buffer +- Many adjustable settings and preferences that are persistent including the 5 most recent files - Context specific LAMMPS command help via online documentation - LAMMPS is running in a concurrent thread, so the GUI remains responsive -- Support for most accelerator packages - Progress bar indicates how far a run command is completed -- LAMMPS can be started and stopped with a hotkey -- Screen output is captured in a Log Window -- Thermodynamic output is captured and displayed as line graph in a Chart Window +- LAMMPS can be started and stopped with a mouse click or a hotkey +- Screen output is captured in an *Output* Window +- Thermodynamic output is captured and displayed as line graph in a *Chart* Window - Indicator for currently executed command - Indicator for line that caused an error - Visualization of current state in Image Viewer (via calling :doc:`write_dump image `) - Capture of images created via :doc:`dump image ` in Slide show window -- Many adjustable settings and preferences that are persistent - Dialog to set variables, similar to the LAMMPS command line flag '-v' / '-var' +- Support for GPU, INTEL, KOKKOS/OpenMP, OPENMAP, and OPT and accelerator packages Parallelization ^^^^^^^^^^^^^^^ @@ -542,6 +541,8 @@ variable so the executables will be found automatically. The LAMMPS-GUI executable is called ``lammps-gui`` and either takes no arguments or attempts to load the first argument as LAMMPS input file. +.. _lammps_gui_compilation: + Compilation ^^^^^^^^^^^ diff --git a/doc/src/angle_hybrid.rst b/doc/src/angle_hybrid.rst index cf8ea1a3fb..fc213c13e9 100644 --- a/doc/src/angle_hybrid.rst +++ b/doc/src/angle_hybrid.rst @@ -1,8 +1,11 @@ .. index:: angle_style hybrid +.. index:: angle_style hybrid/kk angle_style hybrid command ========================== +Accelerator Variants: *hybrid/kk* + Syntax """""" @@ -79,6 +82,10 @@ for specific angle types. ---------- +.. include:: accel_styles.rst + +---------- + Restrictions """""""""""" @@ -87,8 +94,9 @@ MOLECULE package. See the :doc:`Build package ` doc page for more info. Unlike other angle styles, the hybrid angle style does not store angle -coefficient info for individual sub-styles in a :doc:`binary restart files `. Thus when restarting a simulation from a restart -file, you need to re-specify :doc:`angle_coeff ` commands. +coefficient info for individual sub-styles in :doc:`binary restart files +` or :doc:`data files `. Thus when restarting a +simulation, you need to re-specify the angle_coeff commands. Related commands """""""""""""""" diff --git a/doc/src/angle_spica.rst b/doc/src/angle_spica.rst index 4162ce5608..2659dd4fc0 100644 --- a/doc/src/angle_spica.rst +++ b/doc/src/angle_spica.rst @@ -1,10 +1,11 @@ .. index:: angle_style spica .. index:: angle_style spica/omp +.. index:: angle_style spica/kk angle_style spica command ========================= -Accelerator Variants: *spica/omp* +Accelerator Variants: *spica/omp*, *spica/kk* Syntax """""" diff --git a/doc/src/bond_hybrid.rst b/doc/src/bond_hybrid.rst index ea90ed2b57..fce393008e 100644 --- a/doc/src/bond_hybrid.rst +++ b/doc/src/bond_hybrid.rst @@ -75,8 +75,9 @@ package. See the :doc:`Build package ` page for more info. Unlike other bond styles, the hybrid bond style does not store bond -coefficient info for individual sub-styles in a :doc:`binary restart files `. Thus when restarting a simulation from a restart -file, you need to re-specify bond_coeff commands. +coefficient info for individual sub-styles in :doc:`binary restart files +` or :doc:`data files `. Thus when restarting a +simulation, you need to re-specify the bond_coeff commands. Related commands """""""""""""""" diff --git a/doc/src/dihedral_hybrid.rst b/doc/src/dihedral_hybrid.rst index 998a752275..460c329de9 100644 --- a/doc/src/dihedral_hybrid.rst +++ b/doc/src/dihedral_hybrid.rst @@ -1,8 +1,11 @@ .. index:: dihedral_style hybrid +.. index:: dihedral_style hybrid/kk dihedral_style hybrid command ============================= +Accelerator Variants: *hybrid/kk* + Syntax """""" @@ -80,6 +83,10 @@ for specific dihedral types. ---------- +.. include:: accel_styles.rst + +---------- + Restrictions """""""""""" @@ -88,8 +95,10 @@ MOLECULE package. See the :doc:`Build package ` doc page for more info. Unlike other dihedral styles, the hybrid dihedral style does not store -dihedral coefficient info for individual sub-styles in a :doc:`binary restart files `. Thus when restarting a simulation from a -restart file, you need to re-specify dihedral_coeff commands. +dihedral coefficient info for individual sub-styles in :doc:`binary +restart files ` or :doc:`data files `. Thus when +restarting a simulation, you need to re-specify the dihedral_coeff +commands. Related commands """""""""""""""" diff --git a/doc/src/fix_meso_move.rst b/doc/src/fix_meso_move.rst index 55d54b2107..64b451b7f1 100644 --- a/doc/src/fix_meso_move.rst +++ b/doc/src/fix_meso_move.rst @@ -247,6 +247,11 @@ defined by the :doc:`atom_style sph ` command. All particles in the group must be mesoscopic SPH/SDPD particles. +.. versionchanged:: TBD + +This fix is incompatible with deformation controls that remap velocity, +for instance the *remap v* option of :doc:`fix deform `. + Related commands """""""""""""""" diff --git a/doc/src/fix_mvv_dpd.rst b/doc/src/fix_mvv_dpd.rst index ff5b169f97..e64a162bf4 100644 --- a/doc/src/fix_mvv_dpd.rst +++ b/doc/src/fix_mvv_dpd.rst @@ -97,6 +97,11 @@ These fixes are part of the DPD-MESO package. They are only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +.. versionchanged:: TBD + +This fix is incompatible with deformation controls that remap velocity, +for instance the *remap v* option of :doc:`fix deform `. + Related commands """""""""""""""" diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index a2e137da25..0c7f763ced 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -236,7 +236,7 @@ The keyword *fixcom* specifies whether the center-of-mass of the extended ring-p Once *fixcom* is set to be *yes*, the center-of-mass velocity will be distracted from the centroid-mode velocities in each step. The keyword *lj* should be used if :doc:`lj units ` is used for *fix pimd/langevin*. Typically one may want to use -reduced units to run the simulation, and then convert the results into some physical units (for example, :doc:`metal units `). In this case, the 5 quantities in the physical mass units are needed: epsilon (energy scale), sigma (length scale), mass, Planck's constant, mvv2e (mass * velocity^2 to energy conversion factor). Planck's constant and mvv2e can be found in src/update.cpp. If there is no need to convert reduced units to physical units, set all these five value to 1. +reduced units to run the simulation, and then convert the results into some physical units (for example, :doc:`metal units `). In this case, the 5 quantities in the physical mass units are needed: epsilon (energy scale), sigma (length scale), mass, Planck's constant, mvv2e (mass * velocity^2 to energy conversion factor). Planck's constant and mvv2e can be found in src/update.cpp. If there is no need to convert reduced units to physical units, you can omit the keyword *lj* and these five values will be set to 1. The PIMD algorithm in LAMMPS is implemented as a hyper-parallel scheme as described in :ref:`Calhoun `. In LAMMPS this is done by using diff --git a/doc/src/fix_rigid_meso.rst b/doc/src/fix_rigid_meso.rst index c8c994fd26..3f734e3fef 100644 --- a/doc/src/fix_rigid_meso.rst +++ b/doc/src/fix_rigid_meso.rst @@ -353,6 +353,11 @@ defined by the :doc:`atom_style sph ` command. All particles in the group must be mesoscopic SPH/SDPD particles. +.. versionchanged:: TBD + +This fix is incompatible with deformation controls that remap velocity, +for instance the *remap v* option of :doc:`fix deform `. + Related commands """""""""""""""" diff --git a/doc/src/fix_shake.rst b/doc/src/fix_shake.rst index 73caa9c668..4129dcd9af 100644 --- a/doc/src/fix_shake.rst +++ b/doc/src/fix_shake.rst @@ -27,9 +27,9 @@ Syntax .. parsed-literal:: - *b* values = one or more bond types - *a* values = one or more angle types - *t* values = one or more atom types + *b* values = one or more bond types (may use type labels) + *a* values = one or more angle types (may use type labels) + *t* values = one or more atom types (may use type labels) *m* value = one or more mass values * zero or more keyword/value pairs may be appended @@ -137,7 +137,17 @@ constrained (within a fudge factor of MASSDELTA specified in both bonds in the angle are constrained then the angle will also be constrained if its type is in the list. -For all constraints, a particular bond is only constrained if both +.. versionchanged:: TBD + +The types may be given as type labels *only* if there is no atom, bond, +or angle type label named *b*, *a*, *t*, or *m* defined in the +simulation. If that is the case, type labels cannot be used as +constraint type index with these two fixes, because the type labels +would be incorrectly treated as a new type of constraint instead. +Thus, LAMMPS will print a warning and type label handling is disabled +and numeric types must be used. + +For all constraints, a particular bond is only constrained if *both* atoms in the bond are in the group specified with the SHAKE fix. The degrees-of-freedom removed by SHAKE bonds and angles are accounted diff --git a/doc/src/fix_smd_integrate_tlsph.rst b/doc/src/fix_smd_integrate_tlsph.rst index 515b30d4ff..44d4bab3a5 100644 --- a/doc/src/fix_smd_integrate_tlsph.rst +++ b/doc/src/fix_smd_integrate_tlsph.rst @@ -53,6 +53,11 @@ Restrictions This fix is part of the MACHDYN package. It is only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +.. versionchanged:: TBD + +This fix is incompatible with deformation controls that remap velocity, +for instance the *remap v* option of :doc:`fix deform `. + Related commands """""""""""""""" diff --git a/doc/src/fix_smd_integrate_ulsph.rst b/doc/src/fix_smd_integrate_ulsph.rst index 17dfdb7b17..6b1e070763 100644 --- a/doc/src/fix_smd_integrate_ulsph.rst +++ b/doc/src/fix_smd_integrate_ulsph.rst @@ -61,6 +61,11 @@ Restrictions This fix is part of the MACHDYN package. It is only enabled if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +.. versionchanged:: TBD + +This fix is incompatible with deformation controls that remap velocity, +for instance the *remap v* option of :doc:`fix deform `. + Related commands """""""""""""""" diff --git a/doc/src/improper_hybrid.rst b/doc/src/improper_hybrid.rst index a829d9989c..d7b9a425f3 100644 --- a/doc/src/improper_hybrid.rst +++ b/doc/src/improper_hybrid.rst @@ -1,8 +1,11 @@ .. index:: improper_style hybrid +.. index:: improper_style hybrid/kk improper_style hybrid command ============================= +Accelerator Variants: *hybrid/kk* + Syntax """""" @@ -79,6 +82,10 @@ types. ---------- +.. include:: accel_styles.rst + +---------- + Restrictions """""""""""" @@ -87,9 +94,10 @@ MOLECULE package. See the :doc:`Build package ` doc page for more info. Unlike other improper styles, the hybrid improper style does not store -improper coefficient info for individual sub-styles in a :doc:`binary restart files `. -Thus when restarting a simulation from a -restart file, you need to re-specify improper_coeff commands. +improper coefficient info for individual sub-styles in :doc:`binary +restart files ` or :doc:`data files `. Thus when +restarting a simulation, you need to re-specify the improper_coeff +commands. Related commands """""""""""""""" diff --git a/doc/src/neigh_modify.rst b/doc/src/neigh_modify.rst index 3ec6578b3f..63d7221c70 100644 --- a/doc/src/neigh_modify.rst +++ b/doc/src/neigh_modify.rst @@ -32,7 +32,7 @@ Syntax group-ID = only build pair neighbor lists for atoms in this group *exclude* values: *type* M N - M,N = exclude if one atom in pair is type M, other is type N + M,N = exclude if one atom in pair is type M, other is type N (M and N may be type labels) *group* group1-ID group2-ID group1-ID,group2-ID = exclude if one atom is in 1st group, other in 2nd *molecule/intra* group-ID @@ -159,15 +159,19 @@ sample scenarios where this is useful: * When one or more rigid bodies are specified, interactions within each body can be turned off to save needless computation. See the :doc:`fix rigid ` command for more details. -The *exclude type* option turns off the pairwise interaction if one -atom is of type M and the other of type N. M can equal N. The -*exclude group* option turns off the interaction if one atom is in the -first group and the other is the second. Group1-ID can equal -group2-ID. The *exclude molecule/intra* option turns off the -interaction if both atoms are in the specified group and in the same -molecule, as determined by their molecule ID. The *exclude -molecule/inter* turns off the interaction between pairs of atoms that -have different molecule IDs and are both in the specified group. +.. versionchanged:: TBD + + Support for type labels was added. + +The *exclude type* option turns off the pairwise interaction if one atom +is of type M and the other of type N. M can equal N. The *exclude +group* option turns off the interaction if one atom is in the first +group and the other is the second. Group1-ID can equal group2-ID. The +*exclude molecule/intra* option turns off the interaction if both atoms +are in the specified group and in the same molecule, as determined by +their molecule ID. The *exclude molecule/inter* turns off the +interaction between pairs of atoms that have different molecule IDs and +are both in the specified group. Each of the exclude options can be specified multiple times. The *exclude type* option is the most efficient option to use; it requires @@ -219,34 +223,34 @@ atom can have. The *binsize* option allows you to specify what size of bins will be used in neighbor list construction to sort and find neighboring atoms. By default, for :doc:`neighbor style bin `, LAMMPS uses bins -that are 1/2 the size of the maximum pair cutoff. For :doc:`neighbor style multi `, -the bins are 1/2 the size of the collection interaction cutoff. -Typically these are good values for minimizing the time for -neighbor list construction. This setting overrides the default. -If you make it too big, there is little overhead due to +that are 1/2 the size of the maximum pair cutoff. For :doc:`neighbor +style multi `, the bins are 1/2 the size of the collection +interaction cutoff. Typically these are good values for minimizing the +time for neighbor list construction. This setting overrides the +default. If you make it too big, there is little overhead due to looping over bins, but more atoms are checked. If you make it too -small, the optimal number of atoms is checked, but bin overhead goes -up. If you set the binsize to 0.0, LAMMPS will use the default -binsize of 1/2 the cutoff. +small, the optimal number of atoms is checked, but bin overhead goes up. +If you set the binsize to 0.0, LAMMPS will use the default binsize of +1/2 the cutoff. The *collection/type* option allows you to define collections of atom -types, used by the *multi* neighbor mode. By grouping atom types with -similar physical size or interaction cutoff lengths, one may be able -to improve performance by reducing -overhead. You must first specify the number of collections N to be -defined followed by N lists of types. Each list consists of a series of type -ranges separated by commas. The range can be specified as a -single numeric value, or a wildcard asterisk can be used to specify a range -of values. This takes the form "\*" or "\*n" or "n\*" or "m\*n". For -example, if M = the number of atom types, then an asterisk with no numeric -values means all types from 1 to M. A leading asterisk means all types -from 1 to n (inclusive). A trailing asterisk means all types from n to M -(inclusive). A middle asterisk means all types from m to n (inclusive). -Note that all atom types must be included in exactly one of the N collections. +types, used by the *multi* neighbor mode. By grouping atom types with +similar physical size or interaction cutoff lengths, one may be able to +improve performance by reducing overhead. You must first specify the +number of collections N to be defined followed by N lists of types. +Each list consists of a series of type ranges separated by commas. The +range can be specified as a single numeric value, or a wildcard asterisk +can be used to specify a range of values. This takes the form "\*" or +"\*n" or "n\*" or "m\*n". For example, if M = the number of atom types, +then an asterisk with no numeric values means all types from 1 to M. A +leading asterisk means all types from 1 to n (inclusive). A trailing +asterisk means all types from n to M (inclusive). A middle asterisk +means all types from m to n (inclusive). Note that all atom types must +be included in exactly one of the N collections. The *collection/interval* option provides a similar capability. This command allows a user to define collections by specifying a series of -cutoff intervals. LAMMPS will automatically sort atoms into these +cutoff intervals. LAMMPS will automatically sort atoms into these intervals based on their type-dependent cutoffs or their finite size. You must first specify the number of collections N to be defined followed by N values representing the upper cutoff of each interval. diff --git a/doc/src/pair_born_gauss.rst b/doc/src/pair_born_gauss.rst index 97f0042ee7..58796438ad 100644 --- a/doc/src/pair_born_gauss.rst +++ b/doc/src/pair_born_gauss.rst @@ -19,7 +19,7 @@ Examples .. code-block:: LAMMPS pair_style born/gauss 10.0 - pair_coeff 1 1 1 1 8.2464e13 12.48 0.042644277 0.44 3.56 + pair_coeff 1 1 8.2464e13 12.48 0.042644277 0.44 3.56 Description """"""""""" diff --git a/doc/src/pair_hybrid.rst b/doc/src/pair_hybrid.rst index 634717f8a8..617b0c4372 100644 --- a/doc/src/pair_hybrid.rst +++ b/doc/src/pair_hybrid.rst @@ -479,11 +479,12 @@ For the hybrid pair styles, the list of sub-styles and their respective settings are written to :doc:`binary restart files `, so a :doc:`pair_style ` command does not need to specified in an input script that reads a restart file. However, the coefficient -information is not stored in the restart file. Thus, pair_coeff -commands need to be re-specified in the restart input script. For pair -style *hybrid/scaled* also the names of any variables used as scale -factors are restored, but not the variables themselves, so those may -need to be redefined when continuing from a restart. +information is not stored in the restart file. The same is true for +:doc:`data files `. Thus, pair_coeff commands need to be +re-specified in the restart input script. For pair style +*hybrid/scaled* also the names of any variables used as scale factors +are restored, but not the variables themselves, so those may need to be +redefined when continuing from a restart. These pair styles support the use of the *inner*, *middle*, and *outer* keywords of the :doc:`run_style respa ` command, if diff --git a/doc/src/pair_spica.rst b/doc/src/pair_spica.rst index 859506593f..b86639e806 100644 --- a/doc/src/pair_spica.rst +++ b/doc/src/pair_spica.rst @@ -5,6 +5,7 @@ .. index:: pair_style lj/spica/coul/long .. index:: pair_style lj/spica/coul/long/gpu .. index:: pair_style lj/spica/coul/long/omp +.. index:: pair_style lj/spica/coul/long/kk .. index:: pair_style lj/spica/coul/msm .. index:: pair_style lj/spica/coul/msm/omp @@ -16,7 +17,7 @@ Accelerator Variants: *lj/spica/gpu*, *lj/spica/kk*, *lj/spica/omp* pair_style lj/spica/coul/long command ===================================== -Accelerator Variants: *lj/spica/coul/long/gpu*, *lj/spica/coul/long/omp* +Accelerator Variants: *lj/spica/coul/long/gpu*, *lj/spica/coul/long/omp*, *lj/spica/coul/long/kk* pair_style lj/spica/coul/msm command ==================================== diff --git a/doc/src/write_data.rst b/doc/src/write_data.rst index e1e5b04953..937ab5ba02 100644 --- a/doc/src/write_data.rst +++ b/doc/src/write_data.rst @@ -51,10 +51,12 @@ value. The write_data command may not always write all coefficient settings to the corresponding Coeff sections of the data file. This can have - one of multiple reasons. 1) A few styles may be missing the code that - would write those sections (if you come across one, please notify - the LAMMPS developers). 2) Some pair styles require a single pair_coeff - statement and those are not compatible with data files. 3) The + one of multiple reasons. 1) The style may be a hybrid style. In that + case *no* coeff information is written. 2) A few styles may be + missing the code that would write those sections (This is rare these + days, but if you come across one, please notify the LAMMPS + developers). 3) Some pair styles require a single pair_coeff + statement and those are not compatible with data files. 4) The default for write_data is to write a PairCoeff section, which has only entries for atom types i == j. The remaining coefficients would be inferred through the currently selected mixing rule. If there has diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index d18ab66181..002e861dc7 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1355,6 +1355,7 @@ Grama grana granregion graphene +Gravelle Greathouse greenyellow Greffet @@ -3080,6 +3081,7 @@ qx qy qz Rackers +Radeon radi radialscreened radialscreenedspin diff --git a/examples/PACKAGES/cgspica/sds-monolayer/in.sds-regular b/examples/PACKAGES/cgspica/sds-monolayer/in.sds-regular index e64882aaa0..fef6b80eca 100644 --- a/examples/PACKAGES/cgspica/sds-monolayer/in.sds-regular +++ b/examples/PACKAGES/cgspica/sds-monolayer/in.sds-regular @@ -5,9 +5,9 @@ dimension 3 atom_style full processors * * 1 -pair_style lj/sdk/coul/long 15.0 # compatible with "lj/spica/coul/long" +pair_style lj/spica/coul/long 15.0 bond_style harmonic -angle_style sdk # compatible with "spica" +angle_style spica special_bonds lj/coul 0.0 0.0 1.0 read_data data.sds.gz diff --git a/examples/charmmfsw/charmmff.cmap b/examples/charmmfsw/charmmff.cmap new file mode 100644 index 0000000000..6fea0c508f --- /dev/null +++ b/examples/charmmfsw/charmmff.cmap @@ -0,0 +1,340 @@ +#CMAP for C NH1 CT1 C NH1 CT1 C NH1; id=1 +#phi = -180.000000 + 0.130000 0.770000 0.970000 1.250000 2.120000 + 2.720000 2.090000 1.790000 0.780000 -0.690000 + 1.000000 -2.200000 -4.830000 -4.820000 -4.910000 + -3.590000 -2.770000 -2.780000 -2.450000 -2.350000 + -2.340000 -1.520000 -0.950000 -0.040000 + +#phi = -165.000000 + -0.130000 1.380000 1.580000 1.870000 2.400000 + 2.490000 2.440000 1.930000 1.090000 0.640000 + 0.260000 -2.800000 -4.010000 -4.140000 -3.420000 + -2.600000 -2.300000 -1.500000 -1.100000 -0.860000 + -0.640000 -0.210000 -1.080000 -1.120000 + +#phi = -150.000000 + 0.080000 1.420000 1.620000 2.050000 2.650000 + 2.720000 2.320000 1.990000 1.560000 2.460000 + -0.230000 -1.820000 -2.580000 -3.010000 -2.550000 + -1.890000 -1.350000 -0.730000 0.070000 -0.230000 + -0.770000 -1.280000 -1.290000 -0.820000 + +#phi = -135.000000 + 0.930000 1.520000 2.240000 2.550000 3.110000 + 2.920000 2.460000 2.190000 2.060000 1.850000 + 0.120000 -1.180000 -2.000000 -2.280000 -1.960000 + -1.340000 -0.930000 0.020000 0.310000 -0.520000 + -1.150000 -0.980000 -0.570000 -0.440000 + +#phi = -120.000000 + 1.360000 1.960000 2.700000 3.040000 3.700000 + 3.560000 2.640000 2.770000 2.720000 1.630000 + 0.710000 -0.790000 -2.120000 -2.630000 -1.800000 + -0.430000 -0.060000 0.440000 0.910000 -0.550000 + -0.970000 -0.860000 -0.250000 0.450000 + +#phi = -105.000000 + 2.050000 2.540000 2.820000 3.090000 3.370000 + 3.550000 3.070000 2.900000 2.960000 2.120000 + 0.910000 -0.820000 -2.090000 -2.240000 -1.460000 + 0.210000 0.080000 0.770000 1.040000 -0.120000 + -0.320000 -0.160000 0.310000 0.730000 + +#phi = -90.000000 + 1.450000 2.750000 2.740000 3.160000 3.450000 + 3.340000 3.180000 3.900000 3.340000 2.440000 + 0.910000 -0.610000 -1.510000 -1.620000 -0.960000 + -0.020000 0.420000 0.910000 0.460000 0.150000 + -0.070000 0.020000 0.280000 0.750000 + +#phi = -75.000000 + 1.380000 3.350000 2.350000 3.060000 3.810000 + 3.700000 3.580000 4.210000 3.540000 1.690000 + 0.100000 -0.680000 -0.120000 -0.430000 -0.600000 + 0.230000 0.420000 0.300000 0.550000 0.190000 + -0.250000 -0.190000 -0.250000 0.470000 + +#phi = -60.000000 + 0.240000 1.230000 1.720000 3.170000 4.210000 + 4.390000 4.280000 3.670000 2.270000 -0.480000 + -0.410000 -0.040000 -0.360000 -0.820000 -0.170000 + 0.140000 0.270000 0.320000 0.310000 -0.670000 + -0.950000 -1.530000 -1.480000 -0.200000 + +#phi = -45.000000 + -1.180000 0.080000 2.350000 4.210000 5.380000 + 5.390000 4.380000 2.460000 1.120000 0.110000 + 0.010000 -0.150000 -0.800000 -0.580000 0.080000 + 0.270000 -0.050000 0.380000 0.250000 -0.890000 + -1.580000 -1.950000 -1.980000 -2.000000 + +#phi = -30.000000 + -1.170000 1.070000 4.180000 6.740000 6.070000 + 4.810000 2.780000 1.320000 0.770000 -0.010000 + 0.280000 -0.710000 1.310000 1.520000 1.920000 + 2.220000 0.190000 0.530000 0.330000 -1.600000 + -2.850000 -3.550000 -3.280000 -2.660000 + +#phi = -15.000000 + 0.290000 5.590000 3.730000 3.220000 3.270000 + 2.520000 1.590000 1.380000 0.860000 0.660000 + 1.620000 0.850000 0.510000 0.740000 1.020000 + 1.620000 -0.340000 0.180000 -0.610000 -2.560000 + -3.790000 -3.810000 -3.160000 -1.750000 + +#phi = 0.000000 + 2.830000 0.790000 0.320000 0.480000 0.630000 + 0.980000 1.240000 1.670000 1.650000 2.520000 + 1.610000 0.780000 0.120000 0.070000 0.120000 + -1.570000 -1.210000 -1.930000 -2.600000 -3.790000 + -3.930000 -3.620000 -2.680000 -0.920000 + +#phi = 15.000000 + -0.780000 -1.910000 -2.050000 -1.850000 -1.050000 + 0.180000 1.680000 2.220000 1.360000 2.450000 + 1.440000 0.680000 -0.240000 -0.540000 -0.790000 + -2.180000 -3.210000 -4.350000 -3.940000 -3.910000 + -3.460000 -2.770000 1.760000 0.310000 + +#phi = 30.000000 + -2.960000 -3.480000 -3.440000 -2.400000 -1.130000 + 0.340000 1.430000 1.390000 0.970000 2.460000 + 1.520000 0.550000 -0.410000 -1.480000 -3.580000 + -4.130000 -4.560000 -4.440000 -3.580000 -2.960000 + -1.960000 -1.070000 -1.600000 -2.450000 + +#phi = 45.000000 + -4.020000 -3.840000 -3.370000 -2.330000 -0.980000 + 0.360000 0.810000 0.750000 0.500000 1.900000 + 0.770000 -0.420000 -3.290000 -3.910000 -4.520000 + -4.890000 -3.850000 -4.150000 -2.670000 -2.370000 + -2.860000 -3.420000 -3.670000 -3.600000 + +#phi = 60.000000 + -3.350000 -2.980000 -2.320000 -1.240000 -0.260000 + 0.720000 0.670000 0.440000 2.400000 1.630000 + -2.010000 -3.310000 -3.990000 -4.530000 -4.850000 + -3.770000 -3.940000 -3.890000 -2.610000 -3.510000 + -3.760000 -3.640000 -3.450000 -3.340000 + +#phi = 75.000000 + -2.250000 -1.640000 -1.010000 0.040000 0.640000 + 0.820000 0.520000 -0.010000 -0.370000 -1.190000 + -2.390000 -3.380000 -4.500000 -5.590000 -5.510000 + -4.940000 -3.830000 -3.840000 -3.700000 -4.150000 + -4.170000 -3.730000 -3.740000 -2.620000 + +#phi = 90.000000 + -1.720000 -1.180000 -0.430000 0.280000 0.810000 + 0.800000 0.480000 -0.340000 -0.790000 -1.770000 + -2.810000 -3.800000 -5.220000 -6.280000 -6.580000 + -5.640000 -5.060000 -4.020000 -4.150000 -4.470000 + -4.100000 -3.770000 -3.160000 -2.650000 + +#phi = 105.000000 + -1.850000 -1.090000 -0.450000 0.130000 1.010000 + 0.880000 0.490000 -0.220000 -0.860000 -1.680000 + -3.010000 -4.130000 -5.990000 -6.860000 -6.830000 + -5.850000 -3.860000 -4.860000 -4.910000 -4.720000 + -4.600000 -4.090000 -3.270000 -2.410000 + +#phi = 120.000000 + -1.970000 -1.120000 -0.540000 -0.150000 0.760000 + 1.040000 0.760000 0.310000 -0.330000 -1.870000 + -3.370000 -5.010000 -6.120000 -7.050000 -6.980000 + -3.700000 -4.510000 -5.090000 -5.420000 -4.850000 + -4.440000 -4.000000 -3.420000 -2.750000 + +#phi = 135.000000 + -2.110000 -1.170000 -0.320000 -0.010000 0.320000 + 1.090000 0.940000 0.630000 -0.170000 -1.830000 + -3.470000 -4.950000 -6.110000 -1.920000 -4.050000 + -5.000000 -5.000000 -4.840000 -4.890000 -4.300000 + -4.490000 -4.440000 -4.160000 -3.180000 + +#phi = 150.000000 + -1.760000 -0.400000 0.020000 0.360000 0.630000 + 1.260000 1.360000 0.950000 -0.070000 -1.480000 + -3.150000 1.840000 -1.760000 -5.090000 -5.740000 + -5.390000 -4.780000 -4.190000 -4.120000 -4.040000 + -4.130000 -4.030000 -4.030000 -2.940000 + +#phi = 165.000000 + -0.810000 -0.070000 0.380000 0.540000 1.280000 + 1.640000 1.700000 1.520000 0.630000 -1.090000 + -2.740000 -0.740000 -4.560000 -6.410000 -5.890000 + -5.140000 -4.190000 -3.670000 -3.840000 -3.560000 + -3.550000 -3.250000 -2.750000 -1.810000 + + +#CMAP for C NH1 CT2 C NH1 CT2 C NH1; id=2 +#phi = -180.000000 + 0.235350 0.182300 0.177200 0.396800 0.859400 + 1.489700 2.092500 2.297700 1.808600 0.696200 + -0.563300 -1.432700 -1.015100 1.426300 -0.564300 + 0.696200 1.808200 2.301700 2.092600 1.489100 + 0.859500 0.396900 0.176900 0.182400 + +#phi = -165.000000 + 0.020100 -0.203800 -0.269700 0.014200 0.620800 + 1.392400 2.046200 2.188200 1.683900 0.688500 + -0.373700 -0.703500 0.837800 3.704000 -0.730100 + 0.594100 1.713100 2.205800 2.026400 1.529800 + 1.027400 0.623800 0.348400 0.182800 + +#phi = -150.000000 + -0.533600 -0.807400 -0.804600 -0.379800 0.365300 + 1.168000 1.641000 1.618100 1.302200 0.615100 + 0.065700 0.738500 2.959500 -2.036600 -0.934600 + 0.407900 1.517000 1.984800 1.833100 1.435200 + 0.995600 0.562200 0.150600 -0.209000 + +#phi = -135.000000 + -1.208500 -1.429400 -1.319200 -0.817500 -0.112400 + 0.454400 0.737600 0.879300 0.850100 0.670300 + 0.943500 -2.651200 -2.829400 -2.199100 -1.065700 + 0.279600 1.322000 1.668300 1.521300 1.193900 + 0.765300 0.246000 -0.315500 -0.823200 + +#phi = -120.000000 + -1.789100 -1.965500 -1.860700 -1.447900 -0.896500 + -0.401000 -0.015100 0.321300 0.634600 0.976300 + -1.977500 -2.883200 -2.848500 -2.137900 -0.960300 + 0.308700 1.098100 1.245300 1.133600 0.881800 + 0.448200 -0.153900 -0.823700 -1.404300 + +#phi = -105.000000 + -2.246700 -2.487000 -2.473700 -2.135600 -1.577700 + -0.980600 -0.429100 0.144700 0.734000 -0.918300 + -2.299200 -2.882200 -2.668600 -1.847100 -0.719800 + 0.107000 0.496000 0.553500 0.584300 0.494000 + 0.098300 -0.529800 -1.237900 -1.840100 + +#phi = -90.000000 + -2.851100 -3.181100 -3.199500 -2.785300 -2.054300 + -1.242900 -0.476500 0.288100 -0.045300 -1.470600 + -2.558800 -2.869400 -2.450300 -1.582200 -0.930800 + -0.426400 -0.022700 0.000000 -0.097400 -0.136100 + -0.439600 -1.038600 -1.741000 -2.373200 + +#phi = -75.000000 + -3.961800 -4.268200 -4.109000 -3.364700 -2.252200 + -1.140400 -0.209800 0.487300 -0.746200 -2.127700 + -2.932100 -2.898500 -2.247900 -1.730400 -1.177200 + -0.448200 0.034900 -0.073300 -0.531600 -0.933300 + -1.360700 -2.009200 -2.745700 -3.424900 + +#phi = -60.000000 + -5.408000 -5.355100 -4.640100 -3.283200 -1.710200 + -0.423800 0.354400 -0.103700 -1.577700 -2.828300 + -3.151200 -2.649200 -2.183000 -1.761200 -0.981700 + -0.174700 0.262600 0.039200 -0.663000 -1.530700 + -2.478200 -3.465600 -4.334200 -5.011200 + +#phi = -45.000000 + -6.093200 -5.298400 -3.816620 -1.922530 -0.196160 + 0.768200 0.568500 -0.831300 -2.343900 -3.037100 + -2.663700 -2.191100 -2.022900 -1.438500 -0.649000 + 0.077000 0.441500 0.257500 -0.491100 -1.820600 + -3.473100 -4.895200 -5.790700 -6.205900 + +#phi = -30.000000 + -5.258225 -3.675795 -1.631110 0.430085 1.496470 + 0.318200 -0.555100 -1.695500 -2.434200 -2.192600 + -1.691300 -1.890000 -1.708500 -1.206300 -0.567400 + 0.054300 0.497200 0.599600 -0.171000 -2.137600 + -4.237000 -5.584100 -6.135100 -6.067000 + +#phi = -15.000000 + -3.161820 -0.902080 1.432450 -1.452885 -1.560780 + -1.665600 -1.783100 -1.755100 -1.329300 -0.731100 + -1.317000 -1.662800 -1.601200 -1.294900 -0.817300 + -0.197100 0.549500 0.850400 -0.689700 -2.819900 + -4.393000 -5.111500 -5.205690 -4.654785 + +#phi = 0.000000 + 0.034035 -2.349860 -3.412065 -3.620070 -3.450950 + -2.875650 -1.787800 -0.541250 0.410450 -0.372500 + -1.126850 -1.498450 -1.608700 -1.498450 -1.126850 + -0.372500 0.410450 -0.541250 -1.787800 -2.875650 + -3.450950 -3.620070 -3.412065 -2.349860 + +#phi = 15.000000 + -3.162345 -4.654785 -5.205690 -5.111500 -4.393000 + -2.819900 -0.689700 0.850400 0.549500 -0.197100 + -0.817300 -1.294900 -1.601200 -1.662800 -1.317000 + -0.731100 -1.329300 -1.755100 -1.783100 -1.665600 + -1.560780 -1.452885 1.432450 -0.902080 + +#phi = 30.000000 + -5.258220 -6.067000 -6.135100 -5.584100 -4.237000 + -2.137600 -0.171000 0.599600 0.497200 0.054300 + -0.567400 -1.206300 -1.708500 -1.890000 -1.691300 + -2.192600 -2.434200 -1.695500 -0.555100 0.318200 + 1.496470 0.430085 -1.631110 -3.675795 + +#phi = 45.000000 + -6.093300 -6.205900 -5.790700 -4.895200 -3.473100 + -1.820600 -0.491100 0.257500 0.441500 0.077000 + -0.649000 -1.438500 -2.022900 -2.191100 -2.663700 + -3.037100 -2.343900 -0.831300 0.568500 0.768200 + -0.196160 -1.922530 -3.816620 -5.298400 + +#phi = 60.000000 + -5.407500 -5.011200 -4.334200 -3.465600 -2.478200 + -1.530700 -0.663000 0.039200 0.262600 -0.174700 + -0.981700 -1.761200 -2.183000 -2.649200 -3.151200 + -2.828300 -1.577700 -0.103700 0.354400 -0.423800 + -1.710200 -3.283200 -4.640100 -5.355100 + +#phi = 75.000000 + -3.961900 -3.424900 -2.745700 -2.009200 -1.360700 + -0.933300 -0.531600 -0.073300 0.034900 -0.448200 + -1.177200 -1.730400 -2.247900 -2.898500 -2.932100 + -2.127700 -0.746200 0.487300 -0.209800 -1.140400 + -2.252200 -3.364700 -4.109000 -4.268200 + +#phi = 90.000000 + -2.854500 -2.373200 -1.741000 -1.038600 -0.439600 + -0.136100 -0.097400 0.000000 -0.022700 -0.426400 + -0.930800 -1.582200 -2.450300 -2.869400 -2.558800 + -1.470600 -0.045300 0.288100 -0.476500 -1.242900 + -2.054300 -2.785300 -3.199500 -3.181100 + +#phi = 105.000000 + -2.246400 -1.840100 -1.237900 -0.529800 0.098300 + 0.494000 0.584300 0.553500 0.496000 0.107000 + -0.719800 -1.847100 -2.668600 -2.882200 -2.299200 + -0.918300 0.734000 0.144700 -0.429100 -0.980600 + -1.577700 -2.135600 -2.473700 -2.487000 + +#phi = 120.000000 + -1.788800 -1.404300 -0.823700 -0.153900 0.448200 + 0.881800 1.133600 1.245300 1.098100 0.308700 + -0.960300 -2.137900 -2.848500 -2.883200 -1.977500 + 0.976300 0.634600 0.321300 -0.015100 -0.401000 + -0.896500 -1.447900 -1.860700 -1.965500 + +#phi = 135.000000 + -1.208900 -0.823200 -0.315500 0.246000 0.765300 + 1.193900 1.521300 1.668300 1.322000 0.279600 + -1.065700 -2.199100 -2.829400 -2.651200 0.943500 + 0.670300 0.850100 0.879300 0.737600 0.454400 + -0.112400 -0.817500 -1.319200 -1.429400 + +#phi = 150.000000 + -0.533400 -0.209000 0.150600 0.562200 0.995600 + 1.435200 1.833100 1.984800 1.517000 0.407900 + -0.934600 -2.036600 2.959500 0.738500 0.065700 + 0.615100 1.302200 1.618100 1.641000 1.168000 + 0.365300 -0.379800 -0.804600 -0.807400 + +#phi = 165.000000 + 0.019900 0.182800 0.348400 0.623800 1.027400 + 1.529800 2.026400 2.205800 1.713100 0.594100 + -0.730100 3.704000 0.837800 -0.703500 -0.373700 + 0.688500 1.683900 2.188200 2.046200 1.392400 + 0.620800 0.014200 -0.269700 -0.203800 + + diff --git a/examples/charmmfsw/data.charmmfsw.gz b/examples/charmmfsw/data.charmmfsw.gz new file mode 100644 index 0000000000..8d5741d0f9 Binary files /dev/null and b/examples/charmmfsw/data.charmmfsw.gz differ diff --git a/examples/charmmfsw/in.charmmfsw b/examples/charmmfsw/in.charmmfsw new file mode 100644 index 0000000000..204c2627d3 --- /dev/null +++ b/examples/charmmfsw/in.charmmfsw @@ -0,0 +1,46 @@ +# charmmfsw example generated by https://charmm-gui.org/ +# from PDB structure 1HVN (https://www.rcsb.org/structure/1HVN) +# +# Dependencies: packages MOLECULE / KSPACE / RIGID +# To test with KOKKOS: lmp -k on g 1 -sf kk -pk kokkos neigh half -in in.charmmfsw + +units real +boundary p p p + +newton off +pair_style lj/charmmfsw/coul/long 10 12 +pair_modify mix arithmetic +kspace_style pppm 1e-6 + +atom_style full +bond_style harmonic +angle_style charmm +dihedral_style charmmfsw +special_bonds charmm +improper_style harmonic +timestep 2 + +fix cmap all cmap charmmff.cmap +fix_modify cmap energy yes +read_data data.charmmfsw.gz fix cmap crossterm CMAP + +neighbor 2 bin +neigh_modify delay 2 every 1 + +fix 1 all shake 1e-6 100 100 m 1.008 a 142 +fix 2 all nvt temp 303.15 303.15 100.0 + +# for visualization with LAMMPS-GUI +group water type 18 60 +group nowater subtract all water +group ions type 63 64 +group other subtract all water ions + +# dump viz other image 10 myimage-*.ppm element type size 800 800 zoom 2.82954 shiny 0.5 fsaa yes bond none none view 20 10 box no 0.0 axes no 0.0 0.0 center s 0.521318 0.489856 0.489856 +# dump_modify viz pad 9 boxcolor darkblue backcolor darkgray element H H H H H H H H H H H H H H H H H H C C C C C C C C C C C C C C C C C C C N N N N N N N N N N N N N N O O O O O O O O O P S Cl K adiam 1 1.92 adiam 2 1.92 adiam 3 1.92 adiam 4 1.92 adiam 5 1.92 adiam 6 1.92 adiam 7 1.92 adiam 8 1.92 adiam 9 1.92 adiam 10 1.92 adiam 11 1.92 adiam 12 1.92 adiam 13 1.92 adiam 14 1.92 adiam 15 1.92 adiam 16 1.92 adiam 17 1.92 adiam 18 1.92 adiam 19 2.72 adiam 20 2.72 adiam 21 2.72 adiam 22 2.72 adiam 23 2.72 adiam 24 2.72 adiam 25 2.72 adiam 26 2.72 adiam 27 2.72 adiam 28 2.72 adiam 29 2.72 adiam 30 2.72 adiam 31 2.72 adiam 32 2.72 adiam 33 2.72 adiam 34 2.72 adiam 35 2.72 adiam 36 2.72 adiam 37 2.72 adiam 38 2.48 adiam 39 2.48 adiam 40 2.48 adiam 41 2.48 adiam 42 2.48 adiam 43 2.48 adiam 44 2.48 adiam 45 2.48 adiam 46 2.48 adiam 47 2.48 adiam 48 2.48 adiam 49 2.48 adiam 50 2.48 adiam 51 2.48 adiam 52 2.432 adiam 53 2.432 adiam 54 2.432 adiam 55 2.432 adiam 56 2.432 adiam 57 2.432 adiam 58 2.432 adiam 59 2.432 adiam 60 2.432 adiam 61 2.88 adiam 62 2.88 adiam 63 3.632 adiam 64 2.816 + +thermo 10 +thermo_style custom step etotal evdwl ecoul elong edihed pe ke temp press + +run 100 + diff --git a/examples/charmmfsw/log.26Jul24.charmmfsw.g++.1 b/examples/charmmfsw/log.26Jul24.charmmfsw.g++.1 new file mode 100644 index 0000000000..f56052b140 --- /dev/null +++ b/examples/charmmfsw/log.26Jul24.charmmfsw.g++.1 @@ -0,0 +1,221 @@ +LAMMPS (27 Jun 2024) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# charmmfsw example generated by https://charmm-gui.org/ +# from PDB structure 1HVN (https://www.rcsb.org/structure/1HVN) +# +# Dependencies: packages MOLECULE / KSPACE / RIGID +# To test with KOKKOS: lmp -k on g 1 -sf kk -pk kokkos neigh half -in in.charmmfsw + +units real +boundary p p p + +newton off +pair_style lj/charmmfsw/coul/long 10 12 +Switching to CHARMM coulomb energy conversion constant (src/KSPACE/pair_lj_charmmfsw_coul_long.cpp:63) +pair_modify mix arithmetic +kspace_style pppm 1e-6 + +atom_style full +bond_style harmonic +angle_style charmm +dihedral_style charmmfsw +special_bonds charmm +improper_style harmonic +timestep 2 + +fix cmap all cmap charmmff.cmap +Reading CMAP parameters from: charmmff.cmap + Read in CMAP data for 2 crossterm types +fix_modify cmap energy yes +read_data data.charmmfsw.gz fix cmap crossterm CMAP +Reading data file ... + orthogonal box = (-24 -24 -24) to (24 24 24) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 10245 atoms + reading velocities ... + 10245 velocities + scanning bonds ... + 4 = max bonds/atom + scanning angles ... + 15 = max angles/atom + scanning dihedrals ... + 48 = max dihedrals/atom + scanning impropers ... + 4 = max impropers/atom + orthogonal box = (-24 -24 -24) to (24 24 24) + 1 by 1 by 1 MPI processor grid + reading bonds ... + 6973 bonds + reading angles ... + 4057 angles + reading dihedrals ... + 1363 dihedrals + reading impropers ... + 70 impropers +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 4 = max # of 1-2 neighbors + 9 = max # of 1-3 neighbors + 17 = max # of 1-4 neighbors + 21 = max # of special neighbors + special bonds CPU = 0.002 seconds + read_data CPU = 0.072 seconds + +neighbor 2 bin +neigh_modify delay 2 every 1 + +fix 1 all shake 1e-6 100 100 m 1.008 a 142 +Finding SHAKE clusters ... + 75 = # of size 2 clusters + 47 = # of size 3 clusters + 9 = # of size 4 clusters + 3265 = # of frozen angles + find clusters CPU = 0.003 seconds +fix 2 all nvt temp 303.15 303.15 100.0 + +thermo 10 +thermo_style custom step etotal evdwl ecoul elong edihed pe ke temp press + +run 100 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- Type Label Framework: https://doi.org/10.1021/acs.jpcb.3c08419 + +@Article{Gissinger24, + author = {Jacob R. Gissinger, Ilia Nikiforov, Yaser Afshar, Brendon Waters, Moon-ki Choi, Daniel S. Karls, Alexander Stukowski, Wonpil Im, Hendrik Heinz, Axel Kohlmeyer, and Ellad B. Tadmor}, + title = {Type Label Framework for Bonded Force Fields in LAMMPS}, + journal = {J. Phys. Chem. B}, + year = 2024, + volume = 128, + number = 13, + pages = {3282–-3297} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + G vector (1/distance) = 0.27938162 + grid = 54 54 54 + stencil order = 5 + estimated absolute RMS force accuracy = 0.00036407395 + estimated relative force accuracy = 1.0963718e-06 + using double precision FFTW3 + 3d grid and FFT values/proc = 226981 157464 +Generated 2016 of 2016 mixed pair_coeff terms from arithmetic mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 2 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 14 + ghost atom cutoff = 14 + binsize = 7, bins = 7 7 7 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/charmmfsw/coul/long, perpetual + attributes: half, newton off + pair build: half/bin/newtoff + stencil: full/bin/3d + bin: standard +SHAKE stats (type/ave/delta/count) on step 0 +Bond: 16 1.09 1.38032e-07 6 +Bond: 18 1.09 1.00046e-07 3 +Bond: 34 1.111 1.11388e-06 10 +Bond: 39 1.111 4.83041e-08 5 +Bond: 43 1.111 1.97842e-07 10 +Bond: 44 1.111 1.71815e-06 10 +Bond: 59 1.111 8.42509e-08 2 +Bond: 62 1.111 2.84854e-08 2 +Bond: 63 1.111 2.14153e-07 46 +Bond: 64 1.111 1.59305e-07 18 +Bond: 65 1.08 5.67061e-07 16 +Bond: 66 1.08 1.43965e-06 4 +Bond: 67 1 1.81926e-07 10 +Bond: 68 1.01 0 1 +Bond: 69 1.08 1.34571e-07 5 +Bond: 70 1.09 0 1 +Bond: 71 1.083 0 1 +Bond: 72 0.9572 2.71955e-07 6530 +Bond: 75 1 1.46045e-07 10 +Bond: 79 0.997 5.24499e-07 17 +Bond: 81 1 1.32984e-07 4 +Bond: 84 1.04 7.65389e-07 9 +Bond: 87 1 0 1 +Bond: 95 0.96 5.75241e-07 2 +Bond: 97 1.325 4.3613e-08 3 +Angle: 142 104.52 2.67611e-05 3265 +Per MPI rank memory allocation (min/avg/max) = 143.6 | 143.6 | 143.6 Mbytes + Step TotEng E_vdwl E_coul E_long E_dihed PotEng KinEng Temp Press + 0 -27877.652 3447.5013 144035.68 -182420.51 343.05623 -34213.5 6335.8474 307.44113 -989.27065 + 10 -27879.086 3334.4154 144205.4 -182416.19 348.14696 -34133.566 6254.4808 303.49289 -1211.2863 + 20 -27882.193 3293.7931 144272.04 -182415.87 333.20456 -34116.91 6234.7164 302.53384 -1041.5231 + 30 -27886.779 3177.7183 144344.61 -182409.28 340.77044 -34166.241 6279.462 304.70508 -1538.0247 + 40 -27892.698 3186.4294 144409.85 -182417.01 337.80177 -34097.62 6204.9214 301.08807 -1516.1201 + 50 -27898.215 3198.5531 144426.3 -182405.24 336.58074 -34049.909 6151.6947 298.50529 -1349.4431 + 60 -27900.589 3163.4592 144400.32 -182414.85 341.17705 -34110.926 6210.3369 301.35085 -1695.3697 + 70 -27900.487 3223.7183 144242.71 -182409.21 341.09496 -34188.493 6288.0059 305.11967 -1493.2031 + 80 -27901.07 3274.244 144265.07 -182417.68 344.0409 -34177.343 6276.2725 304.55032 -1273.0263 + 90 -27905.672 3237.6056 144288.71 -182418.22 342.15013 -34187.814 6282.1417 304.83511 -1268.0436 +SHAKE stats (type/ave/delta/count) on step 100 +Bond: 16 1.09 3.78281e-07 6 +Bond: 18 1.09 1.12288e-07 3 +Bond: 34 1.111 7.60709e-07 10 +Bond: 39 1.111 2.37855e-07 5 +Bond: 43 1.111 6.00872e-07 10 +Bond: 44 1.111 3.75324e-07 10 +Bond: 59 1.111 1.12311e-07 2 +Bond: 62 1.111 2.99471e-07 2 +Bond: 63 1.111 6.10589e-07 46 +Bond: 64 1.111 4.50733e-07 18 +Bond: 65 1.08 2.90668e-07 16 +Bond: 66 1.08 1.61592e-07 4 +Bond: 67 1 5.4508e-07 10 +Bond: 68 1.01 0 1 +Bond: 69 1.08 4.1398e-07 5 +Bond: 70 1.09 0 1 +Bond: 71 1.083 0 1 +Bond: 72 0.9572 1.76706e-06 6530 +Bond: 75 1 3.96686e-07 10 +Bond: 79 0.997 7.72922e-07 17 +Bond: 81 1 1.30673e-07 4 +Bond: 84 1.04 1.44551e-07 9 +Bond: 87 1 0 1 +Bond: 95 0.96 1.03526e-07 2 +Bond: 97 1.325 3.64689e-08 3 +Angle: 142 104.52 0.000130126 3265 + 100 -27913.241 3159.0677 144299.1 -182414.94 336.48839 -34254.412 6341.1706 307.69943 -1421.2905 +Loop time of 11.5304 on 1 procs for 100 steps with 10245 atoms + +Performance: 1.499 ns/day, 16.014 hours/ns, 8.673 timesteps/s, 88.852 katom-step/s +99.7% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 8.6772 | 8.6772 | 8.6772 | 0.0 | 75.25 +Bond | 0.012444 | 0.012444 | 0.012444 | 0.0 | 0.11 +Kspace | 1.2286 | 1.2286 | 1.2286 | 0.0 | 10.66 +Neigh | 1.5276 | 1.5276 | 1.5276 | 0.0 | 13.25 +Comm | 0.010441 | 0.010441 | 0.010441 | 0.0 | 0.09 +Output | 0.00055001 | 0.00055001 | 0.00055001 | 0.0 | 0.00 +Modify | 0.07101 | 0.07101 | 0.07101 | 0.0 | 0.62 +Other | | 0.002628 | | | 0.02 + +Nlocal: 10245 ave 10245 max 10245 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 30479 ave 30479 max 30479 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 7.05928e+06 ave 7.05928e+06 max 7.05928e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 7059275 +Ave neighs/atom = 689.04588 +Ave special neighs/atom = 2.3664226 +Neighbor list builds = 10 +Dangerous builds = 0 + +Total wall time: 0:00:11 diff --git a/examples/charmmfsw/log.26Jul24.charmmfsw.g++.4 b/examples/charmmfsw/log.26Jul24.charmmfsw.g++.4 new file mode 100644 index 0000000000..b2dc69b0a5 --- /dev/null +++ b/examples/charmmfsw/log.26Jul24.charmmfsw.g++.4 @@ -0,0 +1,221 @@ +LAMMPS (27 Jun 2024) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# charmmfsw example generated by https://charmm-gui.org/ +# from PDB structure 1HVN (https://www.rcsb.org/structure/1HVN) +# +# Dependencies: packages MOLECULE / KSPACE / RIGID +# To test with KOKKOS: lmp -k on g 1 -sf kk -pk kokkos neigh half -in in.charmmfsw + +units real +boundary p p p + +newton off +pair_style lj/charmmfsw/coul/long 10 12 +Switching to CHARMM coulomb energy conversion constant (src/KSPACE/pair_lj_charmmfsw_coul_long.cpp:63) +pair_modify mix arithmetic +kspace_style pppm 1e-6 + +atom_style full +bond_style harmonic +angle_style charmm +dihedral_style charmmfsw +special_bonds charmm +improper_style harmonic +timestep 2 + +fix cmap all cmap charmmff.cmap +Reading CMAP parameters from: charmmff.cmap + Read in CMAP data for 2 crossterm types +fix_modify cmap energy yes +read_data data.charmmfsw.gz fix cmap crossterm CMAP +Reading data file ... + orthogonal box = (-24 -24 -24) to (24 24 24) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 10245 atoms + reading velocities ... + 10245 velocities + scanning bonds ... + 4 = max bonds/atom + scanning angles ... + 15 = max angles/atom + scanning dihedrals ... + 48 = max dihedrals/atom + scanning impropers ... + 4 = max impropers/atom + orthogonal box = (-24 -24 -24) to (24 24 24) + 1 by 2 by 2 MPI processor grid + reading bonds ... + 6973 bonds + reading angles ... + 4057 angles + reading dihedrals ... + 1363 dihedrals + reading impropers ... + 70 impropers +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 4 = max # of 1-2 neighbors + 9 = max # of 1-3 neighbors + 17 = max # of 1-4 neighbors + 21 = max # of special neighbors + special bonds CPU = 0.001 seconds + read_data CPU = 0.068 seconds + +neighbor 2 bin +neigh_modify delay 2 every 1 + +fix 1 all shake 1e-6 100 100 m 1.008 a 142 +Finding SHAKE clusters ... + 75 = # of size 2 clusters + 47 = # of size 3 clusters + 9 = # of size 4 clusters + 3265 = # of frozen angles + find clusters CPU = 0.001 seconds +fix 2 all nvt temp 303.15 303.15 100.0 + +thermo 10 +thermo_style custom step etotal evdwl ecoul elong edihed pe ke temp press + +run 100 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- Type Label Framework: https://doi.org/10.1021/acs.jpcb.3c08419 + +@Article{Gissinger24, + author = {Jacob R. Gissinger, Ilia Nikiforov, Yaser Afshar, Brendon Waters, Moon-ki Choi, Daniel S. Karls, Alexander Stukowski, Wonpil Im, Hendrik Heinz, Axel Kohlmeyer, and Ellad B. Tadmor}, + title = {Type Label Framework for Bonded Force Fields in LAMMPS}, + journal = {J. Phys. Chem. B}, + year = 2024, + volume = 128, + number = 13, + pages = {3282–-3297} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + G vector (1/distance) = 0.27938162 + grid = 54 54 54 + stencil order = 5 + estimated absolute RMS force accuracy = 0.00036407395 + estimated relative force accuracy = 1.0963718e-06 + using double precision FFTW3 + 3d grid and FFT values/proc = 70516 40824 +Generated 2016 of 2016 mixed pair_coeff terms from arithmetic mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 2 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 14 + ghost atom cutoff = 14 + binsize = 7, bins = 7 7 7 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/charmmfsw/coul/long, perpetual + attributes: half, newton off + pair build: half/bin/newtoff + stencil: full/bin/3d + bin: standard +SHAKE stats (type/ave/delta/count) on step 0 +Bond: 16 1.09 1.38032e-07 6 +Bond: 18 1.09 1.00046e-07 3 +Bond: 34 1.111 1.11388e-06 10 +Bond: 39 1.111 4.83041e-08 5 +Bond: 43 1.111 1.97842e-07 10 +Bond: 44 1.111 1.71815e-06 10 +Bond: 59 1.111 8.42509e-08 2 +Bond: 62 1.111 2.84854e-08 2 +Bond: 63 1.111 2.14153e-07 46 +Bond: 64 1.111 1.59305e-07 18 +Bond: 65 1.08 5.67061e-07 16 +Bond: 66 1.08 1.43965e-06 4 +Bond: 67 1 1.81926e-07 10 +Bond: 68 1.01 0 1 +Bond: 69 1.08 1.34571e-07 5 +Bond: 70 1.09 0 1 +Bond: 71 1.083 0 1 +Bond: 72 0.9572 2.71955e-07 6530 +Bond: 75 1 1.46045e-07 10 +Bond: 79 0.997 5.24499e-07 17 +Bond: 81 1 1.32984e-07 4 +Bond: 84 1.04 7.65389e-07 9 +Bond: 87 1 0 1 +Bond: 95 0.96 5.75241e-07 2 +Bond: 97 1.325 4.3613e-08 3 +Angle: 142 104.52 2.67611e-05 3265 +Per MPI rank memory allocation (min/avg/max) = 76.88 | 77.06 | 77.25 Mbytes + Step TotEng E_vdwl E_coul E_long E_dihed PotEng KinEng Temp Press + 0 -27877.652 3447.5013 144035.68 -182420.51 343.05623 -34213.5 6335.8474 307.44113 -989.27065 + 10 -27879.086 3334.4154 144205.4 -182416.19 348.14696 -34133.566 6254.4808 303.49289 -1211.2863 + 20 -27882.193 3293.7931 144272.04 -182415.87 333.20456 -34116.91 6234.7164 302.53384 -1041.5231 + 30 -27886.779 3177.7183 144344.61 -182409.28 340.77044 -34166.241 6279.462 304.70508 -1538.0247 + 40 -27892.698 3186.4294 144409.85 -182417.01 337.80177 -34097.62 6204.9214 301.08807 -1516.1201 + 50 -27898.215 3198.5531 144426.3 -182405.24 336.58074 -34049.909 6151.6947 298.50529 -1349.4431 + 60 -27900.589 3163.4592 144400.32 -182414.85 341.17705 -34110.926 6210.3369 301.35085 -1695.3697 + 70 -27900.487 3223.7183 144242.71 -182409.21 341.09496 -34188.493 6288.0059 305.11967 -1493.2032 + 80 -27901.07 3274.244 144265.07 -182417.68 344.0409 -34177.343 6276.2725 304.55032 -1273.0263 + 90 -27905.672 3237.6056 144288.71 -182418.22 342.15013 -34187.814 6282.1417 304.83511 -1268.0436 +SHAKE stats (type/ave/delta/count) on step 100 +Bond: 16 1.09 3.78281e-07 6 +Bond: 18 1.09 1.12288e-07 3 +Bond: 34 1.111 7.60709e-07 10 +Bond: 39 1.111 2.37855e-07 5 +Bond: 43 1.111 6.00872e-07 10 +Bond: 44 1.111 3.75324e-07 10 +Bond: 59 1.111 1.12311e-07 2 +Bond: 62 1.111 2.99471e-07 2 +Bond: 63 1.111 6.10589e-07 46 +Bond: 64 1.111 4.50733e-07 18 +Bond: 65 1.08 2.90668e-07 16 +Bond: 66 1.08 1.61592e-07 4 +Bond: 67 1 5.4508e-07 10 +Bond: 68 1.01 0 1 +Bond: 69 1.08 4.1398e-07 5 +Bond: 70 1.09 0 1 +Bond: 71 1.083 0 1 +Bond: 72 0.9572 1.76706e-06 6530 +Bond: 75 1 3.96686e-07 10 +Bond: 79 0.997 7.72922e-07 17 +Bond: 81 1 1.30673e-07 4 +Bond: 84 1.04 1.44551e-07 9 +Bond: 87 1 0 1 +Bond: 95 0.96 1.03526e-07 2 +Bond: 97 1.325 3.64689e-08 3 +Angle: 142 104.52 0.000130126 3265 + 100 -27913.241 3159.0676 144299.1 -182414.94 336.48839 -34254.412 6341.1706 307.69943 -1421.2905 +Loop time of 3.49837 on 4 procs for 100 steps with 10245 atoms + +Performance: 4.939 ns/day, 4.859 hours/ns, 28.585 timesteps/s, 292.851 katom-step/s +99.4% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.4572 | 2.5133 | 2.5634 | 2.6 | 71.84 +Bond | 0.0040264 | 0.0050718 | 0.0069286 | 1.6 | 0.14 +Kspace | 0.45979 | 0.50903 | 0.56364 | 5.6 | 14.55 +Neigh | 0.42029 | 0.42034 | 0.42036 | 0.0 | 12.02 +Comm | 0.013207 | 0.013292 | 0.013404 | 0.1 | 0.38 +Output | 0.00026525 | 0.00029549 | 0.00038249 | 0.0 | 0.01 +Modify | 0.035024 | 0.035546 | 0.03621 | 0.3 | 1.02 +Other | | 0.001504 | | | 0.04 + +Nlocal: 2561.25 ave 2599 max 2520 min +Histogram: 1 1 0 0 0 0 0 0 0 2 +Nghost: 16491.5 ave 16541 max 16442 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Neighs: 1.99855e+06 ave 2.04035e+06 max 1.95468e+06 min +Histogram: 1 1 0 0 0 0 0 0 0 2 + +Total # of neighbors = 7994217 +Ave neighs/atom = 780.30425 +Ave special neighs/atom = 2.3664226 +Neighbor list builds = 10 +Dangerous builds = 0 + +Total wall time: 0:00:03 diff --git a/lib/gpu/lal_dpd_coul_slater_long.cu b/lib/gpu/lal_dpd_coul_slater_long.cu index d9679ccdfd..4835b8777b 100644 --- a/lib/gpu/lal_dpd_coul_slater_long.cu +++ b/lib/gpu/lal_dpd_coul_slater_long.cu @@ -186,15 +186,13 @@ __kernel void k_dpd_coul_slater_long(const __global numtyp4 *restrict x_, atom_info(t_per_atom,ii,tid,offset); __local numtyp sp_cl[4]; - ///local_allocate_store_charge(); - sp_cl[0]=sp_cl_in[0]; sp_cl[1]=sp_cl_in[1]; sp_cl[2]=sp_cl_in[2]; sp_cl[3]=sp_cl_in[3]; int n_stride; - local_allocate_store_pair(); + local_allocate_store_charge(); acctyp3 f; f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; @@ -332,8 +330,7 @@ __kernel void k_dpd_coul_slater_long(const __global numtyp4 *restrict x_, } // for nbor } // if ii - store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, - ans,engv); + store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag,ans,engv); } __kernel void k_dpd_coul_slater_long_fast(const __global numtyp4 *restrict x_, @@ -378,7 +375,7 @@ __kernel void k_dpd_coul_slater_long_fast(const __global numtyp4 *restrict x_, int n_stride; - local_allocate_store_pair(); + local_allocate_store_charge(); acctyp3 f; f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; @@ -517,7 +514,6 @@ __kernel void k_dpd_coul_slater_long_fast(const __global numtyp4 *restrict x_, } // for nbor } // if ii - store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, - ans,engv); + 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_sw.cpp b/lib/gpu/lal_sw.cpp index 9687a0352d..60d388f100 100644 --- a/lib/gpu/lal_sw.cpp +++ b/lib/gpu/lal_sw.cpp @@ -52,12 +52,12 @@ int SWT::init(const int ntypes, const int nlocal, const int nall, double ***costheta, const int *map, int ***e2param) { _lj_types=ntypes; - int oldparam=-1; int onetype=-1; int onetype3=0; int spq=1; - int mtypes=0; #ifdef USE_OPENCL + int oldparam=-1; + int mtypes=0; for (int ii=1; ii, local_offset_value = element_values(team_id, i - 1); // FIXME_OPENMPTARGET We seem to access memory illegaly on AMD GPUs #if defined(KOKKOS_ARCH_AMD_GPU) && !defined(KOKKOS_ARCH_AMD_GFX1030) && \ - !defined(KOKKOS_ARCH_AMD_GFX1100) + !defined(KOKKOS_ARCH_AMD_GFX1100) && !defined(KOKKOS_ARCH_AMD_GFX1103) if constexpr (Analysis::Reducer::has_join_member_function()) { if constexpr (std::is_void_v) a_functor_reducer.get_functor().join(local_offset_value, diff --git a/lib/kokkos/core/src/impl/Kokkos_Core.cpp b/lib/kokkos/core/src/impl/Kokkos_Core.cpp index 4a69652616..c7addbe337 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Core.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Core.cpp @@ -750,6 +750,9 @@ void pre_initialize_internal(const Kokkos::InitializationSettings& settings) { #elif defined(KOKKOS_ARCH_AMD_GFX1100) declare_configuration_metadata("architecture", "GPU architecture", "AMD_GFX1100"); +#elif defined(KOKKOS_ARCH_AMD_GFX1103) + declare_configuration_metadata("architecture", "GPU architecture", + "AMD_GFX1103"); #else declare_configuration_metadata("architecture", "GPU architecture", "none"); diff --git a/lib/kokkos/generate_makefile.bash b/lib/kokkos/generate_makefile.bash index 25370daa3f..70dd61f9af 100755 --- a/lib/kokkos/generate_makefile.bash +++ b/lib/kokkos/generate_makefile.bash @@ -164,6 +164,7 @@ display_help_text() { echo " AMD_GFX942 = AMD GPU MI300 GFX942" echo " AMD_GFX1030 = AMD GPU V620/W6800 GFX1030" echo " AMD_GFX1100 = AMD GPU RX 7900 XT(X) GFX1100" + echo " AMD_GFX1103 = AMD APU Radeon 740M/760M/780M/880M/890M GFX1103" echo " [ARM]" echo " ARMV80 = ARMv8.0 Compatible CPU" echo " ARMV81 = ARMv8.1 Compatible CPU" diff --git a/python/lammps/core.py b/python/lammps/core.py index dbadebe7f2..97bcb5157d 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -992,7 +992,7 @@ class lammps(object): return None dim = self.extract_pair_dimension(name) - if dim == None: + if dim is None: return None elif dim == 0: self.lib.lammps_extract_pair.restype = POINTER(c_double) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index 96384255c2..49a2c6cb09 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -463,13 +463,19 @@ class PyLammps(object): self.lmp = lammps(name=name,cmdargs=cmdargs,ptr=ptr,comm=comm) else: self.lmp = lammps(name=name,cmdargs=cmdargs,ptr=None,comm=comm) - print("LAMMPS output is captured by PyLammps wrapper") + self.comm_nprocs = self.lmp.extract_setting("world_size") + self.comm_me = self.lmp.extract_setting("world_rank") + if self.comm_me == 0: + print("LAMMPS output is captured by PyLammps wrapper") + if self.comm_nprocs > 1: + print("WARNING: Using PyLammps with multiple MPI ranks is experimental. Not all functionality is supported.") self._cmd_history = [] self._enable_cmd_history = False self.runs = [] if not self.lmp.has_package("PYTHON"): - print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled") + if self.comm_me == 0: + print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled") def __enter__(self): return self @@ -727,7 +733,15 @@ class PyLammps(object): def eval(self, expr): """ - Evaluate expression + Evaluate LAMMPS input file expression. + + This is equivalent to using immediate variable expressions in the format "$(...)" + in the LAMMPS input and will return the result of that expression. + + .. warning:: + + This function is only supported on MPI rank 0. Calling it from a different + MPI rank will raise an exception. :param expr: the expression string that should be evaluated inside of LAMMPS :type expr: string @@ -735,6 +749,9 @@ class PyLammps(object): :return: the value of the evaluated expression :rtype: float if numeric, string otherwise """ + if self.comm_me > 0: + raise Exception("PyLammps.eval() may only be used on MPI rank 0") + value = self.lmp_print('"$(%s)"' % expr).strip() try: return float(value) diff --git a/src/CG-SPICA/angle_spica.cpp b/src/CG-SPICA/angle_spica.cpp index 45b28d812a..bf86a6ec45 100644 --- a/src/CG-SPICA/angle_spica.cpp +++ b/src/CG-SPICA/angle_spica.cpp @@ -54,7 +54,7 @@ AngleSPICA::AngleSPICA(LAMMPS *lmp) : AngleSPICA::~AngleSPICA() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(theta0); diff --git a/src/CG-SPICA/angle_spica.h b/src/CG-SPICA/angle_spica.h index f0085fe2fd..539512c0e9 100644 --- a/src/CG-SPICA/angle_spica.h +++ b/src/CG-SPICA/angle_spica.h @@ -52,7 +52,7 @@ class AngleSPICA : public Angle { void ev_tally13(int, int, int, int, double, double, double, double, double); - void allocate(); + virtual void allocate(); }; } // namespace LAMMPS_NS diff --git a/src/CG-SPICA/pair_lj_spica_coul_long.cpp b/src/CG-SPICA/pair_lj_spica_coul_long.cpp index 9e0d4dc276..176c076da9 100644 --- a/src/CG-SPICA/pair_lj_spica_coul_long.cpp +++ b/src/CG-SPICA/pair_lj_spica_coul_long.cpp @@ -55,6 +55,8 @@ PairLJSPICACoulLong::PairLJSPICACoulLong(LAMMPS *lmp) : PairLJSPICACoulLong::~PairLJSPICACoulLong() { + if (copymode) return; + if (allocated) { memory->destroy(setflag); memory->destroy(lj_type); @@ -356,7 +358,7 @@ void PairLJSPICACoulLong::coeff(int narg, char **arg) void PairLJSPICACoulLong::init_style() { - if (!atom->q_flag) error->all(FLERR, "Pair style lj/cut/coul/long requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR, "Pair style lj/spica/coul/long requires atom attribute q"); neighbor->add_request(this); @@ -385,7 +387,8 @@ double PairLJSPICACoulLong::init_one(int i, int j) const int ljt = lj_type[i][j]; - if (ljt == LJ_NOT_SET) error->all(FLERR, "unrecognized LJ parameter flag"); + if (ljt == LJ_NOT_SET) + error->all(FLERR,"unrecognized LJ parameter flag"); double cut = MAX(cut_lj[i][j], cut_coul); cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j]; diff --git a/src/CG-SPICA/pair_lj_spica_coul_long.h b/src/CG-SPICA/pair_lj_spica_coul_long.h index e6ef5ea539..48b2aaa37f 100644 --- a/src/CG-SPICA/pair_lj_spica_coul_long.h +++ b/src/CG-SPICA/pair_lj_spica_coul_long.h @@ -64,7 +64,7 @@ class PairLJSPICACoulLong : public Pair { double cut_lj_global; double g_ewald; - void allocate(); + virtual void allocate(); private: template void eval(); diff --git a/src/DPD-MESO/fix_mvv_dpd.cpp b/src/DPD-MESO/fix_mvv_dpd.cpp index d51000b15b..6b5440902b 100644 --- a/src/DPD-MESO/fix_mvv_dpd.cpp +++ b/src/DPD-MESO/fix_mvv_dpd.cpp @@ -24,6 +24,7 @@ #include "fix_mvv_dpd.h" #include "atom.h" +#include "domain.h" #include "error.h" #include "force.h" #include "update.h" @@ -65,6 +66,11 @@ void FixMvvDPD::init() if (!atom->vest_flag) error->all(FLERR,"Fix mvv/dpd requires atom attribute vest e.g. from atom style mdpd"); + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix mvv/dpd cannot be used with velocity remapping"); + if (!force->pair_match("^mdpd",0) && !force->pair_match("^dpd",0)) { if (force->pair_match("^hybrid",0)) { if (!(force->pair_match("^mdpd",0,1) || force->pair_match("^dpd",0),1)) { diff --git a/src/DPD-MESO/fix_mvv_edpd.cpp b/src/DPD-MESO/fix_mvv_edpd.cpp index 7ac0dc3de7..32a1608d6e 100644 --- a/src/DPD-MESO/fix_mvv_edpd.cpp +++ b/src/DPD-MESO/fix_mvv_edpd.cpp @@ -33,6 +33,7 @@ #include "fix_mvv_edpd.h" #include "atom.h" +#include "domain.h" #include "error.h" #include "force.h" #include "update.h" @@ -73,6 +74,11 @@ void FixMvvEDPD::init() { if (!atom->edpd_flag) error->all(FLERR,"Fix mvv/edpd requires atom style edpd"); + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix mvv/edpd cannot be used with velocity remapping"); + if (!force->pair_match("^edpd",0)) { if (force->pair_match("^hybrid",0)) { if (!force->pair_match("^edpd",0,1)) { diff --git a/src/DPD-MESO/fix_mvv_tdpd.cpp b/src/DPD-MESO/fix_mvv_tdpd.cpp index 122fd56365..d4e2d8a5c9 100644 --- a/src/DPD-MESO/fix_mvv_tdpd.cpp +++ b/src/DPD-MESO/fix_mvv_tdpd.cpp @@ -29,6 +29,7 @@ #include "fix_mvv_tdpd.h" #include "atom.h" +#include "domain.h" #include "error.h" #include "force.h" #include "update.h" @@ -71,6 +72,11 @@ void FixMvvTDPD::init() { if (!atom->tdpd_flag) error->all(FLERR,"Fix mvv/tdpd requires atom style tdpd"); + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix mvv/tdpd cannot be used with velocity remapping"); + if (!force->pair_match("^tdpd",0)) { if (force->pair_match("^hybrid",0)) { if (!force->pair_match("^tdpd",0,1)) { diff --git a/src/DPD-SMOOTH/fix_meso_move.cpp b/src/DPD-SMOOTH/fix_meso_move.cpp index 2c3213c3cd..c9d4a41400 100644 --- a/src/DPD-SMOOTH/fix_meso_move.cpp +++ b/src/DPD-SMOOTH/fix_meso_move.cpp @@ -350,7 +350,14 @@ void FixMesoMove::init () { } void FixMesoMove::setup_pre_force (int /*vflag*/) { + + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix meso/move cannot be used with velocity remapping"); + // set vest equal to v + double **v = atom->v; double **vest = atom->vest; int *mask = atom->mask; diff --git a/src/DPD-SMOOTH/fix_rigid_meso.cpp b/src/DPD-SMOOTH/fix_rigid_meso.cpp index e0ad501e02..38b9d0a09c 100644 --- a/src/DPD-SMOOTH/fix_rigid_meso.cpp +++ b/src/DPD-SMOOTH/fix_rigid_meso.cpp @@ -29,11 +29,12 @@ ------------------------------------------------------------------------- */ #include "fix_rigid_meso.h" -#include "math_extra.h" + #include "atom.h" #include "domain.h" -#include "memory.h" #include "error.h" +#include "math_extra.h" +#include "memory.h" using namespace LAMMPS_NS; using namespace FixConst; @@ -92,6 +93,11 @@ void FixRigidMeso::setup (int vflag) { conjqm[ibody][2] *= 2.0; conjqm[ibody][3] *= 2.0; } + + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix rigid/meso cannot be used with velocity remapping"); } /* ---------------------------------------------------------------------- diff --git a/src/Depend.sh b/src/Depend.sh index e55b100975..85542b21c0 100755 --- a/src/Depend.sh +++ b/src/Depend.sh @@ -195,6 +195,10 @@ if (test $1 = "ML-SNAP") then depend INTEL fi +if (test $1 = "ML-UF3") then + depend KOKKOS +fi + if (test $1 = "CG-SPICA") then depend GPU depend KOKKOS diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index aa920981e2..31359d4e4a 100755 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -53,6 +53,10 @@ action angle_cosine_kokkos.cpp angle_cosine.cpp action angle_cosine_kokkos.h angle_cosine.h action angle_harmonic_kokkos.cpp angle_harmonic.cpp action angle_harmonic_kokkos.h angle_harmonic.h +action angle_hybrid_kokkos.cpp angle_hybrid.cpp +action angle_hybrid_kokkos.h angle_hybrid.h +action angle_spica_kokkos.cpp angle_spica.cpp +action angle_spica_kokkos.h angle_spica.h action atom_kokkos.cpp action atom_kokkos.h action atom_map_kokkos.cpp @@ -116,6 +120,8 @@ action dihedral_harmonic_kokkos.cpp dihedral_harmonic.cpp action dihedral_harmonic_kokkos.h dihedral_harmonic.h action dihedral_opls_kokkos.cpp dihedral_opls.cpp action dihedral_opls_kokkos.h dihedral_opls.h +action dihedral_hybrid_kokkos.cpp dihedral_hybrid.cpp +action dihedral_hybrid_kokkos.h dihedral_hybrid.h action domain_kokkos.cpp action domain_kokkos.h action dynamical_matrix_kokkos.cpp dynamical_matrix.cpp @@ -205,6 +211,8 @@ action improper_class2_kokkos.cpp improper_class2.cpp action improper_class2_kokkos.h improper_class2.h action improper_harmonic_kokkos.cpp improper_harmonic.cpp action improper_harmonic_kokkos.h improper_harmonic.h +action improper_hybrid_kokkos.cpp improper_hybrid.cpp +action improper_hybrid_kokkos.h improper_hybrid.h action kissfft_kokkos.h kissfft.h action kokkos_base_fft.h fft3d.h action kokkos_base.h @@ -344,6 +352,8 @@ action pair_lj_gromacs_coul_gromacs_kokkos.cpp pair_lj_gromacs_coul_gromacs.cpp action pair_lj_gromacs_coul_gromacs_kokkos.h pair_lj_gromacs_coul_gromacs.h action pair_lj_gromacs_kokkos.cpp pair_lj_gromacs.cpp action pair_lj_gromacs_kokkos.h pair_lj_gromacs.h +action pair_lj_spica_coul_long_kokkos.cpp pair_lj_spica_coul_long.cpp +action pair_lj_spica_coul_long_kokkos.h pair_lj_spica_coul_long.h action pair_lj_spica_kokkos.cpp pair_lj_spica.cpp action pair_lj_spica_kokkos.h pair_lj_spica.h action pair_meam_kokkos.cpp pair_meam.cpp @@ -381,6 +391,8 @@ action pair_tersoff_mod_kokkos.cpp pair_tersoff_mod.cpp action pair_tersoff_mod_kokkos.h pair_tersoff_mod.h action pair_tersoff_zbl_kokkos.cpp pair_tersoff_zbl.cpp action pair_tersoff_zbl_kokkos.h pair_tersoff_zbl.h +action pair_uf3_kokkos.cpp pair_uf3.cpp +action pair_uf3_kokkos.h pair_uf3.h action pair_vashishta_kokkos.cpp pair_vashishta.cpp action pair_vashishta_kokkos.h pair_vashishta.h action pair_yukawa_kokkos.cpp diff --git a/src/KOKKOS/angle_charmm_kokkos.cpp b/src/KOKKOS/angle_charmm_kokkos.cpp index 666002686c..22d2b924dd 100644 --- a/src/KOKKOS/angle_charmm_kokkos.cpp +++ b/src/KOKKOS/angle_charmm_kokkos.cpp @@ -38,6 +38,7 @@ static constexpr double SMALL = 0.001; template AngleCharmmKokkos::AngleCharmmKokkos(LAMMPS *lmp) : AngleCharmm(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -125,12 +126,12 @@ void AngleCharmmKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -284,10 +285,10 @@ void AngleCharmmKokkos::coeff(int narg, char **arg) k_r_ub.h_view[i] = r_ub[i]; } - k_k.template modify(); - k_theta0.template modify(); - k_k_ub.template modify(); - k_r_ub.template modify(); + k_k.modify_host(); + k_theta0.modify_host(); + k_k_ub.modify_host(); + k_r_ub.modify_host(); k_k.template sync(); k_theta0.template sync(); @@ -322,10 +323,10 @@ void AngleCharmmKokkos::read_restart(FILE *fp) k_r_ub.h_view[i] = r_ub[i]; } - k_k.template modify(); - k_theta0.template modify(); - k_k_ub.template modify(); - k_r_ub.template modify(); + k_k.modify_host(); + k_theta0.modify_host(); + k_k_ub.modify_host(); + k_r_ub.modify_host(); k_k.template sync(); k_theta0.template sync(); diff --git a/src/KOKKOS/angle_charmm_kokkos.h b/src/KOKKOS/angle_charmm_kokkos.h index 197f9160a0..2bb06725f9 100644 --- a/src/KOKKOS/angle_charmm_kokkos.h +++ b/src/KOKKOS/angle_charmm_kokkos.h @@ -58,19 +58,18 @@ class AngleCharmmKokkos : public AngleCharmm { const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1, const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const; + using KKDeviceType = typename KKDevice::value; + Kokkos::DualView k_eatom; + Kokkos::DualView k_vatom; + protected: class NeighborKokkos *neighborKK; typedef ArrayTypes AT; typename AT::t_x_array_randomread x; - - using KKDeviceType = typename KKDevice::value; typename Kokkos::View > f; typename AT::t_int_2d anglelist; - - Kokkos::DualView k_eatom; - Kokkos::DualView k_vatom; Kokkos::View> d_eatom; Kokkos::View> d_vatom; diff --git a/src/KOKKOS/angle_class2_kokkos.cpp b/src/KOKKOS/angle_class2_kokkos.cpp index e831ae2283..e9d4797e71 100644 --- a/src/KOKKOS/angle_class2_kokkos.cpp +++ b/src/KOKKOS/angle_class2_kokkos.cpp @@ -38,6 +38,7 @@ static constexpr double SMALL = 0.001; template AngleClass2Kokkos::AngleClass2Kokkos(LAMMPS *lmp) : AngleClass2(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -141,12 +142,12 @@ void AngleClass2Kokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -386,21 +387,21 @@ void AngleClass2Kokkos::coeff(int narg, char **arg) k_theta0.h_view[i] = theta0[i]; } - k_k2.template modify(); - k_k3.template modify(); - k_k4.template modify(); - k_bb_k.template modify(); - k_bb_r1.template modify(); - k_bb_r2.template modify(); - k_ba_k1.template modify(); - k_ba_k2.template modify(); - k_ba_r1.template modify(); - k_ba_r2.template modify(); - k_setflag.template modify(); - k_setflag_a.template modify(); - k_setflag_bb.template modify(); - k_setflag_ba.template modify(); - k_theta0.template modify(); + k_k2.modify_host(); + k_k3.modify_host(); + k_k4.modify_host(); + k_bb_k.modify_host(); + k_bb_r1.modify_host(); + k_bb_r2.modify_host(); + k_ba_k1.modify_host(); + k_ba_k2.modify_host(); + k_ba_r1.modify_host(); + k_ba_r2.modify_host(); + k_setflag.modify_host(); + k_setflag_a.modify_host(); + k_setflag_bb.modify_host(); + k_setflag_ba.modify_host(); + k_theta0.modify_host(); } /* ---------------------------------------------------------------------- @@ -465,21 +466,21 @@ void AngleClass2Kokkos::read_restart(FILE *fp) k_theta0.h_view[i] = theta0[i]; } - k_k2.template modify(); - k_k3.template modify(); - k_k4.template modify(); - k_bb_k.template modify(); - k_bb_r1.template modify(); - k_bb_r2.template modify(); - k_ba_k1.template modify(); - k_ba_k2.template modify(); - k_ba_r1.template modify(); - k_ba_r2.template modify(); - k_setflag.template modify(); - k_setflag_a.template modify(); - k_setflag_bb.template modify(); - k_setflag_ba.template modify(); - k_theta0.template modify(); + k_k2.modify_host(); + k_k3.modify_host(); + k_k4.modify_host(); + k_bb_k.modify_host(); + k_bb_r1.modify_host(); + k_bb_r2.modify_host(); + k_ba_k1.modify_host(); + k_ba_k2.modify_host(); + k_ba_r1.modify_host(); + k_ba_r2.modify_host(); + k_setflag.modify_host(); + k_setflag_a.modify_host(); + k_setflag_bb.modify_host(); + k_setflag_ba.modify_host(); + k_theta0.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/angle_class2_kokkos.h b/src/KOKKOS/angle_class2_kokkos.h index 81bed169bc..7ef9e9b652 100644 --- a/src/KOKKOS/angle_class2_kokkos.h +++ b/src/KOKKOS/angle_class2_kokkos.h @@ -36,8 +36,8 @@ class AngleClass2Kokkos : public AngleClass2 { public: typedef DeviceType device_type; - typedef ArrayTypes AT; typedef EV_FLOAT value_type; + typedef ArrayTypes AT; AngleClass2Kokkos(class LAMMPS *); ~AngleClass2Kokkos() override; @@ -60,6 +60,9 @@ class AngleClass2Kokkos : public AngleClass2 { const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1, const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const; + typename AT::tdual_efloat_1d k_eatom; + typename AT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -67,9 +70,6 @@ class AngleClass2Kokkos : public AngleClass2 { typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_int_2d anglelist; - - typename AT::tdual_efloat_1d k_eatom; - typename AT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; diff --git a/src/KOKKOS/angle_cosine_kokkos.cpp b/src/KOKKOS/angle_cosine_kokkos.cpp index 768dfd43ca..5d61213df8 100644 --- a/src/KOKKOS/angle_cosine_kokkos.cpp +++ b/src/KOKKOS/angle_cosine_kokkos.cpp @@ -36,6 +36,7 @@ using namespace MathConst; template AngleCosineKokkos::AngleCosineKokkos(LAMMPS *lmp) : AngleCosine(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -124,12 +125,12 @@ void AngleCosineKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -254,7 +255,7 @@ void AngleCosineKokkos::coeff(int narg, char **arg) for (int i = 1; i <= n; i++) k_k.h_view[i] = k[i]; - k_k.template modify(); + k_k.modify_host(); } /* ---------------------------------------------------------------------- @@ -270,7 +271,7 @@ void AngleCosineKokkos::read_restart(FILE *fp) for (int i = 1; i <= n; i++) k_k.h_view[i] = k[i]; - k_k.template modify(); + k_k.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/angle_cosine_kokkos.h b/src/KOKKOS/angle_cosine_kokkos.h index 33b80f5a5f..3cfa5a73df 100644 --- a/src/KOKKOS/angle_cosine_kokkos.h +++ b/src/KOKKOS/angle_cosine_kokkos.h @@ -37,6 +37,7 @@ class AngleCosineKokkos : public AngleCosine { public: typedef DeviceType device_type; typedef EV_FLOAT value_type; + typedef ArrayTypes AT; AngleCosineKokkos(class LAMMPS *); ~AngleCosineKokkos() override; @@ -59,6 +60,9 @@ class AngleCosineKokkos : public AngleCosine { const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1, const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const; + typename AT::tdual_efloat_1d k_eatom; + typename AT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -66,9 +70,6 @@ class AngleCosineKokkos : public AngleCosine { typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_f_array f; typename ArrayTypes::t_int_2d anglelist; - - typename ArrayTypes::tdual_efloat_1d k_eatom; - typename ArrayTypes::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; diff --git a/src/KOKKOS/angle_harmonic_kokkos.cpp b/src/KOKKOS/angle_harmonic_kokkos.cpp index d7be418326..2b3c283732 100644 --- a/src/KOKKOS/angle_harmonic_kokkos.cpp +++ b/src/KOKKOS/angle_harmonic_kokkos.cpp @@ -38,6 +38,7 @@ static constexpr double SMALL = 0.001; template AngleHarmonicKokkos::AngleHarmonicKokkos(LAMMPS *lmp) : AngleHarmonic(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -71,14 +72,18 @@ void AngleHarmonicKokkos::compute(int eflag_in, int vflag_in) // reallocate per-atom arrays if necessary if (eflag_atom) { + if(k_eatom.extent(0) < maxeatom) { memoryKK->destroy_kokkos(k_eatom,eatom); memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"angle:eatom"); d_eatom = k_eatom.template view(); + } else Kokkos::deep_copy(d_eatom,0.0); } if (vflag_atom) { + if(k_vatom.extent(0) < maxvatom) { memoryKK->destroy_kokkos(k_vatom,vatom); memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"angle:vatom"); d_vatom = k_vatom.template view(); + } else Kokkos::deep_copy(d_vatom,0.0); } //atomKK->sync(execution_space,datamask_read); @@ -127,12 +132,12 @@ void AngleHarmonicKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -264,8 +269,8 @@ void AngleHarmonicKokkos::coeff(int narg, char **arg) k_theta0.h_view[i] = theta0[i]; } - k_k.template modify(); - k_theta0.template modify(); + k_k.modify_host(); + k_theta0.modify_host(); } /* ---------------------------------------------------------------------- @@ -283,8 +288,8 @@ void AngleHarmonicKokkos::read_restart(FILE *fp) k_theta0.h_view[i] = theta0[i]; } - k_k.template modify(); - k_theta0.template modify(); + k_k.modify_host(); + k_theta0.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/angle_harmonic_kokkos.h b/src/KOKKOS/angle_harmonic_kokkos.h index ce4b9d9976..4e427d2417 100644 --- a/src/KOKKOS/angle_harmonic_kokkos.h +++ b/src/KOKKOS/angle_harmonic_kokkos.h @@ -37,6 +37,7 @@ class AngleHarmonicKokkos : public AngleHarmonic { public: typedef DeviceType device_type; typedef EV_FLOAT value_type; + typedef ArrayTypes AT; AngleHarmonicKokkos(class LAMMPS *); ~AngleHarmonicKokkos() override; @@ -59,6 +60,9 @@ class AngleHarmonicKokkos : public AngleHarmonic { const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1, const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const; + typename AT::tdual_efloat_1d k_eatom; + typename AT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -66,9 +70,6 @@ class AngleHarmonicKokkos : public AngleHarmonic { typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_f_array f; typename ArrayTypes::t_int_2d anglelist; - - typename ArrayTypes::tdual_efloat_1d k_eatom; - typename ArrayTypes::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; diff --git a/src/KOKKOS/angle_hybrid_kokkos.cpp b/src/KOKKOS/angle_hybrid_kokkos.cpp new file mode 100644 index 0000000000..06b2845545 --- /dev/null +++ b/src/KOKKOS/angle_hybrid_kokkos.cpp @@ -0,0 +1,224 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain 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 "angle_hybrid_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "kokkos.h" +#include "memory_kokkos.h" +#include "neighbor_kokkos.h" + +#include + +using namespace LAMMPS_NS; + +#define EXTRA 1000 + +/* ---------------------------------------------------------------------- */ + +AngleHybridKokkos::AngleHybridKokkos(LAMMPS *lmp) : AngleHybrid(lmp) +{ + kokkosable = 1; + + atomKK = (AtomKokkos *) atom; + neighborKK = (NeighborKokkos *) neighbor; + + execution_space = Device; + + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- */ + +AngleHybridKokkos::~AngleHybridKokkos() +{ + deallocate(); +} + +/* ---------------------------------------------------------------------- */ + +void AngleHybridKokkos::compute(int eflag, int vflag) +{ + // save ptrs to original anglelist + + int nanglelist_orig = neighbor->nanglelist; + neighborKK->k_anglelist.sync_device(); + auto k_anglelist_orig = neighborKK->k_anglelist; + auto d_anglelist_orig = k_anglelist_orig.d_view; + auto d_nanglelist = k_nanglelist.d_view; + auto h_nanglelist = k_nanglelist.h_view; + + // if this is re-neighbor step, create sub-style anglelists + // nanglelist[] = length of each sub-style list + // realloc sub-style anglelist if necessary + // load sub-style anglelist with 3 values from original anglelist + + if (neighbor->ago == 0) { + Kokkos::deep_copy(d_nanglelist,0); + + k_map.sync_device(); + auto d_map = k_map.d_view; + + Kokkos::parallel_for(nanglelist_orig,LAMMPS_LAMBDA(int i) { + const int m = d_map[d_anglelist_orig(i,3)]; + if (m >= 0) Kokkos::atomic_increment(&d_nanglelist[m]); + }); + + k_nanglelist.modify_device(); + k_nanglelist.sync_host(); + + maxangle_all = 0; + for (int m = 0; m < nstyles; m++) + if (h_nanglelist[m] > maxangle_all) + maxangle_all = h_nanglelist[m] + EXTRA; + + if (k_anglelist.d_view.extent(1) < maxangle_all) + MemKK::realloc_kokkos(k_anglelist, "angle_hybrid:anglelist", nstyles, maxangle_all, 4); + auto d_anglelist = k_anglelist.d_view; + + Kokkos::deep_copy(d_nanglelist,0); + + Kokkos::parallel_for(nanglelist_orig,LAMMPS_LAMBDA(int i) { + const int m = d_map[d_anglelist_orig(i,3)]; + if (m < 0) return; + const int n = Kokkos::atomic_fetch_add(&d_nanglelist[m],1); + d_anglelist(m,n,0) = d_anglelist_orig(i,0); + d_anglelist(m,n,1) = d_anglelist_orig(i,1); + d_anglelist(m,n,2) = d_anglelist_orig(i,2); + d_anglelist(m,n,3) = d_anglelist_orig(i,3); + }); + } + + // call each sub-style's compute function + // set neighbor->anglelist to sub-style anglelist before call + // accumulate sub-style global/peratom energy/virial in hybrid + + ev_init(eflag, vflag); + + k_nanglelist.modify_device(); + k_nanglelist.sync_host(); + + for (int m = 0; m < nstyles; m++) { + neighbor->nanglelist = h_nanglelist[m]; + auto k_anglelist_m = Kokkos::subview(k_anglelist,m,Kokkos::ALL,Kokkos::ALL); + k_anglelist_m.modify_device(); + neighborKK->k_anglelist = k_anglelist_m; + + auto style = styles[m]; + atomKK->sync(style->execution_space,style->datamask_read); + style->compute(eflag, vflag); + atomKK->modified(style->execution_space,style->datamask_modify); + + if (eflag_global) energy += style->energy; + if (vflag_global) + for (int n = 0; n < 6; n++) virial[n] += style->virial[n]; + + if (eflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double *eatom_substyle = styles[m]->eatom; + for (int i = 0; i < n; i++) eatom[i] += eatom_substyle[i]; + } + if (vflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double **vatom_substyle = styles[m]->vatom; + for (int i = 0; i < n; i++) + for (int j = 0; j < 6; j++) vatom[i][j] += vatom_substyle[i][j]; + } + if (cvflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double **cvatom_substyle = styles[m]->cvatom; + for (int i = 0; i < n; i++) + for (int j = 0; j < 9; j++) cvatom[i][j] += cvatom_substyle[i][j]; + } + } + + // restore ptrs to original anglelist + + neighbor->nanglelist = nanglelist_orig; + neighborKK->k_anglelist = k_anglelist_orig; +} + +/* ---------------------------------------------------------------------- */ + +void AngleHybridKokkos::allocate() +{ + allocated = 1; + int np1 = atom->nangletypes + 1; + + memoryKK->create_kokkos(k_map, map, np1, "angle:map"); + memory->create(setflag, np1, "angle:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; + + k_nanglelist = DAT::tdual_int_1d("angle:nanglelist", nstyles); +} + +/* ---------------------------------------------------------------------- */ + +void AngleHybridKokkos::deallocate() +{ + if (!allocated) return; + + allocated = 0; + + memory->destroy(setflag); + memoryKK->destroy_kokkos(k_map,map); +} + +/* ---------------------------------------------------------------------- + set coeffs for one type +---------------------------------------------------------------------- */ + +void AngleHybridKokkos::coeff(int narg, char **arg) +{ + AngleHybrid::coeff(narg,arg); + + k_map.modify_host(); +} + +/* ---------------------------------------------------------------------- */ + +void AngleHybridKokkos::init_style() +{ + AngleHybrid::init_style(); + + for (int m = 0; m < nstyles; m++) { + if (!styles[m]->kokkosable) + error->all(FLERR,"Must use only Kokkos-enabled angle styles with angle_style hybrid/kk"); + + if (styles[m]->execution_space == Host) + lmp->kokkos->allow_overlap = 0; + } +} + +/* ---------------------------------------------------------------------- + memory usage +------------------------------------------------------------------------- */ + +double AngleHybridKokkos::memory_usage() +{ + double bytes = (double) maxeatom * sizeof(double); + bytes += (double) maxvatom * 6 * sizeof(double); + bytes += (double) maxcvatom * 9 * sizeof(double); + for (int m = 0; m < nstyles; m++) bytes += (double) maxangle_all * 4 * sizeof(int); + for (int m = 0; m < nstyles; m++) + if (styles[m]) bytes += styles[m]->memory_usage(); + return bytes; +} diff --git a/src/KOKKOS/angle_hybrid_kokkos.h b/src/KOKKOS/angle_hybrid_kokkos.h new file mode 100644 index 0000000000..09b51958eb --- /dev/null +++ b/src/KOKKOS/angle_hybrid_kokkos.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 ANGLE_CLASS +// clang-format off +AngleStyle(hybrid/kk,AngleHybridKokkos); +AngleStyle(hybrid/kk/device,AngleHybridKokkos); +AngleStyle(hybrid/kk/host,AngleHybridKokkos); +// clang-format on +#else + +// clang-format off +#ifndef LMP_ANGLE_HYBRID_KOKKOS_H +#define LMP_ANGLE_HYBRID_KOKKOS_H + +#include "angle_hybrid.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class AngleHybridKokkos : public AngleHybrid { + friend class Force; + + public: + AngleHybridKokkos(class LAMMPS *); + ~AngleHybridKokkos() override; + void compute(int, int) override; + void coeff(int, char **) override; + void init_style() override; + double memory_usage() override; + + private: + int maxangle_all; + + class NeighborKokkos *neighborKK; + + DAT::tdual_int_1d k_map; // which style each angle type points to + DAT::tdual_int_1d k_nanglelist; // # of angles in sub-style anglelists + DAT::tdual_int_3d k_anglelist; // anglelist for each sub-style + + void allocate() override; + void deallocate() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/KOKKOS/angle_spica_kokkos.cpp b/src/KOKKOS/angle_spica_kokkos.cpp new file mode 100644 index 0000000000..05da415f32 --- /dev/null +++ b/src/KOKKOS/angle_spica_kokkos.cpp @@ -0,0 +1,656 @@ +// 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: Mitch Murphy (alphataubio@gmail.com) +------------------------------------------------------------------------- */ + +#include "angle_spica_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "math_const.h" +#include "memory_kokkos.h" +#include "neighbor_kokkos.h" +#include "respa.h" +#include "update.h" + +#include "lj_spica_common.h" + +#include + +using namespace LAMMPS_NS; +using namespace MathConst; +using namespace LJSPICAParms; + +static constexpr double SMALL = 0.001; + +/* ---------------------------------------------------------------------- */ + +template +AngleSPICAKokkos::AngleSPICAKokkos(LAMMPS *lmp) : AngleSPICA(lmp) +{ + atomKK = (AtomKokkos *) atom; + neighborKK = (NeighborKokkos *) neighbor; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + + centroidstressflag = CENTROID_NOTAVAIL; +} + +/* ---------------------------------------------------------------------- */ + +template +AngleSPICAKokkos::~AngleSPICAKokkos() +{ + if (!copymode) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->destroy_kokkos(k_vatom,vatom); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void AngleSPICAKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + ev_init(eflag,vflag,0); + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"angle:eatom"); + d_eatom = k_eatom.template view(); + } + if (vflag_atom) { + memoryKK->destroy_kokkos(k_vatom,vatom); + memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"angle:vatom"); + d_vatom = k_vatom.template view(); + } + + k_k.template sync(); + k_theta0.template sync(); + k_repscale.template sync(); + k_lj_type.template sync(); + k_lj1.template sync(); + k_lj2.template sync(); + k_lj3.template sync(); + k_lj4.template sync(); + k_rminsq.template sync(); + k_emin.template sync(); + + + // "It has to do with overlapping host/device in verlet_kokkos.cpp. For this reason, all topology styles (bond, angle, etc.) must set DATAMASK_READ, DATAMASK_MODIFY in the constructor and must not use atomKK->sync/modified. This is a gotcha that needed to be better documented." + // https://matsci.org/t/a-few-kokkos-development-questions/56598 + // + // atomKK->sync(execution_space,datamask_read); + // if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + // else atomKK->modified(execution_space,F_MASK); + //atomKK->k_type.template sync(); + + x = atomKK->k_x.template view(); + f = atomKK->k_f.template view(); + neighborKK->k_anglelist.template sync(); + anglelist = neighborKK->k_anglelist.template view(); + int nanglelist = neighborKK->nanglelist; + d_type = atomKK->k_type.template view(); + nlocal = atom->nlocal; + newton_bond = force->newton_bond; + + copymode = 1; + + // loop over neighbors of my atoms + + EV_FLOAT ev; + + if (evflag) { + if (newton_bond) { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nanglelist),*this,ev); + } else { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nanglelist),*this,ev); + } + } else { + if (newton_bond) { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,nanglelist),*this); + } else { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,nanglelist),*this); + } + } + + if (eflag_global) energy += ev.evdwl; + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + copymode = 0; +} + +template +template +KOKKOS_INLINE_FUNCTION +void AngleSPICAKokkos::operator()(TagAngleSPICACompute, const int &n, EV_FLOAT& ev) const { + + // The f array is atomic + Kokkos::View::value,Kokkos::MemoryTraits > a_f = f; + + const int i1 = anglelist(n,0); + const int i2 = anglelist(n,1); + const int i3 = anglelist(n,2); + const int type = anglelist(n,3); + + // 1st bond + + const F_FLOAT delx1 = x(i1,0) - x(i2,0); + const F_FLOAT dely1 = x(i1,1) - x(i2,1); + const F_FLOAT delz1 = x(i1,2) - x(i2,2); + + const F_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; + const F_FLOAT r1 = sqrt(rsq1); + + // 2nd bond + + const F_FLOAT delx2 = x(i3,0) - x(i2,0); + const F_FLOAT dely2 = x(i3,1) - x(i2,1); + const F_FLOAT delz2 = x(i3,2) - x(i2,2); + + const F_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; + const F_FLOAT r2 = sqrt(rsq2); + + // angle (cos and sin) + + F_FLOAT c = delx1*delx2 + dely1*dely2 + delz1*delz2; + c /= r1*r2; + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + F_FLOAT s = sqrt(1.0 - c*c); + if (s < SMALL) s = SMALL; + s = 1.0/s; + + // 1-3 LJ interaction. + // we only want to use the repulsive part, + // and it can be scaled (or off). + // so this has to be done here and not in the + // general non-bonded code. + + F_FLOAT f13, e13, delx3, dely3, delz3; + f13 = e13 = delx3 = dely3 = delz3 = 0.0; + + if (repflag) { + + delx3 = x(i1,0) - x(i3,0); + dely3 = x(i1,1) - x(i3,1); + delz3 = x(i1,2) - x(i3,2); + const F_FLOAT rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3; + + const int type1 = d_type[i1]; + const int type3 = d_type[i3]; + + f13=0.0; + e13=0.0; + + if (rsq3 < d_rminsq(type1,type3)) { + const int ljt = d_lj_type(type1,type3); + const double r2inv = 1.0/rsq3; + + if (ljt == LJ12_4) { + const double r4inv=r2inv*r2inv; + + f13 = r4inv*(d_lj1(type1,type3)*r4inv*r4inv - d_lj2(type1,type3)); + if (eflag) e13 = r4inv*(d_lj3(type1,type3)*r4inv*r4inv - d_lj4(type1,type3)); + + } else if (ljt == LJ9_6) { + const double r3inv = r2inv*sqrt(r2inv); + const double r6inv = r3inv*r3inv; + + f13 = r6inv*(d_lj1(type1,type3)*r3inv - d_lj2(type1,type3)); + if (eflag) e13 = r6inv*(d_lj3(type1,type3)*r3inv - d_lj4(type1,type3)); + + } else if (ljt == LJ12_6) { + const double r6inv = r2inv*r2inv*r2inv; + + f13 = r6inv*(d_lj1(type1,type3)*r6inv - d_lj2(type1,type3)); + if (eflag) e13 = r6inv*(d_lj3(type1,type3)*r6inv - d_lj4(type1,type3)); + + } else if (ljt == LJ12_5) { + const double r5inv = r2inv*r2inv*sqrt(r2inv); + const double r7inv = r5inv*r2inv; + + f13 = r5inv*(d_lj1(type1,type3)*r7inv - d_lj2(type1,type3)); + if (eflag) e13 = r5inv*(d_lj3(type1,type3)*r7inv - d_lj4(type1,type3)); + } + + // make sure energy is 0.0 at the cutoff. + if (eflag) e13 -= d_emin(type1,type3); + + f13 *= r2inv; + } + } + + // force & energy + + const F_FLOAT dtheta = acos(c) - d_theta0[type]; + const F_FLOAT tk = d_k[type] * dtheta; + + F_FLOAT eangle = 0.0; + if (eflag) eangle = tk*dtheta; + + const F_FLOAT a = -2.0 * tk * s; + const F_FLOAT a11 = a*c / rsq1; + const F_FLOAT a12 = -a / (r1*r2); + const F_FLOAT a22 = a*c / rsq2; + + F_FLOAT f1[3],f3[3]; + f1[0] = a11*delx1 + a12*delx2; + f1[1] = a11*dely1 + a12*dely2; + f1[2] = a11*delz1 + a12*delz2; + f3[0] = a22*delx2 + a12*delx1; + f3[1] = a22*dely2 + a12*dely1; + f3[2] = a22*delz2 + a12*delz1; + + // apply force to each of 3 atoms + + if (NEWTON_BOND || i1 < nlocal) { + a_f(i1,0) += f1[0] + f13*delx3; + a_f(i1,1) += f1[1] + f13*dely3; + a_f(i1,2) += f1[2] + f13*delz3; + } + + if (NEWTON_BOND || i2 < nlocal) { + a_f(i2,0) -= f1[0] + f3[0]; + a_f(i2,1) -= f1[1] + f3[1]; + a_f(i2,2) -= f1[2] + f3[2]; + } + + if (NEWTON_BOND || i3 < nlocal) { + a_f(i3,0) += f3[0] - f13*delx3; + a_f(i3,1) += f3[1] - f13*dely3; + a_f(i3,2) += f3[2] - f13*delz3; + } + + if (EVFLAG) { + ev_tally(ev,i1,i2,i3,eangle,f1,f3,delx1,dely1,delz1,delx2,dely2,delz2); + + if (repflag) + ev_tally13(ev,i1,i3,e13,f13,delx3,dely3,delz3); + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void AngleSPICAKokkos::operator()(TagAngleSPICACompute, const int &n) const { + EV_FLOAT ev; + this->template operator()(TagAngleSPICACompute(), n, ev); +} + +/* ---------------------------------------------------------------------- */ + +template +void AngleSPICAKokkos::allocate() +{ + AngleSPICA::allocate(); + + int nangletypes = atom->nangletypes; + k_k = typename ArrayTypes::tdual_ffloat_1d("AngleSPICA::k",nangletypes+1); + k_theta0 = typename ArrayTypes::tdual_ffloat_1d("AngleSPICA::theta0",nangletypes+1); + k_repscale = typename ArrayTypes::tdual_ffloat_1d("AngleSPICA::repscale",nangletypes+1); + k_setflag = typename ArrayTypes::tdual_int_1d("AngleSPICA::setflag",nangletypes+1); + + d_k = k_k.template view(); + d_theta0 = k_theta0.template view(); + d_repscale = k_repscale.template view(); + d_setflag = k_setflag.template view(); + + int ntypes = atom->ntypes; + k_lj_type = typename ArrayTypes::tdual_int_2d("AngleSPICA::lj_type",ntypes+1,ntypes+1); + k_lj1 = typename ArrayTypes::tdual_ffloat_2d("AngleSPICA::lj1",ntypes+1,ntypes+1); + k_lj2 = typename ArrayTypes::tdual_ffloat_2d("AngleSPICA::lj2",ntypes+1,ntypes+1); + k_lj3 = typename ArrayTypes::tdual_ffloat_2d("AngleSPICA::lj3",ntypes+1,ntypes+1); + k_lj4 = typename ArrayTypes::tdual_ffloat_2d("AngleSPICA::lj4",ntypes+1,ntypes+1); + k_rminsq = typename ArrayTypes::tdual_ffloat_2d("AngleSPICA::rminsq",ntypes+1,ntypes+1); + k_emin = typename ArrayTypes::tdual_ffloat_2d("AngleSPICA::emin",ntypes+1,ntypes+1); + + d_lj_type = k_lj_type.template view(); + d_lj1 = k_lj1.template view(); + d_lj2 = k_lj2.template view(); + d_lj3 = k_lj3.template view(); + d_lj4 = k_lj4.template view(); + d_rminsq = k_rminsq.template view(); + d_emin = k_emin.template view(); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +template +void AngleSPICAKokkos::init_style() +{ + AngleSPICA::init_style(); + + // error if rRESPA with inner levels + + if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) { + int respa = 0; + if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; + if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; + if (respa) + error->all(FLERR,"Cannot use Kokkos pair style with rRESPA inner/middle"); + } + + int ntypes = atom->ntypes; + for (int i = 1; i <= ntypes; i++) { + for (int j = 1; j <= ntypes; j++) { + k_lj_type.h_view(i,j) = lj_type[i][j]; + k_lj1.h_view(i,j) = lj1[i][j]; + k_lj2.h_view(i,j) = lj2[i][j]; + k_lj3.h_view(i,j) = lj3[i][j]; + k_lj4.h_view(i,j) = lj4[i][j]; + k_rminsq.h_view(i,j) = rminsq[i][j]; + k_emin.h_view(i,j) = emin[i][j]; + } + } + + k_lj_type.template modify(); + k_lj1.template modify(); + k_lj2.template modify(); + k_lj3.template modify(); + k_lj4.template modify(); + k_rminsq.template modify(); + k_emin.template modify(); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more types +------------------------------------------------------------------------- */ + +template +void AngleSPICAKokkos::coeff(int narg, char **arg) +{ + AngleSPICA::coeff(narg, arg); + + int n = atom->nangletypes; + for (int i = 1; i <= n; i++) { + k_k.h_view[i] = k[i]; + k_theta0.h_view[i] = theta0[i]; + k_repscale.h_view[i] = repscale[i]; + k_setflag.h_view[i] = setflag[i]; + } + + k_k.template modify(); + k_theta0.template modify(); + k_repscale.template modify(); + k_setflag.template modify(); +} + +/* ---------------------------------------------------------------------- + proc 0 reads coeffs from restart file, bcasts them +------------------------------------------------------------------------- */ + +template +void AngleSPICAKokkos::read_restart(FILE *fp) +{ + AngleSPICA::read_restart(fp); + + int n = atom->nangletypes; + for (int i = 1; i <= n; i++) { + k_k.h_view[i] = k[i]; + k_theta0.h_view[i] = theta0[i]; + k_repscale.h_view[i] = repscale[i]; + k_setflag.h_view[i] = setflag[i]; + } + + k_k.template modify(); + k_theta0.template modify(); + k_repscale.template modify(); + k_setflag.template modify(); +} + +/* ---------------------------------------------------------------------- + tally energy and virial into global and per-atom accumulators + virial = r1F1 + r2F2 + r3F3 = (r1-r2) F1 + (r3-r2) F3 = del1*f1 + del2*f3 +------------------------------------------------------------------------- */ + +template +//template +KOKKOS_INLINE_FUNCTION +void AngleSPICAKokkos::ev_tally(EV_FLOAT &ev, const int i, const int j, const int k, + F_FLOAT &eangle, F_FLOAT *f1, F_FLOAT *f3, + const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1, + const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const +{ + E_FLOAT eanglethird; + F_FLOAT v[6]; + + // The eatom and vatom arrays are atomic + Kokkos::View::value,Kokkos::MemoryTraits > v_eatom = k_eatom.template view(); + Kokkos::View::value,Kokkos::MemoryTraits > v_vatom = k_vatom.template view(); + + if (eflag_either) { + if (eflag_global) { + if (newton_bond) ev.evdwl += eangle; + else { + eanglethird = THIRD*eangle; + + if (i < nlocal) ev.evdwl += eanglethird; + if (j < nlocal) ev.evdwl += eanglethird; + if (k < nlocal) ev.evdwl += eanglethird; + } + } + if (eflag_atom) { + eanglethird = THIRD*eangle; + + if (newton_bond || i < nlocal) v_eatom[i] += eanglethird; + if (newton_bond || j < nlocal) v_eatom[j] += eanglethird; + if (newton_bond || k < nlocal) v_eatom[k] += eanglethird; + } + } + + if (vflag_either) { + v[0] = delx1*f1[0] + delx2*f3[0]; + v[1] = dely1*f1[1] + dely2*f3[1]; + v[2] = delz1*f1[2] + delz2*f3[2]; + v[3] = delx1*f1[1] + delx2*f3[1]; + v[4] = delx1*f1[2] + delx2*f3[2]; + v[5] = dely1*f1[2] + dely2*f3[2]; + + if (vflag_global) { + if (newton_bond) { + ev.v[0] += v[0]; + ev.v[1] += v[1]; + ev.v[2] += v[2]; + ev.v[3] += v[3]; + ev.v[4] += v[4]; + ev.v[5] += v[5]; + } else { + if (i < nlocal) { + ev.v[0] += THIRD*v[0]; + ev.v[1] += THIRD*v[1]; + ev.v[2] += THIRD*v[2]; + ev.v[3] += THIRD*v[3]; + ev.v[4] += THIRD*v[4]; + ev.v[5] += THIRD*v[5]; + } + if (j < nlocal) { + ev.v[0] += THIRD*v[0]; + ev.v[1] += THIRD*v[1]; + ev.v[2] += THIRD*v[2]; + ev.v[3] += THIRD*v[3]; + ev.v[4] += THIRD*v[4]; + ev.v[5] += THIRD*v[5]; + } + if (k < nlocal) { + ev.v[0] += THIRD*v[0]; + + ev.v[1] += THIRD*v[1]; + ev.v[2] += THIRD*v[2]; + ev.v[3] += THIRD*v[3]; + ev.v[4] += THIRD*v[4]; + ev.v[5] += THIRD*v[5]; + } + } + } + + if (vflag_atom) { + if (newton_bond || i < nlocal) { + v_vatom(i,0) += THIRD*v[0]; + v_vatom(i,1) += THIRD*v[1]; + v_vatom(i,2) += THIRD*v[2]; + v_vatom(i,3) += THIRD*v[3]; + v_vatom(i,4) += THIRD*v[4]; + v_vatom(i,5) += THIRD*v[5]; + } + if (newton_bond || j < nlocal) { + v_vatom(j,0) += THIRD*v[0]; + v_vatom(j,1) += THIRD*v[1]; + v_vatom(j,2) += THIRD*v[2]; + v_vatom(j,3) += THIRD*v[3]; + v_vatom(j,4) += THIRD*v[4]; + v_vatom(j,5) += THIRD*v[5]; + } + if (newton_bond || k < nlocal) { + v_vatom(k,0) += THIRD*v[0]; + v_vatom(k,1) += THIRD*v[1]; + v_vatom(k,2) += THIRD*v[2]; + v_vatom(k,3) += THIRD*v[3]; + v_vatom(k,4) += THIRD*v[4]; + v_vatom(k,5) += THIRD*v[5]; + + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void AngleSPICAKokkos::ev_tally13(EV_FLOAT &ev, const int i, const int j, + const F_FLOAT &evdwl, const F_FLOAT &fpair, + const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const +{ + double v[6]; + + // The eatom and vatom arrays are atomic + Kokkos::View::value,Kokkos::MemoryTraits > v_eatom = k_eatom.template view(); + Kokkos::View::value,Kokkos::MemoryTraits > v_vatom = k_vatom.template view(); + + if (eflag_either) { + if (eflag_global) { + if (newton_bond) { + ev.evdwl += evdwl; + } else { + if (i < nlocal) + ev.evdwl += 0.5*evdwl; + if (j < nlocal) + ev.evdwl += 0.5*evdwl; + } + } + if (eflag_atom) { + if (newton_bond || i < nlocal) v_eatom[i] += 0.5*evdwl; + if (newton_bond || j < nlocal) v_eatom[j] += 0.5*evdwl; + } + } + + if (vflag_either) { + v[0] = delx*delx*fpair; + v[1] = dely*dely*fpair; + v[2] = delz*delz*fpair; + v[3] = delx*dely*fpair; + v[4] = delx*delz*fpair; + v[5] = dely*delz*fpair; + + if (vflag_global) { + if (newton_bond) { + ev.v[0] += v[0]; + ev.v[1] += v[1]; + ev.v[2] += v[2]; + ev.v[3] += v[3]; + ev.v[4] += v[4]; + ev.v[5] += v[5]; + } else { + if (i < nlocal) { + ev.v[0] += 0.5*v[0]; + ev.v[1] += 0.5*v[1]; + ev.v[2] += 0.5*v[2]; + ev.v[3] += 0.5*v[3]; + ev.v[4] += 0.5*v[4]; + ev.v[5] += 0.5*v[5]; + } + if (j < nlocal) { + ev.v[0] += 0.5*v[0]; + ev.v[1] += 0.5*v[1]; + ev.v[2] += 0.5*v[2]; + ev.v[3] += 0.5*v[3]; + ev.v[4] += 0.5*v[4]; + ev.v[5] += 0.5*v[5]; + } + } + } + + if (vflag_atom) { + if (newton_bond || i < nlocal) { + v_vatom(i,0) += 0.5*v[0]; + v_vatom(i,1) += 0.5*v[1]; + v_vatom(i,2) += 0.5*v[2]; + v_vatom(i,3) += 0.5*v[3]; + v_vatom(i,4) += 0.5*v[4]; + v_vatom(i,5) += 0.5*v[5]; + } + if (newton_bond || j < nlocal) { + v_vatom(j,0) += 0.5*v[0]; + v_vatom(j,1) += 0.5*v[1]; + v_vatom(j,2) += 0.5*v[2]; + v_vatom(j,3) += 0.5*v[3]; + v_vatom(j,4) += 0.5*v[4]; + v_vatom(j,5) += 0.5*v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +namespace LAMMPS_NS { +template class AngleSPICAKokkos; +#ifdef LMP_KOKKOS_GPU +template class AngleSPICAKokkos; +#endif +} + diff --git a/src/KOKKOS/angle_spica_kokkos.h b/src/KOKKOS/angle_spica_kokkos.h new file mode 100644 index 0000000000..7b96e9b8a9 --- /dev/null +++ b/src/KOKKOS/angle_spica_kokkos.h @@ -0,0 +1,106 @@ +/* -*- 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 ANGLE_CLASS +// clang-format off +AngleStyle(spica/kk,AngleSPICAKokkos); +AngleStyle(spica/kk/device,AngleSPICAKokkos); +AngleStyle(spica/kk/host,AngleSPICAKokkos); +AngleStyle(sdk/kk,AngleSPICAKokkos); +AngleStyle(sdk/kk/device,AngleSPICAKokkos); +AngleStyle(sdk/kk/host,AngleSPICAKokkos); +// clang-format on +#else + +// clang-format off +#ifndef LMP_ANGLE_SPICA_KOKKOS_H +#define LMP_ANGLE_SPICA_KOKKOS_H + +#include "angle_spica.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +struct TagAngleSPICACompute{}; + +template +class AngleSPICAKokkos : public AngleSPICA { + + public: + typedef DeviceType device_type; + typedef EV_FLOAT value_type; + + AngleSPICAKokkos(class LAMMPS *); + ~AngleSPICAKokkos() override; + void compute(int, int) override; + void coeff(int, char **) override; + void init_style() override; + void read_restart(FILE *) override; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagAngleSPICACompute, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagAngleSPICACompute, const int&) const; + + //template + KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int i, const int j, const int k, + F_FLOAT &eangle, F_FLOAT *f1, F_FLOAT *f3, + const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1, + const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const; + + KOKKOS_INLINE_FUNCTION + void ev_tally13(EV_FLOAT &ev, const int i, const int j, + const F_FLOAT &evdwl, const F_FLOAT &fpair, + const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const; + + protected: + + class NeighborKokkos *neighborKK; + + typename ArrayTypes::t_x_array_randomread x; + typename ArrayTypes::t_f_array f; + typename ArrayTypes::t_int_2d anglelist; + + typename ArrayTypes::tdual_efloat_1d k_eatom; + typename ArrayTypes::tdual_virial_array k_vatom; + typename ArrayTypes::t_efloat_1d d_eatom; + typename ArrayTypes::t_virial_array d_vatom; + + int nlocal,newton_bond; + int eflag,vflag; + + typename ArrayTypes::tdual_int_1d k_setflag; + typename ArrayTypes::t_int_1d d_setflag, d_type; + + typename ArrayTypes::tdual_ffloat_1d k_k, k_theta0, k_repscale; + typename ArrayTypes::t_ffloat_1d d_k, d_theta0, d_repscale; + + typename ArrayTypes::tdual_int_2d k_lj_type; + typename ArrayTypes::t_int_2d d_lj_type; + + typename ArrayTypes::tdual_ffloat_2d k_lj1, k_lj2, k_lj3, k_lj4, k_rminsq, k_emin; + typename ArrayTypes::t_ffloat_2d d_lj1, d_lj2, d_lj3, d_lj4, d_rminsq, d_emin; + + void allocate() override; +}; + +} + +#endif +#endif + diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 6707deddd5..e2ae9ffb19 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -276,22 +276,6 @@ void AtomKokkos::sort_device() if (domain->triclinic) domain->x2lamda(nlocal); } -/* ---------------------------------------------------------------------- - reallocate memory to the pointer selected by the mask -------------------------------------------------------------------------- */ - -void AtomKokkos::grow(unsigned int mask) -{ - if (mask & SPECIAL_MASK) { - memoryKK->destroy_kokkos(k_special, special); - sync(Device, mask); - modified(Device, mask); - memoryKK->grow_kokkos(k_special, special, nmax, maxspecial, "atom:special"); - avec->grow_pointers(); - sync(Host, mask); - } -} - /* ---------------------------------------------------------------------- add a custom variable with name of type flag = 0/1 for int/double assumes name does not already exist diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index 8501af2a24..d978a771de 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -165,7 +165,6 @@ class AtomKokkos : public Atom { void modified(const ExecutionSpace space, unsigned int mask); void sync_overlapping_device(const ExecutionSpace space, unsigned int mask); void sort() override; - virtual void grow(unsigned int mask); int add_custom(const char *, int, int, int border = 0) override; void remove_custom(int, int, int) override; void deallocate_topology() override; diff --git a/src/KOKKOS/bond_hybrid_kokkos.cpp b/src/KOKKOS/bond_hybrid_kokkos.cpp index d63ebccac6..db247c7100 100644 --- a/src/KOKKOS/bond_hybrid_kokkos.cpp +++ b/src/KOKKOS/bond_hybrid_kokkos.cpp @@ -153,11 +153,11 @@ void BondHybridKokkos::compute(int eflag, int vflag) void BondHybridKokkos::allocate() { allocated = 1; - int n = atom->nbondtypes; + int np1 = atom->nbondtypes + 1; - memoryKK->create_kokkos(k_map, map, n + 1, "bond:map"); - memory->create(setflag, n + 1, "bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; + memoryKK->create_kokkos(k_map, map, np1, "bond:map"); + memory->create(setflag, np1, "bond:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; k_nbondlist = DAT::tdual_int_1d("bond:nbondlist", nstyles); } diff --git a/src/KOKKOS/dihedral_charmm_kokkos.cpp b/src/KOKKOS/dihedral_charmm_kokkos.cpp index b385ec7f01..a8939770df 100644 --- a/src/KOKKOS/dihedral_charmm_kokkos.cpp +++ b/src/KOKKOS/dihedral_charmm_kokkos.cpp @@ -40,6 +40,7 @@ static constexpr double TOLERANCE = 0.05; template DihedralCharmmKokkos::DihedralCharmmKokkos(LAMMPS *lmp) : DihedralCharmm(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -115,7 +116,7 @@ void DihedralCharmmKokkos::compute(int eflag_in, int vflag_in) qqrd2e = force->qqrd2e; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -141,7 +142,7 @@ void DihedralCharmmKokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Dihedral problem"); @@ -174,20 +175,20 @@ void DihedralCharmmKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); k_eatom_pair.template modify(); - k_eatom_pair.template sync(); + k_eatom_pair.sync_host(); for (int i = 0; i < n; i++) force->pair->eatom[i] += k_eatom_pair.h_view(i); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); k_vatom_pair.template modify(); - k_vatom_pair.template sync(); + k_vatom_pair.sync_host(); for (int i = 0; i < n; i++) { force->pair->vatom[i][0] += k_vatom_pair.h_view(i,0); force->pair->vatom[i][1] += k_vatom_pair.h_view(i,1); @@ -454,12 +455,12 @@ void DihedralCharmmKokkos::coeff(int narg, char **arg) k_weight.h_view[i] = weight[i]; } - k_k.template modify(); - k_multiplicity.template modify(); - k_shift.template modify(); - k_cos_shift.template modify(); - k_sin_shift.template modify(); - k_weight.template modify(); + k_k.modify_host(); + k_multiplicity.modify_host(); + k_shift.modify_host(); + k_cos_shift.modify_host(); + k_sin_shift.modify_host(); + k_weight.modify_host(); k_k.template sync(); k_multiplicity.template sync(); @@ -502,10 +503,10 @@ void DihedralCharmmKokkos::init_style() } } - k_lj14_1.template modify(); - k_lj14_2.template modify(); - k_lj14_3.template modify(); - k_lj14_4.template modify(); + k_lj14_1.modify_host(); + k_lj14_2.modify_host(); + k_lj14_3.modify_host(); + k_lj14_4.modify_host(); k_lj14_1.template sync(); k_lj14_2.template sync(); @@ -547,12 +548,12 @@ void DihedralCharmmKokkos::read_restart(FILE *fp) k_weight.h_view[i] = weight[i]; } - k_k.template modify(); - k_multiplicity.template modify(); - k_shift.template modify(); - k_cos_shift.template modify(); - k_sin_shift.template modify(); - k_weight.template modify(); + k_k.modify_host(); + k_multiplicity.modify_host(); + k_shift.modify_host(); + k_cos_shift.modify_host(); + k_sin_shift.modify_host(); + k_weight.modify_host(); k_k.template sync(); k_multiplicity.template sync(); diff --git a/src/KOKKOS/dihedral_charmm_kokkos.h b/src/KOKKOS/dihedral_charmm_kokkos.h index dea251473b..74510ed515 100644 --- a/src/KOKKOS/dihedral_charmm_kokkos.h +++ b/src/KOKKOS/dihedral_charmm_kokkos.h @@ -104,6 +104,10 @@ class DihedralCharmmKokkos : public DihedralCharmm { const F_FLOAT &evdwl, const F_FLOAT &ecoul, const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const; + typedef typename KKDevice::value KKDeviceType; + Kokkos::DualView k_eatom; + Kokkos::DualView k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -114,9 +118,6 @@ class DihedralCharmmKokkos : public DihedralCharmm { typename AT::t_f_array f; typename AT::t_int_2d dihedrallist; - typedef typename KKDevice::value KKDeviceType; - Kokkos::DualView k_eatom; - Kokkos::DualView k_vatom; Kokkos::View > d_eatom; Kokkos::View > d_vatom; diff --git a/src/KOKKOS/dihedral_charmmfsw_kokkos.cpp b/src/KOKKOS/dihedral_charmmfsw_kokkos.cpp index aeb9b022a7..a3c000b3cf 100644 --- a/src/KOKKOS/dihedral_charmmfsw_kokkos.cpp +++ b/src/KOKKOS/dihedral_charmmfsw_kokkos.cpp @@ -47,6 +47,7 @@ static constexpr double TOLERANCE = 0.05; template DihedralCharmmfswKokkos::DihedralCharmmfswKokkos(LAMMPS *lmp) : DihedralCharmmfsw(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -122,7 +123,7 @@ void DihedralCharmmfswKokkos::compute(int eflag_in, int vflag_in) qqrd2e = force->qqrd2e; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -148,7 +149,7 @@ void DihedralCharmmfswKokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Dihedral problem"); @@ -181,20 +182,20 @@ void DihedralCharmmfswKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); k_eatom_pair.template modify(); - k_eatom_pair.template sync(); + k_eatom_pair.sync_host(); for (int i = 0; i < n; i++) force->pair->eatom[i] += k_eatom_pair.h_view(i); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); k_vatom_pair.template modify(); - k_vatom_pair.template sync(); + k_vatom_pair.sync_host(); for (int i = 0; i < n; i++) { force->pair->vatom[i][0] += k_vatom_pair.h_view(i,0); force->pair->vatom[i][1] += k_vatom_pair.h_view(i,1); @@ -379,16 +380,17 @@ void DihedralCharmmfswKokkos::operator()(TagDihedralCharmmfswCompute const F_FLOAT dely = x(i1,1) - x(i4,1); const F_FLOAT delz = x(i1,2) - x(i4,2); const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const F_FLOAT r = sqrt(rsq); const F_FLOAT r2inv = 1.0/rsq; const F_FLOAT r6inv = r2inv*r2inv*r2inv; F_FLOAT forcecoul; if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; - else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); + else if (dihedflag) forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); + else forcecoul = qqrd2e * q[i1]*q[i4]*(sqrt(r2inv) - r*cut_coulinv14*cut_coulinv14); const F_FLOAT forcelj = r6inv * (d_lj14_1(itype,jtype)*r6inv - d_lj14_2(itype,jtype)); const F_FLOAT fpair = d_weight[type] * (forcelj+forcecoul)*r2inv; - const F_FLOAT r = sqrt(rsq); F_FLOAT ecoul = 0.0; F_FLOAT evdwl = 0.0; F_FLOAT evdwl14_12, evdwl14_6; @@ -471,12 +473,12 @@ void DihedralCharmmfswKokkos::coeff(int narg, char **arg) k_weight.h_view[i] = weight[i]; } - k_k.template modify(); - k_multiplicity.template modify(); - k_shift.template modify(); - k_cos_shift.template modify(); - k_sin_shift.template modify(); - k_weight.template modify(); + k_k.modify_host(); + k_multiplicity.modify_host(); + k_shift.modify_host(); + k_cos_shift.modify_host(); + k_sin_shift.modify_host(); + k_weight.modify_host(); k_k.template sync(); k_multiplicity.template sync(); @@ -519,10 +521,10 @@ void DihedralCharmmfswKokkos::init_style() } } - k_lj14_1.template modify(); - k_lj14_2.template modify(); - k_lj14_3.template modify(); - k_lj14_4.template modify(); + k_lj14_1.modify_host(); + k_lj14_2.modify_host(); + k_lj14_3.modify_host(); + k_lj14_4.modify_host(); k_lj14_1.template sync(); k_lj14_2.template sync(); @@ -564,12 +566,12 @@ void DihedralCharmmfswKokkos::read_restart(FILE *fp) k_weight.h_view[i] = weight[i]; } - k_k.template modify(); - k_multiplicity.template modify(); - k_shift.template modify(); - k_cos_shift.template modify(); - k_sin_shift.template modify(); - k_weight.template modify(); + k_k.modify_host(); + k_multiplicity.modify_host(); + k_shift.modify_host(); + k_cos_shift.modify_host(); + k_sin_shift.modify_host(); + k_weight.modify_host(); k_k.template sync(); k_multiplicity.template sync(); diff --git a/src/KOKKOS/dihedral_charmmfsw_kokkos.h b/src/KOKKOS/dihedral_charmmfsw_kokkos.h index b1c65ae477..845d2192d7 100644 --- a/src/KOKKOS/dihedral_charmmfsw_kokkos.h +++ b/src/KOKKOS/dihedral_charmmfsw_kokkos.h @@ -67,6 +67,10 @@ class DihedralCharmmfswKokkos : public DihedralCharmmfsw { const F_FLOAT &evdwl, const F_FLOAT &ecoul, const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const; + typedef typename KKDevice::value KKDeviceType; + Kokkos::DualView k_eatom; + Kokkos::DualView k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -76,10 +80,6 @@ class DihedralCharmmfswKokkos : public DihedralCharmmfsw { typename AT::t_ffloat_1d_randomread q; typename AT::t_f_array f; typename AT::t_int_2d dihedrallist; - - typedef typename KKDevice::value KKDeviceType; - Kokkos::DualView k_eatom; - Kokkos::DualView k_vatom; Kokkos::View > d_eatom; Kokkos::View > d_vatom; diff --git a/src/KOKKOS/dihedral_class2_kokkos.cpp b/src/KOKKOS/dihedral_class2_kokkos.cpp index 204a6d0d1a..83c03d856a 100644 --- a/src/KOKKOS/dihedral_class2_kokkos.cpp +++ b/src/KOKKOS/dihedral_class2_kokkos.cpp @@ -38,6 +38,7 @@ static constexpr double SMALL = 0.001; template DihedralClass2Kokkos::DihedralClass2Kokkos(LAMMPS *lmp) : DihedralClass2(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -137,7 +138,7 @@ void DihedralClass2Kokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -163,7 +164,7 @@ void DihedralClass2Kokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Dihedral problem"); @@ -179,12 +180,12 @@ void DihedralClass2Kokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -786,44 +787,44 @@ void DihedralClass2Kokkos::coeff(int narg, char **arg) k_setflag_bb13t.h_view[i] = setflag_bb13t[i]; } - k_k1.template modify(); - k_k2.template modify(); - k_k3.template modify(); - k_phi1.template modify(); - k_phi2.template modify(); - k_phi3.template modify(); - k_mbt_f1.template modify(); - k_mbt_f2.template modify(); - k_mbt_f3.template modify(); - k_mbt_r0.template modify(); - k_ebt_f1_1.template modify(); - k_ebt_f2_1.template modify(); - k_ebt_f3_1.template modify(); - k_ebt_r0_1.template modify(); - k_ebt_f1_2.template modify(); - k_ebt_f2_2.template modify(); - k_ebt_f3_2.template modify(); - k_ebt_r0_2.template modify(); - k_at_f1_1.template modify(); - k_at_f2_1.template modify(); - k_at_f3_1.template modify(); - k_at_f1_2.template modify(); - k_at_f2_2.template modify(); - k_at_f3_2.template modify(); - k_at_theta0_1.template modify(); - k_at_theta0_2.template modify(); - k_aat_k.template modify(); - k_aat_theta0_1.template modify(); - k_aat_theta0_2.template modify(); - k_bb13t_k.template modify(); - k_bb13t_r10.template modify(); - k_bb13t_r30.template modify(); - k_setflag_d.template modify(); - k_setflag_mbt.template modify(); - k_setflag_ebt.template modify(); - k_setflag_at.template modify(); - k_setflag_aat.template modify(); - k_setflag_bb13t.template modify(); + k_k1.modify_host(); + k_k2.modify_host(); + k_k3.modify_host(); + k_phi1.modify_host(); + k_phi2.modify_host(); + k_phi3.modify_host(); + k_mbt_f1.modify_host(); + k_mbt_f2.modify_host(); + k_mbt_f3.modify_host(); + k_mbt_r0.modify_host(); + k_ebt_f1_1.modify_host(); + k_ebt_f2_1.modify_host(); + k_ebt_f3_1.modify_host(); + k_ebt_r0_1.modify_host(); + k_ebt_f1_2.modify_host(); + k_ebt_f2_2.modify_host(); + k_ebt_f3_2.modify_host(); + k_ebt_r0_2.modify_host(); + k_at_f1_1.modify_host(); + k_at_f2_1.modify_host(); + k_at_f3_1.modify_host(); + k_at_f1_2.modify_host(); + k_at_f2_2.modify_host(); + k_at_f3_2.modify_host(); + k_at_theta0_1.modify_host(); + k_at_theta0_2.modify_host(); + k_aat_k.modify_host(); + k_aat_theta0_1.modify_host(); + k_aat_theta0_2.modify_host(); + k_bb13t_k.modify_host(); + k_bb13t_r10.modify_host(); + k_bb13t_r30.modify_host(); + k_setflag_d.modify_host(); + k_setflag_mbt.modify_host(); + k_setflag_ebt.modify_host(); + k_setflag_at.modify_host(); + k_setflag_aat.modify_host(); + k_setflag_bb13t.modify_host(); } @@ -956,44 +957,44 @@ void DihedralClass2Kokkos::read_restart(FILE *fp) k_setflag_bb13t.h_view[i] = setflag_bb13t[i]; } - k_k1.template modify(); - k_k2.template modify(); - k_k3.template modify(); - k_phi1.template modify(); - k_phi2.template modify(); - k_phi3.template modify(); - k_mbt_f1.template modify(); - k_mbt_f2.template modify(); - k_mbt_f3.template modify(); - k_mbt_r0.template modify(); - k_ebt_f1_1.template modify(); - k_ebt_f2_1.template modify(); - k_ebt_f3_1.template modify(); - k_ebt_r0_1.template modify(); - k_ebt_f1_2.template modify(); - k_ebt_f2_2.template modify(); - k_ebt_f3_2.template modify(); - k_ebt_r0_2.template modify(); - k_at_f1_1.template modify(); - k_at_f2_1.template modify(); - k_at_f3_1.template modify(); - k_at_f1_2.template modify(); - k_at_f2_2.template modify(); - k_at_f3_2.template modify(); - k_at_theta0_1.template modify(); - k_at_theta0_2.template modify(); - k_aat_k.template modify(); - k_aat_theta0_1.template modify(); - k_aat_theta0_2.template modify(); - k_bb13t_k.template modify(); - k_bb13t_r10.template modify(); - k_bb13t_r30.template modify(); - k_setflag_d.template modify(); - k_setflag_mbt.template modify(); - k_setflag_ebt.template modify(); - k_setflag_at.template modify(); - k_setflag_aat.template modify(); - k_setflag_bb13t.template modify(); + k_k1.modify_host(); + k_k2.modify_host(); + k_k3.modify_host(); + k_phi1.modify_host(); + k_phi2.modify_host(); + k_phi3.modify_host(); + k_mbt_f1.modify_host(); + k_mbt_f2.modify_host(); + k_mbt_f3.modify_host(); + k_mbt_r0.modify_host(); + k_ebt_f1_1.modify_host(); + k_ebt_f2_1.modify_host(); + k_ebt_f3_1.modify_host(); + k_ebt_r0_1.modify_host(); + k_ebt_f1_2.modify_host(); + k_ebt_f2_2.modify_host(); + k_ebt_f3_2.modify_host(); + k_ebt_r0_2.modify_host(); + k_at_f1_1.modify_host(); + k_at_f2_1.modify_host(); + k_at_f3_1.modify_host(); + k_at_f1_2.modify_host(); + k_at_f2_2.modify_host(); + k_at_f3_2.modify_host(); + k_at_theta0_1.modify_host(); + k_at_theta0_2.modify_host(); + k_aat_k.modify_host(); + k_aat_theta0_1.modify_host(); + k_aat_theta0_2.modify_host(); + k_bb13t_k.modify_host(); + k_bb13t_r10.modify_host(); + k_bb13t_r30.modify_host(); + k_setflag_d.modify_host(); + k_setflag_mbt.modify_host(); + k_setflag_ebt.modify_host(); + k_setflag_at.modify_host(); + k_setflag_aat.modify_host(); + k_setflag_bb13t.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/dihedral_class2_kokkos.h b/src/KOKKOS/dihedral_class2_kokkos.h index 6e1dceb0cf..ddc79d21d9 100644 --- a/src/KOKKOS/dihedral_class2_kokkos.h +++ b/src/KOKKOS/dihedral_class2_kokkos.h @@ -60,6 +60,9 @@ class DihedralClass2Kokkos : public DihedralClass2 { const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -67,9 +70,6 @@ class DihedralClass2Kokkos : public DihedralClass2 { typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_int_2d dihedrallist; - - DAT::tdual_efloat_1d k_eatom; - DAT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; diff --git a/src/KOKKOS/dihedral_harmonic_kokkos.cpp b/src/KOKKOS/dihedral_harmonic_kokkos.cpp index 78860800be..05babd69b4 100644 --- a/src/KOKKOS/dihedral_harmonic_kokkos.cpp +++ b/src/KOKKOS/dihedral_harmonic_kokkos.cpp @@ -37,6 +37,7 @@ static constexpr double TOLERANCE = 0.05; template DihedralHarmonicKokkos::DihedralHarmonicKokkos(LAMMPS *lmp) : DihedralHarmonic(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -74,14 +75,18 @@ void DihedralHarmonicKokkos::compute(int eflag_in, int vflag_in) // reallocate per-atom arrays if necessary if (eflag_atom) { + if(k_eatom.extent(0) < maxeatom) { memoryKK->destroy_kokkos(k_eatom,eatom); memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"dihedral:eatom"); d_eatom = k_eatom.view(); + } else Kokkos::deep_copy(d_eatom,0.0); } if (vflag_atom) { + if(k_vatom.extent(0) < maxvatom) { memoryKK->destroy_kokkos(k_vatom,vatom); memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"dihedral:vatom"); d_vatom = k_vatom.view(); + } else Kokkos::deep_copy(d_vatom,0.0); } k_k.template sync(); @@ -99,7 +104,7 @@ void DihedralHarmonicKokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -125,7 +130,7 @@ void DihedralHarmonicKokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Dihedral problem"); @@ -141,12 +146,12 @@ void DihedralHarmonicKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -362,11 +367,11 @@ void DihedralHarmonicKokkos::coeff(int narg, char **arg) k_multiplicity.h_view[i] = multiplicity[i]; } - k_k.template modify(); - k_cos_shift.template modify(); - k_sin_shift.template modify(); - k_sign.template modify(); - k_multiplicity.template modify(); + k_k.modify_host(); + k_cos_shift.modify_host(); + k_sin_shift.modify_host(); + k_sign.modify_host(); + k_multiplicity.modify_host(); } /* ---------------------------------------------------------------------- @@ -387,11 +392,11 @@ void DihedralHarmonicKokkos::read_restart(FILE *fp) k_multiplicity.h_view[i] = multiplicity[i]; } - k_k.template modify(); - k_cos_shift.template modify(); - k_sin_shift.template modify(); - k_sign.template modify(); - k_multiplicity.template modify(); + k_k.modify_host(); + k_cos_shift.modify_host(); + k_sin_shift.modify_host(); + k_sign.modify_host(); + k_multiplicity.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/dihedral_harmonic_kokkos.h b/src/KOKKOS/dihedral_harmonic_kokkos.h index e73f19afd1..1ad62398f7 100644 --- a/src/KOKKOS/dihedral_harmonic_kokkos.h +++ b/src/KOKKOS/dihedral_harmonic_kokkos.h @@ -60,6 +60,9 @@ class DihedralHarmonicKokkos : public DihedralHarmonic { const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -67,9 +70,6 @@ class DihedralHarmonicKokkos : public DihedralHarmonic { typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_int_2d dihedrallist; - - DAT::tdual_efloat_1d k_eatom; - DAT::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; diff --git a/src/KOKKOS/dihedral_hybrid_kokkos.cpp b/src/KOKKOS/dihedral_hybrid_kokkos.cpp new file mode 100644 index 0000000000..88dbeaf13b --- /dev/null +++ b/src/KOKKOS/dihedral_hybrid_kokkos.cpp @@ -0,0 +1,225 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain 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 "dihedral_hybrid_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "kokkos.h" +#include "memory_kokkos.h" +#include "neighbor_kokkos.h" + +#include + +using namespace LAMMPS_NS; + +#define EXTRA 1000 + +/* ---------------------------------------------------------------------- */ + +DihedralHybridKokkos::DihedralHybridKokkos(LAMMPS *lmp) : DihedralHybrid(lmp) +{ + kokkosable = 1; + + atomKK = (AtomKokkos *) atom; + neighborKK = (NeighborKokkos *) neighbor; + + execution_space = Device; + + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- */ + +DihedralHybridKokkos::~DihedralHybridKokkos() +{ + deallocate(); +} + +/* ---------------------------------------------------------------------- */ + +void DihedralHybridKokkos::compute(int eflag, int vflag) +{ + // save ptrs to original dihedrallist + + int ndihedrallist_orig = neighbor->ndihedrallist; + neighborKK->k_dihedrallist.sync_device(); + auto k_dihedrallist_orig = neighborKK->k_dihedrallist; + auto d_dihedrallist_orig = k_dihedrallist_orig.d_view; + auto d_ndihedrallist = k_ndihedrallist.d_view; + auto h_ndihedrallist = k_ndihedrallist.h_view; + + // if this is re-neighbor step, create sub-style dihedrallists + // ndihedrallist[] = length of each sub-style list + // realloc sub-style dihedrallist if necessary + // load sub-style dihedrallist with 3 values from original dihedrallist + + if (neighbor->ago == 0) { + Kokkos::deep_copy(d_ndihedrallist,0); + + k_map.sync_device(); + auto d_map = k_map.d_view; + + Kokkos::parallel_for(ndihedrallist_orig,LAMMPS_LAMBDA(int i) { + const int m = d_map[d_dihedrallist_orig(i,4)]; + if (m >= 0) Kokkos::atomic_increment(&d_ndihedrallist[m]); + }); + + k_ndihedrallist.modify_device(); + k_ndihedrallist.sync_host(); + + maxdihedral_all = 0; + for (int m = 0; m < nstyles; m++) + if (h_ndihedrallist[m] > maxdihedral_all) + maxdihedral_all = h_ndihedrallist[m] + EXTRA; + + if (k_dihedrallist.d_view.extent(1) < maxdihedral_all) + MemKK::realloc_kokkos(k_dihedrallist, "dihedral_hybrid:dihedrallist", nstyles, maxdihedral_all, 5); + auto d_dihedrallist = k_dihedrallist.d_view; + + Kokkos::deep_copy(d_ndihedrallist,0); + + Kokkos::parallel_for(ndihedrallist_orig,LAMMPS_LAMBDA(int i) { + const int m = d_map[d_dihedrallist_orig(i,4)]; + if (m < 0) return; + const int n = Kokkos::atomic_fetch_add(&d_ndihedrallist[m],1); + d_dihedrallist(m,n,0) = d_dihedrallist_orig(i,0); + d_dihedrallist(m,n,1) = d_dihedrallist_orig(i,1); + d_dihedrallist(m,n,2) = d_dihedrallist_orig(i,2); + d_dihedrallist(m,n,3) = d_dihedrallist_orig(i,3); + d_dihedrallist(m,n,4) = d_dihedrallist_orig(i,4); + }); + } + + // call each sub-style's compute function + // set neighbor->dihedrallist to sub-style dihedrallist before call + // accumulate sub-style global/peratom energy/virial in hybrid + + ev_init(eflag, vflag); + + k_ndihedrallist.modify_device(); + k_ndihedrallist.sync_host(); + + for (int m = 0; m < nstyles; m++) { + neighbor->ndihedrallist = h_ndihedrallist[m]; + auto k_dihedrallist_m = Kokkos::subview(k_dihedrallist,m,Kokkos::ALL,Kokkos::ALL); + k_dihedrallist_m.modify_device(); + neighborKK->k_dihedrallist = k_dihedrallist_m; + + auto style = styles[m]; + atomKK->sync(style->execution_space,style->datamask_read); + style->compute(eflag, vflag); + atomKK->modified(style->execution_space,style->datamask_modify); + + if (eflag_global) energy += style->energy; + if (vflag_global) + for (int n = 0; n < 6; n++) virial[n] += style->virial[n]; + + if (eflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double *eatom_substyle = styles[m]->eatom; + for (int i = 0; i < n; i++) eatom[i] += eatom_substyle[i]; + } + if (vflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double **vatom_substyle = styles[m]->vatom; + for (int i = 0; i < n; i++) + for (int j = 0; j < 6; j++) vatom[i][j] += vatom_substyle[i][j]; + } + if (cvflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double **cvatom_substyle = styles[m]->cvatom; + for (int i = 0; i < n; i++) + for (int j = 0; j < 9; j++) cvatom[i][j] += cvatom_substyle[i][j]; + } + } + + // restore ptrs to original dihedrallist + + neighbor->ndihedrallist = ndihedrallist_orig; + neighborKK->k_dihedrallist = k_dihedrallist_orig; +} + +/* ---------------------------------------------------------------------- */ + +void DihedralHybridKokkos::allocate() +{ + allocated = 1; + int np1 = atom->ndihedraltypes + 1; + + memoryKK->create_kokkos(k_map, map, np1, "dihedral:map"); + memory->create(setflag, np1, "dihedral:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; + + k_ndihedrallist = DAT::tdual_int_1d("dihedral:ndihedrallist", nstyles); +} + +/* ---------------------------------------------------------------------- */ + +void DihedralHybridKokkos::deallocate() +{ + if (!allocated) return; + + allocated = 0; + + memory->destroy(setflag); + memoryKK->destroy_kokkos(k_map,map); +} + +/* ---------------------------------------------------------------------- + set coeffs for one type +---------------------------------------------------------------------- */ + +void DihedralHybridKokkos::coeff(int narg, char **arg) +{ + DihedralHybrid::coeff(narg,arg); + + k_map.modify_host(); +} + +/* ---------------------------------------------------------------------- */ + +void DihedralHybridKokkos::init_style() +{ + DihedralHybrid::init_style(); + + for (int m = 0; m < nstyles; m++) { + if (!styles[m]->kokkosable) + error->all(FLERR,"Must use only Kokkos-enabled dihedral styles with dihedral_style hybrid/kk"); + + if (styles[m]->execution_space == Host) + lmp->kokkos->allow_overlap = 0; + } +} + +/* ---------------------------------------------------------------------- + memory usage +------------------------------------------------------------------------- */ + +double DihedralHybridKokkos::memory_usage() +{ + double bytes = (double) maxeatom * sizeof(double); + bytes += (double) maxvatom * 6 * sizeof(double); + bytes += (double) maxcvatom * 9 * sizeof(double); + for (int m = 0; m < nstyles; m++) bytes += (double) maxdihedral_all * 5 * sizeof(int); + for (int m = 0; m < nstyles; m++) + if (styles[m]) bytes += styles[m]->memory_usage(); + return bytes; +} diff --git a/src/KOKKOS/dihedral_hybrid_kokkos.h b/src/KOKKOS/dihedral_hybrid_kokkos.h new file mode 100644 index 0000000000..63a59505af --- /dev/null +++ b/src/KOKKOS/dihedral_hybrid_kokkos.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 DIHEDRAL_CLASS +// clang-format off +DihedralStyle(hybrid/kk,DihedralHybridKokkos); +DihedralStyle(hybrid/kk/device,DihedralHybridKokkos); +DihedralStyle(hybrid/kk/host,DihedralHybridKokkos); +// clang-format on +#else + +// clang-format off +#ifndef LMP_DIHEDRAL_HYBRID_KOKKOS_H +#define LMP_DIHEDRAL_HYBRID_KOKKOS_H + +#include "dihedral_hybrid.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class DihedralHybridKokkos : public DihedralHybrid { + friend class Force; + + public: + DihedralHybridKokkos(class LAMMPS *); + ~DihedralHybridKokkos() override; + void compute(int, int) override; + void coeff(int, char **) override; + void init_style() override; + double memory_usage() override; + + private: + int maxdihedral_all; + + class NeighborKokkos *neighborKK; + + DAT::tdual_int_1d k_map; // which style each dihedral type points to + DAT::tdual_int_1d k_ndihedrallist; // # of dihedrals in sub-style dihedrallists + DAT::tdual_int_3d k_dihedrallist; // dihedrallist for each sub-style + + void allocate() override; + void deallocate() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/KOKKOS/dihedral_opls_kokkos.cpp b/src/KOKKOS/dihedral_opls_kokkos.cpp index ce7502b25a..b45437b781 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.cpp +++ b/src/KOKKOS/dihedral_opls_kokkos.cpp @@ -39,6 +39,7 @@ static constexpr double SMALLER = 0.00001; template DihedralOPLSKokkos::DihedralOPLSKokkos(LAMMPS *lmp) : DihedralOPLS(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -100,7 +101,7 @@ void DihedralOPLSKokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -126,7 +127,7 @@ void DihedralOPLSKokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Dihedral problem"); @@ -142,12 +143,12 @@ void DihedralOPLSKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -372,10 +373,10 @@ void DihedralOPLSKokkos::coeff(int narg, char **arg) k_k4.h_view[i] = k4[i]; } - k_k1.template modify(); - k_k2.template modify(); - k_k3.template modify(); - k_k4.template modify(); + k_k1.modify_host(); + k_k2.modify_host(); + k_k3.modify_host(); + k_k4.modify_host(); } /* ---------------------------------------------------------------------- @@ -395,10 +396,10 @@ void DihedralOPLSKokkos::read_restart(FILE *fp) k_k4.h_view[i] = k4[i]; } - k_k1.template modify(); - k_k2.template modify(); - k_k3.template modify(); - k_k4.template modify(); + k_k1.modify_host(); + k_k2.modify_host(); + k_k3.modify_host(); + k_k4.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/dihedral_opls_kokkos.h b/src/KOKKOS/dihedral_opls_kokkos.h index 886f4abcae..20c5083ad9 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.h +++ b/src/KOKKOS/dihedral_opls_kokkos.h @@ -60,16 +60,15 @@ class DihedralOPLSKokkos : public DihedralOPLS { const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; - typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_int_2d dihedrallist; - - DAT::tdual_efloat_1d k_eatom; - DAT::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; diff --git a/src/KOKKOS/improper_class2_kokkos.cpp b/src/KOKKOS/improper_class2_kokkos.cpp index 862ba2a52f..1aee9d2144 100644 --- a/src/KOKKOS/improper_class2_kokkos.cpp +++ b/src/KOKKOS/improper_class2_kokkos.cpp @@ -34,6 +34,7 @@ static constexpr double SMALL = 0.001; template ImproperClass2Kokkos::ImproperClass2Kokkos(LAMMPS *lmp) : ImproperClass2(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -110,7 +111,7 @@ void ImproperClass2Kokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -139,7 +140,7 @@ void ImproperClass2Kokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Improper problem"); @@ -171,12 +172,12 @@ void ImproperClass2Kokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -918,17 +919,17 @@ void ImproperClass2Kokkos::coeff(int narg, char **arg) k_setflag_aa.h_view[i] = setflag_aa[i]; } - k_k0.template modify(); - k_chi0.template modify(); - k_aa_k1.template modify(); - k_aa_k2.template modify(); - k_aa_k3.template modify(); - k_aa_theta0_1.template modify(); - k_aa_theta0_2.template modify(); - k_aa_theta0_3 .template modify(); - k_setflag.template modify(); - k_setflag_i.template modify(); - k_setflag_aa.template modify(); + k_k0.modify_host(); + k_chi0.modify_host(); + k_aa_k1.modify_host(); + k_aa_k2.modify_host(); + k_aa_k3.modify_host(); + k_aa_theta0_1.modify_host(); + k_aa_theta0_2.modify_host(); + k_aa_theta0_3 .modify_host(); + k_setflag.modify_host(); + k_setflag_i.modify_host(); + k_setflag_aa.modify_host(); } /* ---------------------------------------------------------------------- @@ -979,17 +980,17 @@ void ImproperClass2Kokkos::read_restart(FILE *fp) k_setflag_aa.h_view[i] = setflag_aa[i]; } - k_k0.template modify(); - k_chi0.template modify(); - k_aa_k1.template modify(); - k_aa_k2.template modify(); - k_aa_k3.template modify(); - k_aa_theta0_1.template modify(); - k_aa_theta0_2.template modify(); - k_aa_theta0_3 .template modify(); - k_setflag.template modify(); - k_setflag_i.template modify(); - k_setflag_aa.template modify(); + k_k0.modify_host(); + k_chi0.modify_host(); + k_aa_k1.modify_host(); + k_aa_k2.modify_host(); + k_aa_k3.modify_host(); + k_aa_theta0_1.modify_host(); + k_aa_theta0_2.modify_host(); + k_aa_theta0_3 .modify_host(); + k_setflag.modify_host(); + k_setflag_i.modify_host(); + k_setflag_aa.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/improper_class2_kokkos.h b/src/KOKKOS/improper_class2_kokkos.h index da939b69b0..7a55c8a5f8 100644 --- a/src/KOKKOS/improper_class2_kokkos.h +++ b/src/KOKKOS/improper_class2_kokkos.h @@ -71,6 +71,9 @@ class ImproperClass2Kokkos : public ImproperClass2 { const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + protected: class NeighborKokkos *neighborKK; @@ -78,9 +81,6 @@ class ImproperClass2Kokkos : public ImproperClass2 { typename AT::t_x_array_randomread x; typename Kokkos::View::value,Kokkos::MemoryTraits > f; typename AT::t_int_2d improperlist; - - DAT::tdual_efloat_1d k_eatom; - DAT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; diff --git a/src/KOKKOS/improper_harmonic_kokkos.cpp b/src/KOKKOS/improper_harmonic_kokkos.cpp index a075238f22..eafa7a08ec 100644 --- a/src/KOKKOS/improper_harmonic_kokkos.cpp +++ b/src/KOKKOS/improper_harmonic_kokkos.cpp @@ -36,6 +36,7 @@ static constexpr double SMALL = 0.001; template ImproperHarmonicKokkos::ImproperHarmonicKokkos(LAMMPS *lmp) : ImproperHarmonic(lmp) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; neighborKK = (NeighborKokkos *) neighbor; execution_space = ExecutionSpaceFromDevice::space; @@ -73,18 +74,18 @@ void ImproperHarmonicKokkos::compute(int eflag_in, int vflag_in) // reallocate per-atom arrays if necessary if (eflag_atom) { - //if(k_eatom.extent(0)destroy_kokkos(k_eatom,eatom); memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"improper:eatom"); d_eatom = k_eatom.template view(); - //} + } else Kokkos::deep_copy(d_eatom,0.0); } if (vflag_atom) { - //if(k_vatom.extent(0)destroy_kokkos(k_vatom,vatom); memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"improper:vatom"); d_vatom = k_vatom.template view(); - //} + } else Kokkos::deep_copy(d_vatom,0.0); } //atomKK->sync(execution_space,datamask_read); @@ -102,7 +103,7 @@ void ImproperHarmonicKokkos::compute(int eflag_in, int vflag_in) newton_bond = force->newton_bond; h_warning_flag() = 0; - k_warning_flag.template modify(); + k_warning_flag.modify_host(); k_warning_flag.template sync(); copymode = 1; @@ -128,7 +129,7 @@ void ImproperHarmonicKokkos::compute(int eflag_in, int vflag_in) // error check k_warning_flag.template modify(); - k_warning_flag.template sync(); + k_warning_flag.sync_host(); if (h_warning_flag()) error->warning(FLERR,"Dihedral problem"); @@ -144,12 +145,12 @@ void ImproperHarmonicKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { k_eatom.template modify(); - k_eatom.template sync(); + k_eatom.sync_host(); } if (vflag_atom) { k_vatom.template modify(); - k_vatom.template sync(); + k_vatom.sync_host(); } copymode = 0; @@ -324,8 +325,8 @@ void ImproperHarmonicKokkos::coeff(int narg, char **arg) k_chi.h_view[i] = chi[i]; } - k_k.template modify(); - k_chi.template modify(); + k_k.modify_host(); + k_chi.modify_host(); } /* ---------------------------------------------------------------------- @@ -343,8 +344,8 @@ void ImproperHarmonicKokkos::read_restart(FILE *fp) k_chi.h_view[i] = chi[i]; } - k_k.template modify(); - k_chi.template modify(); + k_k.modify_host(); + k_chi.modify_host(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/improper_harmonic_kokkos.h b/src/KOKKOS/improper_harmonic_kokkos.h index 8bd206aaf0..ad31447383 100644 --- a/src/KOKKOS/improper_harmonic_kokkos.h +++ b/src/KOKKOS/improper_harmonic_kokkos.h @@ -60,17 +60,17 @@ class ImproperHarmonicKokkos : public ImproperHarmonic { const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + typedef typename KKDevice::value KKDeviceType; + Kokkos::DualView k_eatom; + Kokkos::DualView k_vatom; + protected: class NeighborKokkos *neighborKK; - typedef typename KKDevice::value KKDeviceType; typename AT::t_x_array_randomread x; typename Kokkos::View > f; typename AT::t_int_2d improperlist; - - Kokkos::DualView k_eatom; - Kokkos::DualView k_vatom; Kokkos::View > d_eatom; Kokkos::View > d_vatom; diff --git a/src/KOKKOS/improper_hybrid_kokkos.cpp b/src/KOKKOS/improper_hybrid_kokkos.cpp new file mode 100644 index 0000000000..bfa55978cc --- /dev/null +++ b/src/KOKKOS/improper_hybrid_kokkos.cpp @@ -0,0 +1,226 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain 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 "improper_hybrid_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "kokkos.h" +#include "memory_kokkos.h" +#include "neighbor_kokkos.h" + +#include + +using namespace LAMMPS_NS; + +#define EXTRA 1000 + +/* ---------------------------------------------------------------------- */ + +ImproperHybridKokkos::ImproperHybridKokkos(LAMMPS *lmp) : ImproperHybrid(lmp) +{ + kokkosable = 1; + + atomKK = (AtomKokkos *) atom; + neighborKK = (NeighborKokkos *) neighbor; + + execution_space = Device; + + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- */ + +ImproperHybridKokkos::~ImproperHybridKokkos() +{ + deallocate(); +} + +/* ---------------------------------------------------------------------- */ + +void ImproperHybridKokkos::compute(int eflag, int vflag) +{ + + // save ptrs to original improperlist + + int nimproperlist_orig = neighbor->nimproperlist; + neighborKK->k_improperlist.sync_device(); + auto k_improperlist_orig = neighborKK->k_improperlist; + auto d_improperlist_orig = k_improperlist_orig.d_view; + auto d_nimproperlist = k_nimproperlist.d_view; + auto h_nimproperlist = k_nimproperlist.h_view; + + // if this is re-neighbor step, create sub-style improperlists + // nimproperlist[] = length of each sub-style list + // realloc sub-style improperlist if necessary + // load sub-style improperlist with 3 values from original improperlist + + if (neighbor->ago == 0) { + Kokkos::deep_copy(d_nimproperlist,0); + + k_map.sync_device(); + auto d_map = k_map.d_view; + + Kokkos::parallel_for(nimproperlist_orig,LAMMPS_LAMBDA(int i) { + const int m = d_map[d_improperlist_orig(i,4)]; + if (m >= 0) Kokkos::atomic_increment(&d_nimproperlist[m]); + }); + + k_nimproperlist.modify_device(); + k_nimproperlist.sync_host(); + + maximproper_all = 0; + for (int m = 0; m < nstyles; m++) + if (h_nimproperlist[m] > maximproper_all) + maximproper_all = h_nimproperlist[m] + EXTRA; + + if (k_improperlist.d_view.extent(1) < maximproper_all) + MemKK::realloc_kokkos(k_improperlist, "improper_hybrid:improperlist", nstyles, maximproper_all, 5); + auto d_improperlist = k_improperlist.d_view; + + Kokkos::deep_copy(d_nimproperlist,0); + + Kokkos::parallel_for(nimproperlist_orig,LAMMPS_LAMBDA(int i) { + const int m = d_map[d_improperlist_orig(i,4)]; + if (m < 0) return; + const int n = Kokkos::atomic_fetch_add(&d_nimproperlist[m],1); + d_improperlist(m,n,0) = d_improperlist_orig(i,0); + d_improperlist(m,n,1) = d_improperlist_orig(i,1); + d_improperlist(m,n,2) = d_improperlist_orig(i,2); + d_improperlist(m,n,3) = d_improperlist_orig(i,3); + d_improperlist(m,n,4) = d_improperlist_orig(i,4); + }); + } + + // call each sub-style's compute function + // set neighbor->improperlist to sub-style improperlist before call + // accumulate sub-style global/peratom energy/virial in hybrid + + ev_init(eflag, vflag); + + k_nimproperlist.modify_device(); + k_nimproperlist.sync_host(); + + for (int m = 0; m < nstyles; m++) { + neighbor->nimproperlist = h_nimproperlist[m]; + auto k_improperlist_m = Kokkos::subview(k_improperlist,m,Kokkos::ALL,Kokkos::ALL); + k_improperlist_m.modify_device(); + neighborKK->k_improperlist = k_improperlist_m; + + auto style = styles[m]; + atomKK->sync(style->execution_space,style->datamask_read); + style->compute(eflag, vflag); + atomKK->modified(style->execution_space,style->datamask_modify); + + if (eflag_global) energy += style->energy; + if (vflag_global) + for (int n = 0; n < 6; n++) virial[n] += style->virial[n]; + + if (eflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double *eatom_substyle = styles[m]->eatom; + for (int i = 0; i < n; i++) eatom[i] += eatom_substyle[i]; + } + if (vflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double **vatom_substyle = styles[m]->vatom; + for (int i = 0; i < n; i++) + for (int j = 0; j < 6; j++) vatom[i][j] += vatom_substyle[i][j]; + } + if (cvflag_atom) { + int n = atom->nlocal; + if (force->newton_bond) n += atom->nghost; + double **cvatom_substyle = styles[m]->cvatom; + for (int i = 0; i < n; i++) + for (int j = 0; j < 9; j++) cvatom[i][j] += cvatom_substyle[i][j]; + } + } + + // restore ptrs to original improperlist + + neighbor->nimproperlist = nimproperlist_orig; + neighborKK->k_improperlist = k_improperlist_orig; +} + +/* ---------------------------------------------------------------------- */ + +void ImproperHybridKokkos::allocate() +{ + allocated = 1; + int np1 = atom->nimpropertypes + 1; + + memoryKK->create_kokkos(k_map, map, np1, "improper:map"); + memory->create(setflag, np1, "improper:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; + + k_nimproperlist = DAT::tdual_int_1d("improper:nimproperlist", nstyles); +} + +/* ---------------------------------------------------------------------- */ + +void ImproperHybridKokkos::deallocate() +{ + if (!allocated) return; + + allocated = 0; + + memory->destroy(setflag); + memoryKK->destroy_kokkos(k_map,map); +} + +/* ---------------------------------------------------------------------- + set coeffs for one type +---------------------------------------------------------------------- */ + +void ImproperHybridKokkos::coeff(int narg, char **arg) +{ + ImproperHybrid::coeff(narg,arg); + + k_map.modify_host(); +} + +/* ---------------------------------------------------------------------- */ + +void ImproperHybridKokkos::init_style() +{ + ImproperHybrid::init_style(); + + for (int m = 0; m < nstyles; m++) { + if (!styles[m]->kokkosable) + error->all(FLERR,"Must use only Kokkos-enabled improper styles with improper_style hybrid/kk"); + + if (styles[m]->execution_space == Host) + lmp->kokkos->allow_overlap = 0; + } +} + +/* ---------------------------------------------------------------------- + memory usage +------------------------------------------------------------------------- */ + +double ImproperHybridKokkos::memory_usage() +{ + double bytes = (double) maxeatom * sizeof(double); + bytes += (double) maxvatom * 6 * sizeof(double); + bytes += (double) maxcvatom * 9 * sizeof(double); + for (int m = 0; m < nstyles; m++) bytes += (double) maximproper_all * 5 * sizeof(int); + for (int m = 0; m < nstyles; m++) + if (styles[m]) bytes += styles[m]->memory_usage(); + return bytes; +} diff --git a/src/KOKKOS/improper_hybrid_kokkos.h b/src/KOKKOS/improper_hybrid_kokkos.h new file mode 100644 index 0000000000..78bafe5df6 --- /dev/null +++ b/src/KOKKOS/improper_hybrid_kokkos.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 IMPROPER_CLASS +// clang-format off +ImproperStyle(hybrid/kk,ImproperHybridKokkos); +ImproperStyle(hybrid/kk/device,ImproperHybridKokkos); +ImproperStyle(hybrid/kk/host,ImproperHybridKokkos); +// clang-format on +#else + +// clang-format off +#ifndef LMP_IMPROPER_HYBRID_KOKKOS_H +#define LMP_IMPROPER_HYBRID_KOKKOS_H + +#include "improper_hybrid.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class ImproperHybridKokkos : public ImproperHybrid { + friend class Force; + + public: + ImproperHybridKokkos(class LAMMPS *); + ~ImproperHybridKokkos() override; + void compute(int, int) override; + void coeff(int, char **) override; + void init_style() override; + double memory_usage() override; + + private: + int maximproper_all; + + class NeighborKokkos *neighborKK; + + DAT::tdual_int_1d k_map; // which style each improper type points to + DAT::tdual_int_1d k_nimproperlist; // # of impropers in sub-style improperlists + DAT::tdual_int_3d k_improperlist; // improperlist for each sub-style + + void allocate() override; + void deallocate() override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.cpp index c07a089a35..1c769e82a6 100644 --- a/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.cpp @@ -13,7 +13,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Mitch Murphy (alphataubio) + Contributing author: Mitch Murphy (alphataubio@gmail.com) Based on serial kspace lj-fsw sections (force-switched) provided by Robert Meissner and Lucio Colombi Ciacchi of Bremen University, Germany, @@ -463,7 +463,6 @@ double PairLJCharmmfswCoulLongKokkos::init_one(int i, int j) k_params.h_view(i,j).lj2 = lj2[i][j]; k_params.h_view(i,j).lj3 = lj3[i][j]; k_params.h_view(i,j).lj4 = lj4[i][j]; - //k_params.h_view(i,j).offset = offset[i][j]; k_params.h_view(i,j).cut_ljsq = cut_ljsq; k_params.h_view(i,j).cut_coulsq = cut_coulsq; diff --git a/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.h b/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.h index 7533f40dbc..df5c70298a 100644 --- a/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.h +++ b/src/KOKKOS/pair_lj_charmmfsw_coul_long_kokkos.h @@ -48,30 +48,25 @@ class PairLJCharmmfswCoulLongKokkos : public PairLJCharmmfswCoulLong { protected: template KOKKOS_INLINE_FUNCTION - F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, - const int& itype, const int& jtype) const; + F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, const int& jtype) const; template KOKKOS_INLINE_FUNCTION - F_FLOAT compute_fcoul(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, + F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_fcoul(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, const int& jtype, const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const; template KOKKOS_INLINE_FUNCTION - F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, - const int& itype, const int& jtype) const; - - template - KOKKOS_INLINE_FUNCTION - F_FLOAT compute_ecoul(const F_FLOAT& rsq, const int& i, const int&j, - const int& itype, const int& jtype, const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const; + F_FLOAT compute_ecoul(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, + const int& jtype, const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const; Kokkos::DualView k_params; - typename Kokkos::DualView::t_dev_const_um params; - // hardwired to space for 12 atom types - params_lj_coul m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; - + typename Kokkos::DualView::t_dev_const_um params; + params_lj_coul m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; // hardwired to space for 12 atom types F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; F_FLOAT m_cut_ljsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; F_FLOAT m_cut_coulsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; @@ -100,8 +95,8 @@ class PairLJCharmmfswCoulLongKokkos : public PairLJCharmmfswCoulLong { int neighflag; int nlocal,nall,eflag,vflag; - double special_coul[4]; double special_lj[4]; + double special_coul[4]; double qqrd2e; void allocate() override; diff --git a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp index 5124d40505..f2d22e5cc5 100644 --- a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp @@ -76,7 +76,6 @@ void PairLJCutCoulLongKokkos::compute(int eflag_in, int vflag_in) ev_init(eflag,vflag,0); - // reallocate per-atom arrays if necessary if (eflag_atom) { @@ -125,11 +124,11 @@ void PairLJCutCoulLongKokkos::compute(int eflag_in, int vflag_in) ev = pair_compute,CoulLongTable<0> > (this,(NeighListKokkos*)list); - if (eflag) { eng_vdwl += ev.evdwl; eng_coul += ev.ecoul; } + if (vflag_global) { virial[0] += ev.v[0]; virial[1] += ev.v[1]; diff --git a/src/KOKKOS/pair_lj_spica_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_spica_coul_long_kokkos.cpp new file mode 100644 index 0000000000..63756ed8de --- /dev/null +++ b/src/KOKKOS/pair_lj_spica_coul_long_kokkos.cpp @@ -0,0 +1,503 @@ +// 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: Mitch Murphy (alphataubio@gmail.com) +------------------------------------------------------------------------- */ + +#include "pair_lj_spica_coul_long_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "error.h" +#include "ewald_const.h" +#include "force.h" +#include "kokkos.h" +#include "memory_kokkos.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "respa.h" +#include "update.h" + +#include "lj_spica_common.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace LJSPICAParms; +using namespace EwaldConst; + +/* ---------------------------------------------------------------------- */ + +template +PairLJSPICACoulLongKokkos::PairLJSPICACoulLongKokkos(LAMMPS *lmp) : PairLJSPICACoulLong(lmp) +{ + respa_enable = 0; + + kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; +} + +/* ---------------------------------------------------------------------- */ + +template +PairLJSPICACoulLongKokkos::~PairLJSPICACoulLongKokkos() +{ + if (copymode) return; + + if (allocated) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->destroy_kokkos(k_vatom,vatom); + memoryKK->destroy_kokkos(k_cutsq,cutsq); + memoryKK->destroy_kokkos(k_cut_ljsq,cut_ljsq); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJSPICACoulLongKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (neighflag == FULL) no_virial_fdotr_compute = 1; + + ev_init(eflag,vflag,0); + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); + d_eatom = k_eatom.view(); + } + if (vflag_atom) { + memoryKK->destroy_kokkos(k_vatom,vatom); + memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom"); + d_vatom = k_vatom.view(); + } + + atomKK->sync(execution_space,datamask_read); + k_cutsq.template sync(); + k_cut_ljsq.template sync(); + k_params.template sync(); + if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + else atomKK->modified(execution_space,F_MASK); + + x = atomKK->k_x.view(); + c_x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + q = atomKK->k_q.view(); + type = atomKK->k_type.view(); + nlocal = atom->nlocal; + nall = atom->nlocal + atom->nghost; + special_lj[0] = force->special_lj[0]; + special_lj[1] = force->special_lj[1]; + special_lj[2] = force->special_lj[2]; + special_lj[3] = force->special_lj[3]; + special_coul[0] = force->special_coul[0]; + special_coul[1] = force->special_coul[1]; + special_coul[2] = force->special_coul[2]; + special_coul[3] = force->special_coul[3]; + qqrd2e = force->qqrd2e; + newton_pair = force->newton_pair; + + // loop over neighbors of my atoms + + copymode = 1; + + EV_FLOAT ev; + if (ncoultablebits) + ev = pair_compute,CoulLongTable<1> > + (this,(NeighListKokkos*)list); + else + ev = pair_compute,CoulLongTable<0> > + (this,(NeighListKokkos*)list); + + if (eflag) { + eng_vdwl += ev.evdwl; + eng_coul += ev.ecoul; + } + + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + copymode = 0; +} + +/* ---------------------------------------------------------------------- + compute pair force between atoms i and j + ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairLJSPICACoulLongKokkos:: +compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + (void) j; + const F_FLOAT r2inv = 1.0/rsq; + const int ljt = (STACKPARAMS?m_params[itype][jtype].lj_type:params(itype,jtype).lj_type); + + const F_FLOAT lj_1 = (STACKPARAMS?m_params[itype][jtype].lj1:params(itype,jtype).lj1); + const F_FLOAT lj_2 = (STACKPARAMS?m_params[itype][jtype].lj2:params(itype,jtype).lj2); + + const F_FLOAT r4inv=r2inv*r2inv; + const F_FLOAT r6inv=r2inv*r4inv; + const F_FLOAT a = ljt==LJ12_4?r4inv:(ljt==LJ12_5?r4inv*sqrt(r2inv):r6inv); + const F_FLOAT b = ljt==LJ12_4?r4inv:(ljt==LJ9_6?1.0/sqrt(r2inv):(ljt==LJ12_5?r2inv*sqrt(r2inv):r2inv)); + return a* ( lj_1*r6inv*b - lj_2 * r2inv); +} + +/* ---------------------------------------------------------------------- + compute pair potential energy between atoms i and j + ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairLJSPICACoulLongKokkos:: +compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + (void) j; + const F_FLOAT r2inv = 1.0/rsq; + const int ljt = (STACKPARAMS?m_params[itype][jtype].lj_type:params(itype,jtype).lj_type); + + const F_FLOAT lj_3 = (STACKPARAMS?m_params[itype][jtype].lj3:params(itype,jtype).lj3); + const F_FLOAT lj_4 = (STACKPARAMS?m_params[itype][jtype].lj4:params(itype,jtype).lj4); + const F_FLOAT offset = (STACKPARAMS?m_params[itype][jtype].offset:params(itype,jtype).offset); + + if (ljt == LJ12_4) { + const F_FLOAT r4inv=r2inv*r2inv; + return r4inv*(lj_3*r4inv*r4inv - lj_4) - offset; + } else if (ljt == LJ9_6) { + const F_FLOAT r3inv = r2inv*sqrt(r2inv); + const F_FLOAT r6inv = r3inv*r3inv; + return r6inv*(lj_3*r3inv - lj_4) - offset; + } else if (ljt == LJ12_6) { + const double r6inv = r2inv*r2inv*r2inv; + return r6inv*(lj_3*r6inv - lj_4) - offset; + } else if (ljt == LJ12_5) { + const F_FLOAT r5inv = r2inv*r2inv*sqrt(r2inv); + const F_FLOAT r7inv = r5inv*r2inv; + return r5inv*(lj_3*r7inv - lj_4) - offset; + } else + return 0.0; +} + +/* ---------------------------------------------------------------------- + compute coulomb pair force between atoms i and j +------------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairLJSPICACoulLongKokkos:: +compute_fcoul(const F_FLOAT& rsq, const int& /*i*/, const int&j, + const int& /*itype*/, const int& /*jtype*/, + const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const { + + if (Specialisation::DoTable && rsq > tabinnersq) { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + const int itable = (rsq_lookup.i & ncoulmask) >> ncoulshiftbits; + const F_FLOAT fraction = (rsq_lookup.f - d_rtable[itable]) * d_drtable[itable]; + const F_FLOAT table = d_ftable[itable] + fraction*d_dftable[itable]; + F_FLOAT forcecoul = qtmp*q[j] * table; + if (factor_coul < 1.0) { + const F_FLOAT table = d_ctable[itable] + fraction*d_dctable[itable]; + const F_FLOAT prefactor = qtmp*q[j] * table; + forcecoul -= (1.0-factor_coul)*prefactor; + } + return forcecoul/rsq; + } else { + const F_FLOAT r = sqrt(rsq); + const F_FLOAT grij = g_ewald * r; + const F_FLOAT expm2 = exp(-grij*grij); + const F_FLOAT t = 1.0 / (1.0 + EWALD_P*grij); + const F_FLOAT rinv = 1.0/r; + const F_FLOAT erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + const F_FLOAT prefactor = qqrd2e * qtmp*q[j]*rinv; + F_FLOAT forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); + if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + + return forcecoul*rinv*rinv; + } +} + +/* ---------------------------------------------------------------------- + compute coulomb pair potential energy between atoms i and j +------------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairLJSPICACoulLongKokkos:: +compute_ecoul(const F_FLOAT& rsq, const int& /*i*/, const int&j, + const int& /*itype*/, const int& /*jtype*/, const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const { + if (Specialisation::DoTable && rsq > tabinnersq) { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + const int itable = (rsq_lookup.i & ncoulmask) >> ncoulshiftbits; + const F_FLOAT fraction = (rsq_lookup.f - d_rtable[itable]) * d_drtable[itable]; + const F_FLOAT table = d_etable[itable] + fraction*d_detable[itable]; + F_FLOAT ecoul = qtmp*q[j] * table; + if (factor_coul < 1.0) { + const F_FLOAT table = d_ctable[itable] + fraction*d_dctable[itable]; + const F_FLOAT prefactor = qtmp*q[j] * table; + ecoul -= (1.0-factor_coul)*prefactor; + } + return ecoul; + } else { + const F_FLOAT r = sqrt(rsq); + const F_FLOAT grij = g_ewald * r; + const F_FLOAT expm2 = exp(-grij*grij); + const F_FLOAT t = 1.0 / (1.0 + EWALD_P*grij); + const F_FLOAT erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + const F_FLOAT prefactor = qqrd2e * qtmp*q[j]/r; + F_FLOAT ecoul = prefactor * erfc; + if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + return ecoul; + } +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +template +void PairLJSPICACoulLongKokkos::allocate() +{ + PairLJSPICACoulLong::allocate(); + + int n = atom->ntypes; + memory->destroy(cutsq); + memoryKK->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); + + memory->destroy(cut_ljsq); + memoryKK->create_kokkos(k_cut_ljsq,cut_ljsq,n+1,n+1,"pair:cut_ljsq"); + d_cut_ljsq = k_cut_ljsq.template view(); + + d_cut_coulsq = typename AT::t_ffloat_2d("pair:cut_coulsq",n+1,n+1); + + k_params = Kokkos::DualView("PairLJSPICACoulLong::params",n+1,n+1); + params = k_params.template view(); +} + +/* ---------------------------------------------------------------------- + init tables +------------------------------------------------------------------------- */ + +template +void PairLJSPICACoulLongKokkos::init_tables(double cut_coul, double *cut_respa) +{ + Pair::init_tables(cut_coul,cut_respa); + + typedef typename ArrayTypes::t_ffloat_1d table_type; + typedef typename ArrayTypes::t_ffloat_1d host_table_type; + + int ntable = 1; + for (int i = 0; i < ncoultablebits; i++) ntable *= 2; + + + // Copy rtable and drtable + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + for (int i = 0; i < ntable; i++) { + h_table(i) = rtable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_rtable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + for (int i = 0; i < ntable; i++) { + h_table(i) = drtable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_drtable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + + // Copy ftable and dftable + for (int i = 0; i < ntable; i++) { + h_table(i) = ftable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_ftable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + + for (int i = 0; i < ntable; i++) { + h_table(i) = dftable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_dftable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + + // Copy ctable and dctable + for (int i = 0; i < ntable; i++) { + h_table(i) = ctable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_ctable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + + for (int i = 0; i < ntable; i++) { + h_table(i) = dctable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_dctable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + + // Copy etable and detable + for (int i = 0; i < ntable; i++) { + h_table(i) = etable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_etable = d_table; + } + + { + host_table_type h_table("HostTable",ntable); + table_type d_table("DeviceTable",ntable); + + for (int i = 0; i < ntable; i++) { + h_table(i) = detable[i]; + } + Kokkos::deep_copy(d_table,h_table); + d_detable = d_table; + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +template +void PairLJSPICACoulLongKokkos::init_style() +{ + PairLJSPICACoulLong::init_style(); + + Kokkos::deep_copy(d_cut_coulsq,cut_coulsq); + + // error if rRESPA with inner levels + + if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) { + int respa = 0; + if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; + if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; + if (respa) + error->all(FLERR,"Cannot use Kokkos pair style with rRESPA inner/middle"); + } + + // adjust neighbor list request for KOKKOS + + neighflag = lmp->kokkos->neighflag; + auto request = neighbor->find_request(this); + request->set_kokkos_host(std::is_same_v && + !std::is_same_v); + request->set_kokkos_device(std::is_same_v); + if (neighflag == FULL) request->enable_full(); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairLJSPICACoulLongKokkos::init_one(int i, int j) +{ + double cutone = PairLJSPICACoulLong::init_one(i,j); + + k_params.h_view(i,j).lj1 = lj1[i][j]; + k_params.h_view(i,j).lj2 = lj2[i][j]; + k_params.h_view(i,j).lj3 = lj3[i][j]; + k_params.h_view(i,j).lj4 = lj4[i][j]; + k_params.h_view(i,j).offset = offset[i][j]; + k_params.h_view(i,j).cut_ljsq = cut_ljsq[i][j]; + k_params.h_view(i,j).cut_coulsq = cut_coulsq; + k_params.h_view(i,j).lj_type = lj_type[i][j]; + k_params.h_view(j,i) = k_params.h_view(i,j); + + if (i(); + k_cut_ljsq.template modify(); + k_params.template modify(); + + return cutone; +} + +namespace LAMMPS_NS { +template class PairLJSPICACoulLongKokkos; +#ifdef LMP_KOKKOS_GPU +template class PairLJSPICACoulLongKokkos; +#endif +} + diff --git a/src/KOKKOS/pair_lj_spica_coul_long_kokkos.h b/src/KOKKOS/pair_lj_spica_coul_long_kokkos.h new file mode 100644 index 0000000000..2e5dea9c40 --- /dev/null +++ b/src/KOKKOS/pair_lj_spica_coul_long_kokkos.h @@ -0,0 +1,148 @@ +/* -*- 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/spica/coul/long/kk,PairLJSPICACoulLongKokkos); +PairStyle(lj/spica/coul/long/kk/device,PairLJSPICACoulLongKokkos); +PairStyle(lj/spica/coul/long/kk/host,PairLJSPICACoulLongKokkos); +PairStyle(lj/sdk/coul/long/kk,PairLJSPICACoulLongKokkos); +PairStyle(lj/sdk/coul/long/kk/device,PairLJSPICACoulLongKokkos); +PairStyle(lj/sdk/coul/long/kk/host,PairLJSPICACoulLongKokkos); +// clang-format on +#else + +// clang-format off +#ifndef LMP_PAIR_LJ_SPICA_COUL_LONG_KOKKOS_H +#define LMP_PAIR_LJ_SPICA_COUL_LONG_KOKKOS_H + +#include "pair_kokkos.h" +#include "pair_lj_spica_coul_long.h" +#include "neigh_list_kokkos.h" + +namespace LAMMPS_NS { + +template +class PairLJSPICACoulLongKokkos : public PairLJSPICACoulLong { + public: + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF}; + enum {COUL_FLAG=1}; + typedef DeviceType device_type; + typedef ArrayTypes AT; + PairLJSPICACoulLongKokkos(class LAMMPS *); + ~PairLJSPICACoulLongKokkos() override; + + void compute(int, int) override; + + void init_tables(double cut_coul, double *cut_respa) override; + void init_style() override; + double init_one(int, int) override; + + struct params_lj_spica_coul { + KOKKOS_INLINE_FUNCTION + params_lj_spica_coul() {cut_ljsq=0;cut_coulsq=0;lj1=0;lj2=0;lj3=0;lj4=0;offset=0;lj_type=0;}; + KOKKOS_INLINE_FUNCTION + params_lj_spica_coul(int /*i*/) {cut_ljsq=0;cut_coulsq=0;lj1=0;lj2=0;lj3=0;lj4=0;offset=0;lj_type=0;}; + F_FLOAT cut_ljsq,cut_coulsq,lj1,lj2,lj3,lj4,offset; + int lj_type; + }; + + protected: + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_fcoul(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, + const int& jtype, const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_ecoul(const F_FLOAT& rsq, const int& i, const int& j, const int& itype, + const int& jtype, const F_FLOAT& factor_coul, const F_FLOAT& qtmp) const; + + Kokkos::DualView k_params; + typename Kokkos::DualView::t_dev_const_um params; + params_lj_spica_coul m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; // hardwired to space for 12 atom types + F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + F_FLOAT m_cut_ljsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + F_FLOAT m_cut_coulsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + typename AT::t_x_array_randomread x; + typename AT::t_x_array c_x; + typename AT::t_f_array f; + typename AT::t_int_1d_randomread type; + typename AT::t_float_1d_randomread q; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; + + int newton_pair; + + typename AT::tdual_ffloat_2d k_cutsq, k_cut_ljsq; + typename AT::t_ffloat_2d d_cutsq, d_cut_ljsq, d_cut_coulsq; + + typename AT::t_ffloat_1d_randomread + d_rtable, d_drtable, d_ftable, d_dftable, + d_ctable, d_dctable, d_etable, d_detable; + + int neighflag; + int nlocal,nall,eflag,vflag; + + double special_lj[4]; + double special_coul[4]; + double qqrd2e; + + void allocate() override; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend struct PairComputeFunctor>; + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute>(PairLJSPICACoulLongKokkos*,NeighListKokkos*); + + friend void pair_virial_fdotr_compute(PairLJSPICACoulLongKokkos*); +}; + +} + +#endif +#endif + diff --git a/src/KOKKOS/pair_lj_spica_kokkos.cpp b/src/KOKKOS/pair_lj_spica_kokkos.cpp index 1f6cccf073..f295f7aa7d 100644 --- a/src/KOKKOS/pair_lj_spica_kokkos.cpp +++ b/src/KOKKOS/pair_lj_spica_kokkos.cpp @@ -70,7 +70,6 @@ void PairLJSPICAKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL) no_virial_fdotr_compute = 1; ev_init(eflag,vflag,0); @@ -108,6 +107,8 @@ void PairLJSPICAKokkos::compute(int eflag_in, int vflag_in) // loop over neighbors of my atoms + copymode = 1; + EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); if (eflag) eng_vdwl += ev.evdwl; @@ -132,8 +133,13 @@ void PairLJSPICAKokkos::compute(int eflag_in, int vflag_in) if (vflag_fdotr) pair_virial_fdotr_compute(this); + copymode = 0; } +/* ---------------------------------------------------------------------- + compute pair force between atoms i and j + ---------------------------------------------------------------------- */ + template template KOKKOS_INLINE_FUNCTION @@ -152,6 +158,10 @@ compute_fpair(const F_FLOAT &rsq, const int &, const int &, const int &itype, co return a* ( lj_1*r6inv*b - lj_2 * r2inv); } +/* ---------------------------------------------------------------------- + compute pair potential energy between atoms i and j + ---------------------------------------------------------------------- */ + template template KOKKOS_INLINE_FUNCTION @@ -166,18 +176,14 @@ compute_evdwl(const F_FLOAT &rsq, const int &, const int &, const int &itype, co if (ljt == LJ12_4) { const F_FLOAT r4inv=r2inv*r2inv; - return r4inv*(lj_3*r4inv*r4inv - lj_4) - offset; - } else if (ljt == LJ9_6) { const F_FLOAT r3inv = r2inv*sqrt(r2inv); const F_FLOAT r6inv = r3inv*r3inv; return r6inv*(lj_3*r3inv - lj_4) - offset; - } else if (ljt == LJ12_6) { const double r6inv = r2inv*r2inv*r2inv; return r6inv*(lj_3*r6inv - lj_4) - offset; - } else if (ljt == LJ12_5) { const F_FLOAT r5inv = r2inv*r2inv*sqrt(r2inv); const F_FLOAT r7inv = r5inv*r2inv; @@ -273,8 +279,6 @@ double PairLJSPICAKokkos::init_one(int i, int j) return cutone; } - - namespace LAMMPS_NS { template class PairLJSPICAKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/pair_uf3_kokkos.cpp b/src/KOKKOS/pair_uf3_kokkos.cpp index 4a3bcc164b..59112ddab0 100644 --- a/src/KOKKOS/pair_uf3_kokkos.cpp +++ b/src/KOKKOS/pair_uf3_kokkos.cpp @@ -1655,7 +1655,7 @@ double PairUF3Kokkos::single(int /*i*/, int /*j*/, int itype, int jt namespace LAMMPS_NS { template class PairUF3Kokkos; -#ifdef KOKKOS_ENABLE_CUDA +#ifdef KOKKOS_ENABLE_GPU template class PairUF3Kokkos; #endif } // namespace LAMMPS_NS diff --git a/src/KOKKOS/pair_uf3_kokkos.h b/src/KOKKOS/pair_uf3_kokkos.h index 15c2832da1..952e2aba25 100644 --- a/src/KOKKOS/pair_uf3_kokkos.h +++ b/src/KOKKOS/pair_uf3_kokkos.h @@ -22,6 +22,7 @@ // clang-format off PairStyle(uf3/kk,PairUF3Kokkos) PairStyle(uf3/kk/device,PairUF3Kokkos) +PairStyle(uf3/kk/host,PairUF3Kokkos) // clang-format on #else @@ -44,7 +45,7 @@ template class PairUF3Kokkos : public PairUF3 { void compute(int, int) override; void settings(int, char **) override; void coeff(int, char **) override; - void allocate(); + void allocate() override; void init_style() override; void init_list(int, class NeighList *) override; // needed for ptr to full neigh list double init_one(int, int) override; // needed for cutoff radius for neighbour list @@ -117,9 +118,11 @@ template class PairUF3Kokkos : public PairUF3 { std::vector get_dncoefficients(const double *knots, const double coefficient) const; template + KOKKOS_INLINE_FUNCTION void twobody(const int itype, const int jtype, const F_FLOAT r, F_FLOAT &evdwl, F_FLOAT &fpair) const; template + KOKKOS_INLINE_FUNCTION void threebody(const int itype, const int jtype, const int ktype, const F_FLOAT value_rij, const F_FLOAT value_rik, const F_FLOAT value_rjk, F_FLOAT &evdwl3, F_FLOAT (&fforce)[3]) const; diff --git a/src/MACHDYN/fix_smd_integrate_tlsph.cpp b/src/MACHDYN/fix_smd_integrate_tlsph.cpp index f138a3c387..ee617c1577 100644 --- a/src/MACHDYN/fix_smd_integrate_tlsph.cpp +++ b/src/MACHDYN/fix_smd_integrate_tlsph.cpp @@ -24,15 +24,18 @@ ------------------------------------------------------------------------- */ #include "fix_smd_integrate_tlsph.h" + +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "pair.h" +#include "update.h" + #include #include #include -#include "atom.h" -#include "force.h" -#include "update.h" -#include "error.h" -#include "pair.h" -#include "comm.h" using namespace Eigen; using namespace LAMMPS_NS; @@ -115,6 +118,11 @@ void FixSMDIntegrateTlsph::init() { dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; vlimitsq = vlimit * vlimit; + + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix smd/integrate_tlsph cannot be used with velocity remapping"); } /* ---------------------------------------------------------------------- diff --git a/src/MACHDYN/fix_smd_integrate_ulsph.cpp b/src/MACHDYN/fix_smd_integrate_ulsph.cpp index 8ef5c65b67..6e2934c2ec 100644 --- a/src/MACHDYN/fix_smd_integrate_ulsph.cpp +++ b/src/MACHDYN/fix_smd_integrate_ulsph.cpp @@ -24,15 +24,18 @@ ------------------------------------------------------------------------- */ #include "fix_smd_integrate_ulsph.h" + +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "pair.h" +#include "update.h" + #include #include #include -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "update.h" -#include "error.h" -#include "pair.h" using namespace Eigen; using namespace LAMMPS_NS; @@ -144,6 +147,11 @@ void FixSMDIntegrateUlsph::init() { dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; vlimitsq = vlimit * vlimit; + + // Cannot use vremap since its effects aren't propagated to vest + // see RHEO or SPH packages for examples of patches + if (domain->deform_vremap) + error->all(FLERR, "Fix smd/integrate_ulsph cannot be used with velocity remapping"); } /* ---------------------------------------------------------------------- diff --git a/src/MISC/fix_ipi.cpp b/src/MISC/fix_ipi.cpp index 87668b9192..80666790e2 100644 --- a/src/MISC/fix_ipi.cpp +++ b/src/MISC/fix_ipi.cpp @@ -188,6 +188,7 @@ FixIPI::FixIPI(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), irregul master = (comm->me == 0) ? 1 : 0; inet = 1; reset_flag = 0; + firsttime = 1; int iarg = 5; while (iarg < narg) { @@ -253,6 +254,7 @@ void FixIPI::init() ipisock = 0; // TODO: should check for success in socket opening, // but the current open_socket routine dies brutally if unsuccessful + // tell lammps we have assigned a socket socketflag = 1; @@ -373,13 +375,20 @@ void FixIPI::initial_integrate(int /*vflag*/) if (domain->triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); domain->reset_box(); + // move atoms to new processors via irregular() + // only needed if migrate_check() says an atom moves to far + if (irregular->migrate_check()) irregular->migrate_atoms(); if (domain->triclinic) domain->lamda2x(atom->nlocal); // ensures continuity of trajectories relative to the // snapshot at neighbor list creation, minimizing the // number of neighbor list updates auto xhold = neighbor->get_xhold(); - if (xhold != NULL) { // don't wrap if xhold is not used in the NL + if (xhold != NULL && !firsttime) { + // don't wrap if xhold is not used in the NL, or the + // first call (because the NL is initialized from the + // data file that might have nothing to do with the + // current structure for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { auto delx = x[i][0] - xhold[i][0]; @@ -394,11 +403,7 @@ void FixIPI::initial_integrate(int /*vflag*/) } } } - // move atoms to new processors via irregular() - // only needed if migrate_check() says an atom moves to far - if (domain->triclinic) domain->x2lamda(atom->nlocal); - if (irregular->migrate_check()) irregular->migrate_atoms(); - if (domain->triclinic) domain->lamda2x(atom->nlocal); + firsttime = 0; // check if kspace solver is used if (reset_flag && kspace_flag) { diff --git a/src/MISC/fix_ipi.h b/src/MISC/fix_ipi.h index de954c8578..31bd59b2fa 100644 --- a/src/MISC/fix_ipi.h +++ b/src/MISC/fix_ipi.h @@ -42,6 +42,7 @@ class FixIPI : public Fix { long bsize; int kspace_flag; int reset_flag; + int firsttime; private: class Irregular *irregular; diff --git a/src/ML-IAP/mliap_unified.cpp b/src/ML-IAP/mliap_unified.cpp index 3f0d0b2a8f..9998ff2af4 100644 --- a/src/ML-IAP/mliap_unified.cpp +++ b/src/ML-IAP/mliap_unified.cpp @@ -253,8 +253,10 @@ void LAMMPS_NS::update_pair_energy(MLIAPData *data, double *eij) double e = 0.5 * eij[ii]; // must not count any contribution where i is not a local atom - data->eatoms[i] += e; - e_total += e; + if (i < data->nlocal) { + data->eatoms[i] += e; + e_total += e; + } } data->energy = e_total; } diff --git a/src/ML-UF3/pair_uf3.cpp b/src/ML-UF3/pair_uf3.cpp index a952403287..1f91f25f5b 100644 --- a/src/ML-UF3/pair_uf3.cpp +++ b/src/ML-UF3/pair_uf3.cpp @@ -120,7 +120,6 @@ void PairUF3::settings(int narg, char **arg) "Invalid number of arguments for pair_style uf3" " Are you using a 2-body or 2 & 3-body UF potential?"); nbody_flag = utils::numeric(FLERR, arg[0], true, lmp); - const int num_of_elements = atom->ntypes; if (nbody_flag == 2) { pot_3b = false; manybody_flag = 0; diff --git a/src/OPENMP/reaxff_forces_omp.cpp b/src/OPENMP/reaxff_forces_omp.cpp index 26922add1e..ce8ad0716f 100644 --- a/src/OPENMP/reaxff_forces_omp.cpp +++ b/src/OPENMP/reaxff_forces_omp.cpp @@ -155,7 +155,7 @@ namespace ReaxFF { /* ---------------------------------------------------------------------- */ static void Validate_ListsOMP(reax_system *system, reax_list **lists, - int step, int n, int N, int numH) + int step, int N, int numH) { int comp, Hindex; reax_list *bonds, *hbonds; @@ -195,7 +195,7 @@ namespace ReaxFF { #if defined(_OPENMP) #pragma omp for schedule(guided) #endif - for (int i = 0; i < n; ++i) { + for (int i = 0; i < N; ++i) { Hindex = system->my_atoms[i].Hindex; if (Hindex > -1) { system->my_atoms[i].num_hbonds = @@ -457,8 +457,7 @@ namespace ReaxFF { workspace->realloc.num_bonds = num_bonds; workspace->realloc.num_hbonds = num_hbonds; - Validate_ListsOMP(system, lists, data->step, - system->n, system->N, system->numH); + Validate_ListsOMP(system, lists, data->step, system->N, system->numH); } /* ---------------------------------------------------------------------- */ diff --git a/src/PYTHON/python_compat.h b/src/PYTHON/python_compat.h index 775435ffd8..d1194056d8 100644 --- a/src/PYTHON/python_compat.h +++ b/src/PYTHON/python_compat.h @@ -20,13 +20,12 @@ #if PY_MAJOR_VERSION == 2 #if defined(_MSC_VER) || defined(__MINGW32__) #define PY_INT_FROM_LONG(X) PyLong_FromLongLong(X) +#define PY_INT_AS_LONG(X) PyLong_AsLongLong(X) +#define PY_LONG_FROM_STRING(X) std::stoll(X) #else #define PY_INT_FROM_LONG(X) PyInt_FromLong(X) -#endif -#if defined(_MSC_VER) || defined(__MINGW32__) -#define PY_INT_AS_LONG(X) PyLong_AsLongLong(X) -#else #define PY_INT_AS_LONG(X) PyInt_AsLong(X) +#define PY_LONG_FROM_STRING(X) std::stol(X) #endif #define PY_STRING_FROM_STRING(X) PyString_FromString(X) #define PY_VOID_POINTER(X) PyCObject_FromVoidPtr((void *) X, nullptr) @@ -35,13 +34,12 @@ #elif PY_MAJOR_VERSION == 3 #if defined(_MSC_VER) || defined(__MINGW32__) #define PY_INT_FROM_LONG(X) PyLong_FromLongLong(X) +#define PY_INT_AS_LONG(X) PyLong_AsLongLong(X) +#define PY_LONG_FROM_STRING(X) std::stoll(X) #else #define PY_INT_FROM_LONG(X) PyLong_FromLong(X) -#endif -#if defined(_MSC_VER) || defined(__MINGW32__) -#define PY_INT_AS_LONG(X) PyLong_AsLongLong(X) -#else #define PY_INT_AS_LONG(X) PyLong_AsLong(X) +#define PY_LONG_FROM_STRING(X) std::stol(X) #endif #define PY_STRING_FROM_STRING(X) PyUnicode_FromString(X) #define PY_VOID_POINTER(X) PyCapsule_New((void *) X, nullptr, nullptr) diff --git a/src/PYTHON/python_impl.cpp b/src/PYTHON/python_impl.cpp index 87a57187bf..91e0a7abe5 100644 --- a/src/PYTHON/python_impl.cpp +++ b/src/PYTHON/python_impl.cpp @@ -341,7 +341,7 @@ void PythonImpl::invoke_function(int ifunc, char *result) if (!str) error->all(FLERR, "Could not evaluate Python function {} input variable: {}", pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]); - pValue = PY_INT_FROM_LONG(atoi(str)); + pValue = PY_INT_FROM_LONG(PY_LONG_FROM_STRING(str)); } else { pValue = PY_INT_FROM_LONG(pfuncs[ifunc].ivalue[i]); } @@ -351,7 +351,7 @@ void PythonImpl::invoke_function(int ifunc, char *result) if (!str) error->all(FLERR, "Could not evaluate Python function {} input variable: {}", pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]); - pValue = PyFloat_FromDouble(atof(str)); + pValue = PyFloat_FromDouble(std::stod(str)); } else { pValue = PyFloat_FromDouble(pfuncs[ifunc].dvalue[i]); } diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index c24984f152..04dbcb8a90 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -90,6 +90,11 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : integrator = OBABO; thermostat = PILE_L; barostat = BZP; + lj_epsilon = 1; + lj_sigma = 1; + lj_mass = 1; + other_planck = 1; + other_mvv2e = 1; fmass = 1.0; np = universe->nworlds; inverse_np = 1.0 / np; diff --git a/src/RHEO/bond_rheo_shell.cpp b/src/RHEO/bond_rheo_shell.cpp index 258d047086..dbe65e2b2f 100644 --- a/src/RHEO/bond_rheo_shell.cpp +++ b/src/RHEO/bond_rheo_shell.cpp @@ -45,7 +45,8 @@ using namespace RHEO_NS; /* ---------------------------------------------------------------------- */ BondRHEOShell::BondRHEOShell(LAMMPS *_lmp) : - BondBPM(_lmp), compute_surface(nullptr), k(nullptr), ecrit(nullptr), gamma(nullptr) + BondBPM(_lmp), k(nullptr), ecrit(nullptr), gamma(nullptr), dbond(nullptr), nbond(nullptr), + id_fix(nullptr), compute_surface(nullptr) { partial_flag = 1; comm_reverse = 1; diff --git a/src/RHEO/compute_rheo_grad.cpp b/src/RHEO/compute_rheo_grad.cpp index cdf90e1dc5..fdddea18b5 100644 --- a/src/RHEO/compute_rheo_grad.cpp +++ b/src/RHEO/compute_rheo_grad.cpp @@ -42,8 +42,9 @@ enum{COMMGRAD, COMMFIELD}; /* ---------------------------------------------------------------------- */ ComputeRHEOGrad::ComputeRHEOGrad(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), rho0(nullptr), compute_interface(nullptr), compute_kernel(nullptr), - gradv(nullptr), gradr(nullptr), grade(nullptr), gradn(nullptr) + Compute(lmp, narg, arg), gradv(nullptr), gradr(nullptr), grade(nullptr), gradn(nullptr), + fix_rheo(nullptr), rho0(nullptr), compute_kernel(nullptr), compute_interface(nullptr), + list(nullptr) { if (narg < 4) error->all(FLERR,"Illegal compute rheo/grad command"); @@ -130,10 +131,9 @@ void ComputeRHEOGrad::compute_peratom() { int i, j, k, ii, jj, jnum, itype, jtype, a, b, fluidi, fluidj; double xtmp, ytmp, ztmp, delx, dely, delz; - double rsq, imass, jmass; - double rhoi, rhoj, Voli, Volj, drho, de, deta; + double rsq, rhoi, rhoj, Voli, Volj, drho, de, deta; double vi[3], vj[3], vij[3]; - double wp, *dWij, *dWji; + double *dWij, *dWji; int inum, *ilist, *numneigh, **firstneigh; int *jlist; @@ -147,6 +147,7 @@ void ComputeRHEOGrad::compute_peratom() int *status = atom->rheo_status; int *type = atom->type; double *mass = atom->mass; + double *rmass = atom->rmass; int newton = force->newton; int dim = domain->dimension; @@ -225,8 +226,13 @@ void ComputeRHEOGrad::compute_peratom() } } - Voli = mass[itype] / rhoi; - Volj = mass[jtype] / rhoj; + if (rmass) { + Voli = rmass[i] / rhoi; + Volj = rmass[j] / rhoj; + } else { + Voli = mass[itype] / rhoi; + Volj = mass[jtype] / rhoj; + } vij[0] = vi[0] - vj[0]; vij[1] = vi[1] - vj[1]; @@ -236,7 +242,7 @@ void ComputeRHEOGrad::compute_peratom() if (energy_flag) de = energy[i] - energy[j]; if (eta_flag) deta = viscosity[i] - viscosity[j]; - wp = compute_kernel->calc_dw(i, j, delx, dely, delz, sqrt(rsq)); + compute_kernel->calc_dw(i, j, delx, dely, delz, sqrt(rsq)); dWij = compute_kernel->dWij; dWji = compute_kernel->dWji; diff --git a/src/RHEO/compute_rheo_interface.cpp b/src/RHEO/compute_rheo_interface.cpp index 8ccd4e6a3b..2d2a368926 100644 --- a/src/RHEO/compute_rheo_interface.cpp +++ b/src/RHEO/compute_rheo_interface.cpp @@ -45,8 +45,10 @@ static constexpr double EPSILON = 1e-1; /* ---------------------------------------------------------------------- */ ComputeRHEOInterface::ComputeRHEOInterface(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), fix_rheo(nullptr), compute_kernel(nullptr), fp_store(nullptr), - rho0(nullptr), norm(nullptr), normwf(nullptr), chi(nullptr), id_fix_pa(nullptr) + Compute(lmp, narg, arg), chi(nullptr), fp_store(nullptr), fix_rheo(nullptr), + rho0(nullptr), norm(nullptr), normwf(nullptr), id_fix_pa(nullptr), list(nullptr), + compute_kernel(nullptr), fix_pressure(nullptr) + { if (narg != 3) error->all(FLERR,"Illegal compute rheo/interface command"); @@ -228,12 +230,11 @@ void ComputeRHEOInterface::compute_peratom() int ComputeRHEOInterface::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i, j, k, m; - m = 0; + int m = 0; double *rho = atom->rho; - for (i = 0; i < n; i++) { - j = list[i]; + for (int i = 0; i < n; i++) { + int j = list[i]; if (comm_stage == 0) { buf[m++] = fp_store[j][0]; buf[m++] = fp_store[j][1]; @@ -250,11 +251,10 @@ int ComputeRHEOInterface::pack_forward_comm(int n, int *list, double *buf, int / void ComputeRHEOInterface::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last; double *rho = atom->rho; - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { if (comm_stage == 0) { fp_store[i][0] = buf[m++]; fp_store[i][1] = buf[m++]; @@ -270,12 +270,10 @@ void ComputeRHEOInterface::unpack_forward_comm(int n, int first, double *buf) int ComputeRHEOInterface::pack_reverse_comm(int n, int first, double *buf) { - int i, k, m, last; double *rho = atom->rho; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { buf[m++] = norm[i]; buf[m++] = chi[i]; buf[m++] = normwf[i]; @@ -288,12 +286,11 @@ int ComputeRHEOInterface::pack_reverse_comm(int n, int first, double *buf) void ComputeRHEOInterface::unpack_reverse_comm(int n, int *list, double *buf) { - int i, k, j, m; double *rho = atom->rho; int *status = atom->rheo_status; - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; norm[j] += buf[m++]; chi[j] += buf[m++]; if (status[j] & PHASECHECK){ @@ -338,6 +335,7 @@ void ComputeRHEOInterface::store_forces() int *type = atom->type; int *mask = atom->mask; double *mass = atom->mass; + double *rmass = atom->rmass; double **f = atom->f; // When this is called, fp_store stores the pressure force @@ -349,7 +347,8 @@ void ComputeRHEOInterface::store_forces() if (fixlist.size() != 0) { for (const auto &fix : fixlist) { for (int i = 0; i < atom->nlocal; i++) { - minv = 1.0 / mass[type[i]]; + if (rmass) minv = 1.0 / rmass[i]; + else minv = 1.0 / mass[type[i]]; if (mask[i] & fix->groupbit) for (int a = 0; a < 3; a++) fp_store[i][a] = f[i][a] * minv; @@ -359,10 +358,18 @@ void ComputeRHEOInterface::store_forces() } } } else { - for (int i = 0; i < atom->nlocal; i++) { - minv = 1.0 / mass[type[i]]; - for (int a = 0; a < 3; a++) - fp_store[i][a] = (f[i][a] - fp_store[i][a]) * minv; + if (rmass) { + for (int i = 0; i < atom->nlocal; i++) { + minv = 1.0 / rmass[i]; + for (int a = 0; a < 3; a++) + fp_store[i][a] = (f[i][a] - fp_store[i][a]) * minv; + } + } else { + for (int i = 0; i < atom->nlocal; i++) { + minv = 1.0 / mass[type[i]]; + for (int a = 0; a < 3; a++) + fp_store[i][a] = (f[i][a] - fp_store[i][a]) * minv; + } } } diff --git a/src/RHEO/compute_rheo_kernel.cpp b/src/RHEO/compute_rheo_kernel.cpp index 4558ddccc8..108ec58b09 100644 --- a/src/RHEO/compute_rheo_kernel.cpp +++ b/src/RHEO/compute_rheo_kernel.cpp @@ -48,13 +48,11 @@ using namespace RHEO_NS; using namespace MathConst; using namespace MathExtra; -static constexpr int DELTA = 2000; - /* ---------------------------------------------------------------------- */ ComputeRHEOKernel::ComputeRHEOKernel(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - list(nullptr), C(nullptr), C0(nullptr), coordination(nullptr), compute_interface(nullptr) + Compute(lmp, narg, arg), coordination(nullptr), fix_rheo(nullptr), C(nullptr), C0(nullptr), + list(nullptr), compute_interface(nullptr) { if (narg != 4) error->all(FLERR,"Illegal compute rheo/kernel command"); @@ -190,7 +188,7 @@ double ComputeRHEOKernel::calc_w_self(int i, int j) double ComputeRHEOKernel::calc_w(int i, int j, double delx, double dely, double delz, double r) { - double w; + double w = 0.0; int corrections_i, corrections_j, corrections; if (kernel_style == WENDLANDC4) @@ -282,8 +280,6 @@ double ComputeRHEOKernel::calc_w_quintic(int i, int j, double delx, double dely, double ComputeRHEOKernel::calc_dw_quintic(int i, int j, double delx, double dely, double delz, double r, double *dW1, double *dW2) { double wp, tmp1, tmp2, tmp3, tmp1sq, tmp2sq, tmp3sq, s, wprinv; - double *mass = atom->mass; - int *type = atom->type; s = r * 3.0 * cutinv; @@ -326,9 +322,9 @@ double ComputeRHEOKernel::calc_w_wendlandc4(int i, int j, double delx, double de double w, tmp6, s; s = r * cutinv; - if (s > 1.0) { - w = 0.0; - } else { + if (s > 1.0) { + w = 0.0; + } else { tmp6 = (1.0 - s) * (1.0 - s); tmp6 *= tmp6 * tmp6; w = tmp6 * (1.0 + 6.0 * s + 35.0 * THIRD * s * s); @@ -347,14 +343,12 @@ double ComputeRHEOKernel::calc_w_wendlandc4(int i, int j, double delx, double de double ComputeRHEOKernel::calc_dw_wendlandc4(int i, int j, double delx, double dely, double delz, double r, double *dW1, double *dW2) { double wp, tmp1, tmp5, tmp6, s, wprinv; - double *mass = atom->mass; - int *type = atom->type; s = r * cutinv; - if (s > 1.0) { - wp = 0.0; - } else { + if (s > 1.0) { + wp = 0.0; + } else { tmp1 = 1.0 - s; tmp5 = tmp1 * tmp1; tmp5 = tmp5 * tmp5 * tmp1; @@ -395,7 +389,7 @@ double ComputeRHEOKernel::calc_w_rk0(int i, int j, double delx, double dely, dou double ComputeRHEOKernel::calc_w_rk1(int i, int j, double delx, double dely, double delz, double r) { int b; - double w, wR, dx[3], H[Mdim]; + double w, dx[3], H[Mdim]; dx[0] = delx; dx[1] = dely; @@ -437,7 +431,7 @@ double ComputeRHEOKernel::calc_w_rk1(int i, int j, double delx, double dely, dou double ComputeRHEOKernel::calc_w_rk2(int i, int j, double delx, double dely, double delz, double r) { int b; - double w, wR, dx[3], H[Mdim]; + double w, dx[3], H[Mdim]; dx[0] = delx; dx[1] = dely; dx[2] = delz; @@ -574,7 +568,7 @@ void ComputeRHEOKernel::compute_peratom() if (kernel_style == QUINTIC) return; corrections_calculated = 1; - int i, j, ii, jj, inum, jnum, itype, g, a, b, gsl_error; + int i, j, ii, jj, inum, jnum, a, b, gsl_error; double xtmp, ytmp, ztmp, r, rsq, w, vj, rhoj; double dx[3]; gsl_matrix_view gM; @@ -585,6 +579,7 @@ void ComputeRHEOKernel::compute_peratom() double **x = atom->x; int *type = atom->type; double *mass = atom->mass; + double *rmass = atom->rmass; double *rho = atom->rho; int *status = atom->rheo_status; tagint *tag = atom->tag; @@ -630,7 +625,8 @@ void ComputeRHEOKernel::compute_peratom() if (status[j] & PHASECHECK) rhoj = compute_interface->correct_rho(j, i); - vj = mass[type[j]] / rhoj; + if (rmass) vj = rmass[j] / rhoj; + else vj = mass[type[j]] / rhoj; M += w * vj; } } @@ -651,7 +647,6 @@ void ComputeRHEOKernel::compute_peratom() jlist = firstneigh[i]; jnum = numneigh[i]; - itype = type[i]; // Zero upper-triangle M and cut (will be symmetric): for (a = 0; a < Mdim; a++) { @@ -679,7 +674,8 @@ void ComputeRHEOKernel::compute_peratom() if (status[j] & PHASECHECK) rhoj = compute_interface->correct_rho(j, i); - vj = mass[type[j]] / rhoj; + if (rmass) vj = rmass[j] / rhoj; + else vj = mass[type[j]] / rhoj; //Populate the H-vector of polynomials (2D) if (dim == 2) { @@ -854,19 +850,17 @@ void ComputeRHEOKernel::grow_arrays(int nmax) int ComputeRHEOKernel::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i,j,k,m,a,b; - m = 0; - - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; if (comm_stage == 0) { buf[m++] = coordination[j]; } else { if (kernel_style == RK0) { buf[m++] = C0[j]; } else { - for (a = 0; a < ncor; a++) - for (b = 0; b < Mdim; b++) + for (int a = 0; a < ncor; a++) + for (int b = 0; b < Mdim; b++) buf[m++] = C[j][a][b]; } } @@ -878,19 +872,17 @@ int ComputeRHEOKernel::pack_forward_comm(int n, int *list, double *buf, void ComputeRHEOKernel::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last,a,b; - m = 0; - last = first + n; - - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { if (comm_stage == 0) { coordination[i] = buf[m++]; } else { if (kernel_style == RK0) { C0[i] = buf[m++]; } else { - for (a = 0; a < ncor; a++) - for (b = 0; b < Mdim; b++) + for (int a = 0; a < ncor; a++) + for (int b = 0; b < Mdim; b++) C[i][a][b] = buf[m++]; } } diff --git a/src/RHEO/compute_rheo_property_atom.cpp b/src/RHEO/compute_rheo_property_atom.cpp index 7a450e7708..cd0ff6692d 100644 --- a/src/RHEO/compute_rheo_property_atom.cpp +++ b/src/RHEO/compute_rheo_property_atom.cpp @@ -46,9 +46,10 @@ using namespace RHEO_NS; /* ---------------------------------------------------------------------- */ ComputeRHEOPropertyAtom::ComputeRHEOPropertyAtom(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), fix_rheo(nullptr), fix_pressure(nullptr), fix_thermal(nullptr), compute_interface(nullptr), - compute_kernel(nullptr), compute_surface(nullptr), compute_vshift(nullptr), compute_grad(nullptr), - avec_index(nullptr), pack_choice(nullptr), col_index(nullptr) + Compute(lmp, narg, arg), avec_index(nullptr), col_index(nullptr), col_t_index(nullptr), + buf(nullptr), pack_choice(nullptr), fix_rheo(nullptr), fix_pressure(nullptr), + fix_thermal(nullptr), compute_interface(nullptr), compute_kernel(nullptr), + compute_surface(nullptr), compute_vshift(nullptr), compute_grad(nullptr) { if (narg < 4) utils::missing_cmd_args(FLERR, "compute property/atom", error); @@ -88,7 +89,6 @@ ComputeRHEOPropertyAtom::ComputeRHEOPropertyAtom(LAMMPS *lmp, int narg, char **a col_t_index = new int[nvalues]; int i = 0; - int index, a, b; for (int iarg = 3; iarg < narg; iarg++) { if (strcmp(arg[iarg], "phase") == 0) { pack_choice[i] = &ComputeRHEOPropertyAtom::pack_phase; @@ -536,7 +536,7 @@ int ComputeRHEOPropertyAtom::add_tensor_component(char* option, int i, FnPtrPack } shift = dim * dim; } else { - int index; + int index = -1; int dim_error = 0; if (utils::strmatch(option, "xx$")) { @@ -592,7 +592,7 @@ int ComputeRHEOPropertyAtom::add_vector_component(char* option, int i, FnPtrPack } shift = dim; } else { - int index; + int index = -1; if (utils::strmatch(option, "x$")) { index = 0; } else if (utils::strmatch(option, "y$")) { diff --git a/src/RHEO/compute_rheo_rho_sum.cpp b/src/RHEO/compute_rheo_rho_sum.cpp index 6e25b35374..8067bae21b 100644 --- a/src/RHEO/compute_rheo_rho_sum.cpp +++ b/src/RHEO/compute_rheo_rho_sum.cpp @@ -72,7 +72,7 @@ void ComputeRHEORhoSum::init_list(int /*id*/, NeighList *ptr) void ComputeRHEORhoSum::compute_peratom() { - int i, j, ii, jj, inum, jnum, itype, jtype; + int i, j, ii, jj, inum, jnum; double xtmp, ytmp, ztmp, delx, dely, delz; int *ilist, *jlist, *numneigh, **firstneigh; double rsq, w; @@ -81,12 +81,11 @@ void ComputeRHEORhoSum::compute_peratom() double **x = atom->x; double *rho = atom->rho; - int *type = atom->type; double *mass = atom->mass; + double *rmass = atom->rmass; + int *type = atom->type; int newton = force->newton; - double jmass; - inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -96,7 +95,8 @@ void ComputeRHEORhoSum::compute_peratom() // initialize arrays, local with quintic self-contribution, ghosts are zeroed for (i = 0; i < nlocal; i++) { w = compute_kernel->calc_w_self(i, i); - rho[i] = w * mass[type[i]]; + if (rmass) rho[i] = w * rmass[i]; + else rho[i] = w * mass[type[i]]; } for (i = nlocal; i < nall; i++) rho[i] = 0.0; @@ -106,7 +106,6 @@ void ComputeRHEORhoSum::compute_peratom() xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; - itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; @@ -121,14 +120,26 @@ void ComputeRHEORhoSum::compute_peratom() if (rsq < cutsq) { w = compute_kernel->calc_w(i, j, delx, dely, delz, sqrt(rsq)); - if (self_mass_flag) { - rho[i] += w * mass[type[i]]; - if (newton || j < nlocal) - rho[j] += w * mass[type[j]]; + if (rmass) { + if (self_mass_flag) { + rho[i] += w * rmass[i]; + if (newton || j < nlocal) + rho[j] += w * rmass[j]; + } else { + rho[i] += w * rmass[j]; + if (newton || j < nlocal) + rho[j] += w * rmass[i]; + } } else { - rho[i] += w * mass[type[j]]; - if (newton || j < nlocal) - rho[j] += w * mass[type[i]]; + if (self_mass_flag) { + rho[i] += w * mass[type[i]]; + if (newton || j < nlocal) + rho[j] += w * mass[type[j]]; + } else { + rho[i] += w * mass[type[j]]; + if (newton || j < nlocal) + rho[j] += w * mass[type[i]]; + } } } } @@ -143,7 +154,7 @@ void ComputeRHEORhoSum::compute_peratom() int ComputeRHEORhoSum::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i, j, k, m; + int i, j, m; double *rho = atom->rho; m = 0; @@ -157,7 +168,7 @@ int ComputeRHEORhoSum::pack_forward_comm(int n, int *list, double *buf, /* ---------------------------------------------------------------------- */ void ComputeRHEORhoSum::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last; + int i, m, last; double *rho = atom->rho; m = 0; @@ -171,7 +182,7 @@ void ComputeRHEORhoSum::unpack_forward_comm(int n, int first, double *buf) int ComputeRHEORhoSum::pack_reverse_comm(int n, int first, double *buf) { - int i, k, m, last; + int i, m, last; double *rho = atom->rho; m = 0; @@ -186,7 +197,7 @@ int ComputeRHEORhoSum::pack_reverse_comm(int n, int first, double *buf) void ComputeRHEORhoSum::unpack_reverse_comm(int n, int *list, double *buf) { - int i, k, j, m; + int i, j, m; double *rho = atom->rho; m = 0; diff --git a/src/RHEO/compute_rheo_surface.cpp b/src/RHEO/compute_rheo_surface.cpp index c3a3774cdc..314d2d2ef5 100644 --- a/src/RHEO/compute_rheo_surface.cpp +++ b/src/RHEO/compute_rheo_surface.cpp @@ -43,8 +43,9 @@ static constexpr double EPSILON = 1e-10; /* ---------------------------------------------------------------------- */ ComputeRHEOSurface::ComputeRHEOSurface(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), rho0(nullptr), compute_kernel(nullptr), compute_interface(nullptr), - B(nullptr), gradC(nullptr), nsurface(nullptr), divr(nullptr), rsurface(nullptr) + Compute(lmp, narg, arg), nsurface(nullptr), rsurface(nullptr), divr(nullptr), fix_rheo(nullptr), + rho0(nullptr), B(nullptr), gradC(nullptr), list(nullptr), compute_kernel(nullptr), + compute_interface(nullptr) { if (narg != 3) error->all(FLERR,"Illegal compute RHEO/SURFACE command"); @@ -98,8 +99,8 @@ void ComputeRHEOSurface::init_list(int /*id*/, NeighList *ptr) void ComputeRHEOSurface::compute_peratom() { - int i, j, ii, jj, inum, jnum, a, b, itype, jtype, fluidi, fluidj; - double xtmp, ytmp, ztmp, rsq, Voli, Volj, rhoi, rhoj, wp; + int i, j, ii, jj, inum, jnum, a, itype, jtype, fluidi, fluidj; + double xtmp, ytmp, ztmp, rsq, Voli, Volj, rhoi, rhoj; double dWij[3], dWji[3], dx[3]; int *ilist, *jlist, *numneigh, **firstneigh; @@ -112,6 +113,7 @@ void ComputeRHEOSurface::compute_peratom() int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; + double *rmass = atom->rmass; double *rho = atom->rho; int *coordination = compute_kernel->coordination; @@ -172,10 +174,14 @@ void ComputeRHEOSurface::compute_peratom() } } - Voli = mass[itype] / rhoi; - Volj = mass[jtype] / rhoj; - - wp = compute_kernel->calc_dw_quintic(i, j, dx[0], dx[1], dx[2], sqrt(rsq), dWij, dWji); + if (rmass) { + Voli = rmass[i] / rhoi; + Volj = rmass[j] / rhoj; + } else { + Voli = mass[itype] / rhoi; + Volj = mass[jtype] / rhoj; + } + compute_kernel->calc_dw_quintic(i, j, dx[0], dx[1], dx[2], sqrt(rsq), dWij, dWji); for (a = 0; a < dim; a++) { divr[i] -= dWij[a] * dx[a] * Volj; @@ -310,17 +316,15 @@ void ComputeRHEOSurface::compute_peratom() int ComputeRHEOSurface::pack_reverse_comm(int n, int first, double *buf) { - int i,a,b,k,m,last; int dim = domain->dimension; int *status = atom->rheo_status; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { if (comm_stage == 0) { buf[m++] = divr[i]; - for (a = 0; a < dim; a ++ ) - for (b = 0; b < dim; b ++) + for (int a = 0; a < dim; a ++ ) + for (int b = 0; b < dim; b ++) buf[m++] = gradC[i][a * dim + b]; } else if (comm_stage == 1) { buf[m++] = (double) status[i]; @@ -334,27 +338,23 @@ int ComputeRHEOSurface::pack_reverse_comm(int n, int first, double *buf) void ComputeRHEOSurface::unpack_reverse_comm(int n, int *list, double *buf) { - int i,a,b,k,j,m; int dim = domain->dimension; int *status = atom->rheo_status; - int tmp1; - double tmp2; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; if (comm_stage == 0) { divr[j] += buf[m++]; - for (a = 0; a < dim; a ++ ) - for (b = 0; b < dim; b ++) + for (int a = 0; a < dim; a ++ ) + for (int b = 0; b < dim; b ++) gradC[j][a * dim + b] += buf[m++]; } else if (comm_stage == 1) { - tmp1 = (int) buf[m++]; + auto tmp1 = (int) buf[m++]; if ((status[j] & STATUS_BULK) && (tmp1 & STATUS_LAYER)) { status[j] &= SURFACEMASK; status[j] |= STATUS_LAYER; } - tmp2 = buf[m++]; + auto tmp2 = buf[m++]; rsurface[j] = MIN(rsurface[j], tmp2); } } @@ -366,12 +366,10 @@ void ComputeRHEOSurface::unpack_reverse_comm(int n, int *list, double *buf) int ComputeRHEOSurface::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i,j,a,b,k,m; int *status = atom->rheo_status; - m = 0; - - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; if (comm_stage == 0) { buf[m++] = divr[j]; } else if (comm_stage == 1) { @@ -386,12 +384,10 @@ int ComputeRHEOSurface::pack_forward_comm(int n, int *list, double *buf, void ComputeRHEOSurface::unpack_forward_comm(int n, int first, double *buf) { - int i, k, a, b, m, last; int *status = atom->rheo_status; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { if (comm_stage == 0) { divr[i] = buf[m++]; } else if (comm_stage == 1) { diff --git a/src/RHEO/compute_rheo_vshift.cpp b/src/RHEO/compute_rheo_vshift.cpp index c06ef533ac..8d2f04d7f6 100644 --- a/src/RHEO/compute_rheo_vshift.cpp +++ b/src/RHEO/compute_rheo_vshift.cpp @@ -41,8 +41,8 @@ using namespace RHEO_NS; /* ---------------------------------------------------------------------- */ ComputeRHEOVShift::ComputeRHEOVShift(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), list(nullptr), vshift(nullptr), fix_rheo(nullptr), - compute_kernel(nullptr), compute_interface(nullptr), compute_surface(nullptr) + Compute(lmp, narg, arg), vshift(nullptr), fix_rheo(nullptr), rho0(nullptr), list(nullptr), + compute_interface(nullptr), compute_kernel(nullptr), compute_surface(nullptr) { if (narg != 3) error->all(FLERR,"Illegal compute RHEO/VShift command"); @@ -90,7 +90,7 @@ void ComputeRHEOVShift::init_list(int /*id*/, NeighList *ptr) void ComputeRHEOVShift::compute_peratom() { - int i, j, a, b, ii, jj, jnum, itype, jtype; + int i, j, a, ii, jj, jnum, itype, jtype; int fluidi, fluidj; double xtmp, ytmp, ztmp, rsq, r, rinv; double w, wp, dr, w0, w4, vmag, prefactor; @@ -108,6 +108,7 @@ void ComputeRHEOVShift::compute_peratom() double **v = atom->v; double *rho = atom->rho; double *mass = atom->mass; + double *rmass = atom->rmass; int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; @@ -140,7 +141,8 @@ void ComputeRHEOVShift::compute_peratom() itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; - imass = mass[itype]; + if (rmass) imass = rmass[i]; + else imass = mass[itype]; fluidi = !(status[i] & PHASECHECK); for (jj = 0; jj < jnum; jj++) { @@ -160,7 +162,8 @@ void ComputeRHEOVShift::compute_peratom() if (rsq < cutsq) { jtype = type[j]; - jmass = mass[jtype]; + if (rmass) jmass = rmass[j]; + else jmass = mass[jtype]; r = sqrt(rsq); rinv = 1 / r; @@ -229,8 +232,6 @@ void ComputeRHEOVShift::correct_surfaces() { if (!surface_flag) return; - int i, a, b; - int *status = atom->rheo_status; int *mask = atom->mask; double **nsurface = compute_surface->nsurface; @@ -239,7 +240,7 @@ void ComputeRHEOVShift::correct_surfaces() int dim = domain->dimension; double nx, ny, nz, vx, vy, vz, dot; - for (i = 0; i < nlocal; i++) { + for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { if (status[i] & PHASECHECK) continue; @@ -283,11 +284,11 @@ void ComputeRHEOVShift::correct_surfaces() int ComputeRHEOVShift::pack_reverse_comm(int n, int first, double *buf) { - int i,m,last; + int m, last; m = 0; last = first + n; - for (i = first; i < last; i++) { + for (int i = first; i < last; i++) { buf[m++] = vshift[i][0]; buf[m++] = vshift[i][1]; buf[m++] = vshift[i][2]; diff --git a/src/RHEO/fix_rheo.cpp b/src/RHEO/fix_rheo.cpp index f70b9e121f..b093eff681 100644 --- a/src/RHEO/fix_rheo.cpp +++ b/src/RHEO/fix_rheo.cpp @@ -50,8 +50,9 @@ static const char cite_rheo[] = /* ---------------------------------------------------------------------- */ FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), compute_grad(nullptr), compute_kernel(nullptr), compute_surface(nullptr), - compute_interface(nullptr), compute_rhosum(nullptr), compute_vshift(nullptr), rho0(nullptr), csq(nullptr) + Fix(lmp, narg, arg), rho0(nullptr), csq(nullptr), compute_grad(nullptr), compute_kernel(nullptr), + compute_interface(nullptr), compute_surface(nullptr), compute_rhosum(nullptr), + compute_vshift(nullptr) { time_integrate = 1; @@ -457,7 +458,6 @@ void FixRHEO::final_integrate() double dtfm, divu; int i, a; - double **x = atom->x; double **v = atom->v; double **f = atom->f; double **gradv = compute_grad->gradv; @@ -469,7 +469,6 @@ void FixRHEO::final_integrate() int *mask = atom->mask; int *status = atom->rheo_status; - int rmass_flag = atom->rmass_flag; int dim = domain->dimension; // Update velocity @@ -477,7 +476,7 @@ void FixRHEO::final_integrate() if (mask[i] & groupbit) { if (status[i] & STATUS_NO_INTEGRATION) continue; - if (rmass_flag) { + if (rmass) { dtfm = dtf / rmass[i]; } else { dtfm = dtf / mass[type[i]]; diff --git a/src/RHEO/fix_rheo_oxidation.cpp b/src/RHEO/fix_rheo_oxidation.cpp index a51f2feb95..699f3428c8 100644 --- a/src/RHEO/fix_rheo_oxidation.cpp +++ b/src/RHEO/fix_rheo_oxidation.cpp @@ -155,7 +155,6 @@ void FixRHEOOxidation::post_integrate() double delx, dely, delz, rsq; tagint tagi, tagj; - int nlocal = atom->nlocal; int newton_bond = force->newton_bond; tagint *tag = atom->tag; @@ -267,7 +266,7 @@ void FixRHEOOxidation::post_force(int /*vflag*/) int FixRHEOOxidation::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i, j, k, m; + int i, j, m; double **x = atom->x; m = 0; @@ -284,7 +283,7 @@ int FixRHEOOxidation::pack_forward_comm(int n, int *list, double *buf, void FixRHEOOxidation::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last; + int i, m, last; double **x = atom->x; m = 0; last = first + n; diff --git a/src/RHEO/fix_rheo_pressure.cpp b/src/RHEO/fix_rheo_pressure.cpp index 82adf52012..84b0825570 100644 --- a/src/RHEO/fix_rheo_pressure.cpp +++ b/src/RHEO/fix_rheo_pressure.cpp @@ -39,7 +39,9 @@ static constexpr double SEVENTH = 1.0 / 7.0; /* ---------------------------------------------------------------------- */ FixRHEOPressure::FixRHEOPressure(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), fix_rheo(nullptr), rho0(nullptr), csq(nullptr), rho0inv(nullptr), csqinv(nullptr), c_cubic(nullptr), tpower(nullptr), pbackground(nullptr), pressure_style(nullptr) + Fix(lmp, narg, arg), c_cubic(nullptr), csq(nullptr), csqinv(nullptr), rho0(nullptr), + rho0inv(nullptr), tpower(nullptr), pbackground(nullptr), pressure_style(nullptr), + fix_rheo(nullptr) { if (narg < 4) error->all(FLERR,"Illegal fix command"); @@ -160,9 +162,6 @@ void FixRHEOPressure::setup_pre_force(int /*vflag*/) void FixRHEOPressure::pre_force(int /*vflag*/) { - int i; - double dr, rr3, rho_ratio; - int *mask = atom->mask; int *type = atom->type; double *rho = atom->rho; @@ -170,7 +169,7 @@ void FixRHEOPressure::pre_force(int /*vflag*/) int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) pressure[i] = calc_pressure(rho[i], type[i]); @@ -182,12 +181,10 @@ void FixRHEOPressure::pre_force(int /*vflag*/) int FixRHEOPressure::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i,j,k,m; double *pressure = atom->pressure; - m = 0; - - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; buf[m++] = pressure[j]; } return m; @@ -197,12 +194,10 @@ int FixRHEOPressure::pack_forward_comm(int n, int *list, double *buf, void FixRHEOPressure::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last; double *pressure = atom->pressure; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { pressure[i] = buf[m++]; } } @@ -211,7 +206,8 @@ void FixRHEOPressure::unpack_forward_comm(int n, int first, double *buf) double FixRHEOPressure::calc_pressure(double rho, int type) { - double p, dr, rr3, rho_ratio; + double p = 0.0; + double dr, rr3, rho_ratio; if (pressure_style[type] == LINEAR) { p = csq[type] * (rho - rho0[type]); @@ -234,7 +230,7 @@ double FixRHEOPressure::calc_pressure(double rho, int type) double FixRHEOPressure::calc_rho(double p, int type) { - double rho, dr, rr3, rho_ratio; + double rho = 0.0; if (pressure_style[type] == LINEAR) { rho = csqinv[type] * p + rho0[type]; diff --git a/src/RHEO/fix_rheo_thermal.cpp b/src/RHEO/fix_rheo_thermal.cpp index c8c1877e32..a7d9fc8df9 100644 --- a/src/RHEO/fix_rheo_thermal.cpp +++ b/src/RHEO/fix_rheo_thermal.cpp @@ -60,10 +60,9 @@ static const char cite_rheo_oxide[] = /* ---------------------------------------------------------------------- */ FixRHEOThermal::FixRHEOThermal(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), compute_vshift(nullptr), - Tc(nullptr), kappa(nullptr), cv(nullptr), L(nullptr), - Tc_style(nullptr), kappa_style(nullptr), cv_style(nullptr), L_style(nullptr), - fix_update_special_bonds(nullptr) + Fix(lmp, narg, arg), cv(nullptr), Tc(nullptr), kappa(nullptr), L(nullptr), cv_style(nullptr), + Tc_style(nullptr), kappa_style(nullptr), L_style(nullptr), list(nullptr), fix_rheo(nullptr), + compute_grad(nullptr), compute_vshift(nullptr), fix_update_special_bonds(nullptr) { if (narg < 4) error->all(FLERR,"Illegal fix command"); @@ -189,13 +188,14 @@ FixRHEOThermal::FixRHEOThermal(LAMMPS *lmp, int narg, char **arg) : cut_bond = utils::numeric(FLERR, arg[iarg + 1], false, lmp); btype = utils::numeric(FLERR, arg[iarg + 2], false, lmp); comm_forward = 4; - if (cut_bond <= 0.0) error->all(FLERR, "Illegal max bond length must be greater than zero");\ - if (btype < 1 || btype > atom->nbondtypes) error->all(FLERR, "Illegal value for bond type"); + if (cut_bond <= 0.0) error->all(FLERR, "Illegal max bond length must be greater than zero"); + if ((btype < 1) || (btype > atom->nbondtypes)) + error->all(FLERR, "Illegal value {} for bond type", btype); cutsq_bond = cut_bond * cut_bond; iarg += 3; } else { - error->all(FLERR,"Illegal fix command, {}", arg[iarg]); + error->all(FLERR,"Unknown fix rheo/thermal keyword: {}", arg[iarg]); } } @@ -460,20 +460,16 @@ void FixRHEOThermal::post_neighbor() void FixRHEOThermal::pre_force(int /*vflag*/) { - int i, itype; double cvi, Tci, Ti, Li; double *energy = atom->esph; double *temperature = atom->temperature; int *type = atom->type; - int *status = atom->rheo_status; - - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; + int nall = atom->nlocal + atom->nghost; // Calculate temperature - for (i = 0; i < nall; i++) { - itype = type[i]; + for (int i = 0; i < nall; i++) { + int itype = type[i]; cvi = calc_cv(i, itype); temperature[i] = energy[i] / cvi; @@ -529,7 +525,6 @@ void FixRHEOThermal::break_bonds() int nbondlist = neighbor->nbondlist; int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; // Delete all bonds for local atoms that melt of a given type for (int i = 0; i < nlocal; i++) { @@ -753,13 +748,11 @@ double FixRHEOThermal::calc_L(int i, int itype) int FixRHEOThermal::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i, j, k, m; int *status = atom->rheo_status; double **x = atom->x; - m = 0; - - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; buf[m++] = ubuf(status[j]).d; buf[m++] = x[j][0]; buf[m++] = x[j][1]; @@ -772,12 +765,11 @@ int FixRHEOThermal::pack_forward_comm(int n, int *list, double *buf, void FixRHEOThermal::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last; int *status = atom->rheo_status; double **x = atom->x; - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { status[i] = (int) ubuf(buf[m++]).i; x[i][0] = buf[m++]; x[i][1] = buf[m++]; diff --git a/src/RHEO/fix_rheo_viscosity.cpp b/src/RHEO/fix_rheo_viscosity.cpp index 3ca7fd8d13..5f7a1208c5 100644 --- a/src/RHEO/fix_rheo_viscosity.cpp +++ b/src/RHEO/fix_rheo_viscosity.cpp @@ -38,8 +38,8 @@ enum {NONE, CONSTANT, POWER}; /* ---------------------------------------------------------------------- */ FixRHEOViscosity::FixRHEOViscosity(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), eta(nullptr), - npow(nullptr), K(nullptr), gd0(nullptr), tau0(nullptr), viscosity_style(nullptr) + Fix(lmp, narg, arg), eta(nullptr), npow(nullptr), K(nullptr), gd0(nullptr), tau0(nullptr), + viscosity_style(nullptr), fix_rheo(nullptr), compute_grad(nullptr) { if (narg < 4) error->all(FLERR, "Illegal fix command"); @@ -225,12 +225,10 @@ void FixRHEOViscosity::pre_force(int /*vflag*/) int FixRHEOViscosity::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/) { - int i, j, k, m; double *viscosity = atom->viscosity; - m = 0; - - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; buf[m++] = viscosity[j]; } return m; @@ -240,12 +238,10 @@ int FixRHEOViscosity::pack_forward_comm(int n, int *list, double *buf, void FixRHEOViscosity::unpack_forward_comm(int n, int first, double *buf) { - int i, k, m, last; double *viscosity = atom->viscosity; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { viscosity[i] = buf[m++]; } } diff --git a/src/RHEO/pair_rheo.cpp b/src/RHEO/pair_rheo.cpp index 9ebf884b6e..520a1c4470 100644 --- a/src/RHEO/pair_rheo.cpp +++ b/src/RHEO/pair_rheo.cpp @@ -47,8 +47,9 @@ static constexpr double EPSILON = 1e-2; /* ---------------------------------------------------------------------- */ PairRHEO::PairRHEO(LAMMPS *lmp) : - Pair(lmp), compute_kernel(nullptr), compute_grad(nullptr), compute_interface(nullptr), fix_rheo(nullptr), - fix_pressure(nullptr), rho0(nullptr), csq(nullptr), cs(nullptr) + Pair(lmp), csq(nullptr), rho0(nullptr), cs(nullptr), compute_kernel(nullptr), + compute_grad(nullptr), compute_interface(nullptr), fix_rheo(nullptr), + fix_pressure(nullptr) { restartinfo = 0; single_enable = 0; @@ -80,10 +81,10 @@ void PairRHEO::compute(int eflag, int vflag) int i, j, a, b, ii, jj, inum, jnum, itype, jtype; int pair_force_flag, pair_rho_flag, pair_avisc_flag; int fluidi, fluidj; - double xtmp, ytmp, ztmp, w, wp, Ti, Tj, dT, csq_ave, cs_ave; + double xtmp, ytmp, ztmp, wp, Ti, Tj, dT, csq_ave, cs_ave; double rhoi, rhoj, rho0i, rho0j, voli, volj, Pi, Pj, etai, etaj, kappai, kappaj, eta_ave, kappa_ave, dT_prefactor; double mu, q, fp_prefactor, drho_damp, fmag, psi_ij, Fij; - double *dWij, *dWji, *dW1ij, *dW1ji; + double *dWij, *dWji; double dx[3], du[3], dv[3], fv[3], dfp[3], fsolid[3], ft[3], vi[3], vj[3]; int *ilist, *jlist, *numneigh, **firstneigh; @@ -102,16 +103,15 @@ void PairRHEO::compute(int eflag, int vflag) double **f = atom->f; double *rho = atom->rho; double *mass = atom->mass; + double *rmass = atom->rmass; double *drho = atom->drho; double *pressure = atom->pressure; double *viscosity = atom->viscosity; double *conductivity = atom->conductivity; double *temperature = atom->temperature; double *heatflow = atom->heatflow; - double *special_lj = force->special_lj; int *type = atom->type; int *status = atom->rheo_status; - tagint *tag = atom->tag; double **fp_store, *chi; if (compute_interface) { @@ -150,7 +150,8 @@ void PairRHEO::compute(int eflag, int vflag) itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; - imass = mass[itype]; + if (rmass) imass = rmass[i]; + else imass = mass[itype]; etai = viscosity[i]; fluidi = !(status[i] & PHASECHECK); if (thermal_flag) { @@ -172,7 +173,8 @@ void PairRHEO::compute(int eflag, int vflag) r = sqrt(rsq); rinv = 1 / r; - jmass = mass[jtype]; + if (rmass) jmass = rmass[i]; + else jmass = mass[jtype]; etaj = viscosity[j]; fluidj = !(status[j] & PHASECHECK); if (thermal_flag) { @@ -461,11 +463,13 @@ void PairRHEO::setup() { auto fixes = modify->get_fix_by_style("rheo"); if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use pair rheo"); + if (fixes.size() > 1) error->all(FLERR, "Must have only one fix rheo defined"); fix_rheo = dynamic_cast(fixes[0]); // Currently only allow one instance of fix rheo/pressure fixes = modify->get_fix_by_style("rheo/pressure"); if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo/pressure to use pair rheo"); + if (fixes.size() > 1) error->all(FLERR, "Must have only one fix rheo/pressure defined"); fix_pressure = dynamic_cast(fixes[0]); compute_kernel = fix_rheo->compute_kernel; @@ -518,12 +522,10 @@ double PairRHEO::init_one(int i, int j) int PairRHEO::pack_reverse_comm(int n, int first, double *buf) { - int i, k, m, last; double **fp_store = compute_interface->fp_store; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { buf[m++] = fp_store[i][0]; buf[m++] = fp_store[i][1]; buf[m++] = fp_store[i][2]; @@ -536,12 +538,10 @@ int PairRHEO::pack_reverse_comm(int n, int first, double *buf) void PairRHEO::unpack_reverse_comm(int n, int *list, double *buf) { - int i, j, k, m; double **fp_store = compute_interface->fp_store; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; fp_store[j][0] += buf[m++]; fp_store[j][1] += buf[m++]; fp_store[j][2] += buf[m++]; diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index ac71ea01a6..41708823bb 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -21,6 +21,7 @@ #include "comm.h" #include "domain.h" #include "error.h" +#include "label_map.h" #include "fix_respa.h" #include "force.h" #include "group.h" @@ -98,6 +99,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : comm_forward = 3; // parse SHAKE args + auto mystyle = fmt::format("fix {}", style); if (narg < 8) utils::missing_cmd_args(FLERR, mystyle, error); @@ -106,6 +108,21 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : max_iter = utils::inumeric(FLERR, arg[4], false, lmp); output_every = utils::inumeric(FLERR, arg[5], false, lmp); + // check if any typelabels conflict with fix shake arguments. + + bool allow_typelabels = (atom->labelmapflag != 0); + if (allow_typelabels) { + for (int i = Atom::ATOM; i < Atom::DIHEDRAL; ++i) { + if ((atom->lmap->find("b", i) >= 0) || + (atom->lmap->find("a", i) >= 0) || + (atom->lmap->find("t", i) >= 0) || + (atom->lmap->find("m", i) >= 0)) allow_typelabels = false; + } + if (!allow_typelabels && (comm->me == 0)) + error->warning(FLERR, "At least one typelabel conflicts with a fix shake option: " + "support for typelabels is disabled."); + } + // parse SHAKE args for bond and angle types // will be used by find_clusters // store args for "b" "a" "t" as flags in (1:n) list for fast access @@ -124,6 +141,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : char mode = '\0'; int next = 6; while (next < narg) { + int i = -1; if (strcmp(arg[next],"b") == 0) mode = 'b'; else if (strcmp(arg[next],"a") == 0) mode = 'a'; else if (strcmp(arg[next],"t") == 0) mode = 't'; @@ -131,33 +149,40 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : mode = 'm'; atom->check_mass(FLERR); - // break if keyword that is not b,a,t,m + // break if known optional keyword - } else if (isalpha(arg[next][0])) break; + } else if ((strcmp(arg[next], "mol") == 0) || (strcmp(arg[next], "kbond") == 0)) { + break; - // read numeric args of b,a,t,m + // get numeric types for b, a, t, or m keywords. + + } else if (mode == 'b') { + if (allow_typelabels) i = utils::expand_type_int(FLERR, arg[next], Atom::BOND, lmp); + else i = utils::inumeric(FLERR, arg[next], false, lmp); - else if (mode == 'b') { - int i = utils::inumeric(FLERR,arg[next],false,lmp); if (i < 1 || i > atom->nbondtypes) - error->all(FLERR,"Invalid bond type index for {}", mystyle); + error->all(FLERR,"Invalid bond type {} index for {}", arg[next], mystyle); bond_flag[i] = 1; } else if (mode == 'a') { - int i = utils::inumeric(FLERR,arg[next],false,lmp); + if (allow_typelabels) i = utils::expand_type_int(FLERR, arg[next], Atom::ANGLE, lmp); + else i = utils::inumeric(FLERR, arg[next], false, lmp); + if (i < 1 || i > atom->nangletypes) - error->all(FLERR,"Invalid angle type index for {}", mystyle); + error->all(FLERR,"Invalid angle type {} for {}", arg[next], mystyle); angle_flag[i] = 1; } else if (mode == 't') { - int i = utils::inumeric(FLERR,arg[next],false,lmp); + if (allow_typelabels) i = utils::expand_type_int(FLERR, arg[next], Atom::ATOM, lmp); + else i = utils::inumeric(FLERR, arg[next], false, lmp); + if (i < 1 || i > atom->ntypes) - error->all(FLERR,"Invalid atom type index for {}", mystyle); + error->all(FLERR,"Invalid atom type {} for {}", arg[next], mystyle); type_flag[i] = 1; } else if (mode == 'm') { - double massone = utils::numeric(FLERR,arg[next],false,lmp); - if (massone == 0.0) error->all(FLERR,"Invalid atom mass for {}", mystyle); + double massone = utils::numeric(FLERR, arg[next], false, lmp); + if (massone == 0.0) error->all(FLERR,"Invalid atom mass {} for {}", arg[next], mystyle); if (nmass == atom->ntypes) error->all(FLERR,"Too many masses for {}", mystyle); mass_list[nmass++] = massone; diff --git a/src/SPH/compute_sph_e_atom.cpp b/src/SPH/compute_sph_e_atom.cpp index 05e752c49b..b98fd97479 100644 --- a/src/SPH/compute_sph_e_atom.cpp +++ b/src/SPH/compute_sph_e_atom.cpp @@ -13,13 +13,15 @@ ------------------------------------------------------------------------- */ #include "compute_sph_e_atom.h" -#include + #include "atom.h" -#include "update.h" -#include "modify.h" #include "comm.h" -#include "memory.h" #include "error.h" +#include "memory.h" +#include "modify.h" +#include "update.h" + +#include using namespace LAMMPS_NS; @@ -31,7 +33,7 @@ ComputeSPHEAtom::ComputeSPHEAtom(LAMMPS *lmp, int narg, char **arg) : if (narg != 3) error->all(FLERR,"Number of arguments for compute sph/e/atom command != 3"); if (atom->esph_flag != 1) - error->all(FLERR,"Compute sph/e/atom command requires atom_style sph)"); + error->all(FLERR,"Compute sph/e/atom requires atom attribute energy, e.g. in atom_style sph"); peratom_flag = 1; size_peratom_cols = 0; @@ -51,12 +53,11 @@ ComputeSPHEAtom::~ComputeSPHEAtom() void ComputeSPHEAtom::init() { - int count = 0; for (int i = 0; i < modify->ncompute; i++) - if (strcmp(modify->compute[i]->style,"evector/atom") == 0) count++; + if (strcmp(modify->compute[i]->style,"sph/e/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning(FLERR,"More than one compute evector/atom"); + error->warning(FLERR,"More than one compute sph/e/atom"); } /* ---------------------------------------------------------------------- */ @@ -78,14 +79,13 @@ void ComputeSPHEAtom::compute_peratom() int *mask = atom->mask; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - if (mask[i] & groupbit) { - evector[i] = esph[i]; - } - else { - evector[i] = 0.0; - } + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + evector[i] = esph[i]; + } else { + evector[i] = 0.0; } + } } /* ---------------------------------------------------------------------- diff --git a/src/SPH/compute_sph_rho_atom.cpp b/src/SPH/compute_sph_rho_atom.cpp index 9c596bdfc3..54d1237368 100644 --- a/src/SPH/compute_sph_rho_atom.cpp +++ b/src/SPH/compute_sph_rho_atom.cpp @@ -13,13 +13,15 @@ ------------------------------------------------------------------------- */ #include "compute_sph_rho_atom.h" -#include + #include "atom.h" -#include "update.h" -#include "modify.h" #include "comm.h" -#include "memory.h" #include "error.h" +#include "memory.h" +#include "modify.h" +#include "update.h" + +#include using namespace LAMMPS_NS; @@ -30,8 +32,7 @@ ComputeSPHRhoAtom::ComputeSPHRhoAtom(LAMMPS *lmp, int narg, char **arg) : { if (narg != 3) error->all(FLERR,"Illegal compute sph/rho/atom command"); if (atom->rho_flag != 1) - error->all(FLERR,"Compute sph/rho/atom command requires atom_style sph"); - + error->all(FLERR, "Compute sph/rho/atom requires atom attribute density, e.g. in atom_style sph"); peratom_flag = 1; size_peratom_cols = 0; @@ -50,12 +51,11 @@ ComputeSPHRhoAtom::~ComputeSPHRhoAtom() void ComputeSPHRhoAtom::init() { - int count = 0; for (int i = 0; i < modify->ncompute; i++) - if (strcmp(modify->compute[i]->style,"rhoVector/atom") == 0) count++; + if (strcmp(modify->compute[i]->style,"sph/rho/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning(FLERR,"More than one compute rhoVector/atom"); + error->warning(FLERR,"More than one compute sph/rho/atom"); } /* ---------------------------------------------------------------------- */ @@ -73,20 +73,17 @@ void ComputeSPHRhoAtom::compute_peratom() vector_atom = rhoVector; } - // compute kinetic energy for each atom in group - double *rho = atom->rho; int *mask = atom->mask; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - if (mask[i] & groupbit) { - rhoVector[i] = rho[i]; - } - else { - rhoVector[i] = 0.0; - } + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + rhoVector[i] = rho[i]; + } else { + rhoVector[i] = 0.0; } + } } /* ---------------------------------------------------------------------- diff --git a/src/SPH/compute_sph_t_atom.cpp b/src/SPH/compute_sph_t_atom.cpp index 4a83013434..e795c32a5e 100644 --- a/src/SPH/compute_sph_t_atom.cpp +++ b/src/SPH/compute_sph_t_atom.cpp @@ -13,13 +13,15 @@ ------------------------------------------------------------------------- */ #include "compute_sph_t_atom.h" -#include + #include "atom.h" -#include "update.h" -#include "modify.h" #include "comm.h" -#include "memory.h" #include "error.h" +#include "memory.h" +#include "modify.h" +#include "update.h" + +#include using namespace LAMMPS_NS; @@ -31,7 +33,7 @@ ComputeSPHTAtom::ComputeSPHTAtom(LAMMPS *lmp, int narg, char **arg) : if (narg != 3) error->all(FLERR,"Number of arguments for compute sph/t/atom command != 3"); if ((atom->esph_flag != 1) || (atom->cv_flag != 1)) - error->all(FLERR,"Compute sph/t/atom command requires atom_style sph"); + error->all(FLERR, "Compute sph/t/atom requires atom attributes energy and specific heat, e.g. in atom_style sph"); peratom_flag = 1; size_peratom_cols = 0; @@ -51,12 +53,11 @@ ComputeSPHTAtom::~ComputeSPHTAtom() void ComputeSPHTAtom::init() { - int count = 0; for (int i = 0; i < modify->ncompute; i++) - if (strcmp(modify->compute[i]->style,"meso/t/atom") == 0) count++; + if (strcmp(modify->compute[i]->style,"sph/t/atom") == 0) count++; if (count > 1 && comm->me == 0) - error->warning(FLERR,"More than one compute meso/t/atom"); + error->warning(FLERR,"More than one compute sph/t/atom"); } /* ---------------------------------------------------------------------- */ @@ -79,16 +80,15 @@ void ComputeSPHTAtom::compute_peratom() int *mask = atom->mask; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - if (mask[i] & groupbit) { - if (cv[i] > 0.0) { - tvector[i] = esph[i] / cv[i]; - } - } - else { - tvector[i] = 0.0; + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + if (cv[i] > 0.0) { + tvector[i] = esph[i] / cv[i]; } + } else { + tvector[i] = 0.0; } + } } /* ---------------------------------------------------------------------- diff --git a/src/SPH/fix_sph.cpp b/src/SPH/fix_sph.cpp index 0dafcee7c0..876d7ac4fb 100644 --- a/src/SPH/fix_sph.cpp +++ b/src/SPH/fix_sph.cpp @@ -13,10 +13,13 @@ ------------------------------------------------------------------------- */ #include "fix_sph.h" + #include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" #include "force.h" #include "update.h" -#include "error.h" using namespace LAMMPS_NS; using namespace FixConst; @@ -24,11 +27,10 @@ using namespace FixConst; /* ---------------------------------------------------------------------- */ FixSPH::FixSPH(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg) { - - if ((atom->esph_flag != 1) || (atom->rho_flag != 1)) - error->all(FLERR, - "Fix sph command requires atom_style with both energy and density"); + Fix(lmp, narg, arg) +{ + if ((atom->esph_flag != 1) || (atom->rho_flag != 1) || (atom->vest_flag != 1)) + error->all(FLERR, "Fix sph requires atom attributes energy, density, and velocity estimates, e.g. in atom_style sph"); if (narg != 3) error->all(FLERR,"Illegal number of arguments for fix sph command"); @@ -38,7 +40,8 @@ FixSPH::FixSPH(LAMMPS *lmp, int narg, char **arg) : /* ---------------------------------------------------------------------- */ -int FixSPH::setmask() { +int FixSPH::setmask() +{ int mask = 0; mask |= INITIAL_INTEGRATE; mask |= FINAL_INTEGRATE; @@ -48,13 +51,20 @@ int FixSPH::setmask() { /* ---------------------------------------------------------------------- */ -void FixSPH::init() { +void FixSPH::init() +{ dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; } +/* ---------------------------------------------------------------------- */ + void FixSPH::setup_pre_force(int /*vflag*/) { + remap_v_flag = domain->deform_vremap; + if (remap_v_flag && (!comm->ghost_velocity)) + error->all(FLERR, "Fix sph requires ghost atoms store velocity when deforming with remap v"); + // set vest equal to v double **v = atom->v; double **vest = atom->vest; @@ -76,7 +86,8 @@ void FixSPH::setup_pre_force(int /*vflag*/) allow for both per-type and per-atom mass ------------------------------------------------------------------------- */ -void FixSPH::initial_integrate(int /*vflag*/) { +void FixSPH::initial_integrate(int /*vflag*/) +{ // update v and x and rho and e of atoms in group double **x = atom->x; @@ -112,9 +123,16 @@ void FixSPH::initial_integrate(int /*vflag*/) { rho[i] += dtf * drho[i]; // ... and density // extrapolate velocity for use with velocity-dependent potentials, e.g. SPH - vest[i][0] = v[i][0] + 2.0 * dtfm * f[i][0]; - vest[i][1] = v[i][1] + 2.0 * dtfm * f[i][1]; - vest[i][2] = v[i][2] + 2.0 * dtfm * f[i][2]; + // if velocities are remapped, perform this extrapolation after communication + if (remap_v_flag) { + vest[i][0] = dtfm * f[i][0]; + vest[i][1] = dtfm * f[i][1]; + vest[i][2] = dtfm * f[i][2]; + } else { + vest[i][0] = v[i][0] + 2.0 * dtfm * f[i][0]; + vest[i][1] = v[i][1] + 2.0 * dtfm * f[i][1]; + vest[i][2] = v[i][2] + 2.0 * dtfm * f[i][2]; + } v[i][0] += dtfm * f[i][0]; v[i][1] += dtfm * f[i][1]; @@ -129,8 +147,33 @@ void FixSPH::initial_integrate(int /*vflag*/) { /* ---------------------------------------------------------------------- */ -void FixSPH::final_integrate() { +void FixSPH::pre_force(int /*vflag*/) +{ + // if velocities are remapped, calculate estimates here + // note that vest currently stores dtfm * force + if (!remap_v_flag) return; + double **v = atom->v; + double **vest = atom->vest; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) + nlocal = atom->nfirst; + + int nall = nlocal + atom->nghost; + for (int i = 0; i < nall; i++) { + if (mask[i] & groupbit) { + vest[i][0] += v[i][0]; + vest[i][1] += v[i][1]; + vest[i][2] += v[i][2]; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void FixSPH::final_integrate() +{ // update v, rho, and e of atoms in group double **v = atom->v; @@ -169,7 +212,8 @@ void FixSPH::final_integrate() { /* ---------------------------------------------------------------------- */ -void FixSPH::reset_dt() { +void FixSPH::reset_dt() +{ dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; } diff --git a/src/SPH/fix_sph.h b/src/SPH/fix_sph.h index 415e38bd21..7676844dd9 100644 --- a/src/SPH/fix_sph.h +++ b/src/SPH/fix_sph.h @@ -30,6 +30,7 @@ class FixSPH : public Fix { int setmask() override; void init() override; void setup_pre_force(int) override; + void pre_force(int) override; void initial_integrate(int) override; void final_integrate() override; void reset_dt() override; @@ -41,6 +42,7 @@ class FixSPH : public Fix { double dtv, dtf; double *step_respa; int mass_require; + int remap_v_flag; class Pair *pair; }; diff --git a/src/SPH/fix_sph_stationary.cpp b/src/SPH/fix_sph_stationary.cpp index 673a7d50bf..877bb5b17b 100644 --- a/src/SPH/fix_sph_stationary.cpp +++ b/src/SPH/fix_sph_stationary.cpp @@ -13,10 +13,11 @@ ------------------------------------------------------------------------- */ #include "fix_sph_stationary.h" + #include "atom.h" +#include "error.h" #include "force.h" #include "update.h" -#include "error.h" using namespace LAMMPS_NS; using namespace FixConst; @@ -24,11 +25,10 @@ using namespace FixConst; /* ---------------------------------------------------------------------- */ FixSPHStationary::FixSPHStationary(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg) { - + Fix(lmp, narg, arg) +{ if ((atom->esph_flag != 1) || (atom->rho_flag != 1)) - error->all(FLERR, - "Fix sph/stationary command requires atom_style with both energy and density, e.g. meso"); + error->all(FLERR, "Fix sph/stationary requires atom attributes energy and density, e.g. in atom_style sph"); if (narg != 3) error->all(FLERR,"Illegal number of arguments for fix sph/stationary command"); @@ -38,7 +38,8 @@ FixSPHStationary::FixSPHStationary(LAMMPS *lmp, int narg, char **arg) : /* ---------------------------------------------------------------------- */ -int FixSPHStationary::setmask() { +int FixSPHStationary::setmask() +{ int mask = 0; mask |= INITIAL_INTEGRATE; mask |= FINAL_INTEGRATE; @@ -47,7 +48,8 @@ int FixSPHStationary::setmask() { /* ---------------------------------------------------------------------- */ -void FixSPHStationary::init() { +void FixSPHStationary::init() +{ dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; } @@ -56,8 +58,8 @@ void FixSPHStationary::init() { allow for both per-type and per-atom mass ------------------------------------------------------------------------- */ -void FixSPHStationary::initial_integrate(int /*vflag*/) { - +void FixSPHStationary::initial_integrate(int /*vflag*/) +{ double *rho = atom->rho; double *drho = atom->drho; double *esph = atom->esph; @@ -80,8 +82,8 @@ void FixSPHStationary::initial_integrate(int /*vflag*/) { /* ---------------------------------------------------------------------- */ -void FixSPHStationary::final_integrate() { - +void FixSPHStationary::final_integrate() +{ double *esph = atom->esph; double *desph = atom->desph; double *rho = atom->rho; @@ -101,7 +103,8 @@ void FixSPHStationary::final_integrate() { /* ---------------------------------------------------------------------- */ -void FixSPHStationary::reset_dt() { +void FixSPHStationary::reset_dt() +{ dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; } diff --git a/src/SPH/fix_sph_stationary.h b/src/SPH/fix_sph_stationary.h index 51e336a038..78ece5e5d4 100644 --- a/src/SPH/fix_sph_stationary.h +++ b/src/SPH/fix_sph_stationary.h @@ -33,9 +33,6 @@ class FixSPHStationary : public Fix { void final_integrate() override; void reset_dt() override; - private: - class NeighList *list; - protected: double dtv, dtf; double *step_respa; diff --git a/src/SPH/pair_sph_heatconduction.cpp b/src/SPH/pair_sph_heatconduction.cpp index cb27982fa3..145d9cadee 100644 --- a/src/SPH/pair_sph_heatconduction.cpp +++ b/src/SPH/pair_sph_heatconduction.cpp @@ -13,14 +13,15 @@ ------------------------------------------------------------------------- */ #include "pair_sph_heatconduction.h" -#include + #include "atom.h" +#include "domain.h" +#include "error.h" #include "force.h" #include "memory.h" -#include "error.h" #include "neigh_list.h" -#include "domain.h" +#include using namespace LAMMPS_NS; @@ -28,12 +29,16 @@ using namespace LAMMPS_NS; PairSPHHeatConduction::PairSPHHeatConduction(LAMMPS *lmp) : Pair(lmp) { + if ((atom->esph_flag != 1) || (atom->rho_flag != 1)) + error->all(FLERR, "Pair sph/heatconduction requires atom attributes energy and density, e.g. in atom_style sph"); + restartinfo = 0; } /* ---------------------------------------------------------------------- */ -PairSPHHeatConduction::~PairSPHHeatConduction() { +PairSPHHeatConduction::~PairSPHHeatConduction() +{ if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -44,7 +49,8 @@ PairSPHHeatConduction::~PairSPHHeatConduction() { /* ---------------------------------------------------------------------- */ -void PairSPHHeatConduction::compute(int eflag, int vflag) { +void PairSPHHeatConduction::compute(int eflag, int vflag) +{ int i, j, ii, jj, inum, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz; @@ -124,7 +130,6 @@ void PairSPHHeatConduction::compute(int eflag, int vflag) { if (newton_pair || j < nlocal) { desph[j] -= deltaE; } - } } } @@ -134,7 +139,8 @@ void PairSPHHeatConduction::compute(int eflag, int vflag) { allocate all arrays ------------------------------------------------------------------------- */ -void PairSPHHeatConduction::allocate() { +void PairSPHHeatConduction::allocate() +{ allocated = 1; int n = atom->ntypes; @@ -152,7 +158,8 @@ void PairSPHHeatConduction::allocate() { global settings ------------------------------------------------------------------------- */ -void PairSPHHeatConduction::settings(int narg, char **/*arg*/) { +void PairSPHHeatConduction::settings(int narg, char **/*arg*/) +{ if (narg != 0) error->all(FLERR, "Illegal number of arguments for pair_style sph/heatconduction"); @@ -162,7 +169,8 @@ void PairSPHHeatConduction::settings(int narg, char **/*arg*/) { set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSPHHeatConduction::coeff(int narg, char **arg) { +void PairSPHHeatConduction::coeff(int narg, char **arg) +{ if (narg != 4) error->all(FLERR,"Incorrect number of args for pair_style sph/heatconduction coefficients"); if (!allocated) @@ -178,7 +186,6 @@ void PairSPHHeatConduction::coeff(int narg, char **arg) { int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - //printf("setting cut[%d][%d] = %f\n", i, j, cut_one); cut[i][j] = cut_one; alpha[i][j] = alpha_one; setflag[i][j] = 1; @@ -194,7 +201,8 @@ void PairSPHHeatConduction::coeff(int narg, char **arg) { init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSPHHeatConduction::init_one(int i, int j) { +double PairSPHHeatConduction::init_one(int i, int j) +{ if (setflag[i][j] == 0) { error->all(FLERR,"All pair sph/heatconduction coeffs are not set"); @@ -209,7 +217,8 @@ double PairSPHHeatConduction::init_one(int i, int j) { /* ---------------------------------------------------------------------- */ double PairSPHHeatConduction::single(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, - double /*rsq*/, double /*factor_coul*/, double /*factor_lj*/, double &fforce) { + double /*rsq*/, double /*factor_coul*/, double /*factor_lj*/, double &fforce) +{ fforce = 0.0; return 0.0; diff --git a/src/SPH/pair_sph_idealgas.cpp b/src/SPH/pair_sph_idealgas.cpp index 114d323bbd..97cbda2ab3 100644 --- a/src/SPH/pair_sph_idealgas.cpp +++ b/src/SPH/pair_sph_idealgas.cpp @@ -13,14 +13,15 @@ ------------------------------------------------------------------------- */ #include "pair_sph_idealgas.h" -#include -#include "atom.h" -#include "force.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" -#include "domain.h" +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" + +#include using namespace LAMMPS_NS; @@ -28,12 +29,17 @@ using namespace LAMMPS_NS; PairSPHIdealGas::PairSPHIdealGas(LAMMPS *lmp) : Pair(lmp) { + if ((atom->esph_flag != 1) || (atom->rho_flag != 1) || (atom->vest_flag != 1)) + error->all(FLERR, "Pair sph/idealgas requires atom attributes energy, density, and velocity estimates, e.g. in atom_style sph"); + restartinfo = 0; + single_enable = 0; } /* ---------------------------------------------------------------------- */ -PairSPHIdealGas::~PairSPHIdealGas() { +PairSPHIdealGas::~PairSPHIdealGas() +{ if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -45,7 +51,8 @@ PairSPHIdealGas::~PairSPHIdealGas() { /* ---------------------------------------------------------------------- */ -void PairSPHIdealGas::compute(int eflag, int vflag) { +void PairSPHIdealGas::compute(int eflag, int vflag) +{ int i, j, ii, jj, inum, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz, fpair; @@ -160,10 +167,6 @@ void PairSPHIdealGas::compute(int eflag, int vflag) { if (evflag) ev_tally(i, j, nlocal, newton_pair, 0.0, 0.0, fpair, delx, dely, delz); - - if (evflag) - ev_tally(i, j, nlocal, newton_pair, 0.0, 0.0, fpair, delx, dely, - delz); } } } @@ -175,7 +178,8 @@ void PairSPHIdealGas::compute(int eflag, int vflag) { allocate all arrays ------------------------------------------------------------------------- */ -void PairSPHIdealGas::allocate() { +void PairSPHIdealGas::allocate() +{ allocated = 1; int n = atom->ntypes; @@ -194,7 +198,8 @@ void PairSPHIdealGas::allocate() { global settings ------------------------------------------------------------------------- */ -void PairSPHIdealGas::settings(int narg, char **/*arg*/) { +void PairSPHIdealGas::settings(int narg, char **/*arg*/) +{ if (narg != 0) error->all(FLERR, "Illegal number of arguments for pair_style sph/idealgas"); @@ -204,7 +209,8 @@ void PairSPHIdealGas::settings(int narg, char **/*arg*/) { set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSPHIdealGas::coeff(int narg, char **arg) { +void PairSPHIdealGas::coeff(int narg, char **arg) +{ if (narg != 4) error->all(FLERR,"Incorrect number of args for pair_style sph/idealgas coefficients"); if (!allocated) @@ -221,7 +227,6 @@ void PairSPHIdealGas::coeff(int narg, char **arg) { for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { viscosity[i][j] = viscosity_one; - //printf("setting cut[%d][%d] = %f\n", i, j, cut_one); cut[i][j] = cut_one; setflag[i][j] = 1; count++; @@ -236,8 +241,8 @@ void PairSPHIdealGas::coeff(int narg, char **arg) { init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSPHIdealGas::init_one(int i, int j) { - +double PairSPHIdealGas::init_one(int i, int j) +{ if (setflag[i][j] == 0) { error->all(FLERR,"All pair sph/idealgas coeffs are not set"); } @@ -246,12 +251,3 @@ double PairSPHIdealGas::init_one(int i, int j) { return cut[i][j]; } - -/* ---------------------------------------------------------------------- */ - -double PairSPHIdealGas::single(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, - double /*rsq*/, double /*factor_coul*/, double /*factor_lj*/, double &fforce) { - fforce = 0.0; - - return 0.0; -} diff --git a/src/SPH/pair_sph_idealgas.h b/src/SPH/pair_sph_idealgas.h index 3d61d76616..c3c11ac5bd 100644 --- a/src/SPH/pair_sph_idealgas.h +++ b/src/SPH/pair_sph_idealgas.h @@ -32,7 +32,6 @@ class PairSPHIdealGas : public Pair { void settings(int, char **) override; void coeff(int, char **) override; double init_one(int, int) override; - double single(int, int, int, int, double, double, double, double &) override; protected: double **cut, **viscosity; diff --git a/src/SPH/pair_sph_lj.cpp b/src/SPH/pair_sph_lj.cpp index d59a3ad992..4bdefca1a6 100644 --- a/src/SPH/pair_sph_lj.cpp +++ b/src/SPH/pair_sph_lj.cpp @@ -13,14 +13,15 @@ ------------------------------------------------------------------------- */ #include "pair_sph_lj.h" -#include -#include "atom.h" -#include "force.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" -#include "domain.h" +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" + +#include using namespace LAMMPS_NS; @@ -28,12 +29,17 @@ using namespace LAMMPS_NS; PairSPHLJ::PairSPHLJ(LAMMPS *lmp) : Pair(lmp) { + if ((atom->esph_flag != 1) || (atom->rho_flag != 1) || (atom->cv_flag != 1) || (atom->vest_flag != 1)) + error->all(FLERR, "Pair sph/lj requires atom attributes energy, density, specific heat, and velocity estimates, e.g. in atom_style sph"); + restartinfo = 0; + single_enable = 0; } /* ---------------------------------------------------------------------- */ -PairSPHLJ::~PairSPHLJ() { +PairSPHLJ::~PairSPHLJ() +{ if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -45,7 +51,8 @@ PairSPHLJ::~PairSPHLJ() { /* ---------------------------------------------------------------------- */ -void PairSPHLJ::compute(int eflag, int vflag) { +void PairSPHLJ::compute(int eflag, int vflag) +{ int i, j, ii, jj, inum, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz, fpair; @@ -182,7 +189,8 @@ void PairSPHLJ::compute(int eflag, int vflag) { allocate all arrays ------------------------------------------------------------------------- */ -void PairSPHLJ::allocate() { +void PairSPHLJ::allocate() +{ allocated = 1; int n = atom->ntypes; @@ -201,7 +209,8 @@ void PairSPHLJ::allocate() { global settings ------------------------------------------------------------------------- */ -void PairSPHLJ::settings(int narg, char **/*arg*/) { +void PairSPHLJ::settings(int narg, char **/*arg*/) +{ if (narg != 0) error->all(FLERR, "Illegal number of arguments for pair_style sph/lj"); @@ -211,7 +220,8 @@ void PairSPHLJ::settings(int narg, char **/*arg*/) { set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSPHLJ::coeff(int narg, char **arg) { +void PairSPHLJ::coeff(int narg, char **arg) +{ if (narg != 4) error->all(FLERR, "Incorrect args for pair_style sph/lj coefficients"); @@ -229,7 +239,6 @@ void PairSPHLJ::coeff(int narg, char **arg) { for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { viscosity[i][j] = viscosity_one; - printf("setting cut[%d][%d] = %f\n", i, j, cut_one); cut[i][j] = cut_one; setflag[i][j] = 1; count++; @@ -244,8 +253,8 @@ void PairSPHLJ::coeff(int narg, char **arg) { init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSPHLJ::init_one(int i, int j) { - +double PairSPHLJ::init_one(int i, int j) +{ if (setflag[i][j] == 0) { error->all(FLERR,"All pair sph/lj coeffs are not set"); } @@ -256,16 +265,6 @@ double PairSPHLJ::init_one(int i, int j) { return cut[i][j]; } -/* ---------------------------------------------------------------------- */ - -double PairSPHLJ::single(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, - double /*rsq*/, double /*factor_coul*/, double /*factor_lj*/, double &fforce) { - fforce = 0.0; - - return 0.0; -} - - /*double PairSPHLJ::LJEOS2(double rho, double e, double cv) { @@ -297,7 +296,8 @@ double PairSPHLJ::single(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, Journal of Chemical Physics 73 pp. 5401-5403 (1980) */ -void PairSPHLJ::LJEOS2(double rho, double e, double cv, double *p, double *c) { +void PairSPHLJ::LJEOS2(double rho, double e, double cv, double *p, double *c) +{ double T = e/cv; double beta = 1.0 / T; double beta_sqrt = sqrt(beta); diff --git a/src/SPH/pair_sph_lj.h b/src/SPH/pair_sph_lj.h index 47c34159e1..eb93a14de9 100644 --- a/src/SPH/pair_sph_lj.h +++ b/src/SPH/pair_sph_lj.h @@ -32,8 +32,6 @@ class PairSPHLJ : public Pair { void settings(int, char **) override; void coeff(int, char **) override; double init_one(int, int) override; - double single(int, int, int, int, double, double, double, double &) override; - //double LJEOS(int); void LJEOS2(double, double, double, double *, double *); protected: diff --git a/src/SPH/pair_sph_rhosum.cpp b/src/SPH/pair_sph_rhosum.cpp index 34adf3ce87..4fd96319ee 100644 --- a/src/SPH/pair_sph_rhosum.cpp +++ b/src/SPH/pair_sph_rhosum.cpp @@ -29,6 +29,9 @@ using namespace LAMMPS_NS; PairSPHRhoSum::PairSPHRhoSum(LAMMPS *lmp) : Pair(lmp) { + if (atom->rho_flag != 1) + error->all(FLERR, "Pair sph/rhosum requires atom attribute density, e.g. in atom_style sph"); + restartinfo = 0; // set comm size needed by this Pair @@ -39,11 +42,11 @@ PairSPHRhoSum::PairSPHRhoSum(LAMMPS *lmp) : Pair(lmp) /* ---------------------------------------------------------------------- */ -PairSPHRhoSum::~PairSPHRhoSum() { +PairSPHRhoSum::~PairSPHRhoSum() +{ if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); } } @@ -52,14 +55,16 @@ PairSPHRhoSum::~PairSPHRhoSum() { init specific to this pair style ------------------------------------------------------------------------- */ -void PairSPHRhoSum::init_style() { +void PairSPHRhoSum::init_style() +{ // need a full neighbor list neighbor->add_request(this, NeighConst::REQ_FULL); } /* ---------------------------------------------------------------------- */ -void PairSPHRhoSum::compute(int eflag, int vflag) { +void PairSPHRhoSum::compute(int eflag, int vflag) +{ int i, j, ii, jj, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz; double rsq, imass, h, ih, ihsq; @@ -75,25 +80,6 @@ void PairSPHRhoSum::compute(int eflag, int vflag) { int *type = atom->type; double *mass = atom->mass; - // check consistency of pair coefficients - - if (first) { - for (i = 1; i <= atom->ntypes; i++) { - for (j = 1; i <= atom->ntypes; i++) { - if (cutsq[i][j] > 0.0) { - if (!setflag[i][i] || !setflag[j][j]) { - if (comm->me == 0) { - printf( - "SPH particle types %d and %d interact, but not all of their single particle properties are set.\n", - i, j); - } - } - } - } - } - first = 0; - } - inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -186,7 +172,6 @@ void PairSPHRhoSum::compute(int eflag, int vflag) { rho[i] += mass[jtype] * wf; } - } } } @@ -200,7 +185,8 @@ void PairSPHRhoSum::compute(int eflag, int vflag) { allocate all arrays ------------------------------------------------------------------------- */ -void PairSPHRhoSum::allocate() { +void PairSPHRhoSum::allocate() +{ allocated = 1; int n = atom->ntypes; @@ -210,7 +196,6 @@ void PairSPHRhoSum::allocate() { setflag[i][j] = 0; memory->create(cutsq, n + 1, n + 1, "pair:cutsq"); - memory->create(cut, n + 1, n + 1, "pair:cut"); } @@ -218,7 +203,8 @@ void PairSPHRhoSum::allocate() { global settings ------------------------------------------------------------------------- */ -void PairSPHRhoSum::settings(int narg, char **arg) { +void PairSPHRhoSum::settings(int narg, char **arg) +{ if (narg != 1) error->all(FLERR, "Illegal number of arguments for pair_style sph/rhosum"); @@ -229,7 +215,8 @@ void PairSPHRhoSum::settings(int narg, char **arg) { set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSPHRhoSum::coeff(int narg, char **arg) { +void PairSPHRhoSum::coeff(int narg, char **arg) +{ if (narg != 3) error->all(FLERR,"Incorrect number of args for sph/rhosum coefficients"); if (!allocated) @@ -244,7 +231,6 @@ void PairSPHRhoSum::coeff(int narg, char **arg) { int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - //printf("setting cut[%d][%d] = %f\n", i, j, cut_one); cut[i][j] = cut_one; setflag[i][j] = 1; count++; @@ -259,7 +245,8 @@ void PairSPHRhoSum::coeff(int narg, char **arg) { init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSPHRhoSum::init_one(int i, int j) { +double PairSPHRhoSum::init_one(int i, int j) +{ if (setflag[i][j] == 0) { error->all(FLERR,"All pair sph/rhosum coeffs are not set"); } @@ -272,7 +259,8 @@ double PairSPHRhoSum::init_one(int i, int j) { /* ---------------------------------------------------------------------- */ double PairSPHRhoSum::single(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, double /*rsq*/, - double /*factor_coul*/, double /*factor_lj*/, double &fforce) { + double /*factor_coul*/, double /*factor_lj*/, double &fforce) +{ fforce = 0.0; return 0.0; @@ -281,7 +269,8 @@ double PairSPHRhoSum::single(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, /* ---------------------------------------------------------------------- */ int PairSPHRhoSum::pack_forward_comm(int n, int *list, double *buf, - int /*pbc_flag*/, int * /*pbc*/) { + int /*pbc_flag*/, int * /*pbc*/) +{ int i, j, m; double *rho = atom->rho; @@ -295,7 +284,8 @@ int PairSPHRhoSum::pack_forward_comm(int n, int *list, double *buf, /* ---------------------------------------------------------------------- */ -void PairSPHRhoSum::unpack_forward_comm(int n, int first, double *buf) { +void PairSPHRhoSum::unpack_forward_comm(int n, int first, double *buf) +{ int i, m, last; double *rho = atom->rho; diff --git a/src/SPH/pair_sph_taitwater.cpp b/src/SPH/pair_sph_taitwater.cpp index 9a5991718d..d97492de63 100644 --- a/src/SPH/pair_sph_taitwater.cpp +++ b/src/SPH/pair_sph_taitwater.cpp @@ -13,15 +13,16 @@ ------------------------------------------------------------------------- */ #include "pair_sph_taitwater.h" -#include -#include "atom.h" -#include "force.h" -#include "comm.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" -#include "domain.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" + +#include using namespace LAMMPS_NS; @@ -29,6 +30,9 @@ using namespace LAMMPS_NS; PairSPHTaitwater::PairSPHTaitwater(LAMMPS *lmp) : Pair(lmp) { + if ((atom->esph_flag != 1) || (atom->rho_flag != 1) || (atom->vest_flag != 1)) + error->all(FLERR, "Pair sph/taitwater requires atom attributes energy, density, and velocity estimates, e.g. in atom_style sph"); + restartinfo = 0; single_enable = 0; first = 1; @@ -36,7 +40,8 @@ PairSPHTaitwater::PairSPHTaitwater(LAMMPS *lmp) : Pair(lmp) /* ---------------------------------------------------------------------- */ -PairSPHTaitwater::~PairSPHTaitwater() { +PairSPHTaitwater::~PairSPHTaitwater() +{ if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -51,7 +56,8 @@ PairSPHTaitwater::~PairSPHTaitwater() { /* ---------------------------------------------------------------------- */ -void PairSPHTaitwater::compute(int eflag, int vflag) { +void PairSPHTaitwater::compute(int eflag, int vflag) +{ int i, j, ii, jj, inum, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz, fpair; @@ -72,25 +78,6 @@ void PairSPHTaitwater::compute(int eflag, int vflag) { int nlocal = atom->nlocal; int newton_pair = force->newton_pair; - // check consistency of pair coefficients - - if (first) { - for (i = 1; i <= atom->ntypes; i++) { - for (j = 1; i <= atom->ntypes; i++) { - if (cutsq[i][j] > 1.e-32) { - if (!setflag[i][i] || !setflag[j][j]) { - if (comm->me == 0) { - printf( - "SPH particle types %d and %d interact with cutoff=%g, but not all of their single particle properties are set.\n", - i, j, sqrt(cutsq[i][j])); - } - } - } - } - } - first = 0; - } - inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -201,7 +188,8 @@ void PairSPHTaitwater::compute(int eflag, int vflag) { allocate all arrays ------------------------------------------------------------------------- */ -void PairSPHTaitwater::allocate() { +void PairSPHTaitwater::allocate() +{ allocated = 1; int n = atom->ntypes; @@ -223,7 +211,8 @@ void PairSPHTaitwater::allocate() { global settings ------------------------------------------------------------------------- */ -void PairSPHTaitwater::settings(int narg, char **/*arg*/) { +void PairSPHTaitwater::settings(int narg, char **/*arg*/) +{ if (narg != 0) error->all(FLERR, "Illegal number of arguments for pair_style sph/taitwater"); @@ -233,7 +222,8 @@ void PairSPHTaitwater::settings(int narg, char **/*arg*/) { set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSPHTaitwater::coeff(int narg, char **arg) { +void PairSPHTaitwater::coeff(int narg, char **arg) +{ if (narg != 6) error->all(FLERR, "Incorrect args for pair_style sph/taitwater coefficients"); @@ -257,14 +247,8 @@ void PairSPHTaitwater::coeff(int narg, char **arg) { B[i] = B_one; for (int j = MAX(jlo,i); j <= jhi; j++) { viscosity[i][j] = viscosity_one; - //printf("setting cut[%d][%d] = %f\n", i, j, cut_one); cut[i][j] = cut_one; - setflag[i][j] = 1; - - //cut[j][i] = cut[i][j]; - //viscosity[j][i] = viscosity[i][j]; - //setflag[j][i] = 1; count++; } } @@ -277,8 +261,8 @@ void PairSPHTaitwater::coeff(int narg, char **arg) { init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSPHTaitwater::init_one(int i, int j) { - +double PairSPHTaitwater::init_one(int i, int j) +{ if (setflag[i][j] == 0) { error->all(FLERR,"All pair sph/taitwater coeffs are set"); } diff --git a/src/SPH/pair_sph_taitwater_morris.cpp b/src/SPH/pair_sph_taitwater_morris.cpp index 50fcd270f6..2209cc4ecf 100644 --- a/src/SPH/pair_sph_taitwater_morris.cpp +++ b/src/SPH/pair_sph_taitwater_morris.cpp @@ -13,15 +13,16 @@ ------------------------------------------------------------------------- */ #include "pair_sph_taitwater_morris.h" -#include -#include "atom.h" -#include "force.h" -#include "comm.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" -#include "domain.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" + +#include using namespace LAMMPS_NS; @@ -29,6 +30,9 @@ using namespace LAMMPS_NS; PairSPHTaitwaterMorris::PairSPHTaitwaterMorris(LAMMPS *lmp) : Pair(lmp) { + if ((atom->esph_flag != 1) || (atom->rho_flag != 1) || (atom->vest_flag != 1)) + error->all(FLERR, "Pair sph/taitwater/morris requires atom attributes energy, density, and velocity estimates, e.g. in atom_style sph"); + restartinfo = 0; first = 1; single_enable = 0; @@ -36,7 +40,8 @@ PairSPHTaitwaterMorris::PairSPHTaitwaterMorris(LAMMPS *lmp) : Pair(lmp) /* ---------------------------------------------------------------------- */ -PairSPHTaitwaterMorris::~PairSPHTaitwaterMorris() { +PairSPHTaitwaterMorris::~PairSPHTaitwaterMorris() +{ if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -51,7 +56,8 @@ PairSPHTaitwaterMorris::~PairSPHTaitwaterMorris() { /* ---------------------------------------------------------------------- */ -void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { +void PairSPHTaitwaterMorris::compute(int eflag, int vflag) +{ int i, j, ii, jj, inum, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz, fpair; @@ -72,25 +78,6 @@ void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { int nlocal = atom->nlocal; int newton_pair = force->newton_pair; - // check consistency of pair coefficients - - if (first) { - for (i = 1; i <= atom->ntypes; i++) { - for (j = 1; i <= atom->ntypes; i++) { - if (cutsq[i][j] > 1.e-32) { - if (!setflag[i][i] || !setflag[j][j]) { - if (comm->me == 0) { - printf( - "SPH particle types %d and %d interact with cutoff=%g, but not all of their single particle properties are set.\n", - i, j, sqrt(cutsq[i][j])); - } - } - } - } - } - first = 0; - } - inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -152,9 +139,9 @@ void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { fj = tmp * tmp * tmp; fj = B[jtype] * (fj * fj * tmp - 1.0) / (rho[j] * rho[j]); - velx=vxtmp - v[j][0]; - vely=vytmp - v[j][1]; - velz=vztmp - v[j][2]; + velx = vxtmp - v[j][0]; + vely = vytmp - v[j][1]; + velz = vztmp - v[j][2]; // dot product of velocity delta and distance vector delVdotDelR = delx * velx + dely * vely + delz * velz; @@ -169,8 +156,6 @@ void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { fpair = -imass * jmass * (fi + fj) * wfd; deltaE = -0.5 *(fpair * delVdotDelR + fvisc * (velx*velx + vely*vely + velz*velz)); - // printf("testvar= %f, %f \n", delx, dely); - f[i][0] += delx * fpair + velx * fvisc; f[i][1] += dely * fpair + vely * fvisc; f[i][2] += delz * fpair + velz * fvisc; @@ -189,6 +174,7 @@ void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { drho[j] += imass * delVdotDelR * wfd; } + // viscous forces do not contribute to virial if (evflag) ev_tally(i, j, nlocal, newton_pair, 0.0, 0.0, fpair, delx, dely, delz); } @@ -202,7 +188,8 @@ void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { allocate all arrays ------------------------------------------------------------------------- */ -void PairSPHTaitwaterMorris::allocate() { +void PairSPHTaitwaterMorris::allocate() +{ allocated = 1; int n = atom->ntypes; @@ -224,7 +211,8 @@ void PairSPHTaitwaterMorris::allocate() { global settings ------------------------------------------------------------------------- */ -void PairSPHTaitwaterMorris::settings(int narg, char **/*arg*/) { +void PairSPHTaitwaterMorris::settings(int narg, char **/*arg*/) +{ if (narg != 0) error->all(FLERR, "Illegal number of arguments for pair_style sph/taitwater/morris"); @@ -234,7 +222,8 @@ void PairSPHTaitwaterMorris::settings(int narg, char **/*arg*/) { set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSPHTaitwaterMorris::coeff(int narg, char **arg) { +void PairSPHTaitwaterMorris::coeff(int narg, char **arg) +{ if (narg != 6) error->all(FLERR, "Incorrect args for pair_style sph/taitwater/morris coefficients"); @@ -258,7 +247,6 @@ void PairSPHTaitwaterMorris::coeff(int narg, char **arg) { B[i] = B_one; for (int j = MAX(jlo,i); j <= jhi; j++) { viscosity[i][j] = viscosity_one; - //printf("setting cut[%d][%d] = %f\n", i, j, cut_one); cut[i][j] = cut_one; setflag[i][j] = 1; @@ -274,8 +262,8 @@ void PairSPHTaitwaterMorris::coeff(int narg, char **arg) { init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSPHTaitwaterMorris::init_one(int i, int j) { - +double PairSPHTaitwaterMorris::init_one(int i, int j) +{ if (setflag[i][j] == 0) { error->all(FLERR,"All pair sph/taitwater/morris coeffs are not set"); } diff --git a/src/angle.cpp b/src/angle.cpp index 79893cc52f..ccb53dc84f 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -50,7 +50,7 @@ Angle::Angle(LAMMPS *_lmp) : Pointers(_lmp) datamask_read = ALL_MASK; datamask_modify = ALL_MASK; - copymode = 0; + copymode = kokkosable = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/angle.h b/src/angle.h index 542bad4911..759f1a1aa9 100644 --- a/src/angle.h +++ b/src/angle.h @@ -44,7 +44,7 @@ class Angle : protected Pointers { ExecutionSpace execution_space; unsigned int datamask_read, datamask_modify; - int copymode; + int copymode, kokkosable; Angle(class LAMMPS *); ~Angle() override; diff --git a/src/angle_hybrid.cpp b/src/angle_hybrid.cpp index 0c61970a1f..a015882a15 100644 --- a/src/angle_hybrid.cpp +++ b/src/angle_hybrid.cpp @@ -48,14 +48,7 @@ AngleHybrid::~AngleHybrid() delete[] keywords; } - if (allocated) { - memory->destroy(setflag); - memory->destroy(map); - delete[] nanglelist; - delete[] maxangle; - for (int i = 0; i < nstyles; i++) memory->destroy(anglelist[i]); - delete[] anglelist; - } + deallocate(); } /* ---------------------------------------------------------------------- */ @@ -171,6 +164,22 @@ void AngleHybrid::allocate() for (int m = 0; m < nstyles; m++) anglelist[m] = nullptr; } +/* ---------------------------------------------------------------------- */ + +void AngleHybrid::deallocate() +{ + if (!allocated) return; + + allocated = 0; + + memory->destroy(setflag); + memory->destroy(map); + delete[] nanglelist; + delete[] maxangle; + for (int i = 0; i < nstyles; i++) memory->destroy(anglelist[i]); + delete[] anglelist; +} + /* ---------------------------------------------------------------------- create one angle style for each arg in list ------------------------------------------------------------------------- */ @@ -190,15 +199,7 @@ void AngleHybrid::settings(int narg, char **arg) delete[] keywords; } - if (allocated) { - memory->destroy(setflag); - memory->destroy(map); - delete[] nanglelist; - delete[] maxangle; - for (i = 0; i < nstyles; i++) memory->destroy(anglelist[i]); - delete[] anglelist; - } - allocated = 0; + deallocate(); // allocate list of sub-styles @@ -367,7 +368,7 @@ void AngleHybrid::read_restart(FILE *fp) keywords[m] = new char[n]; if (me == 0) utils::sfread(FLERR, keywords[m], sizeof(char), n, fp, nullptr, error); MPI_Bcast(keywords[m], n, MPI_CHAR, 0, world); - styles[m] = force->new_angle(keywords[m], 0, dummy); + styles[m] = force->new_angle(keywords[m], 1, dummy); styles[m]->read_restart_settings(fp); } } diff --git a/src/angle_hybrid.h b/src/angle_hybrid.h index 474ce89673..a6da29245e 100644 --- a/src/angle_hybrid.h +++ b/src/angle_hybrid.h @@ -42,14 +42,14 @@ class AngleHybrid : public Angle { double single(int, int, int, int) override; double memory_usage() override; - private: + protected: int *map; // which style each angle type points to - int *nanglelist; // # of angles in sub-style anglelists int *maxangle; // max # of angles sub-style lists can store int ***anglelist; // anglelist for each sub-style - void allocate(); + virtual void allocate(); + virtual void deallocate(); }; } // namespace LAMMPS_NS diff --git a/src/compute_bond_local.cpp b/src/compute_bond_local.cpp index 9ed591f73f..e3c3e26a85 100644 --- a/src/compute_bond_local.cpp +++ b/src/compute_bond_local.cpp @@ -13,21 +13,23 @@ ------------------------------------------------------------------------- */ #include "compute_bond_local.h" -#include -#include + #include "atom.h" #include "atom_vec.h" -#include "molecule.h" -#include "update.h" -#include "domain.h" -#include "force.h" #include "bond.h" #include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" #include "input.h" -#include "variable.h" #include "math_extra.h" #include "memory.h" -#include "error.h" +#include "molecule.h" +#include "update.h" +#include "variable.h" + +#include +#include using namespace LAMMPS_NS; @@ -80,8 +82,8 @@ ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : bstyle[nvalues++] = VARIABLE; vstr[nvar] = utils::strdup(&arg[iarg][2]); nvar++; - } else if (arg[iarg][0] == 'b') { - int n = atoi(&arg[iarg][1]); + } else if (utils::strmatch(arg[iarg], "^b\\d+$")) { // b1, b2, b3, ... bN + int n = std::stoi(&arg[iarg][1]); if (n <= 0) error->all(FLERR, "Invalid keyword {} in compute bond/local command", arg[iarg]); bstyle[nvalues] = BN; bindex[nvalues++] = n - 1; @@ -96,13 +98,13 @@ ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"set") == 0) { setflag = 1; - if (iarg+3 > narg) error->all(FLERR,"Illegal compute bond/local command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR,"compute bond/local set", error); if (strcmp(arg[iarg+1],"dist") == 0) { delete [] dstr; dstr = utils::strdup(arg[iarg+2]); - } else error->all(FLERR,"Illegal compute bond/local command"); + } else error->all(FLERR,"Unknown compute bond/local set keyword: {}", arg[iarg+2]); iarg += 3; - } else error->all(FLERR,"Illegal compute bond/local command"); + } else error->all(FLERR,"Unknown compute bond/local keyword: {}", arg[iarg]); } // error check @@ -113,9 +115,9 @@ ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : for (int i = 0; i < nvar; i++) { vvar[i] = input->variable->find(vstr[i]); if (vvar[i] < 0) - error->all(FLERR,"Variable name for copute bond/local does not exist"); + error->all(FLERR,"Variable name {} for copute bond/local does not exist", vstr[i]); if (!input->variable->equalstyle(vvar[i])) - error->all(FLERR,"Variable for compute bond/local is invalid style"); + error->all(FLERR,"Variable {} for compute bond/local is invalid style", vstr[i]); } if (dstr) { @@ -126,7 +128,7 @@ ComputeBondLocal::ComputeBondLocal(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR,"Variable for compute bond/local is invalid style"); } } else if (setflag) - error->all(FLERR,"Compute bond/local set with no variable"); + error->all(FLERR,"Compute bond/local set used with without a variable"); // set singleflag if need to call bond->single() diff --git a/src/compute_pair_local.cpp b/src/compute_pair_local.cpp index 88991f7481..351b499468 100644 --- a/src/compute_pair_local.cpp +++ b/src/compute_pair_local.cpp @@ -66,15 +66,13 @@ ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : pstyle[nvalues++] = DY; else if (strcmp(arg[iarg], "dz") == 0) pstyle[nvalues++] = DZ; - else if (arg[iarg][0] == 'p') { - int n = atoi(&arg[iarg][1]); + else if (utils::strmatch(arg[iarg], "^p\\d+$")) { // p1, p2, p3, ... pN + int n = std::stoi(&arg[iarg][1]); if (n <= 0) error->all(FLERR, "Invalid keyword {} in compute pair/local command", arg[iarg]); pstyle[nvalues] = PN; pindex[nvalues++] = n - 1; - } else break; - iarg++; } @@ -84,22 +82,22 @@ ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg], "cutoff") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Illegal compute pair/local command"); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "compute pair/local cutoff", error); if (strcmp(arg[iarg + 1], "type") == 0) cutstyle = TYPE; else if (strcmp(arg[iarg + 1], "radius") == 0) cutstyle = RADIUS; else - error->all(FLERR, "Illegal compute pair/local command"); + error->all(FLERR, "Unknown compute pair/local cutoff keyword: {}", arg[iarg + 1]); iarg += 2; } else - error->all(FLERR, "Illegal compute pair/local command"); + error->all(FLERR, "Unknown compute pair/local keyword: {}", arg[iarg]); } // error check if (cutstyle == RADIUS && !atom->radius_flag) - error->all(FLERR, "Compute pair/local requires atom attribute radius"); + error->all(FLERR, "This compute pair/local requires atom attribute radius"); // set singleflag if need to call pair->single() diff --git a/src/dihedral.cpp b/src/dihedral.cpp index 3e995fc405..2f591b1fc1 100644 --- a/src/dihedral.cpp +++ b/src/dihedral.cpp @@ -48,7 +48,7 @@ Dihedral::Dihedral(LAMMPS *_lmp) : Pointers(_lmp) datamask_read = ALL_MASK; datamask_modify = ALL_MASK; - copymode = 0; + copymode = kokkosable = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/dihedral.h b/src/dihedral.h index cf3d3f7d9a..34210929cd 100644 --- a/src/dihedral.h +++ b/src/dihedral.h @@ -41,7 +41,7 @@ class Dihedral : protected Pointers { ExecutionSpace execution_space; unsigned int datamask_read, datamask_modify; - int copymode; + int copymode, kokkosable; Dihedral(class LAMMPS *); ~Dihedral() override; diff --git a/src/dihedral_hybrid.cpp b/src/dihedral_hybrid.cpp index 4ee0ffdad9..3671391f5d 100644 --- a/src/dihedral_hybrid.cpp +++ b/src/dihedral_hybrid.cpp @@ -48,14 +48,7 @@ DihedralHybrid::~DihedralHybrid() delete[] keywords; } - if (allocated) { - memory->destroy(setflag); - memory->destroy(map); - delete[] ndihedrallist; - delete[] maxdihedral; - for (int i = 0; i < nstyles; i++) memory->destroy(dihedrallist[i]); - delete[] dihedrallist; - } + deallocate(); } /* ---------------------------------------------------------------------- */ @@ -172,6 +165,20 @@ void DihedralHybrid::allocate() for (int m = 0; m < nstyles; m++) dihedrallist[m] = nullptr; } +void DihedralHybrid::deallocate() +{ + if (!allocated) return; + + allocated = 0; + + memory->destroy(setflag); + memory->destroy(map); + delete[] ndihedrallist; + delete[] maxdihedral; + for (int i = 0; i < nstyles; i++) memory->destroy(dihedrallist[i]); + delete[] dihedrallist; +} + /* ---------------------------------------------------------------------- create one dihedral style for each arg in list ------------------------------------------------------------------------- */ @@ -191,15 +198,7 @@ void DihedralHybrid::settings(int narg, char **arg) delete[] keywords; } - if (allocated) { - memory->destroy(setflag); - memory->destroy(map); - delete[] ndihedrallist; - delete[] maxdihedral; - for (i = 0; i < nstyles; i++) memory->destroy(dihedrallist[i]); - delete[] dihedrallist; - } - allocated = 0; + deallocate(); // allocate list of sub-styles @@ -365,7 +364,7 @@ void DihedralHybrid::read_restart(FILE *fp) keywords[m] = new char[n]; if (me == 0) utils::sfread(FLERR, keywords[m], sizeof(char), n, fp, nullptr, error); MPI_Bcast(keywords[m], n, MPI_CHAR, 0, world); - styles[m] = force->new_dihedral(keywords[m], 0, dummy); + styles[m] = force->new_dihedral(keywords[m], 1, dummy); styles[m]->read_restart_settings(fp); } } diff --git a/src/dihedral_hybrid.h b/src/dihedral_hybrid.h index b7d4013afe..debc8a9d8d 100644 --- a/src/dihedral_hybrid.h +++ b/src/dihedral_hybrid.h @@ -40,14 +40,15 @@ class DihedralHybrid : public Dihedral { void read_restart(FILE *) override; double memory_usage() override; - private: + protected: int *map; // which style each dihedral type points to int *ndihedrallist; // # of dihedrals in sub-style dihedrallists int *maxdihedral; // max # of dihedrals sub-style lists can store int ***dihedrallist; // dihedrallist for each sub-style - void allocate(); + virtual void allocate(); + virtual void deallocate(); }; } // namespace LAMMPS_NS diff --git a/src/improper.cpp b/src/improper.cpp index dd4b1b2b25..3476bcdb50 100644 --- a/src/improper.cpp +++ b/src/improper.cpp @@ -47,7 +47,7 @@ Improper::Improper(LAMMPS *_lmp) : Pointers(_lmp) datamask_read = ALL_MASK; datamask_modify = ALL_MASK; - copymode = 0; + copymode = kokkosable = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/improper.h b/src/improper.h index 22a5d09926..400e950967 100644 --- a/src/improper.h +++ b/src/improper.h @@ -46,7 +46,7 @@ class Improper : protected Pointers { ExecutionSpace execution_space; unsigned int datamask_read, datamask_modify; - int copymode; + int copymode, kokkosable; Improper(class LAMMPS *); ~Improper() override; diff --git a/src/improper_hybrid.cpp b/src/improper_hybrid.cpp index a847b7bc95..5337f062b4 100644 --- a/src/improper_hybrid.cpp +++ b/src/improper_hybrid.cpp @@ -48,14 +48,7 @@ ImproperHybrid::~ImproperHybrid() delete[] keywords; } - if (allocated) { - memory->destroy(setflag); - memory->destroy(map); - delete[] nimproperlist; - delete[] maximproper; - for (int i = 0; i < nstyles; i++) memory->destroy(improperlist[i]); - delete[] improperlist; - } + deallocate(); } /* ---------------------------------------------------------------------- */ @@ -172,6 +165,22 @@ void ImproperHybrid::allocate() for (int m = 0; m < nstyles; m++) improperlist[m] = nullptr; } +/* ---------------------------------------------------------------------- */ + +void ImproperHybrid::deallocate() +{ + if (!allocated) return; + + allocated = 0; + + memory->destroy(setflag); + memory->destroy(map); + delete[] nimproperlist; + delete[] maximproper; + for (int i = 0; i < nstyles; i++) memory->destroy(improperlist[i]); + delete[] improperlist; +} + /* ---------------------------------------------------------------------- create one improper style for each arg in list ------------------------------------------------------------------------- */ @@ -191,15 +200,7 @@ void ImproperHybrid::settings(int narg, char **arg) delete[] keywords; } - if (allocated) { - memory->destroy(setflag); - memory->destroy(map); - delete[] nimproperlist; - delete[] maximproper; - for (i = 0; i < nstyles; i++) memory->destroy(improperlist[i]); - delete[] improperlist; - } - allocated = 0; + deallocate(); // allocate list of sub-styles @@ -357,7 +358,7 @@ void ImproperHybrid::read_restart(FILE *fp) keywords[m] = new char[n]; if (me == 0) utils::sfread(FLERR, keywords[m], sizeof(char), n, fp, nullptr, error); MPI_Bcast(keywords[m], n, MPI_CHAR, 0, world); - styles[m] = force->new_improper(keywords[m], 0, dummy); + styles[m] = force->new_improper(keywords[m], 1, dummy); styles[m]->read_restart_settings(fp); } } diff --git a/src/improper_hybrid.h b/src/improper_hybrid.h index e7cb8383d4..89a4664da2 100644 --- a/src/improper_hybrid.h +++ b/src/improper_hybrid.h @@ -40,14 +40,15 @@ class ImproperHybrid : public Improper { void read_restart(FILE *) override; double memory_usage() override; - private: + protected: int *map; // which style each improper type points to int *nimproperlist; // # of impropers in sub-style improperlists int *maximproper; // max # of impropers sub-style lists can store int ***improperlist; // improperlist for each sub-style - void allocate(); + virtual void allocate(); + virtual void deallocate(); }; } // namespace LAMMPS_NS diff --git a/src/lammps.cpp b/src/lammps.cpp index b3659fdf50..8e81f785de 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -191,7 +191,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : int me,nprocs; MPI_Comm_rank(communicator,&me); MPI_Comm_size(communicator,&nprocs); - int color = atoi(arg[iarg+1]); + int color = std::stoi(arg[iarg+1]); MPI_Comm subcomm; MPI_Comm_split(communicator,color,me,&subcomm); external_comm = communicator; diff --git a/src/library.cpp b/src/library.cpp index 5af39ce910..32577e47b4 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2532,7 +2532,7 @@ a char pointer and it should **not** be deallocated. Example: * * \param handle pointer to a previously created LAMMPS instance * \param name name of the variable - * \param group group-ID for atom style variable or ``NULL`` + * \param group group-ID for atom style variable or ``NULL`` or non-NULL to get vector length * \return pointer (cast to ``void *``) to the location of the * requested data or ``NULL`` if not found. */ diff --git a/src/lmptype.h b/src/lmptype.h index 4e62a1a7eb..d2181c9898 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -74,10 +74,8 @@ namespace LAMMPS_NS { #ifdef LAMMPS_LONGLONG_TO_LONG #define MPI_LL MPI_LONG -#define ATOLL atoll #else #define MPI_LL MPI_LONG_LONG -#define ATOLL atol #endif // for atomic problems that exceed 2 billion (2^31) atoms @@ -103,9 +101,6 @@ typedef int64_t bigint; #define TAGINT_FORMAT "%d" #define BIGINT_FORMAT "%" PRId64 -#define ATOTAGINT atoi -#define ATOBIGINT ATOLL - #define LAMMPS_TAGINT LAMMPS_INT #define LAMMPS_TAGINT_2D LAMMPS_INT_2D #define LAMMPS_BIGINT LAMMPS_INT64 @@ -141,9 +136,6 @@ typedef int64_t bigint; #define TAGINT_FORMAT "%" PRId64 #define BIGINT_FORMAT "%" PRId64 -#define ATOTAGINT ATOLL -#define ATOBIGINT ATOLL - #define LAMMPS_TAGINT LAMMPS_INT64 #define LAMMPS_TAGINT_2D LAMMPS_INT64_2D #define LAMMPS_BIGINT LAMMPS_INT64 @@ -178,9 +170,6 @@ typedef int bigint; #define TAGINT_FORMAT "%d" #define BIGINT_FORMAT "%d" -#define ATOTAGINT atoi -#define ATOBIGINT atoi - #define LAMMPS_TAGINT LAMMPS_INT #define LAMMPS_TAGINT_2D LAMMPS_INT_2D #define LAMMPS_BIGINT LAMMPS_INT diff --git a/src/lmpwindows.h b/src/lmpwindows.h deleted file mode 100644 index 34e90a140f..0000000000 --- a/src/lmpwindows.h +++ /dev/null @@ -1,60 +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. -------------------------------------------------------------------------- */ - -#include -#include - -// some symbols have different names in Windows - -#undef ATOBIGINT -#define ATOBIGINT _atoi64 - -#define pclose _pclose -#define strdup _strdup - -// the following functions are defined to get rid of -// 'ambiguous call to overloaded function' error in VSS for mismatched type arguments -#if !defined(__MINGW32__) -inline double pow(int i, int j) -{ - return pow((double) i, j); -} -inline double fabs(int i) -{ - return fabs((double) i); -} -inline double sqrt(int i) -{ - return sqrt((double) i); -} -#endif - -inline double trunc(double x) -{ - return x > 0 ? floor(x) : ceil(x); -} - -// Windows version of mkdir function does not have permission flags -#ifndef S_IRWXU -#define S_IRWXU 0 -#endif -#ifndef S_IRGRP -#define S_IRGRP 0 -#endif -#ifndef S_IXGRP -#define S_IXGRP 0 -#endif -inline int mkdir(const char *path, int) -{ - return _mkdir(path); -} diff --git a/src/molecule.cpp b/src/molecule.cpp index 55dfb4d15d..617402d605 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -599,14 +599,14 @@ void Molecule::read(int flag) } else if (keyword == "Dihedrals") { if (ndihedrals == 0) error->all(FLERR, - "Found Dihedrals section" + "Found Dihedrals section " "but no ndihedrals setting in header"); dihedralflag = tag_require = 1; dihedrals(flag, line); } else if (keyword == "Impropers") { if (nimpropers == 0) error->all(FLERR, - "Found Impropers section" + "Found Impropers section " "but no nimpropers setting in header"); improperflag = tag_require = 1; impropers(flag, line); diff --git a/src/neighbor.cpp b/src/neighbor.cpp index a1c8979ca7..072240b482 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1,4 +1,4 @@ - // clang-format off +// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -2705,8 +2705,8 @@ void Neighbor::modify_params(int narg, char **arg) memory->grow(ex1_type,maxex_type,"neigh:ex1_type"); memory->grow(ex2_type,maxex_type,"neigh:ex2_type"); } - ex1_type[nex_type] = utils::inumeric(FLERR,arg[iarg+2],false,lmp); - ex2_type[nex_type] = utils::inumeric(FLERR,arg[iarg+3],false,lmp); + ex1_type[nex_type] = utils::expand_type_int(FLERR, arg[iarg+2], Atom::ATOM, lmp); + ex2_type[nex_type] = utils::expand_type_int(FLERR, arg[iarg+3], Atom::ATOM, lmp); nex_type++; iarg += 4; } else if (strcmp(arg[iarg+1],"group") == 0) { diff --git a/src/read_restart.cpp b/src/read_restart.cpp index ee46d57fc3..ef30bc81d7 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -527,7 +527,8 @@ std::string ReadRestart::file_search(const std::string &inpfile) loc = pattern.find('*'); if (loc != std::string::npos) { // the regex matcher in utils::strmatch() only checks the first 256 characters. - if (loc > 256) + // a 64-bit integer timestep will consume 20 characters, so 236 chars is the cutoff. + if (loc > 236) error->one(FLERR, "Filename part before '*' is too long to find restart with largest step"); // convert pattern to equivalent regexp @@ -538,7 +539,7 @@ std::string ReadRestart::file_search(const std::string &inpfile) for (const auto &candidate : platform::list_directory(dirname)) { if (utils::strmatch(candidate,pattern)) { - bigint num = ATOBIGINT(utils::strfind(candidate.substr(loc),"\\d+").c_str()); + auto num = (bigint) std::stoll(utils::strfind(candidate.substr(loc),"\\d+")); if (num > maxnum) maxnum = num; } } diff --git a/src/reader_native.cpp b/src/reader_native.cpp index 4dac65e3cb..f252e01644 100644 --- a/src/reader_native.cpp +++ b/src/reader_native.cpp @@ -254,7 +254,7 @@ bigint ReaderNative::read_header(double box[3][3], int &boxinfo, int &triclinic, triclinic = 0; box[0][2] = box[1][2] = box[2][2] = 0.0; read_lines(1); - if (line[strlen("ITEM: BOX BOUNDS ")] == 'x') triclinic = 1; + if (utils::strmatch(line,"ITEM: BOX BOUNDS.*xy\\s+xz\\s+yz")) triclinic = 1; try { read_lines(1); @@ -484,7 +484,7 @@ void ReaderNative::read_atoms(int n, int nfield, double **fields) // convert selected fields to floats for (int m = 0; m < nfield; m++) - fields[i][m] = atof(words[fieldindex[m]].c_str()); + fields[i][m] = std::stod(words[fieldindex[m]]); } } } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 6b87f0c421..a2b95ab89e 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -287,8 +287,20 @@ std::string ValueTokenizer::next_string() int ValueTokenizer::next_int() { std::string current = tokens.next(); - if (!utils::is_integer(current)) { throw InvalidIntegerException(current); } - return atoi(current.c_str()); + try { + std::size_t end; + auto val = std::stoi(current, &end); + // only partially converted + if (current.size() != end) { throw InvalidIntegerException(current); } + return val; + + // rethrow exceptions from std::stoi() + } catch (std::out_of_range const &) { + throw InvalidIntegerException(current); + } catch (std::invalid_argument const &) { + throw InvalidIntegerException(current); + } + return 0; } /*! Retrieve next token and convert to bigint @@ -297,8 +309,22 @@ int ValueTokenizer::next_int() bigint ValueTokenizer::next_bigint() { std::string current = tokens.next(); - if (!utils::is_integer(current)) { throw InvalidIntegerException(current); } - return ATOBIGINT(current.c_str()); + try { + std::size_t end; + auto val = std::stoll(current, &end, 10); + // only partially converted + if (current.size() != end) { throw InvalidIntegerException(current); } + // out of range + if ((val < (-MAXBIGINT - 1) || (val > MAXBIGINT))) { throw InvalidIntegerException(current); }; + return (bigint) val; + + // rethrow exceptions from std::stoll() + } catch (std::out_of_range const &) { + throw InvalidIntegerException(current); + } catch (std::invalid_argument const &) { + throw InvalidIntegerException(current); + } + return 0; } /*! Retrieve next token and convert to tagint @@ -307,8 +333,22 @@ bigint ValueTokenizer::next_bigint() tagint ValueTokenizer::next_tagint() { std::string current = tokens.next(); - if (!utils::is_integer(current)) { throw InvalidIntegerException(current); } - return ATOTAGINT(current.c_str()); + try { + std::size_t end; + auto val = std::stoll(current, &end, 10); + // only partially converted + if (current.size() != end) { throw InvalidIntegerException(current); } + // out of range + if ((val < (-MAXTAGINT - 1) || (val > MAXTAGINT))) { throw InvalidIntegerException(current); } + return (tagint) val; + + // rethrow exceptions from std::stoll() + } catch (std::out_of_range const &) { + throw InvalidIntegerException(current); + } catch (std::invalid_argument const &) { + throw InvalidIntegerException(current); + } + return 0; } /*! Retrieve next token and convert to double @@ -317,8 +357,19 @@ tagint ValueTokenizer::next_tagint() double ValueTokenizer::next_double() { std::string current = tokens.next(); - if (!utils::is_double(current)) { throw InvalidFloatException(current); } - return atof(current.c_str()); + try { + std::size_t end; + auto val = std::stod(current, &end); + // only partially converted + if (current.size() != end) { throw InvalidFloatException(current); } + return val; + // rethrow exceptions from std::stod() + } catch (std::out_of_range const &) { + throw InvalidFloatException(current); + } catch (std::invalid_argument const &) { + throw InvalidFloatException(current); + } + return 0.0; } /*! Skip over a given number of tokens diff --git a/src/universe.cpp b/src/universe.cpp index edd5b01031..fb07e26759 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -181,10 +181,10 @@ void Universe::add_world(char *str) if ((found == 0) || (found == (part.size() - 1))) { valid = false; } else if (found == std::string::npos) { - nper = atoi(part.c_str()); + nper = std::stoi(part); } else { - n = atoi(part.substr(0,found).c_str()); - nper = atoi(part.substr(found+1).c_str()); + n = std::stoi(part.substr(0,found)); + nper = std::stoi(part.substr(found+1)); } } @@ -193,8 +193,7 @@ void Universe::add_world(char *str) if (n < 1 || nper < 1) valid = false; if (!valid) - error->universe_all(FLERR,fmt::format("Invalid partition string '{}'", - str)); + error->universe_all(FLERR, fmt::format("Invalid partition string '{}'", str)); } else nper = nprocs; memory->grow(procs_per_world,nworlds+n,"universe:procs_per_world"); diff --git a/src/utils.cpp b/src/utils.cpp index 87c46c47ab..27d89f1bf5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -398,17 +398,23 @@ double utils::numeric(const char *file, int line, const std::string &str, bool d } double rv = 0; + auto msg = fmt::format("Floating point number {} in input script or data file is invalid", buf); try { - rv = stod(buf); + std::size_t endpos; + rv = std::stod(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } } 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); + 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 @@ -459,10 +465,23 @@ int utils::inumeric(const char *file, int line, const std::string &str, bool do_ } int rv = 0; + auto msg = fmt::format("Integer {} in input script or data file is invalid", buf); try { - rv = stoi(buf); + std::size_t endpos; + rv = std::stoi(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + } catch (std::invalid_argument const &) { + 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("Integer {} in input script or data file is out of range", buf); + 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 @@ -514,9 +533,22 @@ bigint utils::bnumeric(const char *file, int line, const std::string &str, bool } long long rv = 0; + auto msg = fmt::format("Integer {} in input script or data file is invalid", buf); try { - rv = stoll(buf); - if (rv > MAXBIGINT) throw std::out_of_range("64-bit"); + std::size_t endpos; + rv = std::stoll(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + if ((rv < (-MAXBIGINT - 1) || (rv > MAXBIGINT))) throw std::out_of_range("bigint"); + } catch (std::invalid_argument const &) { + 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("Integer {} in input script or data file is out of range", buf); if (do_abort) @@ -570,9 +602,22 @@ tagint utils::tnumeric(const char *file, int line, const std::string &str, bool } long long rv = 0; + auto msg = fmt::format("Integer {} in input script or data file is invalid", buf); try { - rv = stoll(buf); - if (rv > MAXTAGINT) throw std::out_of_range("64-bit"); + std::size_t endpos; + rv = std::stoll(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + if ((rv < (-MAXTAGINT - 1) || (rv > MAXTAGINT))) throw std::out_of_range("tagint"); + } catch (std::invalid_argument const &) { + 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("Integer {} in input script or data file is out of range", buf); if (do_abort) @@ -614,19 +659,19 @@ void utils::bounds(const char *file, int line, const std::string &str, found = str.find_first_of('*'); if (found == std::string::npos) { // contains no '*' - nlo = nhi = strtol(str.c_str(), nullptr, 10); + nlo = nhi = std::stol(str, nullptr, 10); } else if (str.size() == 1) { // is only '*' nlo = nmin; nhi = nmax; } else if (found == 0) { // is '*j' nlo = nmin; - nhi = strtol(str.substr(1).c_str(), nullptr, 10); + nhi = std::stol(str.substr(1), nullptr, 10); } else if (str.size() == found + 1) { // is 'i*' - nlo = strtol(str.c_str(), nullptr, 10); + nlo = std::stol(str, nullptr, 10); nhi = nmax; } else { // is 'i*j' - nlo = strtol(str.c_str(), nullptr, 10); - nhi = strtol(str.substr(found + 1).c_str(), nullptr, 10); + nlo = std::stol(str, nullptr, 10); + nhi = std::stol(str.substr(found + 1), nullptr, 10); } if (error) { @@ -1697,10 +1742,10 @@ double utils::timespec2seconds(const std::string ×pec) int utils::date2num(const std::string &date) { std::size_t found = date.find_first_not_of("0123456789 "); - int num = strtol(date.substr(0, found).c_str(), nullptr, 10); + int num = std::stol(date.substr(0, found), nullptr, 10); auto month = date.substr(found); found = month.find_first_of("0123456789 "); - num += strtol(month.substr(found).c_str(), nullptr, 10) * 10000; + num += std::stol(month.substr(found), nullptr, 10) * 10000; if (num < 1000000) num += 20000000; if (strmatch(month, "^Jan")) diff --git a/src/variable.cpp b/src/variable.cpp index f308ed6efc..d4b2e390d6 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -799,8 +799,8 @@ int Variable::next(int narg, char **arg) fclose(fp); if (strlen(buf) > 0) { - nextindex = atoi(buf); - break; + nextindex = std::stoi(buf); + break; } delay = (int) (1000000*random->uniform()); platform::usleep(delay); @@ -1115,7 +1115,11 @@ double Variable::compute_equal(int ivar) if (ifunc < 0) print_var_error(FLERR,fmt::format("cannot find python function {}",data[ivar][0]),ivar); python->invoke_function(ifunc,data[ivar][1]); - value = atof(data[ivar][1]); + try { + value = std::stod(data[ivar][1]); + } catch (std::exception &e) { + print_var_error(FLERR,"has an invalid value", ivar); + } } eval_in_progress[ivar] = 0; @@ -1461,9 +1465,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (tree) { auto newtree = new Tree(); newtree->type = VALUE; - newtree->value = atof(number); + newtree->value = std::stod(number); treestack[ntreestack++] = newtree; - } else argstack[nargstack++] = atof(number); + } else argstack[nargstack++] = std::stod(number); delete[] number; @@ -2066,9 +2070,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (tree) { auto newtree = new Tree(); newtree->type = VALUE; - newtree->value = atof(var); + newtree->value = std::stod(var); treestack[ntreestack++] = newtree; - } else argstack[nargstack++] = atof(var); + } else argstack[nargstack++] = std::stod(var); // vector from vector-style variable // evaluate the vector-style variable, put result in newtree @@ -3555,7 +3559,7 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow) } else { varflag = 0; while (*ptr && *ptr != ']') { - if (!isdigit(*ptr)) + if (!(isdigit(*ptr) || (*ptr == '-') || (*ptr == '+') || (*ptr == '*') || (*ptr == '/'))) error->all(FLERR,"Non digit character between brackets in variable"); ptr++; } @@ -3566,21 +3570,23 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow) *ptr = '\0'; - // evaluate index as floating point variable or as tagint via ATOTAGINT() + // evaluate index as floating point variable or as tagint via stoll() - if (varflag) { - char *id = start+2; - int ivar = find(id); - if (ivar < 0) - error->all(FLERR,"Invalid variable name {} in variable formula", id); - - char *var = retrieve(id); - if (var == nullptr) - error->all(FLERR,"Invalid variable evaluation for variable {} in variable formula", id); - index = static_cast (atof(var)); - - } else index = ATOTAGINT(start); + try { + if (varflag) { + char *id = start+2; + int ivar = find(id); + if (ivar < 0) + error->all(FLERR,"Invalid variable name {} in variable formula", id); + char *var = retrieve(id); + if (var == nullptr) + error->all(FLERR,"Invalid variable evaluation for variable {} in variable formula", id); + index = static_cast(std::stod(var)); + } else index = static_cast(std::stoll(start)); + } catch (std::exception &e) { + error->all(FLERR,"Illegal value in brackets: {}({})", e.what(), start); + } *ptr = ']'; if (index <= 0) @@ -4685,7 +4691,7 @@ int Variable::special_function(const std::string &word, char *contents, Tree **t // save value in tree or on argstack if (style[ivar] == SCALARFILE) { - double value = atof(data[ivar][0]); + double value = std::stod(data[ivar][0]); int done = reader[ivar]->read_scalar(data[ivar][0]); if (done) remove(ivar); @@ -5278,7 +5284,7 @@ double Variable::evaluate_boolean(char *str) onechar = str[i]; str[i] = '\0'; - argstack[nargstack].value = atof(&str[istart]); + argstack[nargstack].value = std::stod(&str[istart]); str[i] = onechar; argstack[nargstack++].flag = 0; diff --git a/src/write_coeff.cpp b/src/write_coeff.cpp index 11987d4b37..5a7177f62f 100644 --- a/src/write_coeff.cpp +++ b/src/write_coeff.cpp @@ -152,7 +152,7 @@ void WriteCoeff::command(int narg, char **arg) } // parse type number and skip over it - int type = atoi(str); + int type = std::stoi(str); char *p = str; while ((*p != '\0') && (*p == ' ')) ++p; while ((*p != '\0') && isdigit(*p)) ++p; diff --git a/tools/lammps-gui/CMakeLists.txt b/tools/lammps-gui/CMakeLists.txt index 435516a521..7abf8f1e67 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.6.3 LANGUAGES CXX) +project(lammps-gui VERSION 1.6.5 LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) @@ -22,7 +22,13 @@ function(check_omp_h_include) set(CMAKE_REQUIRED_INCLUDES ${OpenMP_CXX_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LINK_OPTIONS ${OpenMP_CXX_FLAGS}) set(CMAKE_REQUIRED_LIBRARIES ${OpenMP_CXX_LIBRARIES}) - check_include_file_cxx(omp.h _have_omp_h) + # there are all kinds of problems with finding omp.h + # for Clang and derived compilers so we pretend it is there. + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(_have_omp_h TRUE) + else() + check_include_file_cxx(omp.h _have_omp_h) + endif() else() set(_have_omp_h FALSE) endif() @@ -199,7 +205,7 @@ if(APPLE) MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE_ICON_FILE lammps.icns - MACOSX_BUNDLE_COPYRIGHT "(c) 2003 - 2023, The LAMMPS Developers" + MACOSX_BUNDLE_COPYRIGHT "(c) 2003 - 2024, The LAMMPS Developers" MACOSX_BUNDLE TRUE ) # additional targets to populate the bundle tree and create the .dmg image file diff --git a/tools/lammps-gui/TODO.md b/tools/lammps-gui/TODO.md index d0b78b5591..bef30c1309 100644 --- a/tools/lammps-gui/TODO.md +++ b/tools/lammps-gui/TODO.md @@ -2,8 +2,9 @@ LAMMPS-GUI TODO list: # Short term goals (v1.x) -- add a "file viewer", also view file option in editor context menu if word under cursor is a file -- add "export to YAML" to chart viewer. +- figure out how widgets can be resized to fraction of available screen size. +- figure out stacking order of frames and whether it can be more flexible +- bundle LAMMPS tutorial input files - implement indenting regions for (nested) loops? - implement data file manager GUI with the following features: diff --git a/tools/lammps-gui/chartviewer.cpp b/tools/lammps-gui/chartviewer.cpp index d176dd98b7..2bbe029ebf 100644 --- a/tools/lammps-gui/chartviewer.cpp +++ b/tools/lammps-gui/chartviewer.cpp @@ -17,6 +17,10 @@ #include #include +#include +#include +#include +#include #include #include #include @@ -30,13 +34,17 @@ #include #include #include +#include +#include #include using namespace QtCharts; ChartWindow::ChartWindow(const QString &_filename, QWidget *parent) : - QWidget(parent), menu(new QMenuBar), file(new QMenu("&File")), filename(_filename) + QWidget(parent), menu(new QMenuBar), file(new QMenu("&File")), saveAsAct(nullptr), + exportCsvAct(nullptr), exportDatAct(nullptr), exportYamlAct(nullptr), closeAct(nullptr), + stopAct(nullptr), quitAct(nullptr), filename(_filename) { auto *top = new QHBoxLayout; menu->addMenu(file); @@ -61,6 +69,8 @@ ChartWindow::ChartWindow(const QString &_filename, QWidget *parent) : exportCsvAct->setIcon(QIcon(":/icons/application-calc.png")); exportDatAct = file->addAction("Export data to &Gnuplot...", this, &ChartWindow::exportDat); exportDatAct->setIcon(QIcon(":/icons/application-plot.png")); + exportYamlAct = file->addAction("Export data to &YAML...", this, &ChartWindow::exportYaml); + exportYamlAct->setIcon(QIcon(":/icons/yaml-file-icon.png")); file->addSeparator(); stopAct = file->addAction("Stop &Run", this, &ChartWindow::stop_run); stopAct->setIcon(QIcon(":/icons/process-stop.png")); @@ -227,6 +237,40 @@ void ChartWindow::exportCsv() } } } +void ChartWindow::exportYaml() +{ + if (charts.empty()) return; + QString defaultname = filename + ".yaml"; + if (filename.isEmpty()) defaultname = "lammpsdata.yaml"; + QString fileName = QFileDialog::getSaveFileName(this, "Save Chart as YAML data", defaultname, + "Image Files (*.yaml, *.yml)"); + if (!fileName.isEmpty()) { + QFile file(fileName); + if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&file); + out.setRealNumberPrecision(8); + out << "---\n"; + + out << "keywords: ['Step'"; + for (auto &c : charts) + out << ", " << c->get_title(); + out << "]\n"; + + out << "data: \n"; + int lines = charts[0]->get_count(); + for (int i = 0; i < lines; ++i) { + // timestep + out << " - [" << charts[0]->get_step(i); + // data + for (auto &c : charts) + out << ", " << c->get_data(i); + out << "]\n"; + } + out << "...\n"; + file.close(); + } + } +} void ChartWindow::change_chart(int) { diff --git a/tools/lammps-gui/chartviewer.h b/tools/lammps-gui/chartviewer.h index da0468eaf8..37a26c8b57 100644 --- a/tools/lammps-gui/chartviewer.h +++ b/tools/lammps-gui/chartviewer.h @@ -20,6 +20,8 @@ #include class QAction; +class QCloseEvent; +class QEvent; class QMenuBar; class QMenu; namespace QtCharts { @@ -50,6 +52,7 @@ private slots: void saveAs(); void exportDat(); void exportCsv(); + void exportYaml(); void change_chart(int index); @@ -61,7 +64,7 @@ private: QMenuBar *menu; QMenu *file; QComboBox *columns; - QAction *saveAsAct, *exportCsvAct, *exportDatAct; + QAction *saveAsAct, *exportCsvAct, *exportDatAct, *exportYamlAct; QAction *closeAct, *stopAct, *quitAct; QString filename; @@ -70,10 +73,10 @@ private: /* -------------------------------------------------------------------- */ -#include #include #include #include +class QChart; namespace QtCharts { class ChartViewer : public QChartView { diff --git a/tools/lammps-gui/codeeditor.cpp b/tools/lammps-gui/codeeditor.cpp index 2d349e28ab..36a811b92d 100644 --- a/tools/lammps-gui/codeeditor.cpp +++ b/tools/lammps-gui/codeeditor.cpp @@ -24,21 +24,27 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include #include -#include #include +#include #include #include +#include +#include +#include +#include #include #include @@ -775,6 +781,11 @@ void CodeEditor::contextMenuEvent(QContextMenuEvent *event) action->setData(QString()); connect(action, &QAction::triggered, this, &CodeEditor::open_help); + action = menu->addAction(QString("LAMMPS Tutorial")); + action->setIcon(QIcon(":/icons/help-tutorial.png")); + action->setData(QString("https://lammpstutorials.github.io/")); + connect(action, &QAction::triggered, this, &CodeEditor::open_url); + menu->exec(event->globalPos()); delete menu; } @@ -1208,6 +1219,12 @@ void CodeEditor::open_help() QUrl(QString("https://docs.lammps.org/%1").arg(act->data().toString()))); } +void CodeEditor::open_url() +{ + auto *act = qobject_cast(sender()); + QDesktopServices::openUrl(QUrl(act->data().toString())); +} + void CodeEditor::view_file() { auto *act = qobject_cast(sender()); diff --git a/tools/lammps-gui/codeeditor.h b/tools/lammps-gui/codeeditor.h index b36f0d8de0..873b13e302 100644 --- a/tools/lammps-gui/codeeditor.h +++ b/tools/lammps-gui/codeeditor.h @@ -14,15 +14,23 @@ #ifndef CODEEDITOR_H #define CODEEDITOR_H -#include #include #include #include #include class QCompleter; -class QStringListModel; +class QContextMenuEvent; +class QDragEnterEvent; +class QDropEvent; +class QFont; +class QKeyEvent; +class QMimeData; +class QPaintEvent; +class QRect; +class QResizeEvent; class QShortcut; +class QWidget; class CodeEditor : public QPlainTextEdit { Q_OBJECT @@ -78,6 +86,7 @@ private slots: void get_help(); void find_help(QString &page, QString &help); void open_help(); + void open_url(); void view_file(); void reformatCurrentLine(); void runCompletion(); diff --git a/tools/lammps-gui/fileviewer.cpp b/tools/lammps-gui/fileviewer.cpp index f93039d809..69bda7d91b 100644 --- a/tools/lammps-gui/fileviewer.cpp +++ b/tools/lammps-gui/fileviewer.cpp @@ -15,15 +15,16 @@ #include "lammpsgui.h" -#include #include -#include #include +#include #include #include +#include #include #include #include +#include #include #include @@ -39,24 +40,65 @@ FileViewer::FileViewer(const QString &_filename, QWidget *parent) : // open and read file. Set editor to read-only. QFile file(fileName); - if (file.open(QIODevice::Text | QIODevice::ReadOnly)) { - QTextStream in(&file); - QString content = in.readAll(); - file.close(); + QFileInfo finfo(file); + QString command; + QString content; + QProcess decomp; + QStringList args = {"-cdf", fileName}; + bool compressed = false; - QFont text_font; - QSettings settings; - text_font.fromString(settings.value("textfont", text_font.toString()).toString()); - document()->setDefaultFont(text_font); - - document()->setPlainText(content); - moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor); - setReadOnly(true); - setLineWrapMode(NoWrap); - setMinimumSize(800, 500); - setWindowIcon(QIcon(":/icons/lammps-icon-128x128.png")); - setWindowTitle("LAMMPS-GUI - Viewer - " + fileName); + // match suffix with decompression program + if (finfo.suffix() == "gz") { + command = "gzip"; + compressed = true; + } else if (finfo.suffix() == "bz2") { + command = "bzip2"; + compressed = true; + } else if (finfo.suffix() == "zst") { + command = "zstd"; + compressed = true; + } else if (finfo.suffix() == "xz") { + command = "xz"; + compressed = true; + } else if (finfo.suffix() == "lzma") { + command = "xz"; + args.insert(1, "--format=lzma"); + compressed = true; + } else if (finfo.suffix() == "lz4") { + command = "lz4"; + compressed = true; } + + // read compressed file from pipe + if (compressed) { + decomp.start(command, args, QIODevice::ReadOnly); + if (decomp.waitForStarted()) { + while (decomp.waitForReadyRead()) + content += decomp.readAll(); + } else { + content = "\nCould not open compressed file %1 with decompression program %2\n"; + content = content.arg(fileName).arg(command); + } + decomp.close(); + } else if (file.open(QIODevice::Text | QIODevice::ReadOnly)) { + // read plain text + QTextStream in(&file); + content = in.readAll(); + file.close(); + } + + QFont text_font; + QSettings settings; + text_font.fromString(settings.value("textfont", text_font.toString()).toString()); + document()->setDefaultFont(text_font); + + document()->setPlainText(content); + moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor); + setReadOnly(true); + setLineWrapMode(NoWrap); + setMinimumSize(800, 500); + setWindowIcon(QIcon(":/icons/lammps-icon-128x128.png")); + setWindowTitle("LAMMPS-GUI - Viewer - " + fileName); } void FileViewer::quit() diff --git a/tools/lammps-gui/icons/application-yaml.png b/tools/lammps-gui/icons/application-yaml.png new file mode 100644 index 0000000000..d1457147d4 Binary files /dev/null and b/tools/lammps-gui/icons/application-yaml.png differ diff --git a/tools/lammps-gui/icons/help-browser.png b/tools/lammps-gui/icons/help-browser.png index f3edf2c430..f61fca4573 100644 Binary files a/tools/lammps-gui/icons/help-browser.png and b/tools/lammps-gui/icons/help-browser.png differ diff --git a/tools/lammps-gui/icons/help-tutorial.png b/tools/lammps-gui/icons/help-tutorial.png new file mode 100644 index 0000000000..94df016852 Binary files /dev/null and b/tools/lammps-gui/icons/help-tutorial.png differ diff --git a/tools/lammps-gui/icons/move-recenter.png b/tools/lammps-gui/icons/move-recenter.png new file mode 100644 index 0000000000..6de5429306 Binary files /dev/null and b/tools/lammps-gui/icons/move-recenter.png differ diff --git a/tools/lammps-gui/imageviewer.cpp b/tools/lammps-gui/imageviewer.cpp index 388f4251ae..0894855a02 100644 --- a/tools/lammps-gui/imageviewer.cpp +++ b/tools/lammps-gui/imageviewer.cpp @@ -20,27 +20,27 @@ #include #include #include +#include #include +#include #include +#include #include #include #include #include -#include +#include #include -#include #include -#include +#include #include -#include #include #include #include +#include #include -#include #include -#include -#include +#include #include @@ -152,6 +152,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge vdwfactor = 0.5; auto pix = QPixmap(":/icons/emblem-photos.png"); + xcenter = ycenter = zcenter = 0.5; auto *renderstatus = new QLabel(QString()); renderstatus->setPixmap(pix.scaled(22, 22, Qt::KeepAspectRatio)); @@ -211,6 +212,8 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge rotup->setToolTip("Rotate up by 15 degrees"); auto *rotdown = new QPushButton(QIcon(":/icons/gtk-go-down.png"), ""); rotdown->setToolTip("Rotate down by 15 degrees"); + auto *recenter = new QPushButton(QIcon(":/icons/move-recenter.png"), ""); + recenter->setToolTip("Recenter on group"); auto *reset = new QPushButton(QIcon(":/icons/gtk-zoom-fit.png"), ""); reset->setToolTip("Reset view to defaults"); auto *combo = new QComboBox; @@ -245,6 +248,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge menuLayout->addWidget(rotright); menuLayout->addWidget(rotup); menuLayout->addWidget(rotdown); + menuLayout->addWidget(recenter); menuLayout->addWidget(reset); menuLayout->addWidget(new QLabel(" Group: ")); menuLayout->addWidget(combo); @@ -260,6 +264,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge connect(rotright, &QPushButton::released, this, &ImageViewer::do_rot_right); connect(rotup, &QPushButton::released, this, &ImageViewer::do_rot_up); connect(rotdown, &QPushButton::released, this, &ImageViewer::do_rot_down); + connect(recenter, &QPushButton::released, this, &ImageViewer::do_recenter); connect(reset, &QPushButton::released, this, &ImageViewer::reset_view); connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(change_group(int))); @@ -301,6 +306,7 @@ void ImageViewer::reset_view() showaxes = settings.value("axes", false).toBool(); usessao = settings.value("ssao", false).toBool(); antialias = settings.value("antialias", false).toBool(); + xcenter = ycenter = zcenter = 0.5; settings.endGroup(); // reset state of checkable push buttons and combo box (if accessible) @@ -421,6 +427,24 @@ void ImageViewer::do_rot_up() createImage(); } +void ImageViewer::do_recenter() +{ + QString commands = QString("variable LAMMPSGUI_CX delete\n" + "variable LAMMPSGUI_CY delete\n" + "variable LAMMPSGUI_CZ delete\n" + "variable LAMMPSGUI_CX equal (xcm(%1,x)-xlo)/lx\n" + "variable LAMMPSGUI_CY equal (xcm(%1,y)-ylo)/ly\n" + "variable LAMMPSGUI_CZ equal (xcm(%1,z)-zlo)/lz\n").arg(group); + lammps->commands_string(commands.toLocal8Bit()); + xcenter = lammps->extract_variable("LAMMPSGUI_CX"); + ycenter = lammps->extract_variable("LAMMPSGUI_CZ"); + zcenter = lammps->extract_variable("LAMMPSGUI_CZ"); + lammps->commands_string("variable LAMMPSGUI_CX delete\n" + "variable LAMMPSGUI_CY delete\n" + "variable LAMMPSGUI_CZ delete\n"); + createImage(); +} + void ImageViewer::cmd_to_clipboard() { auto words = last_dump_cmd.split(" "); @@ -534,6 +558,7 @@ void ImageViewer::createImage() else dumpcmd += " axes no 0.0 0.0"; + dumpcmd += QString(" center s %1 %2 %3").arg(xcenter).arg(ycenter).arg(zcenter); dumpcmd += " modify boxcolor " + settings.value("boxcolor", "yellow").toString(); dumpcmd += " backcolor " + settings.value("background", "black").toString(); if (useelements) dumpcmd += blank + elements + blank + adiams + blank; diff --git a/tools/lammps-gui/imageviewer.h b/tools/lammps-gui/imageviewer.h index 9612a0e5d9..f9b935640e 100644 --- a/tools/lammps-gui/imageviewer.h +++ b/tools/lammps-gui/imageviewer.h @@ -55,6 +55,7 @@ private slots: void do_rot_right(); void do_rot_up(); void do_rot_down(); + void do_recenter(); void cmd_to_clipboard(); void change_group(int); @@ -90,6 +91,7 @@ private: int xsize, ysize; int hrot, vrot; double zoom, vdwfactor; + double xcenter, ycenter, zcenter; bool showbox, showaxes, antialias, usessao, useelements, usediameter, usesigma; }; #endif diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 99fc75d869..d42d59bca2 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -36,8 +36,6 @@ #include #include #include -#include -#include #include #include #include @@ -46,15 +44,15 @@ #include #include #include -#include #include #include +#include +#include #include #include #if defined(_OPENMP) -#include #include #endif @@ -210,6 +208,7 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : connect(ui->action_Help, &QAction::triggered, this, &LammpsGui::help); connect(ui->actionLAMMPS_GUI_Howto, &QAction::triggered, this, &LammpsGui::howto); connect(ui->actionLAMMPS_Manual, &QAction::triggered, this, &LammpsGui::manual); + connect(ui->actionLAMMPS_Tutorial, &QAction::triggered, this, &LammpsGui::tutorial); connect(ui->actionPreferences, &QAction::triggered, this, &LammpsGui::preferences); connect(ui->actionDefaults, &QAction::triggered, this, &LammpsGui::defaults); connect(ui->actionView_in_OVITO, &QAction::triggered, this, &LammpsGui::start_exe); @@ -1332,6 +1331,11 @@ void LammpsGui::manual() QDesktopServices::openUrl(QUrl("https://docs.lammps.org/")); } +void LammpsGui::tutorial() +{ + QDesktopServices::openUrl(QUrl("https://lammpstutorials.github.io/")); +} + void LammpsGui::howto() { QDesktopServices::openUrl(QUrl("https://docs.lammps.org/Howto_lammps_gui.html")); diff --git a/tools/lammps-gui/lammpsgui.h b/tools/lammps-gui/lammpsgui.h index f41266b485..29372efc1c 100644 --- a/tools/lammps-gui/lammpsgui.h +++ b/tools/lammps-gui/lammpsgui.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "lammpswrapper.h" @@ -99,6 +100,7 @@ private slots: void about(); void help(); void manual(); + void tutorial(); void howto(); void logupdate(); void modified(); diff --git a/tools/lammps-gui/lammpsgui.qrc b/tools/lammps-gui/lammpsgui.qrc index b4bf6b578d..eb7c1fbc19 100644 --- a/tools/lammps-gui/lammpsgui.qrc +++ b/tools/lammps-gui/lammpsgui.qrc @@ -9,6 +9,7 @@ icons/application-calc.png icons/application-exit.png icons/application-plot.png + icons/application-yaml.png icons/axes-img.png icons/document-new.png icons/document-open-recent.png @@ -40,9 +41,11 @@ icons/help-about.png icons/help-browser.png icons/help-faq.png + icons/help-tutorial.png icons/image-x-generic.png icons/media-playback-start-2.png icons/media-playlist-repeat.png + icons/move-recenter.png icons/object-rotate-left.png icons/object-rotate-right.png icons/ovito.png diff --git a/tools/lammps-gui/lammpsgui.ui b/tools/lammps-gui/lammpsgui.ui index d0354feb6c..2607e715b9 100644 --- a/tools/lammps-gui/lammpsgui.ui +++ b/tools/lammps-gui/lammpsgui.ui @@ -86,6 +86,7 @@ + @@ -313,6 +314,17 @@ Ctrl+Shift+M + + + + + + LAMMPS &Tutorial + + + Ctrl+Shift+T + + @@ -454,7 +466,7 @@ - LAMMPS-GUI Howto + LAMMPS-&GUI Howto Ctrl+Shift+G diff --git a/tools/lammps-gui/lammpswrapper.cpp b/tools/lammps-gui/lammpswrapper.cpp index 1ccb225a0a..ed2bde1c9f 100644 --- a/tools/lammps-gui/lammpswrapper.cpp +++ b/tools/lammps-gui/lammpswrapper.cpp @@ -102,6 +102,26 @@ void *LammpsWrapper::extract_atom(const char *keyword) return val; } +// note: equal style and compatible variables only +double LammpsWrapper::extract_variable(const char *keyword) +{ + void *ptr = nullptr; + if (lammps_handle) { +#if defined(LAMMPS_GUI_USE_PLUGIN) + ptr = ((liblammpsplugin_t *)plugin_handle)->extract_variable(lammps_handle, keyword, nullptr); +#else + ptr = lammps_extract_variable(lammps_handle, keyword, nullptr); +#endif + } + double val = *((double *)ptr); +#if defined(LAMMPS_GUI_USE_PLUGIN) + ptr = ((liblammpsplugin_t *)plugin_handle)->free(ptr); +#else + lammps_free(ptr); +#endif + return val; +} + int LammpsWrapper::id_count(const char *keyword) { int val = 0; diff --git a/tools/lammps-gui/lammpswrapper.h b/tools/lammps-gui/lammpswrapper.h index 8719ef4491..9157bf77b5 100644 --- a/tools/lammps-gui/lammpswrapper.h +++ b/tools/lammps-gui/lammpswrapper.h @@ -34,6 +34,7 @@ public: void *extract_global(const char *keyword); void *extract_pair(const char *keyword); void *extract_atom(const char *keyword); + double extract_variable(const char *keyword); int id_count(const char *idtype); int id_name(const char *idtype, int idx, char *buf, int buflen); diff --git a/tools/lammps-gui/logwindow.cpp b/tools/lammps-gui/logwindow.cpp index 56dce35179..4527bcb0dd 100644 --- a/tools/lammps-gui/logwindow.cpp +++ b/tools/lammps-gui/logwindow.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/tools/lammps-gui/main.cpp b/tools/lammps-gui/main.cpp index d70e9d3e46..4820d48ebb 100644 --- a/tools/lammps-gui/main.cpp +++ b/tools/lammps-gui/main.cpp @@ -14,7 +14,6 @@ #include "lammpsgui.h" #include -#include #include #include diff --git a/tools/lammps-gui/preferences.cpp b/tools/lammps-gui/preferences.cpp index 207b68cb66..b601a9995f 100644 --- a/tools/lammps-gui/preferences.cpp +++ b/tools/lammps-gui/preferences.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -40,7 +39,9 @@ #include #include #include +#if defined(_OPENMP) #include +#endif #include #if defined(_OPENMP) diff --git a/tools/lammps-gui/setvariables.cpp b/tools/lammps-gui/setvariables.cpp index db5eb1cdea..1b2a54df8a 100644 --- a/tools/lammps-gui/setvariables.cpp +++ b/tools/lammps-gui/setvariables.cpp @@ -14,12 +14,12 @@ #include "setvariables.h" #include -#include #include #include #include #include #include +#include SetVariables::SetVariables(QList> &_vars, QWidget *parent) : QDialog(parent), vars(_vars), layout(new QVBoxLayout) diff --git a/tools/lammps-gui/slideshow.cpp b/tools/lammps-gui/slideshow.cpp index dcc85fc34a..08b854becd 100644 --- a/tools/lammps-gui/slideshow.cpp +++ b/tools/lammps-gui/slideshow.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/unittest/c-library/CMakeLists.txt b/unittest/c-library/CMakeLists.txt index f5793a804e..62ec750a3f 100644 --- a/unittest/c-library/CMakeLists.txt +++ b/unittest/c-library/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable(test_library_open test_library_open.cpp test_main.cpp) target_link_libraries(test_library_open PRIVATE lammps GTest::GMock) add_test(NAME LibraryOpen COMMAND test_library_open) +set_tests_properties(LibraryOpen PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=4;OMP_PROC_BIND=false") add_executable(test_library_commands test_library_commands.cpp test_main.cpp) target_link_libraries(test_library_commands PRIVATE lammps GTest::GMock) @@ -16,7 +17,7 @@ add_executable(test_library_properties test_library_properties.cpp test_main.cpp target_link_libraries(test_library_properties PRIVATE lammps GTest::GMock) target_compile_definitions(test_library_properties PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) add_test(NAME LibraryProperties COMMAND test_library_properties) -set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};OMP_NUM_THREADS=4;OMP_PROC_BIND=false") add_executable(test_library_objects test_library_objects.cpp test_main.cpp) target_link_libraries(test_library_objects PRIVATE lammps GTest::GMock) diff --git a/unittest/c-library/test_library_open.cpp b/unittest/c-library/test_library_open.cpp index 426b2adaa7..6f2ea9ac33 100644 --- a/unittest/c-library/test_library_open.cpp +++ b/unittest/c-library/test_library_open.cpp @@ -2,10 +2,12 @@ #include "lammps.h" #define LAMMPS_LIB_MPI 1 +#include "info.h" #include "library.h" #include // for stdin, stdout #include #include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -78,9 +80,38 @@ TEST(lammps_open, with_args) TEST(lammps_open, with_kokkos) { if (!LAMMPS_NS::LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); - const char *args[] = {"liblammps", "-k", "on", "t", "2", "-sf", "kk", "-log", "none", nullptr}; - char **argv = (char **)args; - int argc = (sizeof(args) / sizeof(char *)) - 1; + std::vector args = {(char *)"lammps", (char *)"-log", (char *)"none", (char *)"-echo", + (char *)"screen", (char *)"-sf", (char *)"kk"}; + + char *one = (char *)"1"; + char *four = (char *)"4"; + char *tee = (char *)"t"; + char *gee = (char *)"g"; + char *kay = (char *)"-k"; + char *yes = (char *)"on"; + + args.push_back(kay); + args.push_back(yes); + + // when GPU support is enabled in KOKKOS, it *must* be used + if (lammps_config_accelerator("KOKKOS", "api", "hip") || + lammps_config_accelerator("KOKKOS", "api", "cuda") || + lammps_config_accelerator("KOKKOS", "api", "sycl")) { + args.push_back(gee); + args.push_back(one); + } + + // use threads or serial + args.push_back(tee); + if (lammps_config_accelerator("KOKKOS", "api", "openmp")) { + args.push_back(four); + } else if (lammps_config_accelerator("KOKKOS", "api", "pthreads")) { + args.push_back(four); + } else { + args.push_back(one); + } + int argc = args.size(); + char **argv = args.data(); ::testing::internal::CaptureStdout(); void *alt_ptr; diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index 3900265f8c..a2df55d120 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -7,6 +7,7 @@ #include "lmptype.h" #include "platform.h" #include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -742,14 +743,45 @@ TEST_F(AtomProperties, position) TEST(SystemSettings, kokkos) { if (!lammps_config_has_package("KOKKOS")) GTEST_SKIP(); - if (!lammps_config_accelerator("KOKKOS", "api", "openmp")) GTEST_SKIP(); + std::vector args = {(char *)"lammps", (char *)"-log", (char *)"none", + (char *)"-echo", (char *)"screen", (char *)"-nocite", + (char *)"-sf", (char *)"kk"}; - // clang-format off - const char *args[] = {"SystemSettings", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk", nullptr}; - // clang-format on - char **argv = (char **)args; - int argc = (sizeof(args) / sizeof(char *)) - 1; + char *one = (char *)"1"; + char *four = (char *)"4"; + char *tee = (char *)"t"; + char *gee = (char *)"g"; + char *kay = (char *)"-k"; + char *yes = (char *)"on"; + + args.push_back(kay); + args.push_back(yes); + + bool has_gpu = false; + bool has_threads = false; + + // when GPU support is enabled in KOKKOS, it *must* be used + if (lammps_config_accelerator("KOKKOS", "api", "hip") || + lammps_config_accelerator("KOKKOS", "api", "cuda") || + lammps_config_accelerator("KOKKOS", "api", "sycl")) { + has_gpu = true; + args.push_back(gee); + args.push_back(one); + } + + // use threads or serial + args.push_back(tee); + if (lammps_config_accelerator("KOKKOS", "api", "openmp")) { + has_threads = true; + args.push_back(four); + } else if (lammps_config_accelerator("KOKKOS", "api", "pthreads")) { + has_threads = true; + args.push_back(four); + } else { + args.push_back(one); + } + int argc = args.size(); + char **argv = args.data(); ::testing::internal::CaptureStdout(); void *lmp = lammps_open_no_mpi(argc, argv, nullptr); @@ -758,7 +790,13 @@ TEST(SystemSettings, kokkos) EXPECT_THAT(output, StartsWith("LAMMPS (")); EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_active"), 1); - EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 4); - EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 0); + if (has_threads) + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 4); + else + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 1); + if (has_gpu) + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 1); + else + EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 0); lammps_close(lmp); } diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index e323c17280..2b9904852e 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -349,7 +349,7 @@ TEST_F(GroupTest, Dynamic) command("group ramp variable grow");); } -constexpr double EPSILON = 1.0e-13; +static constexpr double EPSILON = 1.0e-13; TEST_F(GroupTest, VariableFunctions) { diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index 8f2f4ba9d9..2390b1b675 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -287,6 +287,7 @@ TEST_F(VariableTest, AtomicSystem) ASSERT_DOUBLE_EQ(variable->compute_equal("f_press[1]"), 0.0); ASSERT_DOUBLE_EQ(variable->compute_equal("c_press"), 0.0); ASSERT_DOUBLE_EQ(variable->compute_equal("c_press[2]"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("c_press[1+1]"), 0.0); ASSERT_DOUBLE_EQ(variable->compute_equal("1.5+3.25"), 4.75); ASSERT_DOUBLE_EQ(variable->compute_equal("-2.5*1.5"), -3.75); @@ -302,8 +303,18 @@ TEST_F(VariableTest, AtomicSystem) variable->compute_equal("v_self");); TEST_FAILURE(".*ERROR: Variable sum2: Inconsistent lengths in vector-style variable.*", variable->compute_equal("max(v_sum2)");); - TEST_FAILURE("ERROR: Mismatched fix in variable formula.*", + TEST_FAILURE(".*ERROR: Mismatched fix in variable formula.*", variable->compute_equal("f_press");); + TEST_FAILURE(".*ERROR .*Variable formula compute vector is accessed out-of-range.*", + variable->compute_equal("c_press[10]");); + TEST_FAILURE(".*ERROR: Non digit character between brackets in variable.*", + variable->compute_equal("c_press[axy]");); + TEST_FAILURE(".*ERROR: Illegal value in brackets: stoll.*", + variable->compute_equal("c_press[73786976294838206464]");); + TEST_FAILURE(".*ERROR: Index between variable brackets must be positive.*", + variable->compute_equal("c_press[-2]");); + TEST_FAILURE(".*ERROR: Index between variable brackets must be positive.*", + variable->compute_equal("c_press[0]");); } TEST_F(VariableTest, Expressions) diff --git a/unittest/cplusplus/CMakeLists.txt b/unittest/cplusplus/CMakeLists.txt index 445e0fffeb..dac4cf3e10 100644 --- a/unittest/cplusplus/CMakeLists.txt +++ b/unittest/cplusplus/CMakeLists.txt @@ -3,7 +3,7 @@ add_executable(test_lammps_class test_lammps_class.cpp) target_link_libraries(test_lammps_class PRIVATE lammps GTest::GMockMain) add_test(NAME LammpsClass COMMAND test_lammps_class) -set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=1") +set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=2;OMP_PROC_BIND=false") add_executable(test_input_class test_input_class.cpp) target_link_libraries(test_input_class PRIVATE lammps GTest::GTestMain) diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index 23d83c4ecb..464ecca925 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -253,6 +253,15 @@ protected: { LAMMPS::argv args = {"LAMMPS_test", "-log", "none", "-echo", "none", "-screen", "none", "-k", "on", "t", "1", "-sf", "kk"}; + + // when GPU support is enabled in KOKKOS, it *must* be used + if (Info::has_accelerator_feature("KOKKOS", "api", "hip") || + Info::has_accelerator_feature("KOKKOS", "api", "cuda") || + Info::has_accelerator_feature("KOKKOS", "api", "sycl")) { + args = {"LAMMPS_test", "-log", "none", "-echo", "none", "-screen", "none", "-k", + "on", "t", "1", "g", "1", "-sf", "kk"}; + } + if (Info::has_accelerator_feature("KOKKOS", "api", "openmp")) args[10] = "2"; if (LAMMPS::is_installed_pkg("KOKKOS")) { diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt index 7d29395e39..f47bb75305 100644 --- a/unittest/force-styles/CMakeLists.txt +++ b/unittest/force-styles/CMakeLists.txt @@ -204,11 +204,7 @@ foreach(TEST ${FIX_TIMESTEP_TESTS}) continue() endif() add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST}) -if(WIN32) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}\\\;${LAMMPS_PYTHON_DIR}") -else() - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH};PYTHONDONTWRITEBYTECODE=1") -endif() + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -225,7 +221,7 @@ foreach(TEST ${DIHEDRAL_TESTS}) continue() endif() add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH};PYTHONDONTWRITEBYTECODE=1") + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -242,7 +238,7 @@ foreach(TEST ${IMPROPER_TESTS}) continue() endif() add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST}) - set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH};PYTHONDONTWRITEBYTECODE=1") + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() @@ -250,7 +246,7 @@ if(MLIAP_ENABLE_PYTHON AND (NOT WIN32)) add_executable(test_mliappy_unified test_mliappy_unified.cpp) target_link_libraries(test_mliappy_unified PRIVATE lammps GTest::GMockMain) add_test(NAME TestMliapPyUnified COMMAND test_mliappy_unified) - set_tests_properties(TestMliapPyUnified PROPERTIES ENVIRONMENT "PYTHONPATH=${LAMMPS_PYTHON_DIR};PYTHONDONTWRITEBYTECODE=1") + set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") endif() add_executable(test_pair_list test_pair_list.cpp) diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index bbacdd8f24..e706cc11ac 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -530,6 +530,126 @@ TEST(AngleStyle, omp) if (!verbose) ::testing::internal::GetCapturedStdout(); }; +TEST(AngleStyle, kokkos_omp) +{ + if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP(); + + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = init_lammps(args, test_config, true); + + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + + if (!lmp) { + std::cerr << "One or more prerequisite styles with /kk suffix\n" + "are not available in this LAMMPS configuration:\n"; + for (auto &prerequisite : test_config.prerequisites) { + std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n"; + } + GTEST_SKIP(); + } + + EXPECT_THAT(output, StartsWith("LAMMPS (")); + EXPECT_THAT(output, HasSubstr("Loop time")); + + // abort if running in parallel and not all atoms are local + const int nlocal = lmp->atom->nlocal; + ASSERT_EQ(lmp->atom->natoms, nlocal); + + // relax error a bit for KOKKOS package + double epsilon = 5.0 * test_config.epsilon; + + ErrorStats stats; + auto angle = lmp->force->angle; + + EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton on)", angle->virial, test_config.init_stress, epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton on)", angle->virial, test_config.run_stress, epsilon); + + stats.reset(); + int id = lmp->modify->find_compute("sum"); + double energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.run_energy, epsilon); + EXPECT_FP_LE_WITH_EPS(angle->energy, energy, epsilon); + if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + lmp = init_lammps(args, test_config, false); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + // skip over these tests if newton bond is forced to be on + if (lmp->force->newton_bond == 0) { + angle = lmp->force->angle; + + EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton off)", angle->virial, test_config.init_stress, + 2 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton off)", angle->virial, test_config.run_stress, epsilon); + + stats.reset(); + id = lmp->modify->find_compute("sum"); + energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.run_energy, epsilon); + EXPECT_FP_LE_WITH_EPS(angle->energy, energy, epsilon); + if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl; + } + + if (!verbose) ::testing::internal::CaptureStdout(); + restart_lammps(lmp, test_config); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + angle = lmp->force->angle; + EXPECT_FORCES("restart_forces", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("restart_stress", angle->virial, test_config.init_stress, epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "restart_energy stats:" << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + data_lammps(lmp, test_config); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + angle = lmp->force->angle; + EXPECT_FORCES("data_forces", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("data_stress", angle->virial, test_config.init_stress, epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "data_energy stats:" << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + if (!verbose) ::testing::internal::GetCapturedStdout(); +}; + + TEST(AngleStyle, numdiff) { if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); @@ -645,8 +765,13 @@ TEST(AngleStyle, single) "extra/angle/per/atom 2 extra/special/per/atom 2", nangletypes)); - command("pair_style zero 8.0"); - command("pair_coeff * *"); + if (utils::strmatch(test_config.angle_style, "^spica")) { + command("pair_style lj/spica 8.0"); + command("pair_coeff * * lj9_6 0.02 2.5"); + } else { + command("pair_style zero 8.0"); + command("pair_coeff * *"); + } command("angle_style " + test_config.angle_style); Angle *angle = lmp->force->angle; diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index d2523ff51d..81b105259d 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -532,6 +532,112 @@ TEST(BondStyle, omp) if (!verbose) ::testing::internal::GetCapturedStdout(); }; +TEST(BondStyle, kokkos_omp) +{ + if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP(); + + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = init_lammps(args, test_config, true); + + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + + if (!lmp) { + std::cerr << "One or more prerequisite styles with /kk suffix\n" + "are not available in this LAMMPS configuration:\n"; + for (auto &prerequisite : test_config.prerequisites) { + std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n"; + } + GTEST_SKIP(); + } + + EXPECT_THAT(output, StartsWith("LAMMPS (")); + EXPECT_THAT(output, HasSubstr("Loop time")); + + // abort if running in parallel and not all atoms are local + const int nlocal = lmp->atom->nlocal; + ASSERT_EQ(lmp->atom->natoms, nlocal); + + // relax error a bit for KOKKOS package + double epsilon = 5.0 * test_config.epsilon; + + ErrorStats stats; + auto bond = lmp->force->bond; + + EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton on)", bond->virial, test_config.init_stress, 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton on)", bond->virial, test_config.run_stress, 10 * epsilon); + + stats.reset(); + int id = lmp->modify->find_compute("sum"); + double energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.run_energy, epsilon); + + // FIXME: this is currently broken ??? for KOKKOS with bond style hybrid + // needs to be fixed in the main code somewhere. Not sure where, though. + //if (test_config.bond_style.substr(0, 6) != "hybrid") + // EXPECT_FP_LE_WITH_EPS(bond->energy, energy, epsilon); + + if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + lmp = init_lammps(args, test_config, false); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + // skip over these tests if newton bond is forced to be on + if (lmp->force->newton_bond == 0) { + bond = lmp->force->bond; + + EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton off)", bond->virial, test_config.init_stress, + 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton off)", bond->virial, test_config.run_stress, + 10 * epsilon); + + stats.reset(); + id = lmp->modify->find_compute("sum"); + energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.run_energy, epsilon); + + // FIXME: this is currently broken ??? for KOKKOS with bond style hybrid + // needs to be fixed in the main code somewhere. Not sure where, though. + //if (test_config.bond_style.substr(0, 6) != "hybrid") + // EXPECT_FP_LE_WITH_EPS(bond->energy, energy, epsilon); + + if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl; + } + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + if (!verbose) ::testing::internal::GetCapturedStdout(); +}; + TEST(BondStyle, numdiff) { if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index e6c34843c3..324745cc41 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -534,6 +534,112 @@ TEST(DihedralStyle, omp) if (!verbose) ::testing::internal::GetCapturedStdout(); }; +TEST(DihedralStyle, kokkos_omp) +{ + if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP(); + + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = init_lammps(args, test_config, true); + + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + + if (!lmp) { + std::cerr << "One or more prerequisite styles with /kk suffix\n" + "are not available in this LAMMPS configuration:\n"; + for (auto &prerequisite : test_config.prerequisites) { + std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n"; + } + GTEST_SKIP(); + } + + EXPECT_THAT(output, StartsWith("LAMMPS (")); + EXPECT_THAT(output, HasSubstr("Loop time")); + + // abort if running in parallel and not all atoms are local + const int nlocal = lmp->atom->nlocal; + ASSERT_EQ(lmp->atom->natoms, nlocal); + + // relax error a bit for KOKKOS package + double epsilon = 5.0 * test_config.epsilon; + + ErrorStats stats; + auto dihedral = lmp->force->dihedral; + + EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton on)", dihedral->virial, test_config.init_stress, + 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton on)", dihedral->virial, test_config.run_stress, 10 * epsilon); + + stats.reset(); + int id = lmp->modify->find_compute("sum"); + double energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon); + + // FIXME: this is currently broken ??? for KOKKOS with dihedral style hybrid + // needs to be fixed in the main code somewhere. Not sure where, though. + //if (test_config.dihedral_style.substr(0, 6) != "hybrid") + // EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon); + //if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + lmp = init_lammps(args, test_config, false); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + // skip over these tests if newton bond is forced to be on + if (lmp->force->newton_bond == 0) { + dihedral = lmp->force->dihedral; + + EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton off)", dihedral->virial, test_config.init_stress, + 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton off)", dihedral->virial, test_config.run_stress, + 10 * epsilon); + + stats.reset(); + id = lmp->modify->find_compute("sum"); + energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon); + + // FIXME: this is currently broken ??? for KOKKOS with dihedral style hybrid + // needs to be fixed in the main code somewhere. Not sure where, though. + //if (test_config.dihedral_style.substr(0, 6) != "hybrid") + // EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon); + + if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl; + } + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + if (!verbose) ::testing::internal::GetCapturedStdout(); +}; + TEST(DihedralStyle, numdiff) { if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 59028fb1ff..a65bf438df 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -527,6 +527,108 @@ TEST(ImproperStyle, omp) if (!verbose) ::testing::internal::GetCapturedStdout(); }; +TEST(ImproperStyle, kokkos_omp) +{ + if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); + + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; + + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = init_lammps(args, test_config, true); + + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + + if (!lmp) { + std::cerr << "One or more prerequisite styles with /kk suffix\n" + "are not available in this LAMMPS configuration:\n"; + for (auto &prerequisite : test_config.prerequisites) { + std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n"; + } + GTEST_SKIP(); + } + + EXPECT_THAT(output, StartsWith("LAMMPS (")); + EXPECT_THAT(output, HasSubstr("Loop time")); + + // abort if running in parallel and not all atoms are local + const int nlocal = lmp->atom->nlocal; + ASSERT_EQ(lmp->atom->natoms, nlocal); + + // relax error a bit for KOKKOS package + double epsilon = 5.0 * test_config.epsilon; + + ErrorStats stats; + auto improper = lmp->force->improper; + + EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton on)", improper->virial, test_config.init_stress, + 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton on)", improper->virial, test_config.run_stress, 10 * epsilon); + + stats.reset(); + int id = lmp->modify->find_compute("sum"); + double energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon); + // FIXME: this is currently broken ??? for KOKKOS with improper style hybrid + // needs to be fixed in the main code somewhere. Not sure where, though. + //if (test_config.improper_style.substr(0, 6) != "hybrid") + // EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon); + if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + lmp = init_lammps(args, test_config, false); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + // skip over these tests if newton bond is forced to be on + if (lmp->force->newton_bond == 0) { + improper = lmp->force->improper; + + EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon); + EXPECT_STRESS("init_stress (newton off)", improper->virial, test_config.init_stress, + 10 * epsilon); + + stats.reset(); + EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon); + if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl; + + if (!verbose) ::testing::internal::CaptureStdout(); + run_lammps(lmp); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon); + EXPECT_STRESS("run_stress (newton off)", improper->virial, test_config.run_stress, + 10 * epsilon); + + stats.reset(); + id = lmp->modify->find_compute("sum"); + energy = lmp->modify->compute[id]->compute_scalar(); + EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon); + // FIXME: this is currently broken ??? for KOKKOS with improper style hybrid + // needs to be fixed in the main code somewhere. Not sure where, though. + //if (test_config.improper_style.substr(0, 6) != "hybrid") + // EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon); + if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl; + } + + if (!verbose) ::testing::internal::CaptureStdout(); + cleanup_lammps(lmp, test_config); + if (!verbose) ::testing::internal::GetCapturedStdout(); +}; + TEST(ImproperStyle, numdiff) { if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); diff --git a/unittest/force-styles/tests/angle-spica.yaml b/unittest/force-styles/tests/angle-spica.yaml new file mode 100644 index 0000000000..7f88553c70 --- /dev/null +++ b/unittest/force-styles/tests/angle-spica.yaml @@ -0,0 +1,91 @@ +--- +lammps_version: 7 Feb 2024 +tags: +date_generated: Wed Jun 5 18:31:11 2024 +epsilon: 1e-12 +skip_tests: +prerequisites: ! | + atom full + angle spica + pair lj/spica +pre_commands: ! | + variable write_data_pair index ij +post_commands: ! | + pair_style lj/spica 8.0 +input_file: in.spica +angle_style: spica +angle_coeff: ! | + 1 33.5 110.1 + 2 46.1 111.3 + 3 40.0 120.0 + 4 33.0 108.5 +equilibrium: 4 1.9216075064457565 1.9425514574696887 2.0943951023931953 1.8936822384138474 +extract: ! "" +natoms: 29 +init_energy: 38.36438529349082 +init_stress: ! |2- + 6.2288484633192937e+01 -2.4958587357033732e+01 1.5261156310077459e+02 2.7527094178009044e+01 4.2708401447133369e+01 -2.5265950282815652e+01 +init_forces: ! |2 + 1 1.7230431704651284e+01 4.0071311825737794e+01 2.5153895595391262e+01 + 2 1.4681450443715043e+01 9.4049099264163125e+00 -2.0102364558934152e+01 + 3 -1.9308548347980725e+01 -2.8460741684874360e+01 6.4339170989100403e+00 + 4 -5.2290857572683347e+00 -9.4927850504411957e+00 1.8003472602849664e+00 + 5 -1.6382493884699279e+01 -1.4784175400797803e+01 -6.1931262199840624e+00 + 6 -5.4493064751680564e+01 7.5613258287794565e+01 6.9941734306087866e+01 + 7 -4.7395486031142198e+01 3.7640428970968820e+00 -2.4566126298992822e+02 + 8 4.8960191044380039e+01 -4.5712855041323763e+01 1.9415466008820243e+02 + 9 -8.3924213860655783e+00 2.4590103192063562e+01 3.2878160380265854e+01 + 10 6.8038129570966305e+01 -4.6569300903873433e+01 -7.6671701712056688e+01 + 11 -2.1258622382772373e+01 -7.4008599257925383e+00 8.3610564111488799e+00 + 12 5.9901920466154710e+00 -3.0542621446562030e+00 -7.5713636171526382e+00 + 13 1.4189850824692691e+00 1.0835451791895949e+00 4.9993493214959894e-01 + 14 1.1355220599075533e+01 2.4997321466757656e+00 -5.2256561116849181e+00 + 15 1.3933035015335755e+00 -2.0786326583247088e+00 8.7283364302611144e+00 + 16 4.5875574605935235e+01 -2.7754880718666161e+01 -1.0582764215323260e+02 + 17 -4.2451226361036497e+01 2.8306085448648393e+01 1.1928362036932688e+02 + 18 5.2926497658556788e-02 7.0441277800577096e-01 -2.9584690206819020e+00 + 19 -8.6276212064612834e-01 -1.0756990560638664e+00 1.2826229074637665e+00 + 20 7.9148971075772434e-01 3.3735689913016514e-01 1.7102043999486722e+00 + 21 -5.9956840446092086e+00 -6.6440354071373493e+00 1.8013592125677949e+01 + 22 -1.4065918957775763e+01 -4.6031498182035513e+00 -1.5782854315475038e+01 + 23 2.0049558879496164e+01 1.1260925334020174e+01 -2.2177902350101499e+00 + 24 3.2508269160599186e+00 -1.9979416528015960e+01 1.0409971951734974e+01 + 25 -1.6060493526274090e+01 9.4218054960789366e-01 -1.2854339891002313e+01 + 26 1.2797730884335980e+01 1.9024610945429981e+01 2.4201678955447798e+00 + 27 5.3169168679178105e+00 -2.2776165356368182e+01 9.1726846500285717e+00 + 28 -1.9217628865768805e+01 7.5096140408582208e+00 -1.2798872429928149e+01 + 29 1.3910508062151619e+01 1.5274870243863951e+01 3.6205364526432242e+00 +run_energy: 38.176417113761396 +run_stress: ! |2- + 6.1357382915550481e+01 -2.4715660959892247e+01 1.5186466302604836e+02 2.7218614858138846e+01 4.2112515489269541e+01 -2.5607593286714120e+01 +run_forces: ! |2 + 1 1.7145760907927180e+01 4.0174672565571342e+01 2.5205552180237635e+01 + 2 1.4615170171901832e+01 9.2708448155131897e+00 -2.0078351161345097e+01 + 3 -1.9027637897644411e+01 -2.8642960432918144e+01 6.2314807077302952e+00 + 4 -5.2736618463889080e+00 -9.3424901289763778e+00 1.9422015848783882e+00 + 5 -1.6468832074580213e+01 -1.4729606520686309e+01 -6.2023333708615995e+00 + 6 -5.3718294227422540e+01 7.4801671388546964e+01 6.8368190594240389e+01 + 7 -4.7118098933035071e+01 3.8739803262288781e+00 -2.4290995583077535e+02 + 8 4.7876325968669121e+01 -4.4923173742504034e+01 1.9297993934786507e+02 + 9 -8.3824572561250399e+00 2.4542635562122975e+01 3.2839238074098198e+01 + 10 6.8198580866574645e+01 -4.6830380612887495e+01 -7.6629764788623447e+01 + 11 -2.1232237676690062e+01 -7.3683045541850962e+00 8.3643364257797792e+00 + 12 5.6908584692226185e+00 -2.9956405260312478e+00 -7.3282063658600993e+00 + 13 1.3684378256951288e+00 9.7105537426706034e-01 5.7801503997630133e-01 + 14 1.1379285236061559e+01 2.6704814459393837e+00 -5.2142720262734468e+00 + 15 1.5246096380310767e+00 -1.9886210527177606e+00 8.4529064022347313e+00 + 16 4.5766629638536287e+01 -2.7729192853260034e+01 -1.0555847936417963e+02 + 17 -4.2311907917867423e+01 2.8269504758036135e+01 1.1894203420097222e+02 + 18 4.5978604531469895e-02 6.0605282956542328e-01 -2.5489959663795330e+00 + 19 -7.4282409641952973e-01 -9.2821937232343465e-01 1.1099668747784261e+00 + 20 6.7850316938866917e-01 2.8824602749664086e-01 1.4733945401265087e+00 + 21 -6.1707359561298754e+00 -6.7761831890615607e+00 1.8428059527969836e+01 + 22 -1.3998960882672469e+01 -4.5334962854737153e+00 -1.5964259983712697e+01 + 23 2.0157648747423554e+01 1.1323428247127397e+01 -2.4508469770619676e+00 + 24 3.5283602170234043e+00 -2.0588385440875950e+01 1.0846305899711011e+01 + 25 -1.6431076320543696e+01 1.1358029038847810e+00 -1.3239288833419160e+01 + 26 1.2890779580326928e+01 1.9439960296533382e+01 2.3687830191265684e+00 + 27 5.4188347979018312e+00 -2.2961492507008920e+01 9.2221110477962096e+00 + 28 -1.9337322641186159e+01 7.5984768842531718e+00 -1.2868573316667142e+01 + 29 1.3928283887490117e+01 1.5371333793823325e+01 3.6408125176375652e+00 +... diff --git a/unittest/force-styles/tests/data.spica b/unittest/force-styles/tests/data.spica new file mode 100644 index 0000000000..33b8c21ae7 --- /dev/null +++ b/unittest/force-styles/tests/data.spica @@ -0,0 +1,233 @@ +LAMMPS data file via write_data, version 5 May 2020, timestep = 0 + +29 atoms +5 atom types +24 bonds +5 bond types +30 angles +4 angle types +31 dihedrals +5 dihedral types +2 impropers +2 improper types + + -6.024572 8.975428 xlo xhi + -7.692866 7.307134 ylo yhi + -8.086924 6.913076 zlo zhi + +Masses + +1 12.0107 +2 4.00794 +3 14.0067 +4 15.9994 +5 15.9994 + +PairIJ Coeffs # lj/spica + +1 1 lj9_6 0.02 2.5 +1 2 lj9_6 0.01 1.58114 +1 3 lj9_6 0.02 2.82843 +1 4 lj9_6 0.0173205 2.78388 +1 5 lj9_6 0.0173205 2.78388 +2 2 lj12_4 0.005 1.0 +2 3 lj12_4 0.01 1.78885 +2 4 lj12_4 0.005 0.5 +2 5 lj12_4 0.00866025 1.76068 8 +3 3 lj12_6 0.02 3.2 8 +3 4 lj12_6 0.0173205 3.1496 8 +3 5 lj12_6 0.0173205 3.1496 8 +4 4 lj9_6 0.015 3.1 8 +4 5 lj9_6 0.015 3.1 8 +5 5 lj9_6 0.015 3.1 8 + +Bond Coeffs # zero + +1 1.5 +2 1.1 +3 1.3 +4 1.2 +5 1 + +Angle Coeffs # spica + +1 33.5 110.1 +2 46.1 111.3 +3 40 120 +4 33 108.5 + +Dihedral Coeffs # zero + +1 +2 +3 +4 +5 + +Improper Coeffs # zero + +1 +2 + +Atoms # full + +10 2 1 7.0000000000000007e-02 2.0185283555536988e+00 -1.4283966846517357e+00 -9.6733527271133024e-01 0 0 0 +11 2 2 8.9999999999999997e-02 1.7929780509347666e+00 -1.9871047540768743e+00 -1.8840626643185674e+00 0 0 0 +12 2 1 -2.7000000000000002e-01 3.0030247876861225e+00 -4.8923319967572748e-01 -1.6188658531537248e+00 0 0 0 +13 2 2 8.9999999999999997e-02 4.0447273787895934e+00 -9.0131998547446246e-01 -1.6384447268320836e+00 0 0 0 +14 2 2 8.9999999999999997e-02 2.6033152817257075e+00 -4.0789761505963579e-01 -2.6554413538823063e+00 0 0 0 + 2 1 2 3.1000000000000000e-01 3.0197083955402204e-01 2.9515239068888608e+00 -8.5689735572907566e-01 0 0 0 + 3 1 1 -2.0000000000000000e-02 -6.9435377880558602e-01 1.2440473127136711e+00 -6.2233801468892025e-01 0 0 0 + 4 1 2 8.9999999999999997e-02 -1.5771614164685133e+00 1.4915333140468066e+00 -1.2487126845040522e+00 0 0 0 + 6 1 1 5.1000000000000001e-01 2.9412607937706009e-01 2.2719282656652909e-01 -1.2843094067857870e+00 0 0 0 + 7 1 4 -5.1000000000000001e-01 3.4019871062879609e-01 -9.1277350075786561e-03 -2.4633113224304561e+00 0 0 0 +19 3 2 4.2359999999999998e-01 1.5349125211132961e+00 2.6315969880333707e+00 -4.2472859440220647e+00 0 0 0 +15 2 2 8.9999999999999997e-02 2.9756315249791303e+00 5.6334269722969288e-01 -1.2437650754599008e+00 0 0 0 +18 3 4 -8.4719999999999995e-01 2.1384791188033843e+00 3.0177261773770208e+00 -3.5160827596876225e+00 0 0 0 +20 3 2 4.2359999999999998e-01 2.7641167828863153e+00 3.6833419064000221e+00 -3.9380850623312638e+00 0 0 0 + 8 2 3 -4.6999999999999997e-01 1.1641187171852805e+00 -4.8375305955385234e-01 -6.7659823767368688e-01 0 0 0 + 9 2 2 3.1000000000000000e-01 1.3777459838125838e+00 -2.5366338669522998e-01 2.6877644730326306e-01 0 0 0 +16 2 1 5.1000000000000001e-01 2.6517554244980306e+00 -2.3957110424978438e+00 3.2908335999178327e-02 0 0 0 +17 2 4 -5.1000000000000001e-01 2.2309964792710639e+00 -2.1022918943319384e+00 1.1491948328949437e+00 0 0 0 + 1 1 3 -4.6999999999999997e-01 -2.7993683669226832e-01 2.4726588069312840e+00 -1.7200860244148433e-01 0 0 0 + 5 1 2 8.9999999999999997e-02 -8.9501761359359255e-01 9.3568128743071344e-01 4.0227731871484346e-01 0 0 0 +21 4 5 -8.4719999999999995e-01 4.9064454390208301e+00 -4.0751205255383196e+00 -3.6215576073601046e+00 0 0 0 +22 4 2 4.2359999999999998e-01 4.3687453488627543e+00 -4.2054270536772504e+00 -4.4651491269372565e+00 0 0 0 +23 4 2 4.2359999999999998e-01 5.7374928154769504e+00 -3.5763355905184966e+00 -3.8820297194230728e+00 0 0 0 +24 5 5 -8.4719999999999995e-01 2.0684115301174013e+00 3.1518221747664397e+00 3.1554242678474576e+00 0 0 0 +25 5 2 4.2359999999999998e-01 1.2998381073113014e+00 3.2755513587518097e+00 2.5092990173114837e+00 0 0 0 +26 5 2 4.2359999999999998e-01 2.5807438597688113e+00 4.0120175892854135e+00 3.2133398379059099e+00 0 0 0 +27 6 5 -8.4719999999999995e-01 -1.9613581876744359e+00 -4.3556300596085160e+00 2.1101467673534788e+00 0 0 0 +28 6 2 4.2359999999999998e-01 -2.7406520384725965e+00 -4.0207251278130975e+00 1.5828689861678511e+00 0 0 0 +29 6 2 4.2359999999999998e-01 -1.3108232656499081e+00 -3.5992986322410760e+00 2.2680459788743503e+00 0 0 0 + +Velocities + +1 7.7867804888392077e-04 5.8970331623292821e-04 -2.2179517633030531e-04 +2 2.7129529964126462e-03 4.6286427111164284e-03 3.5805549693846352e-03 +3 -1.2736791029204805e-03 1.6108674226414498e-03 -3.3618185901550799e-04 +4 -9.2828595122009308e-04 -1.2537885319521818e-03 -4.1204974953432108e-03 +5 -1.1800848061603740e-03 7.5424401975844038e-04 6.9023177964912290e-05 +6 -3.0914004879905335e-04 1.2755385764678133e-03 7.9574303350202582e-04 +7 -1.1037894966874103e-04 -7.6764845099077425e-04 -7.7217630460203659e-04 +8 3.9060281273221989e-04 -8.1444231918053418e-04 1.5134641148324972e-04 +9 1.2475530960659720e-03 -2.6608454451432528e-03 1.1117602907112732e-03 +10 4.5008983776042893e-04 4.9530197647538077e-04 -2.3336234361093645e-04 +11 -3.6977669078869707e-04 -1.5289071951960539e-03 -2.9176389881837113e-03 +12 1.0850834530183159e-03 -6.4965897903201833e-04 -1.2971152622619948e-03 +13 4.0754559196230639e-03 3.5043502394946119e-03 -7.8324487687854666e-04 +14 -1.3837220448746613e-04 -4.0656048637594394e-03 -3.9333461173944500e-03 +15 -4.3301707382721859e-03 -3.1802661664634938e-03 3.2037919043360571e-03 +16 -9.6715751018414326e-05 -5.0016572678960377e-04 1.4945658875149626e-03 +17 6.5692180538157174e-04 3.6635779995305095e-04 8.3495414466050911e-04 +18 -6.0936815808025862e-04 -9.3774557532468582e-04 -3.3558072507805731e-04 +19 -6.9919768291957119e-04 -3.6060777270430031e-03 4.2833405289822791e-03 +20 4.7777805013736515e-03 5.1003745845520452e-03 1.8002873923729241e-03 +21 -9.5568188553430398e-04 1.6594630943762931e-04 -1.8199788009966615e-04 +22 -3.3137518957653462e-03 -2.8683968287936054e-03 3.6384389958326871e-03 +23 2.4209481134686401e-04 -4.5457709985051130e-03 2.7663581642115042e-03 +24 2.5447450568861086e-04 4.8412447786110117e-04 -4.8021914527341357e-04 +25 4.3722771097312743e-03 -4.5184411669545515e-03 2.5200952006556795e-03 +26 -1.9250110555001179e-03 -3.0342169883610837e-03 3.5062814567984532e-03 +27 -2.6510179146429716e-04 3.6306203629019116e-04 -5.6235585400647747e-04 +28 -2.3068708109787484e-04 -8.5663070212203200e-04 2.1302563179109169e-03 +29 -2.5054744388303732e-03 -1.6773997805290820e-04 2.8436699761004796e-03 + +Bonds + +1 5 1 2 +2 3 1 3 +3 2 3 4 +4 2 3 5 +5 1 3 6 +6 3 6 8 +7 4 6 7 +8 5 8 9 +9 3 8 10 +10 2 10 11 +11 1 10 12 +12 1 10 16 +13 2 12 13 +14 2 12 14 +15 2 12 15 +16 4 16 17 +17 5 18 19 +18 5 18 20 +19 5 21 22 +20 5 21 23 +21 5 24 25 +22 5 24 26 +23 5 27 28 +24 5 27 29 + +Angles + +1 4 2 1 3 +2 4 1 3 5 +3 4 1 3 4 +4 4 1 3 6 +5 4 4 3 5 +6 2 5 3 6 +7 2 4 3 6 +8 3 3 6 7 +9 3 3 6 8 +10 3 7 6 8 +11 2 6 8 9 +12 2 9 8 10 +13 3 6 8 10 +14 2 8 10 11 +15 3 8 10 16 +16 2 11 10 12 +17 1 12 10 16 +18 1 8 10 12 +19 2 11 10 16 +20 2 10 12 15 +21 2 10 12 14 +22 2 10 12 13 +23 4 13 12 15 +24 4 13 12 14 +25 4 14 12 15 +26 4 10 16 17 +27 1 19 18 20 +28 1 22 21 23 +29 1 25 24 26 +30 1 28 27 29 + +Dihedrals + +1 2 2 1 3 6 +2 2 2 1 3 4 +3 3 2 1 3 5 +4 1 1 3 6 8 +5 1 1 3 6 7 +6 5 4 3 6 8 +7 5 4 3 6 7 +8 5 5 3 6 8 +9 5 5 3 6 7 +10 4 3 6 8 9 +11 3 3 6 8 10 +12 3 7 6 8 9 +13 4 7 6 8 10 +14 2 6 8 10 12 +15 2 6 8 10 16 +16 2 6 8 10 11 +17 2 9 8 10 12 +18 4 9 8 10 16 +19 5 9 8 10 11 +20 5 8 10 12 13 +21 1 8 10 12 14 +22 5 8 10 12 15 +23 4 8 10 16 17 +24 5 11 10 12 13 +25 5 11 10 12 14 +26 5 11 10 12 15 +27 2 11 10 16 17 +28 2 12 10 16 17 +29 5 16 10 12 13 +30 5 16 10 12 14 +31 5 16 10 12 15 + +Impropers + +1 1 6 3 8 7 +2 2 8 6 10 9 diff --git a/unittest/force-styles/tests/improper-class2.yaml b/unittest/force-styles/tests/improper-class2.yaml index 38e8b9120b..4350441eeb 100644 --- a/unittest/force-styles/tests/improper-class2.yaml +++ b/unittest/force-styles/tests/improper-class2.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 date_generated: Fri Mar 18 22:18:02 2022 epsilon: 2.5e-13 -skip_tests: +skip_tests: kokkos_omp prerequisites: ! | atom full improper class2 diff --git a/unittest/force-styles/tests/in.spica b/unittest/force-styles/tests/in.spica new file mode 100644 index 0000000000..6739409759 --- /dev/null +++ b/unittest/force-styles/tests/in.spica @@ -0,0 +1,30 @@ +variable newton_pair index on +variable newton_bond index on +variable bond_factor index 0.10 +variable angle_factor index 0.25 +variable dihedral_factor index 0.50 +variable units index real +variable input_dir index . +variable data_file index ${input_dir}/data.spica +variable pair_style index 'lj/spica 8.0' +variable bond_style index zero +variable angle_style index spica +variable dihedral_style index zero +variable improper_style index zero +variable t_target index 100.0 + +atom_style full +atom_modify map array +neigh_modify delay 2 every 2 check no +units ${units} +timestep 0.1 +newton ${newton_pair} ${newton_bond} +special_bonds lj/coul ${bond_factor} ${angle_factor} ${dihedral_factor} + +pair_style ${pair_style} +bond_style ${bond_style} +angle_style ${angle_style} +dihedral_style ${dihedral_style} +improper_style ${improper_style} + +read_data ${data_file} diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index 68bc0a4437..921d469e31 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -88,7 +88,7 @@ static void create_molecule_files(const std::string &h2o_filename, const std::st // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -const double EPSILON = 5.0e-14; +static const double EPSILON = 5.0e-14; namespace LAMMPS_NS { using ::testing::Eq; diff --git a/unittest/formats/test_molecule_file.cpp b/unittest/formats/test_molecule_file.cpp index 743a8fbbfa..e11a8ea4f1 100644 --- a/unittest/formats/test_molecule_file.cpp +++ b/unittest/formats/test_molecule_file.cpp @@ -32,7 +32,7 @@ using testing::StrEq; using utils::split_words; -const double EPSILON = 5.0e-14; +static constexpr double EPSILON = 5.0e-14; #define test_name test_info_->name() diff --git a/unittest/utils/test_tokenizer.cpp b/unittest/utils/test_tokenizer.cpp index 6db4a5fe5e..d5d6955b32 100644 --- a/unittest/utils/test_tokenizer.cpp +++ b/unittest/utils/test_tokenizer.cpp @@ -11,11 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "fmt/format.h" #include "lmptype.h" #include "tokenizer.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include + using namespace LAMMPS_NS; using ::testing::Eq; @@ -334,46 +337,73 @@ TEST(ValueTokenizer, move_assignment) TEST(ValueTokenizer, bad_integer) { - ValueTokenizer values("f10 f11 f12"); + ValueTokenizer values("f10 f11 f12 0xff 109951162777 " + "36893488147419103232 36893488147419103232"); ASSERT_THROW(values.next_int(), InvalidIntegerException); ASSERT_THROW(values.next_bigint(), InvalidIntegerException); ASSERT_THROW(values.next_tagint(), InvalidIntegerException); + ASSERT_THROW(values.next_int(), InvalidIntegerException); + ASSERT_THROW(values.next_int(), InvalidIntegerException); + ASSERT_THROW(values.next_tagint(), InvalidIntegerException); + ASSERT_THROW(values.next_bigint(), InvalidIntegerException); } TEST(ValueTokenizer, bad_double) { - ValueTokenizer values("1a.0"); + ValueTokenizer values("1a.0 --2.0 2.4d3 -1e20000 1.0e-1.0"); + ASSERT_THROW(values.next_double(), InvalidFloatException); + ASSERT_THROW(values.next_double(), InvalidFloatException); + ASSERT_THROW(values.next_double(), InvalidFloatException); + ASSERT_THROW(values.next_double(), InvalidFloatException); ASSERT_THROW(values.next_double(), InvalidFloatException); } TEST(ValueTokenizer, valid_int) { - ValueTokenizer values("10"); + ValueTokenizer values(fmt::format("10 {} {}", -MAXSMALLINT - 1, MAXSMALLINT)); ASSERT_EQ(values.next_int(), 10); + ASSERT_EQ(values.next_int(), -MAXSMALLINT - 1); + ASSERT_EQ(values.next_int(), MAXSMALLINT); } TEST(ValueTokenizer, valid_tagint) { - ValueTokenizer values("42"); + ValueTokenizer values( + fmt::format("42 {} {} {} {}", -MAXSMALLINT - 1, MAXSMALLINT, -MAXTAGINT - 1, MAXTAGINT)); ASSERT_EQ(values.next_tagint(), 42); + ASSERT_EQ(values.next_tagint(), -MAXSMALLINT - 1); + ASSERT_EQ(values.next_tagint(), MAXSMALLINT); + ASSERT_EQ(values.next_tagint(), -MAXTAGINT - 1); + ASSERT_EQ(values.next_tagint(), MAXTAGINT); } TEST(ValueTokenizer, valid_bigint) { - ValueTokenizer values("42"); + ValueTokenizer values( + fmt::format("42 {} {} {} {}", -MAXSMALLINT - 1, MAXSMALLINT, -MAXBIGINT - 1, MAXBIGINT)); ASSERT_EQ(values.next_bigint(), 42); + ASSERT_EQ(values.next_bigint(), -MAXSMALLINT - 1); + ASSERT_EQ(values.next_bigint(), MAXSMALLINT); + ASSERT_EQ(values.next_bigint(), -MAXBIGINT - 1); + ASSERT_EQ(values.next_bigint(), MAXBIGINT); } TEST(ValueTokenizer, valid_double) { - ValueTokenizer values("3.14"); + ValueTokenizer values("3.14 -0.00002 .1 0xff " + std::to_string(MAXBIGINT)); ASSERT_DOUBLE_EQ(values.next_double(), 3.14); + ASSERT_DOUBLE_EQ(values.next_double(), -0.00002); + ASSERT_DOUBLE_EQ(values.next_double(), 0.1); + ASSERT_DOUBLE_EQ(values.next_double(), 255); + ASSERT_DOUBLE_EQ(values.next_double(), MAXBIGINT); } TEST(ValueTokenizer, valid_double_with_exponential) { - ValueTokenizer values("3.14e22"); + ValueTokenizer values(fmt::format("3.14e22 {} {}", DBL_MAX, DBL_MIN)); ASSERT_DOUBLE_EQ(values.next_double(), 3.14e22); + ASSERT_DOUBLE_EQ(values.next_double(), DBL_MAX); + ASSERT_DOUBLE_EQ(values.next_double(), DBL_MIN); } TEST(ValueTokenizer, contains)