Merge branch 'develop' into dielectric-updates

This commit is contained in:
Axel Kohlmeyer
2022-04-17 17:47:55 -04:00
157 changed files with 13436 additions and 3840 deletions

View File

@ -172,6 +172,7 @@ set(STANDARD_PACKAGES
AWPMD AWPMD
BOCS BOCS
BODY BODY
BPM
BROWNIAN BROWNIAN
CG-DNA CG-DNA
CG-SDK CG-SDK

View File

@ -80,14 +80,14 @@ if(GPU_API STREQUAL "CUDA")
# --arch translates directly instead of JIT, so this should be for the preferred or most common architecture # --arch translates directly instead of JIT, so this should be for the preferred or most common architecture
set(GPU_CUDA_GENCODE "-arch=${GPU_ARCH}") set(GPU_CUDA_GENCODE "-arch=${GPU_ARCH}")
# apply the following to build "fat" CUDA binaries only for known CUDA toolkits # apply the following to build "fat" CUDA binaries only for known CUDA toolkits since version 8.0
if(CUDA_VERSION VERSION_GREATER_EQUAL "12.0") # only the Kepler achitecture and beyond is supported
message(WARNING "Untested CUDA Toolkit version. Use at your own risk") if(CUDA_VERSION VERSION_LESS 8.0)
message(FATAL_ERROR "CUDA Toolkit version 8.0 or later is required")
elseif(CUDA_VERSION VERSION_GREATER_EQUAL "12.0")
message(WARNING "Untested CUDA Toolkit version ${CUDA_VERSION}. Use at your own risk")
set(GPU_CUDA_GENCODE "-arch=all")
else() else()
# Fermi (GPU Arch 2.x) is supported by CUDA 3.2 to CUDA 8.0
if((CUDA_VERSION VERSION_GREATER_EQUAL "3.2") AND (CUDA_VERSION VERSION_LESS "9.0"))
string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_20,code=[sm_20,compute_20] ")
endif()
# Kepler (GPU Arch 3.0) is supported by CUDA 5 to CUDA 10.2 # Kepler (GPU Arch 3.0) is supported by CUDA 5 to CUDA 10.2
if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "11.0")) if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "11.0"))
string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_30,code=[sm_30,compute_30] ") string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_30,code=[sm_30,compute_30] ")
@ -120,6 +120,14 @@ if(GPU_API STREQUAL "CUDA")
if(CUDA_VERSION VERSION_GREATER_EQUAL "11.1") if(CUDA_VERSION VERSION_GREATER_EQUAL "11.1")
string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_86,code=[sm_86,compute_86]") string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_86,code=[sm_86,compute_86]")
endif() endif()
# Hopper (GPU Arch 9.0) is supported by CUDA 12.0? and later
if(CUDA_VERSION VERSION_GREATER_EQUAL "12.0")
string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_90,code=[sm_90,compute_90]")
endif()
# # Lovelace (GPU Arch 9.x) is supported by CUDA 12.0? and later
#if(CUDA_VERSION VERSION_GREATER_EQUAL "12.0")
# string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_9x,code=[sm_9x,compute_9x]")
#endif()
endif() endif()
cuda_compile_fatbin(GPU_GEN_OBJS ${GPU_LIB_CU} OPTIONS ${CUDA_REQUEST_PIC} cuda_compile_fatbin(GPU_GEN_OBJS ${GPU_LIB_CU} OPTIONS ${CUDA_REQUEST_PIC}
@ -257,43 +265,47 @@ elseif(GPU_API STREQUAL "HIP")
find_package(CUDA REQUIRED) find_package(CUDA REQUIRED)
set(HIP_ARCH "sm_50" CACHE STRING "HIP primary CUDA architecture (e.g. sm_60)") set(HIP_ARCH "sm_50" CACHE STRING "HIP primary CUDA architecture (e.g. sm_60)")
# build arch/gencode commands for nvcc based on CUDA toolkit version and use choice if(CUDA_VERSION VERSION_LESS 8.0)
# --arch translates directly instead of JIT, so this should be for the preferred or most common architecture message(FATAL_ERROR "CUDA Toolkit version 8.0 or later is required")
set(HIP_CUDA_GENCODE "-arch=${HIP_ARCH}") elseif(CUDA_VERSION VERSION_GREATER_EQUAL "12.0")
# Fermi (GPU Arch 2.x) is supported by CUDA 3.2 to CUDA 8.0 message(WARNING "Untested CUDA Toolkit version ${CUDA_VERSION}. Use at your own risk")
if((CUDA_VERSION VERSION_GREATER_EQUAL "3.2") AND (CUDA_VERSION VERSION_LESS "9.0")) set(HIP_CUDA_GENCODE "-arch=all")
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_20,code=[sm_20,compute_20]") else()
endif() # build arch/gencode commands for nvcc based on CUDA toolkit version and use choice
# Kepler (GPU Arch 3.0) is supported by CUDA 5 to CUDA 10.2 # --arch translates directly instead of JIT, so this should be for the preferred or most common architecture
if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "11.0")) set(HIP_CUDA_GENCODE "-arch=${HIP_ARCH}")
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_30,code=[sm_30,compute_30]") # Kepler (GPU Arch 3.0) is supported by CUDA 5 to CUDA 10.2
endif() if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "11.0"))
# Kepler (GPU Arch 3.5) is supported by CUDA 5 to CUDA 11.0 string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_30,code=[sm_30,compute_30]")
if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "12.0")) endif()
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_35,code=[sm_35,compute_35]") # Kepler (GPU Arch 3.5) is supported by CUDA 5 to CUDA 11.0
endif() if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "12.0"))
# Maxwell (GPU Arch 5.x) is supported by CUDA 6 and later string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_35,code=[sm_35,compute_35]")
if(CUDA_VERSION VERSION_GREATER_EQUAL "6.0") endif()
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52]") # Maxwell (GPU Arch 5.x) is supported by CUDA 6 and later
endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "6.0")
# Pascal (GPU Arch 6.x) is supported by CUDA 8 and later string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52]")
if(CUDA_VERSION VERSION_GREATER_EQUAL "8.0") endif()
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_60,code=[sm_60,compute_60] -gencode arch=compute_61,code=[sm_61,compute_61]") # Pascal (GPU Arch 6.x) is supported by CUDA 8 and later
endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "8.0")
# Volta (GPU Arch 7.0) is supported by CUDA 9 and later string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_60,code=[sm_60,compute_60] -gencode arch=compute_61,code=[sm_61,compute_61]")
if(CUDA_VERSION VERSION_GREATER_EQUAL "9.0") endif()
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_70,code=[sm_70,compute_70]") # Volta (GPU Arch 7.0) is supported by CUDA 9 and later
endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "9.0")
# Turing (GPU Arch 7.5) is supported by CUDA 10 and later string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_70,code=[sm_70,compute_70]")
if(CUDA_VERSION VERSION_GREATER_EQUAL "10.0") endif()
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_75,code=[sm_75,compute_75]") # Turing (GPU Arch 7.5) is supported by CUDA 10 and later
endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "10.0")
# Ampere (GPU Arch 8.0) is supported by CUDA 11 and later string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_75,code=[sm_75,compute_75]")
if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0") endif()
string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_80,code=[sm_80,compute_80]") # Ampere (GPU Arch 8.0) is supported by CUDA 11 and later
endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
if(CUDA_VERSION VERSION_GREATER_EQUAL "12.0") string(APPEND HIP_CUDA_GENCODE " -gencode arch=compute_80,code=[sm_80,compute_80]")
message(WARNING "Unsupported CUDA version. Use at your own risk.") endif()
# Hopper (GPU Arch 9.0) is supported by CUDA 12.0? and later
if(CUDA_VERSION VERSION_GREATER_EQUAL "12.0")
string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_90,code=[sm_90,compute_90]")
endif()
endif() endif()
endif() endif()

View File

@ -8,8 +8,8 @@ option(DOWNLOAD_MDI "Download and compile the MDI library instead of using an al
if(DOWNLOAD_MDI) if(DOWNLOAD_MDI)
message(STATUS "MDI download requested - we will build our own") message(STATUS "MDI download requested - we will build our own")
set(MDI_URL "https://github.com/MolSSI-MDI/MDI_Library/archive/v1.3.0.tar.gz" CACHE STRING "URL for MDI tarball") set(MDI_URL "https://github.com/MolSSI-MDI/MDI_Library/archive/v1.3.2.tar.gz" CACHE STRING "URL for MDI tarball")
set(MDI_MD5 "8a8da217148bd9b700083b67d795af5e" CACHE STRING "MD5 checksum for MDI tarball") set(MDI_MD5 "836f5da400d8cff0f0e4435640f9454f" CACHE STRING "MD5 checksum for MDI tarball")
mark_as_advanced(MDI_URL) mark_as_advanced(MDI_URL)
mark_as_advanced(MDI_MD5) mark_as_advanced(MDI_MD5)
enable_language(C) enable_language(C)

View File

@ -8,6 +8,7 @@ set(ALL_PACKAGES
AWPMD AWPMD
BOCS BOCS
BODY BODY
BPM
BROWNIAN BROWNIAN
CG-DNA CG-DNA
CG-SDK CG-SDK

View File

@ -10,6 +10,7 @@ set(ALL_PACKAGES
AWPMD AWPMD
BOCS BOCS
BODY BODY
BPM
BROWNIAN BROWNIAN
CG-DNA CG-DNA
CG-SDK CG-SDK

View File

@ -4,6 +4,7 @@ set(WIN_PACKAGES
AWPMD AWPMD
BOCS BOCS
BODY BODY
BPM
BROWNIAN BROWNIAN
CG-DNA CG-DNA
CG-SDK CG-SDK

View File

@ -6,6 +6,7 @@ set(ALL_PACKAGES
ASPHERE ASPHERE
BOCS BOCS
BODY BODY
BPM
BROWNIAN BROWNIAN
CG-DNA CG-DNA
CG-SDK CG-SDK

View File

@ -2,6 +2,7 @@ set(WIN_PACKAGES
ASPHERE ASPHERE
BOCS BOCS
BODY BODY
BPM
BROWNIAN BROWNIAN
CG-DNA CG-DNA
CG-SDK CG-SDK

View File

@ -141,8 +141,6 @@ CMake build
:code:`GPU_ARCH` settings for different GPU hardware is as follows: :code:`GPU_ARCH` settings for different GPU hardware is as follows:
* sm_12 or sm_13 for GT200 (supported by CUDA 3.2 until CUDA 6.5)
* sm_20 or sm_21 for Fermi (supported by CUDA 3.2 until CUDA 7.5)
* sm_30 for Kepler (supported since CUDA 5 and until CUDA 10.x) * sm_30 for Kepler (supported since CUDA 5 and until CUDA 10.x)
* sm_35 or sm_37 for Kepler (supported since CUDA 5 and until CUDA 11.x) * sm_35 or sm_37 for Kepler (supported since CUDA 5 and until CUDA 11.x)
* sm_50 or sm_52 for Maxwell (supported since CUDA 6) * sm_50 or sm_52 for Maxwell (supported since CUDA 6)
@ -160,6 +158,12 @@ Thus the GPU_ARCH setting is merely an optimization, to have code for
the preferred GPU architecture directly included rather than having to wait the preferred GPU architecture directly included rather than having to wait
for the JIT compiler of the CUDA driver to translate it. for the JIT compiler of the CUDA driver to translate it.
When compiling for CUDA or HIP with CUDA, version 8.0 or later of the CUDA toolkit
is required and a GPU architecture of Kepler or later, which must *also* be
supported by the CUDA toolkit in use **and** the CUDA driver in use.
When compiling for OpenCL, OpenCL version 1.2 or later is required and the
GPU must be supported by the GPU driver and OpenCL runtime bundled with the driver.
When building with CMake, you **must NOT** build the GPU library in ``lib/gpu`` When building with CMake, you **must NOT** build the GPU library in ``lib/gpu``
using the traditional build procedure. CMake will detect files generated by that using the traditional build procedure. CMake will detect files generated by that
process and will terminate with an error and a suggestion for how to remove them. process and will terminate with an error and a suggestion for how to remove them.

View File

@ -32,6 +32,8 @@ OPT.
* *
* *
* *
* :doc:`bpm/rotational <bond_bpm_rotational>`
* :doc:`bpm/spring <bond_bpm_spring>`
* :doc:`class2 (ko) <bond_class2>` * :doc:`class2 (ko) <bond_class2>`
* :doc:`fene (iko) <bond_fene>` * :doc:`fene (iko) <bond_fene>`
* :doc:`fene/expand (o) <bond_fene_expand>` * :doc:`fene/expand (o) <bond_fene_expand>`

View File

@ -91,6 +91,7 @@ KOKKOS, o = OPENMP, t = OPT.
* :doc:`msd <compute_msd>` * :doc:`msd <compute_msd>`
* :doc:`msd/chunk <compute_msd_chunk>` * :doc:`msd/chunk <compute_msd_chunk>`
* :doc:`msd/nongauss <compute_msd_nongauss>` * :doc:`msd/nongauss <compute_msd_nongauss>`
* :doc:`nbond/atom <compute_nbond_atom>`
* :doc:`omega/chunk <compute_omega_chunk>` * :doc:`omega/chunk <compute_omega_chunk>`
* :doc:`orientorder/atom (k) <compute_orientorder_atom>` * :doc:`orientorder/atom (k) <compute_orientorder_atom>`
* :doc:`pair <compute_pair>` * :doc:`pair <compute_pair>`

View File

@ -141,6 +141,7 @@ OPT.
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>` * :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>`
* :doc:`nve/noforce <fix_nve_noforce>` * :doc:`nve/noforce <fix_nve_noforce>`
* :doc:`nve/sphere (ko) <fix_nve_sphere>` * :doc:`nve/sphere (ko) <fix_nve_sphere>`
* :doc:`nve/bpm/sphere <fix_nve_bpm_sphere>`
* :doc:`nve/spin <fix_nve_spin>` * :doc:`nve/spin <fix_nve_spin>`
* :doc:`nve/tri <fix_nve_tri>` * :doc:`nve/tri <fix_nve_tri>`
* :doc:`nvk <fix_nvk>` * :doc:`nvk <fix_nvk>`
@ -158,7 +159,6 @@ OPT.
* :doc:`orient/fcc <fix_orient>` * :doc:`orient/fcc <fix_orient>`
* :doc:`orient/eco <fix_orient_eco>` * :doc:`orient/eco <fix_orient_eco>`
* :doc:`pafi <fix_pafi>` * :doc:`pafi <fix_pafi>`
* :doc:`pair/tracker <fix_pair_tracker>`
* :doc:`phonon <fix_phonon>` * :doc:`phonon <fix_phonon>`
* :doc:`pimd <fix_pimd>` * :doc:`pimd <fix_pimd>`
* :doc:`planeforce <fix_planeforce>` * :doc:`planeforce <fix_planeforce>`

View File

@ -53,6 +53,7 @@ OPT.
* :doc:`born/coul/msm (o) <pair_born>` * :doc:`born/coul/msm (o) <pair_born>`
* :doc:`born/coul/wolf (go) <pair_born>` * :doc:`born/coul/wolf (go) <pair_born>`
* :doc:`born/coul/wolf/cs (g) <pair_cs>` * :doc:`born/coul/wolf/cs (g) <pair_cs>`
* :doc:`bpm/spring <pair_bpm_spring>`
* :doc:`brownian (o) <pair_brownian>` * :doc:`brownian (o) <pair_brownian>`
* :doc:`brownian/poly (o) <pair_brownian>` * :doc:`brownian/poly (o) <pair_brownian>`
* :doc:`buck (giko) <pair_buck>` * :doc:`buck (giko) <pair_buck>`

View File

@ -54,6 +54,8 @@ Lowercase directories
+-------------+------------------------------------------------------------------+ +-------------+------------------------------------------------------------------+
| body | body particles, 2d system | | body | body particles, 2d system |
+-------------+------------------------------------------------------------------+ +-------------+------------------------------------------------------------------+
| bpm | BPM simulations of pouring elastic grains and plate impact |
+-------------+------------------------------------------------------------------+
| cmap | CMAP 5-body contributions to CHARMM force field | | cmap | CMAP 5-body contributions to CHARMM force field |
+-------------+------------------------------------------------------------------+ +-------------+------------------------------------------------------------------+
| colloid | big colloid particles in a small particle solvent, 2d system | | colloid | big colloid particles in a small particle solvent, 2d system |

View File

@ -23,6 +23,8 @@ General howto
Howto_library Howto_library
Howto_couple Howto_couple
Howto_mdi Howto_mdi
Howto_bpm
Howto_broken_bonds
Settings howto Settings howto
============== ==============

124
doc/src/Howto_bpm.rst Normal file
View File

@ -0,0 +1,124 @@
Bonded particle models
======================
The BPM package implements bonded particle models which can be used to
simulate mesoscale solids. Solids are constructed as a collection of
particles which each represent a coarse-grained region of space much
larger than the atomistic scale. Particles within a solid region are
then connected by a network of bonds to provide solid elasticity.
Unlike traditional bonds in molecular dynamics, the equilibrium bond
length can vary between bonds. Bonds store the reference state. This
includes setting the equilibrium length equal to the initial distance
between the two particles but can also include data on the bond
orientation for rotational models. This produces a stress free initial
state. Furthermore, bonds are allowed to break under large strains
producing fracture. The examples/bpm directory has sample input scripts
for simulations of the fragmentation of an impacted plate and the
pouring of extended, elastic bodies.
----------
Bonds can be created using a :doc:`read data <read_data>` or
:doc:`create bonds <create_bonds>` command. Alternatively, a
:doc:`molecule <molecule>` template with bonds can be used with
:doc:`fix deposit <fix_deposit>` or :doc:`fix pour <fix_pour>` to
create solid grains.
In this implementation, bonds store their reference state when they are
first computed in the setup of the first simulation run. Data is then
preserved across run commands and is written to :doc:`binary restart
files <restart>` such that restarting the system will not reset the
reference state of a bond. Bonds that are created midway into a run,
such as those created by pouring grains using :doc:`fix pour
<fix_pour>`, are initialized on that timestep.
As bonds can be broken between neighbor list builds, the
:doc:`special_bonds <special_bonds>` command works differently for BPM
bond styles. There are two possible settings which determine how pair
interactions work between bonded particles. First, one can turn off
all pair interactions between bonded particles. Unlike :doc:`bond
quartic <bond_quartic>`, this is not done by subtracting pair forces
during the bond computation but rather by dynamically updating the
special bond list. This is the default behavior of BPM bond styles and
is done by updating the 1-2 special bond list as bonds break. To do
this, LAMMPS requires :doc:`newton <newton>` bond off such that all
processors containing an atom know when a bond breaks. Additionally,
one must do either (A) or (B).
(A)
Use the following special bond settings
.. code-block:: LAMMPS
special_bonds lj 0 1 1 coul 1 1 1
These settings accomplish two goals. First, they turn off 1-3 and 1-4
special bond lists, which are not currently supported for BPMs. As
BPMs often have dense bond networks, generating 1-3 and 1-4 special
bond lists is expensive. By setting the lj weight for 1-2 bonds to
zero, this turns off pairwise interactions. Even though there are no
charges in BPM models, setting a nonzero coul weight for 1-2 bonds
ensures all bonded neighbors are still included in the neighbor list
in case bonds break between neighbor list builds.
(B)
Alternatively, one can simply overlay pair interactions such that all
bonded particles also feel pair interactions. This can be accomplished
by using the *overlay/pair* keyword present in all bpm bond styles and
by using the following special bond settings
.. code-block:: LAMMPS
special_bonds lj/coul 1 1 1
See the :doc:`Howto <Howto_broken_bonds>` page on broken bonds for
more information.
----------
Currently there are two types of bonds included in the BPM
package. The first bond style, :doc:`bond bpm/spring
<bond_bpm_spring>`, only applies pairwise, central body forces. Point
particles must have :doc:`bond atom style <atom_style>` and may be
thought of as nodes in a spring network. Alternatively, the second
bond style, :doc:`bond bpm/rotational <bond_bpm_rotational>`, resolves
tangential forces and torques arising with the shearing, bending, and
twisting of the bond due to rotation or displacement of particles.
Particles are similar to those used in the :doc:`granular package
<Howto_granular>`, :doc:`atom style sphere <atom_style>`. However,
they must also track the current orientation of particles and store bonds
and therefore use a :doc:`bpm/sphere atom style <atom_style>`.
This also requires a unique integrator :doc:`fix nve/bpm/sphere
<fix_nve_bpm_sphere>` which numerically integrates orientation similar
to :doc:`fix nve/asphere <fix_nve_asphere>`.
To monitor the fracture of bonds in the system, all BPM bond styles
have the ability to record instances of bond breakage to output using
the :doc:`dump local <dump>` command. Additionally, one can use
:doc:`compute nbond/atom <compute_nbond_atom>` to tally the current
number of bonds per atom.
In addition to bond styles, a new pair style :doc:`pair bpm/spring
<pair_bpm_spring>` was added to accompany the bpm/spring bond
style. This pair style is simply a hookean repulsion with similar
velocity damping as its sister bond style.
----------
While LAMMPS has many utilities to create and delete bonds, *only*
the following are currently compatible with BPM bond styles:
* :doc:`create_bonds <create_bonds>`
* :doc:`delete_bonds <delete_bonds>`
* :doc:`fix bond/create <fix_bond_create>`
* :doc:`fix bond/break <fix_bond_break>`
* :doc:`fix bond/swap <fix_bond_swap>`
Note :doc:`create_bonds <create_bonds>` requires certain special_bonds settings.
To subtract pair interactions, one will need to switch between different
special_bonds settings in the input script. An example is found in
examples/bpm/impact.

View File

@ -0,0 +1,48 @@
Broken Bonds
============
Typically, bond interactions persist for the duration of a simulation
in LAMMPS. However, there are some exceptions that allow for bonds to
break including the :doc:`quartic bond style <bond_quartic>` and the
bond styles in the :doc:`BPM package <Howto_bpm>` which contains the
:doc:`bpm/spring <bond_bpm_spring>` and
:doc:`bpm/rotational <bond_bpm_rotational>` bond styles. In these cases,
a bond can be broken if it is stretched beyond a user-defined threshold.
LAMMPS accomplishes this by setting the bond type to zero such that the
bond force is no longer computed.
Users are normally able to weight the contribution of pair forces to atoms
that are bonded using the :doc:`special_bonds command <special_bonds>`.
When bonds break, this is not always the case. For the quartic bond style,
pair forces are always turned off between bonded particles. LAMMPS does
this via a computational sleight-of-hand. It subtracts the pairwise
interaction as part of the bond computation. When the bond breaks, the
subtraction stops. For this to work, the pairwise interaction must always
be computed by the :doc:`pair_style <pair_style>` command, whether the bond
is broken or not. This means that :doc:`special_bonds <special_bonds>` must
be set to 1,1,1. After the bond breaks, the pairwise interaction between the
two atoms is turned on, since they are no longer bonded.
In the BPM package, one can either turn off all pair interactions between
bonded particles or leave them on, overlaying pair forces on top of bond
forces. To remove pair forces, the special bond list is dynamically
updated. More details can be found on the :doc:`Howto BPM <Howto_bpm>`
page.
Bonds can also be broken by fixes which change bond topology, including
:doc:`fix bond/break <fix_bond_break>` and
:doc:`fix bond/react <fix_bond_react>`. These fixes will automatically
trigger a rebuild of the neighbor list and update special bond data structures
when bonds are broken.
Note that when bonds are dumped to a file via the :doc:`dump local <dump>` command, bonds with type 0 are not included. The
:doc:`delete_bonds <delete_bonds>` command can also be used to query the
status of broken bonds or permanently delete them, e.g.:
.. code-block:: LAMMPS
delete_bonds all stats
delete_bonds all bond 0 remove
The compute :doc:`nbond/atom <compute_nbond_atom>` can also be used
to tally the current number of bonds per atom, excluding broken bonds.

View File

@ -32,6 +32,7 @@ page gives those details.
* :ref:`AWPMD <PKG-AWPMD>` * :ref:`AWPMD <PKG-AWPMD>`
* :ref:`BOCS <PKG-BOCS>` * :ref:`BOCS <PKG-BOCS>`
* :ref:`BODY <PKG-BODY>` * :ref:`BODY <PKG-BODY>`
* :ref:`BPM <PKG-BPM>`
* :ref:`BROWNIAN <PKG-BROWNIAN>` * :ref:`BROWNIAN <PKG-BROWNIAN>`
* :ref:`CG-DNA <PKG-CG-DNA>` * :ref:`CG-DNA <PKG-CG-DNA>`
* :ref:`CG-SDK <PKG-CG-SDK>` * :ref:`CG-SDK <PKG-CG-SDK>`
@ -283,6 +284,33 @@ overview.
---------- ----------
.. _PKG-BPM:
BPM package
------------
**Contents:**
Pair styles, bond styles, fixes, and computes for bonded particle
models for mesoscale simulations of solids and fracture. See the
:doc:`Howto bpm <Howto_bpm>` page for an overview.
**Authors:** Joel T. Clemmer (Sandia National Labs)
**Supporting info:**
* src/BPM filenames -> commands
* :doc:`Howto_bpm <Howto_bpm>`
* :doc:`atom_style bpm/sphere <atom_style>`
* :doc:`bond_style bpm/rotational <bond_bpm_rotational>`
* :doc:`bond_style bpm/spring <bond_bpm_spring>`
* :doc:`compute nbond/atom <compute_nbond_atom>`
* :doc:`fix nve/bpm/sphere <fix_nve_bpm_sphere>`
* :doc:`pair_style bpm/spring <pair_bpm_spring>`
* examples/bpm
----------
.. _PKG-BROWNIAN: .. _PKG-BROWNIAN:
BROWNIAN package BROWNIAN package
@ -1557,7 +1585,6 @@ listing, "ls src/MISC", to see the list of commands.
* :doc:`pair_style list <pair_list>` * :doc:`pair_style list <pair_list>`
* :doc:`pair_style srp <pair_srp>` * :doc:`pair_style srp <pair_srp>`
* :doc:`pair_style tracker <pair_tracker>` * :doc:`pair_style tracker <pair_tracker>`
* :doc:`fix pair/tracker <fix_pair_tracker>`
---------- ----------

View File

@ -58,6 +58,11 @@ whether an extra library is needed to build and use the package:
- :doc:`Howto body <Howto_body>` - :doc:`Howto body <Howto_body>`
- body - body
- no - no
* - :ref:`BPM <PKG-BPM>`
- bonded particle models
- :doc:`Howto bpm <Howto_bpm>`
- bpm
- no
* - :ref:`BROWNIAN <PKG-BROWNIAN>` * - :ref:`BROWNIAN <PKG-BROWNIAN>`
- Brownian dynamics, self-propelled particles - Brownian dynamics, self-propelled particles
- :doc:`fix brownian <fix_brownian>`, :doc:`fix propel/self <fix_propel_self>` - :doc:`fix brownian <fix_brownian>`, :doc:`fix propel/self <fix_propel_self>`

View File

@ -10,7 +10,7 @@ Syntax
atom_style style args atom_style style args
* style = *angle* or *atomic* or *body* or *bond* or *charge* or *dipole* or *dpd* or *edpd* or *electron* or *ellipsoid* or *full* or *line* or *mdpd* or *molecular* or *oxdna* or *peri* or *smd* or *sph* or *sphere* or *spin* or *tdpd* or *tri* or *template* or *hybrid* * style = *angle* or *atomic* or *body* or *bond* or *charge* or *dipole* or *dpd* or *edpd* or *electron* or *ellipsoid* or *full* or *line* or *mdpd* or *molecular* or *oxdna* or *peri* or *smd* or *sph* or *sphere* or *bpm/sphere* or *spin* or *tdpd* or *tri* or *template* or *hybrid*
.. parsed-literal:: .. parsed-literal::
@ -21,6 +21,7 @@ Syntax
see the :doc:`Howto body <Howto_body>` doc see the :doc:`Howto body <Howto_body>` doc
page for details page for details
*sphere* arg = 0/1 (optional) for static/dynamic particle radii *sphere* arg = 0/1 (optional) for static/dynamic particle radii
*bpm/sphere* arg = 0/1 (optional) for static/dynamic particle radii
*tdpd* arg = Nspecies *tdpd* arg = Nspecies
Nspecies = # of chemical species Nspecies = # of chemical species
*template* arg = template-ID *template* arg = template-ID
@ -120,6 +121,8 @@ quantities.
+--------------+-----------------------------------------------------+--------------------------------------+ +--------------+-----------------------------------------------------+--------------------------------------+
| *sphere* | diameter, mass, angular velocity | granular models | | *sphere* | diameter, mass, angular velocity | granular models |
+--------------+-----------------------------------------------------+--------------------------------------+ +--------------+-----------------------------------------------------+--------------------------------------+
| *bpm/sphere* | diameter, mass, angular velocity, quaternion | granular bonded particle models (BPM)|
+--------------+-----------------------------------------------------+--------------------------------------+
| *spin* | magnetic moment | system with magnetic particles | | *spin* | magnetic moment | system with magnetic particles |
+--------------+-----------------------------------------------------+--------------------------------------+ +--------------+-----------------------------------------------------+--------------------------------------+
| *tdpd* | chemical concentration | tDPD particles | | *tdpd* | chemical concentration | tDPD particles |
@ -141,8 +144,9 @@ quantities.
output the custom values. output the custom values.
All of the above styles define point particles, except the *sphere*, All of the above styles define point particles, except the *sphere*,
*ellipsoid*, *electron*, *peri*, *wavepacket*, *line*, *tri*, and *bpm/sphere*, *ellipsoid*, *electron*, *peri*, *wavepacket*, *line*,
*body* styles, which define finite-size particles. See the :doc:`Howto spherical <Howto_spherical>` page for an overview of using *tri*, and *body* styles, which define finite-size particles. See the
:doc:`Howto spherical <Howto_spherical>` page for an overview of using
finite-size particle models with LAMMPS. finite-size particle models with LAMMPS.
All of the point-particle styles assign mass to particles on a All of the point-particle styles assign mass to particles on a
@ -150,15 +154,15 @@ per-type basis, using the :doc:`mass <mass>` command, The finite-size
particle styles assign mass to individual particles on a per-particle particle styles assign mass to individual particles on a per-particle
basis. basis.
For the *sphere* style, the particles are spheres and each stores a For the *sphere* and *bpm/sphere* styles, the particles are spheres and each stores a
per-particle diameter and mass. If the diameter > 0.0, the particle per-particle diameter and mass. If the diameter > 0.0, the particle
is a finite-size sphere. If the diameter = 0.0, it is a point is a finite-size sphere. If the diameter = 0.0, it is a point
particle. Note that by use of the *disc* keyword with the :doc:`fix particle. Note that by use of the *disc* keyword with the :doc:`fix
nve/sphere <fix_nve_sphere>`, :doc:`fix nvt/sphere <fix_nvt_sphere>`, nve/sphere <fix_nve_sphere>`, :doc:`fix nvt/sphere <fix_nvt_sphere>`,
:doc:`fix nph/sphere <fix_nph_sphere>`, :doc:`fix npt/sphere :doc:`fix nph/sphere <fix_nph_sphere>`, :doc:`fix npt/sphere
<fix_npt_sphere>` commands, spheres can be effectively treated as 2d <fix_npt_sphere>` commands for the *sphere* style, spheres can be effectively treated as 2d
discs for a 2d simulation if desired. See also the :doc:`set discs for a 2d simulation if desired. See also the :doc:`set
density/disc <set>` command. The *sphere* style takes an optional 0 density/disc <set>` command. The *sphere* and *bpm/sphere* styles take an optional 0
or 1 argument. A value of 0 means the radius of each sphere is or 1 argument. A value of 0 means the radius of each sphere is
constant for the duration of the simulation. A value of 1 means the constant for the duration of the simulation. A value of 1 means the
radii may vary dynamically during the simulation, e.g. due to use of radii may vary dynamically during the simulation, e.g. due to use of
@ -195,6 +199,8 @@ position, which is represented by the eradius = electron size.
For the *peri* style, the particles are spherical and each stores a For the *peri* style, the particles are spherical and each stores a
per-particle mass and volume. per-particle mass and volume.
The *bpm/sphere* style is part of the BPM package.
The *oxdna* style is for coarse-grained nucleotides and stores the The *oxdna* style is for coarse-grained nucleotides and stores the
3'-to-5' polarity of the nucleotide strand, which is set through 3'-to-5' polarity of the nucleotide strand, which is set through
the bond topology in the data file. The first (second) atom in a the bond topology in the data file. The first (second) atom in a

View File

@ -0,0 +1,258 @@
.. index:: bond_style bpm/rotational
bond_style bpm/rotational command
=================================
Syntax
""""""
.. code-block:: LAMMPS
bond_style bpm/rotational keyword value attribute1 attribute2 ...
* optional keyword = *overlay/pair* or *store/local* or *smooth*
.. parsed-literal::
*store/local* values = fix_ID N attributes ...
* fix_ID = ID of associated internal fix to store data
* N = prepare data for output every this many timesteps
* attributes = zero or more of the below attributes may be appended
*id1, id2* = IDs of 2 atoms in the bond
*time* = the timestep the bond broke
*x, y, z* = the center of mass position of the 2 atoms when the bond broke (distance units)
*x/ref, y/ref, z/ref* = the initial center of mass position of the 2 atoms (distance units)
*overlay/pair* value = none
bonded particles will still interact with pair forces
*smooth* value = *yes* or *no*
smooths bond forces near the breaking point
Examples
""""""""
.. code-block:: LAMMPS
bond_style bpm/rotational
bond_coeff 1 1.0 0.2 0.02 0.02 0.20 0.04 0.04 0.04 0.1 0.02 0.002 0.002
bond_style bpm/rotational myfix 1000 time id1 id2
fix myfix all store/local 1000 3
dump 1 all local 1000 dump.broken f_myfix[1] f_myfix[2] f_myfix[3]
dump_modify 1 write_header no
Description
"""""""""""
The *bpm/rotational* bond style computes forces and torques based on
deviations from the initial reference state of the two atoms. The
reference state is stored by each bond when it is first computed in
the setup of a run. Data is then preserved across run commands and is
written to :doc:`binary restart files <restart>` such that restarting
the system will not reset the reference state of a bond.
Forces include a normal and tangential component. The base normal force
has a magnitude of
.. math::
f_r = k_r (r - r_0)
where :math:`k_r` is a stiffness and :math:`r` is the current distance and
:math:`r_0` is the initial distance between the two particles.
A tangential force is applied perpendicular to the normal direction
which is proportional to the tangential shear displacement with a
stiffness of :math:`k_s`. This tangential force also induces a torque.
In addition, bending and twisting torques are also applied to
particles which are proportional to angular bending and twisting
displacements with stiffnesses of :math`k_b` and :math:`k_t',
respectively. Details on the calculations of shear displacements and
angular displacements can be found in :ref:`(Wang) <Wang2009>` and
:ref:`(Wang and Mora) <Wang2009b>`.
Bonds will break under sufficient stress. A breaking criteria is calculated
.. math::
B = \mathrm{max}\{0, \frac{f_r}{f_{r,c}} + \frac{|f_s|}{f_{s,c}} +
\frac{|\tau_b|}{\tau_{b,c}} + \frac{|\tau_t|}{\tau_{t,c}} \}
where :math:`|f_s|` is the magnitude of the shear force and
:math:`|\tau_b|` and :math:`|\tau_t|` are the magnitudes of the
bending and twisting forces, respectively. The corresponding variables
:math:`f_{r,c}` :math:`f_{s,c}`, :math:`\tau_{b,c}`, and
:math:`\tau_{t,c}` are critical limits to each force or torque. If
:math:`B` is ever equal to or exceeds one, the bond will break. This
is done by setting by setting its type to 0 such that forces and
torques are no longer computed.
After computing the base magnitudes of the forces and torques, they
can be optionally multiplied by an extra factor :math:`w` to smoothly
interpolate forces and torques to zero as the bond breaks. This term
is calculated as :math:`w = (1.0 - B^4)`. This smoothing factor can be
added or removed using the *smooth* keyword.
Finally, additional damping forces and torques are applied to the two
particles. A force is applied proportional to the difference in the
normal velocity of particles using a similar construction as
dissipative particle dynamics (:ref:`(Groot) <Groot3>`):
.. math::
F_D = - \gamma_n w (\hat{r} \bullet \vec{v})
where :math:`\gamma_n` is the damping strength, :math:`\hat{r}` is the
radial normal vector, and :math:`\vec{v}` is the velocity difference
between the two particles. Similarly, tangential forces are applied to
each atom proportional to the relative differences in sliding
velocities with a constant prefactor :math:`\gamma_s` (:ref:`(Wang et
al.) <Wang20152>`) along with their associated torques. The rolling and
twisting components of the relative angular velocities of the two
atoms are also damped by applying torques with prefactors of
:math:`\gamma_r` and :math:`\gamma_t`, respectively.
The following coefficients must be defined for each bond type via the
:doc:`bond_coeff <bond_coeff>` command as in the example above, or in
the data file or restart files read by the :doc:`read_data <read_data>`
or :doc:`read_restart <read_restart>` commands:
* :math:`k_r` (force/distance units)
* :math:`k_s` (force/distance units)
* :math:`k_t` (force*distance/radians units)
* :math:`k_b` (force*distance/radians units)
* :math:`f_{r,c}` (force units)
* :math:`f_{s,c}` (force units)
* :math:`\tau_{b,c}` (force*distance units)
* :math:`\tau_{t,c}` (force*distance units)
* :math:`\gamma_n` (force/velocity units)
* :math:`\gamma_s` (force/velocity units)
* :math:`\gamma_r` (force*distance/velocity units)
* :math:`\gamma_t` (force*distance/velocity units)
By default, pair forces are not calculated between bonded particles.
Pair forces can alternatively be overlaid on top of bond forces using
the *overlay/pair* keyword. These settings require specific
:doc:`special_bonds <special_bonds>` settings described in the
restrictions. Further details can be found in the `:doc: how to
<Howto_BPM>` page on BPMs.
If the *store/local* keyword is used, this fix will track bonds that
break during the simulation. Whenever a bond breaks, data is processed
and transferred to an internal fix labeled *fix_ID*. This allows the
local data to be accessed by other LAMMPS commands.
Following any optional keyword/value arguments, a list of one or more
attributes is specified. These include the IDs of the two atoms in
the bond. The other attributes for the two atoms include the timestep
during which the bond broke and the current/initial center of mass
position of the two atoms.
Data is continuously accumulated over intervals of *N*
timesteps. At the end of each interval, all of the saved accumulated
data is deleted to make room for new data. Individual datum may
therefore persist anywhere between *1* to *N* timesteps depending on
when they are saved. This data can be accessed using the *fix_ID* and a
:doc:`dump local <dump>` command. To ensure all data is output,
the dump frequency should correspond to the same interval of *N*
timesteps. A dump frequency of an integer multiple of *N* can be used
to regularly output a sample of the accumulated data.
Note that when unbroken bonds are dumped to a file via the
:doc:`dump local <dump>` command, bonds with type 0 (broken bonds)
are not included.
The :doc:`delete_bonds <delete_bonds>` command can also be used to
query the status of broken bonds or permanently delete them, e.g.:
.. code-block:: LAMMPS
delete_bonds all stats
delete_bonds all bond 0 remove
----------
Restart and other info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
This bond style writes the reference state of each bond to
:doc:`binary restart files <restart>`. Loading a restart file will
properly resume bonds.
The single() function of these pair styles returns 0.0 for the energy
of a pairwise interaction, since energy is not conserved in these
dissipative potentials. It also returns only the normal component of
the pairwise interaction force.
The accumulated data is not written to restart files and should be
output before a restart file is written to avoid missing data.
The internal fix calculates a local vector or local array depending on the
number of input values. The length of the vector or number of rows in
the array is the number of recorded, lost interactions. If a single
input is specified, a local vector is produced. If two or more inputs
are specified, a local array is produced where the number of columns =
the number of inputs. The vector or array can be accessed by any
command that uses local values from a compute as input. See the
:doc:`Howto output <Howto_output>` page for an overview of LAMMPS
output options.
The vector or array will be floating point values that correspond to
the specified attribute.
Restrictions
""""""""""""
This bond style can only be used if LAMMPS was built with the BPM
package. See the :doc:`Build package <Build_package>` doc page for
more info.
By default if pair interactions are to be disabled, this bond style
requires setting
.. code-block:: LAMMPS
special_bonds lj 0 1 1 coul 1 1 1
and :doc:`newton <newton>` must be set to bond off. If the
*overlay/pair* option is used, this bond style alternatively requires
setting
.. code-block:: LAMMPS
special_bonds lj/coul 1 1 1
The *bpm/rotational* style requires :doc:`atom style bpm/sphere <atom_style>`.
Related commands
""""""""""""""""
:doc:`bond_coeff <bond_coeff>`, :doc:`fix nve/bpm/sphere <fix_nve_bpm_sphere>`
Default
"""""""
The option defaults are *smooth* = *yes*
----------
.. _Wang2009:
**(Wang)** Wang, Acta Geotechnica, 4,
p 117-127 (2009).
.. _Wang2009b:
**(Wang and Mora)** Wang, Mora, Advances in Geocomputing,
119, p 183-228 (2009).
.. _Groot3:
**(Groot)** Groot and Warren, J Chem Phys, 107, 4423-35 (1997).
.. _Wang20152:
**(Wang et al, 2015)** Wang, Y., Alonso-Marroquin, F., & Guo,
W. W. (2015). Rolling and sliding in 3-D discrete element
models. Particuology, 23, 49-55.

202
doc/src/bond_bpm_spring.rst Normal file
View File

@ -0,0 +1,202 @@
.. index:: bond_style bpm/spring
bond_style bpm/spring command
=============================
Syntax
""""""
.. code-block:: LAMMPS
bond_style bpm/spring keyword value attribute1 attribute2 ...
* optional keyword = *overlay/pair* or *store/local* or *smooth*
.. parsed-literal::
*store/local* values = fix_ID N attributes ...
* fix_ID = ID of associated internal fix to store data
* N = prepare data for output every this many timesteps
* attributes = zero or more of the below attributes may be appended
*id1, id2* = IDs of 2 atoms in the bond
*time* = the timestep the bond broke
*x, y, z* = the center of mass position of the 2 atoms when the bond broke (distance units)
*x/ref, y/ref, z/ref* = the initial center of mass position of the 2 atoms (distance units)
*overlay/pair* value = none
bonded particles will still interact with pair forces
*smooth* value = *yes* or *no*
smooths bond forces near the breaking point
Examples
""""""""
.. code-block:: LAMMPS
bond_style bpm/spring
bond_coeff 1 1.0 0.05 0.1
bond_style bpm/spring myfix 1000 time id1 id2
dump 1 all local 1000 dump.broken f_myfix[1] f_myfix[2] f_myfix[3]
dump_modify 1 write_header no
Description
"""""""""""
The *bpm/spring* bond style computes forces and torques based on
deviations from the initial reference state of the two atoms. The
reference state is stored by each bond when it is first computed in
the setup of a run. Data is then preserved across run commands and is
written to :doc:`binary restart files <restart>` such that restarting
the system will not reset the reference state of a bond.
This bond style only applies central-body forces which conserve the
translational and rotational degrees of freedom of a bonded set of
particles. The force has a magnitude of
.. math::
F = k (r - r_0) w
where :math:`k_r` is a stiffness, :math:`r` is the current distance
and :math:`r_0` is the initial distance between the two particles, and
:math:`w` is an optional smoothing factor discussed below. Bonds will
break at a strain of :math:`\epsilon_c`. This is done by setting by
setting its type to 0 such that forces are no longer computed.
An additional damping force is applied to the bonded
particles. This forces is proportional to the difference in the
normal velocity of particles using a similar construction as
dissipative particle dynamics (:ref:`(Groot) <Groot4>`):
.. math::
F_D = - \gamma w (\hat{r} \bullet \vec{v})
where :math:`\gamma` is the damping strength, :math:`\hat{r}` is the
radial normal vector, and :math:`\vec{v}` is the velocity difference
between the two particles.
The smoothing factor :math:`w` can be added or removed using the
*smooth* keyword. It is constructed such that forces smoothly go
to zero, avoiding discontinuities, as bonds approach the critical strain
.. math::
w = 1.0 - \left( \frac{r - r_0}{r_0 \epsilon_c} \right)^8 .
The following coefficients must be defined for each bond type via the
:doc:`bond_coeff <bond_coeff>` command as in the example above, or in
the data file or restart files read by the :doc:`read_data
<read_data>` or :doc:`read_restart <read_restart>` commands:
* :math:`k` (force/distance units)
* :math:`\epsilon_c` (unit less)
* :math:`\gamma` (force/velocity units)
By default, pair forces are not calculated between bonded particles.
Pair forces can alternatively be overlaid on top of bond forces using
the *overlay/pair* keyword. These settings require specific
:doc:`special_bonds <special_bonds>` settings described in the
restrictions. Further details can be found in the `:doc: how to
<Howto_BPM>` page on BPMs.
If the *store/local* keyword is used, this fix will track bonds that
break during the simulation. Whenever a bond breaks, data is processed
and transferred to an internal fix labeled *fix_ID*. This allows the
local data to be accessed by other LAMMPS commands.
Following any optional keyword/value arguments, a list of one or more
attributes is specified. These include the IDs of the two atoms in
the bond. The other attributes for the two atoms include the timestep
during which the bond broke and the current/initial center of mass
position of the two atoms.
Data is continuously accumulated over intervals of *N*
timesteps. At the end of each interval, all of the saved accumulated
data is deleted to make room for new data. Individual datum may
therefore persist anywhere between *1* to *N* timesteps depending on
when they are saved. This data can be accessed using the *fix_ID* and a
:doc:`dump local <dump>` command. To ensure all data is output,
the dump frequency should correspond to the same interval of *N*
timesteps. A dump frequency of an integer multiple of *N* can be used
to regularly output a sample of the accumulated data.
Note that when unbroken bonds are dumped to a file via the
:doc:`dump local <dump>` command, bonds with type 0 (broken bonds)
are not included.
The :doc:`delete_bonds <delete_bonds>` command can also be used to
query the status of broken bonds or permanently delete them, e.g.:
.. code-block:: LAMMPS
delete_bonds all stats
delete_bonds all bond 0 remove
----------
Restart and other info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
This bond style writes the reference state of each bond to
:doc:`binary restart files <restart>`. Loading a restart
file will properly resume bonds.
The single() function of these pair styles returns 0.0 for the energy
of a pairwise interaction, since energy is not conserved in these
dissipative potentials.
The accumulated data is not written to restart files and should be
output before a restart file is written to avoid missing data.
The internal fix calculates a local vector or local array depending on the
number of input values. The length of the vector or number of rows in
the array is the number of recorded, lost interactions. If a single
input is specified, a local vector is produced. If two or more inputs
are specified, a local array is produced where the number of columns =
the number of inputs. The vector or array can be accessed by any
command that uses local values from a compute as input. See the
:doc:`Howto output <Howto_output>` page for an overview of LAMMPS
output options.
The vector or array will be floating point values that correspond to
the specified attribute.
Restrictions
""""""""""""
This bond style can only be used if LAMMPS was built with the BPM
package. See the :doc:`Build package <Build_package>` doc page for
more info.
By default if pair interactions are to be disabled, this bond style
requires setting
.. code-block:: LAMMPS
special_bonds lj 0 1 1 coul 1 1 1
and :doc:`newton <newton>` must be set to bond off. If the
*overlay/pair* option is used, this bond style alternatively requires
setting
.. code-block:: LAMMPS
special_bonds lj/coul 1 1 1
Related commands
""""""""""""""""
:doc:`bond_coeff <bond_coeff>`, :doc:`pair bpm/spring <pair_bpm_spring>`
Default
"""""""
The option defaults are *smooth* = *yes*
----------
.. _Groot4:
**(Groot)** Groot and Warren, J Chem Phys, 107, 4423-35 (1997).

View File

@ -67,7 +67,8 @@ local maximum. If a bond length ever becomes :math:`> R_c`, LAMMPS "breaks"
the bond, which means two things. First, the bond potential is turned the bond, which means two things. First, the bond potential is turned
off by setting its type to 0, and is no longer computed. Second, a off by setting its type to 0, and is no longer computed. Second, a
pairwise interaction between the two atoms is turned on, since they pairwise interaction between the two atoms is turned on, since they
are no longer bonded. are no longer bonded. See the :doc:`Howto <Howto_broken_bonds>` page
on broken bonds for more information.
LAMMPS does the second task via a computational sleight-of-hand. It LAMMPS does the second task via a computational sleight-of-hand. It
subtracts the pairwise interaction as part of the bond computation. subtracts the pairwise interaction as part of the bond computation.

View File

@ -84,6 +84,8 @@ accelerated styles exist.
* :doc:`zero <bond_zero>` - topology but no interactions * :doc:`zero <bond_zero>` - topology but no interactions
* :doc:`hybrid <bond_hybrid>` - define multiple styles of bond interactions * :doc:`hybrid <bond_hybrid>` - define multiple styles of bond interactions
* :doc:`bpm/rotational <bond_bpm_rotational>` - breakable bond with forces and torques based on deviation from reference state
* :doc:`bpm/spring <bond_bpm_spring>` - breakable bond with forces based on deviation from reference length
* :doc:`class2 <bond_class2>` - COMPASS (class 2) bond * :doc:`class2 <bond_class2>` - COMPASS (class 2) bond
* :doc:`fene <bond_fene>` - FENE (finite-extensible non-linear elastic) bond * :doc:`fene <bond_fene>` - FENE (finite-extensible non-linear elastic) bond
* :doc:`fene/expand <bond_fene_expand>` - FENE bonds with variable size particles * :doc:`fene/expand <bond_fene_expand>` - FENE bonds with variable size particles

View File

@ -236,6 +236,7 @@ The individual style names on the :doc:`Commands compute <Commands_compute>` pag
* :doc:`msd <compute_msd>` - mean-squared displacement of group of atoms * :doc:`msd <compute_msd>` - mean-squared displacement of group of atoms
* :doc:`msd/chunk <compute_msd_chunk>` - mean-squared displacement for each chunk * :doc:`msd/chunk <compute_msd_chunk>` - mean-squared displacement for each chunk
* :doc:`msd/nongauss <compute_msd_nongauss>` - MSD and non-Gaussian parameter of group of atoms * :doc:`msd/nongauss <compute_msd_nongauss>` - MSD and non-Gaussian parameter of group of atoms
* :doc:`nbond/atom <compute_nbond_atom>` - calculates number of bonds per atom
* :doc:`omega/chunk <compute_omega_chunk>` - angular velocity for each chunk * :doc:`omega/chunk <compute_omega_chunk>` - angular velocity for each chunk
* :doc:`orientorder/atom <compute_orientorder_atom>` - Steinhardt bond orientational order parameters Ql * :doc:`orientorder/atom <compute_orientorder_atom>` - Steinhardt bond orientational order parameters Ql
* :doc:`pair <compute_pair>` - values computed by a pair style * :doc:`pair <compute_pair>` - values computed by a pair style

View File

@ -0,0 +1,52 @@
.. index:: compute nbond/atom
compute nbond/atom command
==========================
Syntax
""""""
.. parsed-literal::
compute ID group-ID nbond/atom
* ID, group-ID are documented in :doc:`compute <compute>` command
* nbond/atom = style name of this compute command
Examples
""""""""
.. code-block:: LAMMPS
compute 1 all nbond/atom
Description
"""""""""""
Define a computation that computes the number of bonds each atom is
part of. Bonds which are broken are not counted in the tally. See
the :doc:`Howto broken bonds <Howto_bpm>` page for more information.
The number of bonds will be zero for atoms not in the specified
compute group. This compute does not depend on Newton bond settings.
Output info
"""""""""""
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
the :doc:`Howto output <Howto_output>` doc page for an overview of
LAMMPS output options.
Restrictions
""""""""""""
This fix can only be used if LAMMPS was built with the BPM package.
See the :doc:`Build package <Build_package>` doc page for more info.
Related commands
""""""""""""""""
Default
"""""""
none

View File

@ -474,8 +474,9 @@ The *fileper* keyword is documented below with the *nfile* keyword.
The *header* keyword toggles whether the dump file will include a The *header* keyword toggles whether the dump file will include a
header. Excluding a header will reduce the size of the dump file for header. Excluding a header will reduce the size of the dump file for
fixes such as :doc:`fix pair/tracker <fix_pair_tracker>` which do not data produced by :doc:`pair tracker <pair_tracker>` or
require the information typically written to the header. :doc:`bpm bond styles <Howto_bpm>` which may not require the
information typically written to the header.
---------- ----------

View File

@ -284,6 +284,7 @@ accelerated styles exist.
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>` - * :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>` -
* :doc:`nve/noforce <fix_nve_noforce>` - NVE without forces (v only) * :doc:`nve/noforce <fix_nve_noforce>` - NVE without forces (v only)
* :doc:`nve/sphere <fix_nve_sphere>` - NVE for spherical particles * :doc:`nve/sphere <fix_nve_sphere>` - NVE for spherical particles
* :doc:`nve/bpm/sphere <fix_nve_bpm_sphere>` - NVE for spherical particles used in the BPM package
* :doc:`nve/spin <fix_nve_spin>` - NVE for a spin or spin-lattice system * :doc:`nve/spin <fix_nve_spin>` - NVE for a spin or spin-lattice system
* :doc:`nve/tri <fix_nve_tri>` - NVE for triangles * :doc:`nve/tri <fix_nve_tri>` - NVE for triangles
* :doc:`nvk <fix_nvk>` - constant kinetic energy time integration * :doc:`nvk <fix_nvk>` - constant kinetic energy time integration
@ -301,7 +302,6 @@ accelerated styles exist.
* :doc:`orient/fcc <fix_orient>` - add grain boundary migration force for FCC * :doc:`orient/fcc <fix_orient>` - add grain boundary migration force for FCC
* :doc:`orient/eco <fix_orient_eco>` - add generalized grain boundary migration force * :doc:`orient/eco <fix_orient_eco>` - add generalized grain boundary migration force
* :doc:`pafi <fix_pafi>` - constrained force averages on hyper-planes to compute free energies (PAFI) * :doc:`pafi <fix_pafi>` - constrained force averages on hyper-planes to compute free energies (PAFI)
* :doc:`pair/tracker <fix_pair_tracker>` - track properties of pairwise interactions
* :doc:`phonon <fix_phonon>` - calculate dynamical matrix from MD simulations * :doc:`phonon <fix_phonon>` - calculate dynamical matrix from MD simulations
* :doc:`pimd <fix_pimd>` - Feynman path integral molecular dynamics * :doc:`pimd <fix_pimd>` - Feynman path integral molecular dynamics
* :doc:`planeforce <fix_planeforce>` - constrain atoms to move in a plane * :doc:`planeforce <fix_planeforce>` - constrain atoms to move in a plane

View File

@ -113,6 +113,9 @@ You can dump out snapshots of the current bond topology via the :doc:`dump local
may need to thermostat your system to compensate for energy changes may need to thermostat your system to compensate for energy changes
resulting from broken bonds (and angles, dihedrals, impropers). resulting from broken bonds (and angles, dihedrals, impropers).
See the :doc:`Howto <Howto_broken_bonds>` page on broken bonds for more
information on related features in LAMMPS.
---------- ----------
Restart, fix_modify, output, run start/stop, minimize info Restart, fix_modify, output, run start/stop, minimize info

View File

@ -0,0 +1,87 @@
.. index:: fix nve/bpm/sphere
fix nve/bpm/sphere command
==========================
Syntax
""""""
.. parsed-literal::
fix ID group-ID nve/bpm/sphere
* ID, group-ID are documented in :doc:`fix <fix>` command
* nve/bpm/sphere = style name of this fix command
* zero or more keyword/value pairs may be appended
* keyword = *disc*
.. parsed-literal::
*disc* value = none = treat particles as 2d discs, not spheres
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all nve/bpm/sphere
fix 1 all nve/bpm/sphere disc
Description
"""""""""""
Perform constant NVE integration to update position, velocity, angular
velocity, and quaternion orientation for finite-size spherical
particles in the group each timestep. V is volume; E is energy. This
creates a system trajectory consistent with the microcanonical
ensemble.
This fix differs from the :doc:`fix nve <fix_nve>` command, which
assumes point particles and only updates their position and velocity.
It also differs from the :doc:`fix nve/sphere <fix_nve_sphere>`
command which assumes finite-size spheroid particles which do not
store a quaternion. It thus does not update a particle's orientation
or quaternion.
If the *disc* keyword is used, then each particle is treated as a 2d
disc (circle) instead of as a sphere. This is only possible for 2d
simulations, as defined by the :doc:`dimension <dimension>` keyword.
The only difference between discs and spheres in this context is their
moment of inertia, as used in the time integration.
----------
Restart, fix_modify, output, run start/stop, minimize info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
No information about this fix is written to :doc:`binary restart files
<restart>`. None of the :doc:`fix_modify <fix_modify>` options are
relevant to this fix. No global or per-atom quantities are stored by
this fix for access by various :doc:`output commands <Howto_output>`.
No parameter of this fix can be used with the *start/stop* keywords of
the :doc:`run <run>` command. This fix is not invoked during
:doc:`energy minimization <minimize>`.
Restrictions
""""""""""""
This fix requires that atoms store torque, angular velocity (omega), a
radius, and a quaternion as defined by the :doc:`atom_style bpm/sphere
<atom_style>` command.
All particles in the group must be finite-size spheres with
quaternions. They cannot be point particles.
Use of the *disc* keyword is only allowed for 2d simulations, as
defined by the :doc:`dimension <dimension>` keyword.
Related commands
""""""""""""""""
:doc:`fix nve <fix_nve>`, :doc:`fix nve/sphere <fix_nve_sphere>`
Default
"""""""
none

View File

@ -1,124 +0,0 @@
.. index:: fix pair/tracker
fix pair/tracker command
========================
Syntax
""""""
.. parsed-literal::
fix ID group-ID pair/tracker N attribute1 attribute2 ... keyword values ...
* ID, group-ID are documented in :doc:`fix <fix>` command
* pair/tracker = style name of this fix command
* N = prepare data for output every this many timesteps
* one or more attributes may be appended
.. parsed-literal::
possible attributes = id1 id2 time/created time/broken time/total
rmin rave x y z
.. parsed-literal::
id1, id2 = IDs of the 2 atoms in each pair interaction
time/created = the time that the 2 atoms began interacting
time/broken = the time that the 2 atoms stopped interacting
time/total = the total time the 2 atoms interacted
r/min = the minimum radial distance between the 2 atoms during the interaction
r/ave = the average radial distance between the 2 atoms during the interaction
x, y, z = the center of mass position of the 2 atoms when they stopped interacting
* zero or more keyword/value pairs may be appended
* keyword = *time/min* or *type/include*
.. parsed-literal::
*time/min* value = T
T = minimum interaction time
*type/include* value = arg1 arg2
arg = separate lists of types (see below)
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all pair/tracker 1000 id1 id2 time/min 100
fix 1 all pair/tracker 1000 time/created time/broken type/include 1 * type/include 2 3,4
Description
"""""""""""
Tracks properties of pairwise interactions between two atoms and records data
whenever the atoms move beyond the interaction cutoff.
Must be used in conjunction with :doc:`pair tracker <pair_tracker>`.
Data is accumulated over a span of *N* timesteps before being deleted.
The number of datums generated, aggregated across all processors, equals
the number of broken interactions. Interactions are only included if both
atoms are included in the specified fix group. Additional filters can be
applied using the *time/min* or *type/include* keywords described below.
.. note::
For extremely long-lived interactions, the calculation of *r/ave* may not be
correct due to double overflow.
The *time/min* keyword sets a minimum amount of time that an interaction must
persist to be included. This setting can be used to censor short-lived interactions.
The *type/include* keyword filters interactions based on the types of the two atoms.
Data is only saved for interactions between atoms with types in the two lists.
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).
Multiple *type/include* keywords may be added.
----------
Restart, fix_modify, run start/stop, minimize info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
No information about this fix is written to :doc:`binary restart files <restart>`.
None of the :doc:`fix_modify <fix_modify>` options are
relevant to this fix.
No parameter of this fix can be used with the *start/stop* keywords of
the :doc:`run <run>` command.
Output info
"""""""""""
This compute calculates a local vector or local array depending on the
number of input values. The length of the vector or number of rows in
the array is the number of recorded, lost interactions. If a single input is
specified, a local vector is produced. If two or more inputs are
specified, a local array is produced where the number of columns = the
number of inputs. The vector or array can be accessed by any command
that uses local values from a compute as input. See the :doc:`Howto output <Howto_output>` page for an overview of LAMMPS output
options.
The vector or array values will be doubles that correspond to the
specified attribute.
Restrictions
""""""""""""
Must be used in conjunction with :doc:`pair style tracker <pair_tracker>`.
This fix is part of the MISC package. It is only enabled if LAMMPS
was built with that package. See the :doc:`Build package <Build_package>` page for more info.
Related commands
""""""""""""""""
:doc:`pair tracker <pair_tracker>`
Default
"""""""
none

114
doc/src/pair_bpm_spring.rst Normal file
View File

@ -0,0 +1,114 @@
.. index:: pair_style bpm/spring
pair_style bpm/spring command
=============================
Syntax
""""""
.. code-block:: LAMMPS
pair_style bpm/spring
Examples
""""""""
.. code-block:: LAMMPS
pair_style bpm/spring
pair_coeff * * 1.0 1.0 1.0
pair_coeff 1 1 1.0 1.0 1.0
Description
"""""""""""
Style *bpm/spring* computes pairwise forces with the formula
.. math::
F = k (r - r_c)
where :math:`k` is a stiffness and :math:`r_c` is the cutoff length.
An additional damping force is also applied to interacting
particles. The force is proportional to the difference in the
normal velocity of particles
.. math::
F_D = - \gamma w (\hat{r} \bullet \vec{v})
where :math:`\gamma` is the damping strength, :math:`\hat{r}` is the
radial normal vector, :math:`\vec{v}` is the velocity difference
between the two particles, and :math:`w` is a smoothing factor.
This smoothing factor is constructed such that damping forces go to zero
as particles come out of contact to avoid discontinuities. It is
given by
.. math::
w = 1.0 - \left( \frac{r}{r_c} \right)^8 .
This pair style is designed for use in a spring-based bonded particle
model. It mirrors the construction of the :doc:`bpm/spring
<bond_bpm_spring>` bond style.
This pair interaction is always applied to pairs of non-bonded particles
that are within the interaction distance. For pairs of bonded particles
that are within the interaction distance, there is the option to either
include this pair interaction and overlay the pair force over the bond
force or to exclude this pair interaction such that the two particles
only interact via the bond force. See discussion of the *overlay/pair*
option for BPM bond styles and the :doc:`special_bonds <special_bonds>`
command in the `:doc: how to <Howto_BPM>` page on BPMs for more details.
The following coefficients must be defined for each pair of atom types
via the :doc:`pair_coeff <pair_coeff>` command as in the examples
above, or in the data file or restart files read by the
:doc:`read_data <read_data>` or :doc:`read_restart <read_restart>`
commands, or by mixing as described below:
* :math:`k` (force/distance units)
* :math:`r_c` (distance units)
* :math:`\gamma` (force/velocity units)
----------
Mixing, shift, table, tail correction, restart, rRESPA info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is always mixed via a
*geometric* rule. The cutoff is mixed according to the pair_modify
mix value. The default mix value is *geometric*\ . See the
"pair_modify" command for details.
This pair style does not support the :doc:`pair_modify <pair_modify>`
shift option, since the pair interaction goes to 0.0 at the cutoff.
The :doc:`pair_modify <pair_modify>` table and tail options are not
relevant for this pair style.
This pair style writes its information to :doc:`binary restart files
<restart>`, so pair_style and pair_coeff commands do not need to be
specified in an input script that reads a restart file.
This pair style can only be used via the *pair* keyword of the
:doc:`run_style respa <run_style>` command. It does not support the
*inner*, *middle*, *outer* keywords.
----------
Restrictions
""""""""""""
none
Related commands
""""""""""""""""
:doc:`pair_coeff <pair_coeff>`, :doc:`bond bpm/spring <bond_bpm_spring>`
Default
"""""""
none

View File

@ -238,7 +238,7 @@ none
.. _Veld2: .. _Veld2:
**(In 't Veld)** In 't Veld, Ismail, Grest, J Chem Phys (accepted) (2007). **(In 't Veld)** In 't Veld, Ismail, Grest, J Chem Phys, 127, 144711 (2007).
.. _Jorgensen4: .. _Jorgensen4:

View File

@ -131,6 +131,7 @@ accelerated styles exist.
* :doc:`born/coul/msm <pair_born>` - Born with long-range MSM Coulomb * :doc:`born/coul/msm <pair_born>` - Born with long-range MSM Coulomb
* :doc:`born/coul/wolf <pair_born>` - Born with Wolf potential for Coulomb * :doc:`born/coul/wolf <pair_born>` - Born with Wolf potential for Coulomb
* :doc:`born/coul/wolf/cs <pair_cs>` - Born with Wolf potential for Coulomb and core/shell model * :doc:`born/coul/wolf/cs <pair_cs>` - Born with Wolf potential for Coulomb and core/shell model
* :doc:`bpm/spring <pair_bpm_spring>` - repulsive harmonic force with damping
* :doc:`brownian <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics * :doc:`brownian <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics
* :doc:`brownian/poly <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics with polydispersity * :doc:`brownian/poly <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics with polydispersity
* :doc:`buck <pair_buck>` - Buckingham potential * :doc:`buck <pair_buck>` - Buckingham potential

View File

@ -8,89 +8,182 @@ Syntax
.. code-block:: LAMMPS .. code-block:: LAMMPS
pair_style tracker keyword pair_style tracker fix_ID N keyword values attribute1 attribute2 ...
* zero or more keyword/arg pairs may be appended * fix_ID = ID of associated internal fix to store data
* keyword = *finite* * N = prepare data for output every this many timesteps
* zero or more keywords may be appended
* keyword = *finite* or *time/min* or *type/include*
.. parsed-literal:: .. parsed-literal::
*finite* value = none *finite* value = none
pair style uses atomic diameters to identify contacts pair style uses atomic diameters to identify contacts
*time/min* value = T
T = minimum number of timesteps of interaction
*type/include* value = list1 list2
list1,list2 = separate lists of types (see below)
* one or more attributes may be appended
.. parsed-literal::
possible attributes = id1 id2 time/created time/broken time/total
r/min r/ave x y z
.. parsed-literal::
id1, id2 = IDs of the 2 atoms in each pair interaction
time/created = the timestep that the 2 atoms began interacting
time/broken = the timestep that the 2 atoms stopped interacting
time/total = the total number of timesteps the 2 atoms interacted
r/min = the minimum radial distance between the 2 atoms during the interaction (distance units)
r/ave = the average radial distance between the 2 atoms during the interaction (distance units)
x, y, z = the center of mass position of the 2 atoms when they stopped interacting (distance units)
Examples Examples
"""""""" """"""""
.. code-block:: LAMMPS .. code-block:: LAMMPS
pair_style hybrid/overlay tracker ... pair_style hybrid/overlay tracker myfix 1000 id1 id2 type/include 1 * type/include 2 3,4 lj/cut 2.5
pair_coeff 1 1 tracker 2.0 pair_coeff 1 1 tracker 2.0
pair_style hybrid/overlay tracker finite ... pair_style hybrid/overlay tracker myfix 1000 finite x y z time/min 100 granular
pair_coeff * * tracker pair_coeff * * tracker
fix 1 all pair/tracker 1000 time/created time/broken dump 1 all local 1000 dump.local f_myfix[1] f_myfix[2] f_myfix[3]
dump 1 all local 1000 dump.local f_1[1] f_1[2]
dump_modify 1 write_header no dump_modify 1 write_header no
Description Description
""""""""""" """""""""""
Style *tracker* monitors information about pairwise interactions. Style *tracker* monitors information about pairwise interactions. It
It does not calculate any forces on atoms. does not calculate any forces on atoms. :doc:`Pair hybrid/overlay
:doc:`Pair hybrid/overlay <pair_hybrid>` can be used to combine this pair <pair_hybrid>` can be used to combine this pair style with any other
style with another pair style. Style *tracker* must be used in conjunction pair style, as shown in the examples above.
with about :doc:`fix pair_tracker <fix_pair_tracker>` which contains
information on what data can be output.
If the *finite* keyword is not defined, the following coefficients must be At each timestep, if two neighboring atoms move beyond the interaction
defined for each pair of atom types via the :doc:`pair_coeff <pair_coeff>` cutoff, pairwise data is processed and transferred to an internal fix
command as in the examples above, or in the data file or restart files labeled *fix_ID*. This allows the local data to be accessed by other
read by the :doc:`read_data <read_data>` or :doc:`read_restart <read_restart>` LAMMPS commands. Additional
commands, or by mixing as described below: filters can be applied using the *time/min* or *type/include* keywords
described below. Note that this is the interaction cutoff defined by
this pair style, not the short-range cutoff defined by the pair style
that is calculating forces on atoms.
Following any optional keyword/value arguments, a list of one or more
attributes is specified. These include the IDs of the two atoms in
the pair. The other attributes for the pair of atoms are the
duration of time they were "interacting" or at the point in time they
started or stopped interacting. In this context, "interacting" means
the time window during which the two atoms were closer than the
interaction cutoff distance. The attributes for time/* refer to
timesteps.
Data is continuously accumulated by the internal fix over intervals of *N*
timesteps. At the end of each interval, all of the saved accumulated
data is deleted to make room for new data. Individual datum may
therefore persist anywhere between *1* to *N* timesteps depending on
when they are saved. This data can be accessed using the *fix_ID* and a
:doc:`dump local <dump>` command. To ensure all data is output,
the dump frequency should correspond to the same interval of *N*
timesteps. A dump frequency of an integer multiple of *N* can be used
to regularly output a sample of the accumulated data.
----------
The following optional keywords may be used.
If the *finite* keyword is not used, the following coefficients must
be defined for each pair of atom types via the :doc:`pair_coeff
<pair_coeff>` command as in the examples above, or in the data file or
restart files read by the :doc:`read_data <read_data>` or
:doc:`read_restart <read_restart>` commands, or by mixing as described
below:
* cutoff (distance units) * cutoff (distance units)
If the *finite* keyword is defined, no coefficients may be defined. If the *finite* keyword is used, there are no additional coefficients
Interaction cutoffs are alternatively calculated based on the to set for each pair of atom types via the
diameter of finite particles. :doc:`pair_coeff <pair_coeff>` command. Interaction cutoffs are
instead calculated based on the diameter of finite particles. However
you must still use the :doc:`pair_coeff <pair_coeff>` for all atom
types. For example the command
.. code-block:: LAMMPS
pair_coeff * *
should be used.
The *time/min* keyword sets a minimum amount of time that an
interaction must persist to be included. This setting can be used to
censor short-lived interactions.
The *type/include* keyword filters interactions based on the types of
the two atoms. Data is only saved for interactions between atoms
whose two atom types appear in *list1* and *list2*. Atom type 1 must
be in list1 and atom type 2 in list2. Or vice versa.
Each type list consists of a series of type ranges separated by
commas. Each 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 the *type/include* keyword can be specified
multiple times.
Mixing, shift, table, tail correction, restart, rRESPA info Mixing, shift, table, tail correction, restart, rRESPA info
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""
For atom type pairs I,J and I != J, the cutoff coefficient and cutoff For atom type pairs I,J and I != J, the cutoff coefficient and cutoff
distance for this pair style can be mixed. The cutoff is always mixed via a distance for this pair style can be mixed. The cutoff is always mixed
*geometric* rule. The cutoff is mixed according to the pair_modify via a *geometric* rule. The cutoff is mixed according to the
mix value. The default mix value is *geometric*\ . See the pair_modify mix value. The default mix value is *geometric*\ . See
"pair_modify" command for details. the "pair_modify" command for details.
This pair style writes its information to :doc:`binary restart files <restart>`, so This pair style writes its information to :doc:`binary restart files
pair_style and pair_coeff commands do not need <restart>`, so pair_style and pair_coeff commands do not need to be
to be specified in an input script that reads a restart file. specified in an input script that reads a restart file.
The :doc:`pair_modify <pair_modify>` shift, table, and tail options The :doc:`pair_modify <pair_modify>` shift, table, and tail options
are not relevant for this pair style. are not relevant for this pair style.
The accumulated data is not written to restart files and should be
output before a restart file is written to avoid missing data.
The internal fix calculates a local vector or local array depending on the
number of input values. The length of the vector or number of rows in
the array is the number of recorded, lost interactions. If a single
input is specified, a local vector is produced. If two or more inputs
are specified, a local array is produced where the number of columns =
the number of inputs. The vector or array can be accessed by any
command that uses local values from a compute as input. See the
:doc:`Howto output <Howto_output>` page for an overview of LAMMPS
output options.
The vector or array will be floating point values that correspond to
the specified attribute.
---------- ----------
Restrictions Restrictions
"""""""""""" """"""""""""
A corresponding :doc:`fix pair_tracker <fix_pair_tracker>` must be defined
to use this pair style.
This pair style is currently incompatible with granular pair styles that extend
beyond the contact (e.g. JKR and DMT).
This fix is part of the MISC package. It is only enabled if LAMMPS This fix is part of the MISC package. It is only enabled if LAMMPS
was built with that package. See the :doc:`Build package <Build_package>` page for more info. was built with that package. See the :doc:`Build package
<Build_package>` page for more info.
This pair style is currently incompatible with granular pair styles
that extend beyond the contact (e.g. JKR and DMT).
Related commands Related commands
"""""""""""""""" """"""""""""""""
:doc:`fix pair_tracker <fix_pair_tracker>`
Default Default
""""""" """""""

View File

@ -650,6 +650,8 @@ of analysis.
- atom-ID atom-type rho esph cv x y z - atom-ID atom-type rho esph cv x y z
* - sphere * - sphere
- atom-ID atom-type diameter density x y z - atom-ID atom-type diameter density x y z
* - bpm/sphere
- atom-ID molecule-ID atom-type diameter density x y z
* - spin * - spin
- atom-ID atom-type x y z spx spy spz sp - atom-ID atom-type x y z spx spy spz sp
* - tdpd * - tdpd

View File

@ -328,6 +328,8 @@ boxzlo
bp bp
bpclermont bpclermont
bpls bpls
bpm
BPM
br br
Branduardi Branduardi
Branicio Branicio
@ -1149,8 +1151,10 @@ gdot
GeC GeC
Geier Geier
gencode gencode
Geocomputing
georg georg
Georg Georg
Geotechnica
germain germain
Germann Germann
Germano Germano
@ -1320,6 +1324,7 @@ Holm
holonomic holonomic
Homebrew Homebrew
hooke hooke
hookean
Hookean Hookean
hostname hostname
hotpink hotpink
@ -2074,6 +2079,7 @@ monopole
monovalent monovalent
Montalenti Montalenti
Montero Montero
Mora
Morefoo Morefoo
Morfill Morfill
Mori Mori
@ -2203,6 +2209,7 @@ Nbin
Nbins Nbins
nbody nbody
Nbody Nbody
nbond
nbonds nbonds
nbondtype nbondtype
Nbondtype Nbondtype
@ -3174,6 +3181,7 @@ Steinhauser
Stepaniants Stepaniants
stepwise stepwise
Stesmans Stesmans
stiffnesses
Stillinger Stillinger
stk stk
stochastically stochastically

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
units lj
dimension 3
boundary f f f
atom_style bpm/sphere
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
newton on off
comm_modify vel yes cutoff 2.6
lattice fcc 1.0
region box block -25 15 -22 22 -22 22
create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50
region disk cylinder x 0.0 0.0 20.0 -0.5 0.5
create_atoms 1 region disk
group plate region disk
region ball sphere 8.0 0.0 0.0 6.0
create_atoms 1 region ball
group projectile region ball
displace_atoms all random 0.1 0.1 0.1 134598738
neighbor 1.0 bin
pair_style gran/hooke/history 1.0 NULL 0.5 NULL 0.1 1
pair_coeff 1 1
fix 1 all nve/bpm/sphere
create_bonds many plate plate 1 0.0 1.5
create_bonds many projectile projectile 2 0.0 1.5
neighbor 0.3 bin
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style bpm/rotational store/local brkbond 100 time id1 id2
bond_coeff 1 1.0 0.2 0.02 0.02 0.05 0.01 0.01 0.01 0.1 0.2 0.002 0.002
bond_coeff 2 1.0 0.2 0.02 0.02 0.20 0.04 0.04 0.04 0.1 0.2 0.002 0.002
velocity projectile set -0.05 0.0 0.0
compute nbond all nbond/atom
compute tbond all reduce sum c_nbond
timestep 0.05
thermo_style custom step ke pe pxx pyy pzz c_tbond
thermo 100
thermo_modify lost ignore lost/bond ignore
#dump 1 all custom 100 atomDump id radius x y z c_nbond
dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3]
dump_modify 2 header no
run 7500

View File

@ -0,0 +1,53 @@
units lj
dimension 3
boundary f f f
atom_style bond
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
newton on off
comm_modify vel yes cutoff 2.6
lattice fcc 1.0
region box block -25 15 -22 22 -22 22
create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50
region disk cylinder x 0.0 0.0 20.0 -0.5 0.5
create_atoms 1 region disk
group plate region disk
region ball sphere 8.0 0.0 0.0 6.0
create_atoms 1 region ball
group projectile region ball
displace_atoms all random 0.1 0.1 0.1 134598738
mass 1 1.0
neighbor 1.0 bin
pair_style bpm/spring
pair_coeff 1 1 1.0 1.0 1.0
fix 1 all nve
create_bonds many plate plate 1 0.0 1.5
create_bonds many projectile projectile 2 0.0 1.5
neighbor 0.3 bin
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style bpm/spring store/local brkbond 100 time id1 id2
bond_coeff 1 1.0 0.04 1.0
bond_coeff 2 1.0 0.20 1.0
velocity projectile set -0.05 0.0 0.0
compute nbond all nbond/atom
compute tbond all reduce sum c_nbond
timestep 0.1
thermo_style custom step ke pe pxx pyy pzz c_tbond
thermo 100
thermo_modify lost ignore lost/bond ignore
#dump 1 all custom 100 atomDump id x y z c_nbond
dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3]
dump_modify 2 header no
run 7500

View File

@ -0,0 +1,219 @@
LAMMPS (17 Feb 2022)
units lj
dimension 3
boundary f f f
atom_style bpm/sphere
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
newton on off
comm_modify vel yes cutoff 2.6
lattice fcc 1.0
Lattice spacing in x,y,z = 1.5874011 1.5874011 1.5874011
region box block -25 15 -22 22 -22 22
create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50
Created orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823)
1 by 2 by 2 MPI processor grid
region disk cylinder x 0.0 0.0 20.0 -0.5 0.5
create_atoms 1 region disk
Created 7529 atoms
using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823)
create_atoms CPU = 0.002 seconds
group plate region disk
7529 atoms in group plate
region ball sphere 8.0 0.0 0.0 6.0
create_atoms 1 region ball
Created 3589 atoms
using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823)
create_atoms CPU = 0.001 seconds
group projectile region ball
3589 atoms in group projectile
displace_atoms all random 0.1 0.1 0.1 134598738
Displacing atoms ...
neighbor 1.0 bin
pair_style gran/hooke/history 1.0 NULL 0.5 NULL 0.1 1
pair_coeff 1 1
fix 1 all nve/bpm/sphere
create_bonds many plate plate 1 0.0 1.5
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update every 1 steps, delay 10 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 2
ghost atom cutoff = 2.6
binsize = 1, bins = 64 70 70
2 neighbor lists, perpetual/occasional/extra = 1 1 0
(1) command create_bonds, occasional
attributes: full, newton on
pair build: full/bin
stencil: full/bin/3d
bin: standard
(2) pair gran/hooke/history, perpetual
attributes: half, newton on, size, history
pair build: half/size/bin/newton
stencil: half/bin/3d
bin: standard
Added 38559 bonds, new total = 38559
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
15 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.001 seconds
create_bonds many projectile projectile 2 0.0 1.5
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
WARNING: Bonds are defined but no bond style is set (../force.cpp:192)
WARNING: Likewise 1-2 special neighbor interactions != 1.0 (../force.cpp:194)
Added 21869 bonds, new total = 60428
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
16 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.001 seconds
neighbor 0.3 bin
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style bpm/rotational store/local brkbond 100 time id1 id2
bond_coeff 1 1.0 0.2 0.02 0.02 0.05 0.01 0.01 0.01 0.1 0.2 0.002 0.002
bond_coeff 2 1.0 0.2 0.02 0.02 0.20 0.04 0.04 0.04 0.1 0.2 0.002 0.002
velocity projectile set -0.05 0.0 0.0
compute nbond all nbond/atom
compute tbond all reduce sum c_nbond
timestep 0.05
thermo_style custom step ke pe pxx pyy pzz c_tbond
thermo 100
thermo_modify lost ignore lost/bond ignore
#dump 1 all custom 100 atomDump id radius x y z c_nbond
dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3]
dump_modify 2 header no
run 7500
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update every 1 steps, delay 10 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 1.3
ghost atom cutoff = 2.6
binsize = 0.65, bins = 98 108 108
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair gran/hooke/history, perpetual
attributes: half, newton on, size, history
pair build: half/size/bin/newton
stencil: half/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 33.34 | 33.34 | 33.35 Mbytes
Step KinEng PotEng Pxx Pyy Pzz c_tbond
0 0.00053238861 0 3.8217307e-05 0 0 10.8703
100 0.00053238861 0 3.8217307e-05 1.2166373e-20 1.2308212e-20 10.8703
200 0.00053238861 0 3.8217307e-05 1.2454467e-20 1.2479589e-20 10.8703
300 0.00053238861 0 3.8217307e-05 1.2256702e-20 1.2621091e-20 10.8703
400 0.00053238861 0 3.8217307e-05 1.2170534e-20 1.2751666e-20 10.8703
500 0.00053093549 0 3.8484194e-05 7.645531e-08 1.4861825e-07 10.8703
600 0.00051485902 0 4.0340751e-05 3.8615876e-07 4.8663463e-07 10.869221
700 0.00049942978 0 3.8684008e-05 4.5363318e-07 4.4560229e-07 10.85501
800 0.00049465262 0 3.6604612e-05 1.4755468e-07 2.0062093e-07 10.820651
900 0.00048784775 0 3.5333139e-05 3.5118328e-07 6.6697625e-07 10.769563
1000 0.00048345699 0 3.4702137e-05 7.0312998e-07 4.0218318e-07 10.730347
1100 0.00047945073 0 3.5065961e-05 6.2813891e-07 7.4640359e-07 10.703184
1200 0.00047512604 0 3.4833144e-05 8.5208604e-07 8.7277583e-07 10.686634
1300 0.00047401428 0 3.4236869e-05 1.0321827e-06 7.4545242e-07 10.678
1400 0.00047619121 0 3.4416549e-05 8.7518021e-07 7.3979503e-07 10.671704
1500 0.0004668728 0 3.4495751e-05 1.4077823e-06 1.517373e-06 10.666127
1600 0.00045088371 0 3.3264301e-05 1.8499661e-06 1.9842415e-06 10.66073
1700 0.00044275099 0 3.2471064e-05 1.9028747e-06 2.2248947e-06 10.6458
1800 0.0004424362 0 3.1846336e-05 1.6208492e-06 1.9291602e-06 10.620615
1900 0.00043678957 0 3.1260936e-05 1.4673956e-06 1.6120523e-06 10.603166
2000 0.00042747562 0 3.0652107e-05 1.6455486e-06 1.53127e-06 10.576003
2100 0.0004214344 0 3.0240727e-05 1.8873967e-06 1.5258622e-06 10.539845
2200 0.00041712779 0 3.0329566e-05 1.8846152e-06 1.4971471e-06 10.49937
2300 0.00041095769 0 3.0000572e-05 2.3585924e-06 1.6773177e-06 10.471668
2400 0.00040883568 0 2.9625158e-05 1.9105554e-06 1.8720763e-06 10.45116
2500 0.00040762685 0 2.9441541e-05 1.6848938e-06 1.8877532e-06 10.437309
2600 0.00040579873 0 2.9255988e-05 1.7523874e-06 1.636423e-06 10.422378
2700 0.00040340975 0 2.9035693e-05 1.673158e-06 1.9038932e-06 10.410505
2800 0.00040170914 0 2.8829361e-05 1.6711978e-06 1.9776001e-06 10.400792
2900 0.00040015113 0 2.8614186e-05 1.5982427e-06 1.7994733e-06 10.393416
3000 0.00040029253 0 2.8470718e-05 1.5589166e-06 1.6682302e-06 10.385321
3100 0.00040037329 0 2.8483376e-05 1.2831526e-06 1.4788005e-06 10.378485
3200 0.00040142612 0 2.8481287e-05 1.1577988e-06 1.3495778e-06 10.373988
3300 0.00040105092 0 2.8547009e-05 1.2155138e-06 1.2633439e-06 10.370031
3400 0.00039950673 0 2.8340939e-05 1.1182251e-06 1.1624668e-06 10.364274
3500 0.00039715236 0 2.824813e-05 1.3086462e-06 1.2029185e-06 10.360496
3600 0.00039446552 0 2.8112283e-05 1.1232321e-06 1.0077217e-06 10.353121
3700 0.00039263296 0 2.7927975e-05 1.1083636e-06 1.2091857e-06 10.346645
3800 0.00039061341 0 2.7819957e-05 1.1836841e-06 1.3566272e-06 10.341069
3900 0.00038985051 0 2.7681947e-05 1.3588359e-06 1.4099727e-06 10.329196
4000 0.00038815347 0 2.7492102e-05 1.1111719e-06 1.1700718e-06 10.318043
4100 0.00038651302 0 2.7444105e-05 9.9563429e-07 1.4085969e-06 10.311027
4200 0.00038565809 0 2.7177341e-05 9.5736307e-07 1.0404482e-06 10.299155
4300 0.0003847255 0 2.7029216e-05 9.6204756e-07 1.140804e-06 10.292319
4400 0.0003844421 0 2.6841047e-05 9.6570404e-07 1.2319818e-06 10.286203
4500 0.0003842788 0 2.6633558e-05 9.6452478e-07 1.1954945e-06 10.278287
4600 0.00038365139 0 2.6514403e-05 9.6185846e-07 1.2002452e-06 10.270732
4700 0.00038271503 0 2.6374349e-05 9.4061833e-07 1.1774211e-06 10.264796
4800 0.00038233688 0 2.638398e-05 1.1644119e-06 1.3746239e-06 10.25742
4900 0.00038223496 0 2.6279821e-05 1.1345508e-06 1.4709213e-06 10.246987
5000 0.00038219402 0 2.6188871e-05 1.0115151e-06 1.2024203e-06 10.240511
5100 0.00038195153 0 2.6137945e-05 1.009856e-06 1.1961088e-06 10.236014
5200 0.00038170903 0 2.6103563e-05 1.0046761e-06 1.1881008e-06 10.232236
5300 0.00038194303 0 2.6111938e-05 1.0533375e-06 1.2621634e-06 10.230617
5400 0.00038147407 0 2.6078641e-05 1.082228e-06 1.2915223e-06 10.230098
5500 0.00038156894 0 2.6084488e-05 1.1395485e-06 1.3592644e-06 10.227759
5600 0.00038169434 0 2.6085704e-05 1.1173618e-06 1.3003599e-06 10.2256
5700 0.00038219734 0 2.6095279e-05 1.1026614e-06 1.280455e-06 10.223621
5800 0.00038268758 0 2.6113437e-05 1.1096198e-06 1.2565503e-06 10.222902
5900 0.00038300658 0 2.6131709e-05 1.1123595e-06 1.235992e-06 10.222182
6000 0.00038250316 0 2.606995e-05 1.1590744e-06 1.2888416e-06 10.221123
6100 0.0003821526 0 2.6025605e-05 1.1434025e-06 1.3141861e-06 10.219503
6200 0.00038185711 0 2.5991255e-05 1.1471391e-06 1.3427373e-06 10.219503
6300 0.00038197679 0 2.5996965e-05 1.1338082e-06 1.3315258e-06 10.218604
6400 0.00038232311 0 2.6035805e-05 1.1353407e-06 1.3306683e-06 10.217884
6500 0.00038255543 0 2.6091572e-05 1.1768703e-06 1.3629611e-06 10.217704
6600 0.00038251887 0 2.6068968e-05 1.1808094e-06 1.3969697e-06 10.217344
6700 0.00038177389 0 2.6004288e-05 1.1659866e-06 1.423638e-06 10.218084
6800 0.00038096291 0 2.5969494e-05 1.1377343e-06 1.4348787e-06 10.218103
6900 0.00038090601 0 2.5951546e-05 1.1327767e-06 1.4311663e-06 10.217024
7000 0.00038088094 0 2.5946255e-05 1.1652568e-06 1.4567559e-06 10.215944
7100 0.00038094624 0 2.5972593e-05 1.1558871e-06 1.4692935e-06 10.214684
7200 0.00038168738 0 2.6002e-05 1.1562707e-06 1.4881081e-06 10.212705
7300 0.00038200854 0 2.6038768e-05 1.1339903e-06 1.4808455e-06 10.212345
7400 0.00038187543 0 2.6044759e-05 1.101743e-06 1.4758679e-06 10.213084
7500 0.00038165297 0 2.6004536e-05 1.0892731e-06 1.4872621e-06 10.214742
Loop time of 28.804 on 4 procs for 7500 steps with 11111 atoms
Performance: 1124843.305 tau/day, 260.380 timesteps/s
97.5% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.26977 | 0.28058 | 0.2866 | 1.3 | 0.97
Bond | 22.742 | 23.598 | 24.671 | 16.6 | 81.92
Neigh | 0.54555 | 0.5728 | 0.60272 | 3.2 | 1.99
Comm | 1.4024 | 2.5619 | 3.5079 | 54.8 | 8.89
Output | 0.025307 | 0.025833 | 0.027022 | 0.4 | 0.09
Modify | 1.592 | 1.6506 | 1.7059 | 4.0 | 5.73
Other | | 0.1147 | | | 0.40
Nlocal: 2777.75 ave 2887 max 2682 min
Histogram: 1 0 0 0 2 0 0 0 0 1
Nghost: 1152.5 ave 1189 max 1125 min
Histogram: 1 0 1 0 0 1 0 0 0 1
Neighs: 11515.5 ave 12520 max 10831 min
Histogram: 1 1 0 0 1 0 0 0 0 1
Total # of neighbors = 46062
Ave neighs/atom = 4.1456215
Ave special neighs/atom = 10.214742
Neighbor list builds = 408
Dangerous builds = 0
Total wall time: 0:00:28

View File

@ -0,0 +1,221 @@
LAMMPS (17 Feb 2022)
units lj
dimension 3
boundary f f f
atom_style bond
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
newton on off
comm_modify vel yes cutoff 2.6
lattice fcc 1.0
Lattice spacing in x,y,z = 1.5874011 1.5874011 1.5874011
region box block -25 15 -22 22 -22 22
create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50
Created orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823)
1 by 2 by 2 MPI processor grid
region disk cylinder x 0.0 0.0 20.0 -0.5 0.5
create_atoms 1 region disk
Created 7529 atoms
using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823)
create_atoms CPU = 0.001 seconds
group plate region disk
7529 atoms in group plate
region ball sphere 8.0 0.0 0.0 6.0
create_atoms 1 region ball
Created 3589 atoms
using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823)
create_atoms CPU = 0.000 seconds
group projectile region ball
3589 atoms in group projectile
displace_atoms all random 0.1 0.1 0.1 134598738
Displacing atoms ...
mass 1 1.0
neighbor 1.0 bin
pair_style bpm/spring
pair_coeff 1 1 1.0 1.0 1.0
fix 1 all nve
create_bonds many plate plate 1 0.0 1.5
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update every 1 steps, delay 10 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 2
ghost atom cutoff = 2.6
binsize = 1, bins = 64 70 70
2 neighbor lists, perpetual/occasional/extra = 1 1 0
(1) command create_bonds, occasional
attributes: full, newton on
pair build: full/bin
stencil: full/bin/3d
bin: standard
(2) pair bpm/spring, perpetual
attributes: half, newton on
pair build: half/bin/newton
stencil: half/bin/3d
bin: standard
Added 38559 bonds, new total = 38559
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
15 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.001 seconds
create_bonds many projectile projectile 2 0.0 1.5
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
WARNING: Bonds are defined but no bond style is set (../force.cpp:192)
WARNING: Likewise 1-2 special neighbor interactions != 1.0 (../force.cpp:194)
Added 21869 bonds, new total = 60428
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
16 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.001 seconds
neighbor 0.3 bin
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style bpm/spring store/local brkbond 100 time id1 id2
bond_coeff 1 1.0 0.04 1.0
bond_coeff 2 1.0 0.20 1.0
velocity projectile set -0.05 0.0 0.0
compute nbond all nbond/atom
compute tbond all reduce sum c_nbond
timestep 0.1
thermo_style custom step ke pe pxx pyy pzz c_tbond
thermo 100
thermo_modify lost ignore lost/bond ignore
#dump 1 all custom 100 atomDump id x y z c_nbond
dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3]
dump_modify 2 header no
run 7500
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update every 1 steps, delay 10 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 1.3
ghost atom cutoff = 2.6
binsize = 0.65, bins = 98 108 108
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair bpm/spring, perpetual
attributes: half, newton on
pair build: half/bin/newton
stencil: half/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 17.74 | 17.74 | 17.74 Mbytes
Step KinEng PotEng Pxx Pyy Pzz c_tbond
0 0.0010167873 0 7.298968e-05 0 0 10.8703
100 0.0010167873 0 7.298968e-05 -8.7429897e-20 -8.8470837e-20 10.8703
200 0.0010167873 0 7.298968e-05 -7.2809565e-20 -8.0915788e-20 10.8703
300 0.0009951439 0 9.9273671e-05 8.1569216e-06 8.0922512e-06 10.868142
400 0.00095142792 0 0.00012669557 -1.3413721e-05 -1.4800745e-05 10.849793
500 0.00092272662 0 8.1708784e-05 -9.7488701e-06 -1.3603634e-05 10.819752
600 0.00088967612 0 6.2587266e-05 -5.1954127e-06 -6.781587e-06 10.797985
700 0.00086070919 0 8.8529902e-05 -9.9431205e-06 -7.9905211e-06 10.776579
800 0.00083543943 0 7.5920357e-05 3.6381024e-07 3.7747551e-06 10.759309
900 0.00081190799 0 6.3678219e-05 5.4158243e-06 1.2751247e-05 10.744199
1000 0.00078828988 0 7.3079869e-05 -6.6410613e-06 -1.198683e-06 10.728368
1100 0.00075664718 0 6.2976995e-05 -4.7863299e-06 -3.9814556e-06 10.711819
1200 0.00072472205 0 4.9680233e-05 9.3093553e-06 4.4426393e-06 10.69401
1300 0.00070176532 0 5.4048176e-05 1.3051954e-05 7.5448558e-06 10.671164
1400 0.00068599319 0 5.4062404e-05 9.9930199e-06 1.0353154e-05 10.650117
1500 0.0006786164 0 4.5038593e-05 8.067571e-06 9.8825461e-06 10.636266
1600 0.00067466823 0 4.6733251e-05 9.8595584e-06 1.1551081e-05 10.621335
1700 0.00066847126 0 5.1472453e-05 2.1569974e-07 6.0070599e-06 10.6127
1800 0.00065711827 0 5.0355189e-05 -8.030203e-06 -3.1395588e-06 10.599568
1900 0.00063882539 0 4.7146888e-05 -2.0596242e-05 -1.6494542e-05 10.581939
2000 0.00061717894 0 4.6698781e-05 -2.5473048e-05 -2.7703615e-05 10.567188
2100 0.00059261327 0 3.7701055e-05 -2.4637803e-05 -3.3919162e-05 10.552617
2200 0.00056527158 0 3.2239421e-05 -1.8786685e-05 -2.4202734e-05 10.538406
2300 0.00054054919 0 2.7410334e-05 -6.701111e-06 -7.4354974e-06 10.520777
2400 0.00051820065 0 2.2997206e-05 1.5623767e-05 1.8687824e-05 10.501889
2500 0.00049647925 0 1.746693e-05 2.8814144e-05 3.5569425e-05 10.487498
2600 0.00047837258 0 1.4127067e-05 3.4245611e-05 4.0208577e-05 10.472387
2700 0.00046626924 0 1.3714876e-05 3.7922196e-05 4.1550346e-05 10.456377
2800 0.0004560167 0 1.5260976e-05 3.5632577e-05 3.7885738e-05 10.440007
2900 0.00045331059 0 1.5194832e-05 3.1036124e-05 2.8633755e-05 10.427955
3000 0.00045227799 0 1.4877378e-05 1.9327028e-05 2.1189487e-05 10.414283
3100 0.00044866178 0 2.0424612e-05 -2.7242288e-06 7.7121438e-06 10.40349
3200 0.00044336453 0 2.3276121e-05 -1.979069e-05 -4.2311089e-06 10.395575
3300 0.00043526526 0 2.3338132e-05 -2.834945e-05 -1.7302033e-05 10.389998
3400 0.00042817758 0 2.4374527e-05 -2.9870076e-05 -3.0623264e-05 10.382803
3500 0.00042182658 0 2.6120627e-05 -2.9449521e-05 -3.787776e-05 10.378126
3600 0.00041794291 0 2.4736957e-05 -2.4098172e-05 -3.0529166e-05 10.373628
3700 0.0004156005 0 2.7543305e-05 -1.2431749e-05 -1.8626096e-05 10.37075
3800 0.0004141461 0 2.4630482e-05 -6.345489e-06 -1.7375803e-05 10.368771
3900 0.00041328832 0 2.2220142e-05 4.1471034e-07 -1.3339476e-05 10.366972
4000 0.00041121725 0 2.3491321e-05 1.1284551e-05 -5.8651834e-06 10.364634
4100 0.00040761876 0 2.6688248e-05 1.9721625e-05 3.7536871e-06 10.362655
4200 0.00040301362 0 2.7601916e-05 1.9212118e-05 9.7175996e-06 10.359417
4300 0.00040001545 0 2.7243769e-05 1.6889359e-05 1.1857147e-05 10.3551
4400 0.00039654521 0 2.561083e-05 1.3863551e-05 1.0593597e-05 10.351142
4500 0.00039435924 0 2.4366458e-05 1.2545563e-05 1.1323962e-05 10.348804
4600 0.00039250006 0 2.3719127e-05 1.1015167e-05 8.5964046e-06 10.348444
4700 0.00039145496 0 2.2943915e-05 8.7824224e-06 5.0397129e-06 10.346825
4800 0.00039105331 0 2.4005757e-05 7.5899773e-06 9.033741e-07 10.344846
4900 0.0003898798 0 2.3819433e-05 4.9673894e-06 -2.3466459e-06 10.343587
5000 0.00038747508 0 2.3605028e-05 -1.1717437e-06 -6.1096657e-06 10.343047
5100 0.00038549022 0 2.3453798e-05 -9.9256693e-06 -9.3584148e-06 10.341788
5200 0.00038283936 0 2.5243567e-05 -1.5877598e-05 -9.9474447e-06 10.340169
5300 0.00038140888 0 2.5522223e-05 -1.9331435e-05 -1.1067039e-05 10.33873
5400 0.00037916674 0 2.5181488e-05 -2.1581255e-05 -1.1252641e-05 10.336931
5500 0.00037782932 0 2.691805e-05 -1.5768241e-05 -5.6704695e-06 10.334952
5600 0.00037628832 0 2.5851445e-05 -1.4239811e-05 -1.9122536e-06 10.333153
5700 0.00037451913 0 2.4758416e-05 -1.3252284e-05 -1.9222041e-06 10.331714
5800 0.00037328662 0 2.2507032e-05 -9.6704092e-06 -7.5470215e-06 10.330095
5900 0.00037253111 0 2.3303086e-05 -4.2828034e-06 -7.888056e-06 10.328476
6000 0.00037171133 0 2.4042456e-05 -4.7684985e-06 -6.5164336e-06 10.327397
6100 0.00036986726 0 2.4938695e-05 -4.8738316e-06 -4.5380007e-06 10.327037
6200 0.0003675822 0 2.3322229e-05 -4.6333093e-06 -5.7086464e-06 10.327037
6300 0.00036552389 0 2.1435354e-05 -4.8971566e-06 -3.5935426e-06 10.327037
6400 0.00036488091 0 2.0813994e-05 -3.8333319e-06 -3.6595059e-06 10.327037
6500 0.00036447973 0 2.2241876e-05 8.7797361e-08 -4.141203e-06 10.327037
6600 0.00036383343 0 2.269485e-05 4.9364593e-06 1.3062133e-06 10.326677
6700 0.00036305076 0 2.1838759e-05 6.4587048e-06 4.7758772e-06 10.326318
6800 0.00036226601 0 2.2916622e-05 6.044926e-06 5.0291597e-06 10.325598
6900 0.00036175279 0 2.2691667e-05 6.9998847e-06 5.8988637e-06 10.324699
7000 0.00036143633 0 2.1725813e-05 8.1268152e-06 5.0390503e-06 10.324519
7100 0.0003610248 0 2.1799675e-05 8.65795e-06 3.1360368e-06 10.323439
7200 0.00036086259 0 2.2198029e-05 5.1764734e-06 5.4798783e-07 10.32308
7300 0.00036099757 0 2.4160496e-05 1.0310325e-06 -5.115075e-07 10.32254
7400 0.00036129334 0 2.5325018e-05 -9.4918158e-07 -1.7064957e-06 10.32218
7500 0.00036136655 0 2.3513198e-05 -3.8618451e-06 -4.4344772e-06 10.321281
Loop time of 4.51074 on 4 procs for 7500 steps with 11118 atoms
Performance: 14365719.597 tau/day, 1662.699 timesteps/s
93.8% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.25733 | 0.26952 | 0.28068 | 1.6 | 5.98
Bond | 1.9391 | 2.0128 | 2.0851 | 3.7 | 44.62
Neigh | 0.56308 | 0.5941 | 0.62077 | 2.8 | 13.17
Comm | 0.68282 | 0.80856 | 0.94406 | 10.7 | 17.93
Output | 0.19287 | 0.1933 | 0.19426 | 0.1 | 4.29
Modify | 0.53239 | 0.55343 | 0.57349 | 2.0 | 12.27
Other | | 0.07902 | | | 1.75
Nlocal: 2779.5 ave 2862 max 2686 min
Histogram: 1 0 0 0 0 1 1 0 0 1
Nghost: 1183.25 ave 1220 max 1134 min
Histogram: 1 0 0 0 1 0 0 0 1 1
Neighs: 11828.8 ave 12387 max 11053 min
Histogram: 1 0 0 0 1 0 0 0 1 1
Total # of neighbors = 47315
Ave neighs/atom = 4.2557115
Ave special neighs/atom = 10.321461
Neighbor list builds = 421
Dangerous builds = 11
Total wall time: 0:00:04

View File

@ -0,0 +1,35 @@
units lj
dimension 3
boundary m m m
atom_style bpm/sphere
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
newton on off
comm_modify vel yes cutoff 3.3
region box block -15 15 -15 15 0 60.0
create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50
molecule my_mol "rect.mol"
region wall_cyl cylinder z 0.0 0.0 10.0 EDGE EDGE side in
region dropzone cylinder z 0.0 0.0 10.0 40.0 50.0 side in
pair_style gran/hertz/history 1.0 NULL 0.5 NULL 0.1 1
bond_style bpm/rotational
pair_coeff 1 1
bond_coeff 1 1.0 0.2 0.01 0.01 2.0 0.4 0.02 0.02 0.2 0.04 0.002 0.002
compute nbond all nbond/atom
compute tbond all reduce sum c_nbond
compute_modify thermo_temp dynamic/dof yes
fix 1 all wall/gran hertz/history 1.0 NULL 0.5 NULL 0.1 1 zplane 0.0 NULL
fix 2 all wall/gran/region hertz/history 1.0 NULL 0.5 NULL 0.1 1 region wall_cyl
fix 3 all gravity 1e-4 vector 0 0 -1
fix 4 all deposit 40 0 1500 712511343 mol my_mol region dropzone near 2.0 vz -0.05 -0.05
fix 5 all nve/bpm/sphere
timestep 0.05
thermo_style custom step ke pe pxx pyy pzz c_tbond
thermo 100
#dump 1 all custom 500 atomDump id radius x y z c_nbond mol
run 100000

File diff suppressed because it is too large Load Diff

568
examples/bpm/pour/rect.mol Normal file
View File

@ -0,0 +1,568 @@
#Made with create_mol.py
63 atoms
297 bonds
Coords
#ID x y z
1 0.0 0.0 0.0
2 0.7348518971806154 0.7348518971806154 0.0
3 0.7348518971806154 0.0 0.7348518971806154
4 0.0 0.7348518971806154 0.7348518971806154
5 1.4697037943612308 0.0 0.0
6 1.4697037943612308 0.7348518971806154 0.7348518971806154
7 0.0 1.4697037943612308 0.0
8 0.7348518971806154 1.4697037943612308 0.7348518971806154
9 1.4697037943612308 1.4697037943612308 0.0
10 0.0 0.0 1.4697037943612308
11 0.7348518971806154 0.7348518971806154 1.4697037943612308
12 0.7348518971806154 0.0 2.204555691541846
13 0.0 0.7348518971806154 2.204555691541846
14 1.4697037943612308 0.0 1.4697037943612308
15 1.4697037943612308 0.7348518971806154 2.204555691541846
16 0.0 1.4697037943612308 1.4697037943612308
17 0.7348518971806154 1.4697037943612308 2.204555691541846
18 1.4697037943612308 1.4697037943612308 1.4697037943612308
19 0.0 0.0 2.9394075887224616
20 0.7348518971806154 0.7348518971806154 2.9394075887224616
21 0.7348518971806154 0.0 3.674259485903077
22 0.0 0.7348518971806154 3.674259485903077
23 1.4697037943612308 0.0 2.9394075887224616
24 1.4697037943612308 0.7348518971806154 3.674259485903077
25 0.0 1.4697037943612308 2.9394075887224616
26 0.7348518971806154 1.4697037943612308 3.674259485903077
27 1.4697037943612308 1.4697037943612308 2.9394075887224616
28 0.0 0.0 4.409111383083692
29 0.7348518971806154 0.7348518971806154 4.409111383083692
30 0.7348518971806154 0.0 5.143963280264308
31 0.0 0.7348518971806154 5.143963280264308
32 1.4697037943612308 0.0 4.409111383083692
33 1.4697037943612308 0.7348518971806154 5.143963280264308
34 0.0 1.4697037943612308 4.409111383083692
35 0.7348518971806154 1.4697037943612308 5.143963280264308
36 1.4697037943612308 1.4697037943612308 4.409111383083692
37 0.0 0.0 5.878815177444923
38 0.7348518971806154 0.7348518971806154 5.878815177444923
39 0.7348518971806154 0.0 6.613667074625538
40 0.0 0.7348518971806154 6.613667074625538
41 1.4697037943612308 0.0 5.878815177444923
42 1.4697037943612308 0.7348518971806154 6.613667074625538
43 0.0 1.4697037943612308 5.878815177444923
44 0.7348518971806154 1.4697037943612308 6.613667074625538
45 1.4697037943612308 1.4697037943612308 5.878815177444923
46 0.0 0.0 7.348518971806154
47 0.7348518971806154 0.7348518971806154 7.348518971806154
48 0.7348518971806154 0.0 8.08337086898677
49 0.0 0.7348518971806154 8.08337086898677
50 1.4697037943612308 0.0 7.348518971806154
51 1.4697037943612308 0.7348518971806154 8.08337086898677
52 0.0 1.4697037943612308 7.348518971806154
53 0.7348518971806154 1.4697037943612308 8.08337086898677
54 1.4697037943612308 1.4697037943612308 7.348518971806154
55 0.0 0.0 8.818222766167384
56 0.7348518971806154 0.7348518971806154 8.818222766167384
57 0.7348518971806154 0.0 9.553074663348
58 0.0 0.7348518971806154 9.553074663348
59 1.4697037943612308 0.0 8.818222766167384
60 1.4697037943612308 0.7348518971806154 9.553074663348
61 0.0 1.4697037943612308 8.818222766167384
62 0.7348518971806154 1.4697037943612308 9.553074663348
63 1.4697037943612308 1.4697037943612308 8.818222766167384
Types
#ID type
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
23 1
24 1
25 1
26 1
27 1
28 1
29 1
30 1
31 1
32 1
33 1
34 1
35 1
36 1
37 1
38 1
39 1
40 1
41 1
42 1
43 1
44 1
45 1
46 1
47 1
48 1
49 1
50 1
51 1
52 1
53 1
54 1
55 1
56 1
57 1
58 1
59 1
60 1
61 1
62 1
63 1
Diameters
#ID diameter
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
23 1
24 1
25 1
26 1
27 1
28 1
29 1
30 1
31 1
32 1
33 1
34 1
35 1
36 1
37 1
38 1
39 1
40 1
41 1
42 1
43 1
44 1
45 1
46 1
47 1
48 1
49 1
50 1
51 1
52 1
53 1
54 1
55 1
56 1
57 1
58 1
59 1
60 1
61 1
62 1
63 1
Masses
#ID mass
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
23 1
24 1
25 1
26 1
27 1
28 1
29 1
30 1
31 1
32 1
33 1
34 1
35 1
36 1
37 1
38 1
39 1
40 1
41 1
42 1
43 1
44 1
45 1
46 1
47 1
48 1
49 1
50 1
51 1
52 1
53 1
54 1
55 1
56 1
57 1
58 1
59 1
60 1
61 1
62 1
63 1
Bonds
#ID type atom1 atom2
1 1 1 2
2 1 1 3
3 1 1 4
4 1 1 5
5 1 1 7
6 1 1 10
7 1 2 3
8 1 2 4
9 1 2 5
10 1 2 6
11 1 2 7
12 1 2 8
13 1 2 9
14 1 2 11
15 1 3 4
16 1 3 5
17 1 3 6
18 1 3 8
19 1 3 10
20 1 3 11
21 1 3 12
22 1 3 14
23 1 4 6
24 1 4 7
25 1 4 8
26 1 4 10
27 1 4 11
28 1 4 13
29 1 4 16
30 1 5 6
31 1 5 9
32 1 5 14
33 1 6 8
34 1 6 9
35 1 6 11
36 1 6 14
37 1 6 18
38 1 7 8
39 1 7 9
40 1 7 16
41 1 8 9
42 1 8 11
43 1 8 16
44 1 8 17
45 1 8 18
46 1 9 18
47 1 10 11
48 1 10 12
49 1 10 13
50 1 10 14
51 1 10 16
52 1 10 19
53 1 11 12
54 1 11 13
55 1 11 14
56 1 11 15
57 1 11 16
58 1 11 17
59 1 11 18
60 1 12 13
61 1 12 14
62 1 12 15
63 1 12 17
64 1 12 19
65 1 12 20
66 1 12 21
67 1 12 23
68 1 13 15
69 1 13 16
70 1 13 17
71 1 13 19
72 1 13 20
73 1 13 22
74 1 13 25
75 1 14 15
76 1 14 18
77 1 14 23
78 1 15 17
79 1 15 18
80 1 15 20
81 1 15 23
82 1 15 27
83 1 16 17
84 1 16 18
85 1 16 25
86 1 17 18
87 1 17 20
88 1 17 25
89 1 17 27
90 1 18 27
91 1 19 20
92 1 19 21
93 1 19 22
94 1 19 23
95 1 19 25
96 1 19 28
97 1 20 21
98 1 20 22
99 1 20 23
100 1 20 24
101 1 20 25
102 1 20 26
103 1 20 27
104 1 20 29
105 1 21 22
106 1 21 23
107 1 21 24
108 1 21 26
109 1 21 28
110 1 21 29
111 1 21 30
112 1 21 32
113 1 22 24
114 1 22 25
115 1 22 26
116 1 22 28
117 1 22 29
118 1 22 34
119 1 23 24
120 1 23 27
121 1 23 32
122 1 24 26
123 1 24 27
124 1 24 29
125 1 24 32
126 1 24 36
127 1 25 26
128 1 25 27
129 1 25 34
130 1 26 27
131 1 26 29
132 1 26 34
133 1 26 35
134 1 26 36
135 1 27 36
136 1 28 29
137 1 28 30
138 1 28 31
139 1 28 32
140 1 28 34
141 1 28 37
142 1 29 30
143 1 29 31
144 1 29 32
145 1 29 33
146 1 29 34
147 1 29 35
148 1 29 36
149 1 29 38
150 1 30 31
151 1 30 32
152 1 30 33
153 1 30 35
154 1 30 37
155 1 30 38
156 1 30 41
157 1 31 33
158 1 31 34
159 1 31 35
160 1 31 37
161 1 31 38
162 1 31 40
163 1 31 43
164 1 32 33
165 1 32 36
166 1 32 41
167 1 33 35
168 1 33 36
169 1 33 38
170 1 33 41
171 1 33 42
172 1 33 45
173 1 34 35
174 1 34 36
175 1 34 43
176 1 35 36
177 1 35 38
178 1 35 43
179 1 35 45
180 1 36 45
181 1 37 38
182 1 37 39
183 1 37 40
184 1 37 41
185 1 37 43
186 1 37 46
187 1 38 39
188 1 38 40
189 1 38 41
190 1 38 42
191 1 38 43
192 1 38 44
193 1 38 45
194 1 38 47
195 1 39 40
196 1 39 41
197 1 39 42
198 1 39 44
199 1 39 46
200 1 39 47
201 1 39 50
202 1 40 42
203 1 40 43
204 1 40 44
205 1 40 46
206 1 40 47
207 1 40 52
208 1 41 42
209 1 41 45
210 1 41 50
211 1 42 44
212 1 42 45
213 1 42 47
214 1 42 50
215 1 42 51
216 1 42 54
217 1 43 44
218 1 43 45
219 1 43 52
220 1 44 45
221 1 44 47
222 1 44 52
223 1 44 53
224 1 44 54
225 1 45 54
226 1 46 47
227 1 46 48
228 1 46 49
229 1 46 50
230 1 46 52
231 1 46 55
232 1 47 48
233 1 47 49
234 1 47 50
235 1 47 51
236 1 47 52
237 1 47 53
238 1 47 54
239 1 47 56
240 1 48 49
241 1 48 50
242 1 48 51
243 1 48 53
244 1 48 55
245 1 48 56
246 1 48 57
247 1 48 59
248 1 49 51
249 1 49 52
250 1 49 53
251 1 49 55
252 1 49 56
253 1 49 58
254 1 49 61
255 1 50 51
256 1 50 54
257 1 50 59
258 1 51 53
259 1 51 54
260 1 51 56
261 1 51 59
262 1 51 63
263 1 52 53
264 1 52 54
265 1 52 61
266 1 53 54
267 1 53 56
268 1 53 61
269 1 53 62
270 1 53 63
271 1 54 63
272 1 55 56
273 1 55 57
274 1 55 58
275 1 55 59
276 1 55 61
277 1 56 57
278 1 56 58
279 1 56 59
280 1 56 60
281 1 56 61
282 1 56 62
283 1 56 63
284 1 57 58
285 1 57 59
286 1 57 60
287 1 57 62
288 1 58 60
289 1 58 61
290 1 58 62
291 1 59 60
292 1 59 63
293 1 60 62
294 1 60 63
295 1 61 62
296 1 61 63
297 1 62 63

View File

@ -23,7 +23,7 @@ fix 1 all nve
# NPT # NPT
#fix 1 all npt temp 1.0 1.0 0.1 iso 1.0 1.0 1.0 #fix 1 all npt temp 1.0 1.0 0.1 iso 1.0 1.0 1.0
fix 2 all mdi/aimd plugin fix 2 all mdi/aimd
fix_modify 2 energy yes virial yes fix_modify 2 energy yes virial yes
thermo_style custom step temp pe etotal press vol thermo_style custom step temp pe etotal press vol

View File

@ -286,18 +286,15 @@ while iarg < narg:
if not mdiarg: error() if not mdiarg: error()
mdi.MDI_Init(mdiarg)
# LAMMPS engine is a stand-alone code # LAMMPS engine is a stand-alone code
# world = MPI communicator for just this driver # world = MPI communicator for just this driver
# invoke perform_tasks() directly # invoke perform_tasks() directly
if not plugin: if not plugin:
mdi.MDI_Init(mdiarg)
world = mdi.MDI_MPI_get_world_comm() world = mdi.MDI_MPI_get_world_comm()
# connect to engine
mdicomm = mdi.MDI_Accept_Communicator() mdicomm = mdi.MDI_Accept_Communicator()
perform_tasks(world,mdicomm,None) perform_tasks(world,mdicomm,None)
# LAMMPS engine is a plugin library # LAMMPS engine is a plugin library
@ -305,7 +302,6 @@ if not plugin:
# MDI will call back to perform_tasks() # MDI will call back to perform_tasks()
if plugin: if plugin:
mdi.MDI_Init(mdiarg)
world = MPI.COMM_WORLD world = MPI.COMM_WORLD
plugin_args += " -mdi \"-role ENGINE -name lammps -method LINK\"" plugin_args += " -mdi \"-role ENGINE -name lammps -method LINK\""
mdi.MDI_Launch_plugin(plugin,plugin_args,world,perform_tasks,None) mdi.MDI_Launch_plugin(plugin,plugin_args,world,perform_tasks,None)

View File

@ -13,14 +13,6 @@ endif
NVCC = nvcc NVCC = nvcc
# obsolete hardware. not supported by current drivers anymore.
#CUDA_ARCH = -arch=sm_13
#CUDA_ARCH = -arch=sm_10 -DCUDA_PRE_THREE
# Fermi hardware
#CUDA_ARCH = -arch=sm_20
#CUDA_ARCH = -arch=sm_21
# Kepler hardware # Kepler hardware
#CUDA_ARCH = -arch=sm_30 #CUDA_ARCH = -arch=sm_30
#CUDA_ARCH = -arch=sm_32 #CUDA_ARCH = -arch=sm_32
@ -45,6 +37,9 @@ CUDA_ARCH = -arch=sm_50
#CUDA_ARCH = -arch=sm_80 #CUDA_ARCH = -arch=sm_80
#CUDA_ARCH = -arch=sm_86 #CUDA_ARCH = -arch=sm_86
# Hopper hardware
#CUDA_ARCH = -arch=sm_90
CUDA_CODE = -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52] \ CUDA_CODE = -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52] \
-gencode arch=compute_60,code=[sm_60,compute_60] -gencode arch=compute_61,code=[sm_61,compute_61] \ -gencode arch=compute_60,code=[sm_60,compute_60] -gencode arch=compute_61,code=[sm_61,compute_61] \
-gencode arch=compute_70,code=[sm_70,compute_70] -gencode arch=compute_75,code=[sm_75,compute_75] \ -gencode arch=compute_70,code=[sm_70,compute_70] -gencode arch=compute_75,code=[sm_75,compute_75] \

View File

@ -171,7 +171,13 @@ NOTE: when compiling with CMake, all of the considerations listed below
are considered within the CMake configuration process, so no separate are considered within the CMake configuration process, so no separate
compilation of the gpu library is required. Also this will build in support compilation of the gpu library is required. Also this will build in support
for all compute architecture that are supported by the CUDA toolkit version for all compute architecture that are supported by the CUDA toolkit version
used to build the gpu library. used to build the gpu library. A similar setup is possible using
Makefile.linux_multi after adjusting the settings for the CUDA toolkit in use.
Only CUDA toolkit version 8.0 and later and only GPU architecture 3.0
(aka Kepler) and later are supported by this version of LAMMPS. If you want
to use older hard- or software you have to compile for OpenCL or use an older
version of LAMMPS.
If you do not want to use a fat binary, that supports multiple CUDA If you do not want to use a fat binary, that supports multiple CUDA
architectures, the CUDA_ARCH must be set to match the GPU architecture. This architectures, the CUDA_ARCH must be set to match the GPU architecture. This
@ -225,7 +231,8 @@ If GERYON_NUMA_FISSION is defined at build time, LAMMPS will consider separate
NUMA nodes on GPUs or accelerators as separate devices. For example, a 2-socket NUMA nodes on GPUs or accelerators as separate devices. For example, a 2-socket
CPU would appear as two separate devices for OpenCL (and LAMMPS would require CPU would appear as two separate devices for OpenCL (and LAMMPS would require
two MPI processes to use both sockets with the GPU library - each with its two MPI processes to use both sockets with the GPU library - each with its
own device ID as output by ocl_get_devices). own device ID as output by ocl_get_devices). OpenCL version 1.2 or later is
required.
For a debug build, use "-DUCL_DEBUG -DGERYON_KERNEL_DUMP" and remove For a debug build, use "-DUCL_DEBUG -DGERYON_KERNEL_DUMP" and remove
"-DUCL_NO_EXIT" and "-DMPI_GERYON" from the build options. "-DUCL_NO_EXIT" and "-DMPI_GERYON" from the build options.

View File

@ -379,18 +379,9 @@ UCL_Device::UCL_Device() {
prop.regsPerBlock = hip_prop.regsPerBlock; prop.regsPerBlock = hip_prop.regsPerBlock;
prop.clockRate = hip_prop.clockRate; prop.clockRate = hip_prop.clockRate;
prop.computeMode = hip_prop.computeMode; prop.computeMode = hip_prop.computeMode;
//CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.memPitch, CU_DEVICE_ATTRIBUTE_MAX_PITCH, dev));
//CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.textureAlign, CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, dev));
//#if CUDA_VERSION >= 2020
//CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.kernelExecTimeoutEnabled, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT,dev));
CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.integrated, hipDeviceAttributeIntegrated, dev)); CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.integrated, hipDeviceAttributeIntegrated, dev));
//CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.canMapHostMemory, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, dev));
//#endif
//#if CUDA_VERSION >= 3010
prop.concurrentKernels = hip_prop.concurrentKernels; prop.concurrentKernels = hip_prop.concurrentKernels;
//CU_SAFE_CALL_NS(hipDeviceGetAttribute(&prop.ECCEnabled, CU_DEVICE_ATTRIBUTE_ECC_ENABLED, dev));
//#endif
_properties.push_back(prop); _properties.push_back(prop);
} }
@ -447,13 +438,11 @@ void UCL_Device::clear() {
// List all devices along with all properties // List all devices along with all properties
void UCL_Device::print_all(std::ostream &out) { void UCL_Device::print_all(std::ostream &out) {
//#if CUDA_VERSION >= 2020
int driver_version; int driver_version;
hipDriverGetVersion(&driver_version); hipDriverGetVersion(&driver_version);
out << "Driver Version: " out << "Driver Version: "
<< driver_version/1000 << "." << driver_version%100 << driver_version/1000 << "." << driver_version%100
<< std::endl; << std::endl;
//#endif
if (num_devices() == 0) if (num_devices() == 0)
out << "There is no device supporting HIP\n"; out << "There is no device supporting HIP\n";
@ -470,12 +459,10 @@ void UCL_Device::print_all(std::ostream &out) {
out << "No\n"; out << "No\n";
out << " Total amount of global memory: " out << " Total amount of global memory: "
<< gigabytes(i) << " GB\n"; << gigabytes(i) << " GB\n";
//#if CUDA_VERSION >= 2000
out << " Number of compute units/multiprocessors: " out << " Number of compute units/multiprocessors: "
<< _properties[i].multiProcessorCount << std::endl; << _properties[i].multiProcessorCount << std::endl;
out << " Number of cores: " out << " Number of cores: "
<< cores(i) << std::endl; << cores(i) << std::endl;
//#endif
out << " Total amount of constant memory: " out << " Total amount of constant memory: "
<< _properties[i].totalConstantMemory << " bytes\n"; << _properties[i].totalConstantMemory << " bytes\n";
out << " Total amount of local/shared memory per block: " out << " Total amount of local/shared memory per block: "
@ -494,58 +481,29 @@ void UCL_Device::print_all(std::ostream &out) {
<< _properties[i].maxGridSize[0] << " x " << _properties[i].maxGridSize[0] << " x "
<< _properties[i].maxGridSize[1] << " x " << _properties[i].maxGridSize[1] << " x "
<< _properties[i].maxGridSize[2] << std::endl; << _properties[i].maxGridSize[2] << std::endl;
//out << " Maximum memory pitch: "
// << max_pitch(i) << " bytes\n";
//out << " Texture alignment: "
// << _properties[i].textureAlign << " bytes\n";
out << " Clock rate: " out << " Clock rate: "
<< clock_rate(i) << " GHz\n"; << clock_rate(i) << " GHz\n";
//#if CUDA_VERSION >= 2020
//out << " Run time limit on kernels: ";
//if (_properties[i].kernelExecTimeoutEnabled)
// out << "Yes\n";
//else
// out << "No\n";
out << " Integrated: "; out << " Integrated: ";
if (_properties[i].integrated) if (_properties[i].integrated)
out << "Yes\n"; out << "Yes\n";
else else
out << "No\n"; out << "No\n";
//out << " Support host page-locked memory mapping: ";
//if (_properties[i].canMapHostMemory)
// out << "Yes\n";
//else
// out << "No\n";
out << " Compute mode: "; out << " Compute mode: ";
if (_properties[i].computeMode == hipComputeModeDefault) if (_properties[i].computeMode == hipComputeModeDefault)
out << "Default\n"; // multiple threads can use device out << "Default\n"; // multiple threads can use device
//#if CUDA_VERSION >= 8000
// else if (_properties[i].computeMode == hipComputeModeExclusiveProcess)
//#else
else if (_properties[i].computeMode == hipComputeModeExclusive) else if (_properties[i].computeMode == hipComputeModeExclusive)
//#endif
out << "Exclusive\n"; // only thread can use device out << "Exclusive\n"; // only thread can use device
else if (_properties[i].computeMode == hipComputeModeProhibited) else if (_properties[i].computeMode == hipComputeModeProhibited)
out << "Prohibited\n"; // no thread can use device out << "Prohibited\n"; // no thread can use device
//#if CUDART_VERSION >= 4000
else if (_properties[i].computeMode == hipComputeModeExclusiveProcess) else if (_properties[i].computeMode == hipComputeModeExclusiveProcess)
out << "Exclusive Process\n"; // multiple threads 1 process out << "Exclusive Process\n"; // multiple threads 1 process
//#endif
else else
out << "Unknown\n"; out << "Unknown\n";
//#endif
//#if CUDA_VERSION >= 3010
out << " Concurrent kernel execution: "; out << " Concurrent kernel execution: ";
if (_properties[i].concurrentKernels) if (_properties[i].concurrentKernels)
out << "Yes\n"; out << "Yes\n";
else else
out << "No\n"; out << "No\n";
//out << " Device has ECC support enabled: ";
//if (_properties[i].ECCEnabled)
// out << "Yes\n";
//else
// out << "No\n";
//#endif
} }
} }

View File

@ -5,11 +5,7 @@
#include <cassert> #include <cassert>
#include <hip/hip_runtime.h> #include <hip/hip_runtime.h>
//#if CUDA_VERSION >= 3020
#define CUDA_INT_TYPE size_t #define CUDA_INT_TYPE size_t
//#else
//#define CUDA_INT_TYPE unsigned
//#endif
#ifdef MPI_GERYON #ifdef MPI_GERYON
#include "mpi.h" #include "mpi.h"

View File

@ -71,9 +71,6 @@ class UCL_Texture {
/// Make a texture reference available to kernel /// Make a texture reference available to kernel
inline void allow(UCL_Kernel &) { inline void allow(UCL_Kernel &) {
//#if CUDA_VERSION < 4000
//CU_SAFE_CALL(cuParamSetTexRef(kernel._kernel, CU_PARAM_TR_DEFAULT, _tex));
//#endif
} }
private: private:

View File

@ -320,6 +320,9 @@ class UCL_Device {
// Grabs the properties for all devices // Grabs the properties for all devices
UCL_Device::UCL_Device() { UCL_Device::UCL_Device() {
#if CUDA_VERSION < 8000
#error CUDA Toolkit version 8 or later required
#endif
CU_SAFE_CALL_NS(cuInit(0)); CU_SAFE_CALL_NS(cuInit(0));
CU_SAFE_CALL_NS(cuDeviceGetCount(&_num_devices)); CU_SAFE_CALL_NS(cuDeviceGetCount(&_num_devices));
for (int i=0; i<_num_devices; ++i) { for (int i=0; i<_num_devices; ++i) {
@ -358,16 +361,12 @@ UCL_Device::UCL_Device() {
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.clockRate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.clockRate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, dev));
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.textureAlign, CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.textureAlign, CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, dev));
#if CUDA_VERSION >= 2020
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.kernelExecTimeoutEnabled, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT,dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.kernelExecTimeoutEnabled, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT,dev));
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.integrated, CU_DEVICE_ATTRIBUTE_INTEGRATED, dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.integrated, CU_DEVICE_ATTRIBUTE_INTEGRATED, dev));
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.canMapHostMemory, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.canMapHostMemory, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, dev));
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE,dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE,dev));
#endif
#if CUDA_VERSION >= 3010
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.concurrentKernels, CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS, dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.concurrentKernels, CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS, dev));
CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.ECCEnabled, CU_DEVICE_ATTRIBUTE_ECC_ENABLED, dev)); CU_SAFE_CALL_NS(cuDeviceGetAttribute(&prop.ECCEnabled, CU_DEVICE_ATTRIBUTE_ECC_ENABLED, dev));
#endif
_properties.push_back(prop); _properties.push_back(prop);
} }
@ -415,13 +414,10 @@ void UCL_Device::clear() {
// List all devices along with all properties // List all devices along with all properties
void UCL_Device::print_all(std::ostream &out) { void UCL_Device::print_all(std::ostream &out) {
#if CUDA_VERSION >= 2020
int driver_version; int driver_version;
cuDriverGetVersion(&driver_version); cuDriverGetVersion(&driver_version);
out << "CUDA Driver Version: " out << "CUDA Driver Version: "
<< driver_version/1000 << "." << driver_version%100 << driver_version/1000 << "." << driver_version%100 << std::endl;
<< std::endl;
#endif
if (num_devices() == 0) if (num_devices() == 0)
out << "There is no device supporting CUDA\n"; out << "There is no device supporting CUDA\n";
@ -438,12 +434,10 @@ void UCL_Device::print_all(std::ostream &out) {
out << "No\n"; out << "No\n";
out << " Total amount of global memory: " out << " Total amount of global memory: "
<< gigabytes(i) << " GB\n"; << gigabytes(i) << " GB\n";
#if CUDA_VERSION >= 2000
out << " Number of compute units/multiprocessors: " out << " Number of compute units/multiprocessors: "
<< _properties[i].multiProcessorCount << std::endl; << _properties[i].multiProcessorCount << std::endl;
out << " Number of cores: " out << " Number of cores: "
<< cores(i) << std::endl; << cores(i) << std::endl;
#endif
out << " Total amount of constant memory: " out << " Total amount of constant memory: "
<< _properties[i].totalConstantMemory << " bytes\n"; << _properties[i].totalConstantMemory << " bytes\n";
out << " Total amount of local/shared memory per block: " out << " Total amount of local/shared memory per block: "
@ -468,7 +462,6 @@ void UCL_Device::print_all(std::ostream &out) {
<< _properties[i].textureAlign << " bytes\n"; << _properties[i].textureAlign << " bytes\n";
out << " Clock rate: " out << " Clock rate: "
<< clock_rate(i) << " GHz\n"; << clock_rate(i) << " GHz\n";
#if CUDA_VERSION >= 2020
out << " Run time limit on kernels: "; out << " Run time limit on kernels: ";
if (_properties[i].kernelExecTimeoutEnabled) if (_properties[i].kernelExecTimeoutEnabled)
out << "Yes\n"; out << "Yes\n";
@ -487,22 +480,14 @@ void UCL_Device::print_all(std::ostream &out) {
out << " Compute mode: "; out << " Compute mode: ";
if (_properties[i].computeMode == CU_COMPUTEMODE_DEFAULT) if (_properties[i].computeMode == CU_COMPUTEMODE_DEFAULT)
out << "Default\n"; // multiple threads can use device out << "Default\n"; // multiple threads can use device
#if CUDA_VERSION >= 8000
else if (_properties[i].computeMode == CU_COMPUTEMODE_EXCLUSIVE_PROCESS) else if (_properties[i].computeMode == CU_COMPUTEMODE_EXCLUSIVE_PROCESS)
#else
else if (_properties[i].computeMode == CU_COMPUTEMODE_EXCLUSIVE)
#endif
out << "Exclusive\n"; // only thread can use device out << "Exclusive\n"; // only thread can use device
else if (_properties[i].computeMode == CU_COMPUTEMODE_PROHIBITED) else if (_properties[i].computeMode == CU_COMPUTEMODE_PROHIBITED)
out << "Prohibited\n"; // no thread can use device out << "Prohibited\n"; // no thread can use device
#if CUDART_VERSION >= 4000
else if (_properties[i].computeMode == CU_COMPUTEMODE_EXCLUSIVE_PROCESS) else if (_properties[i].computeMode == CU_COMPUTEMODE_EXCLUSIVE_PROCESS)
out << "Exclusive Process\n"; // multiple threads 1 process out << "Exclusive Process\n"; // multiple threads 1 process
#endif
else else
out << "Unknown\n"; out << "Unknown\n";
#endif
#if CUDA_VERSION >= 3010
out << " Concurrent kernel execution: "; out << " Concurrent kernel execution: ";
if (_properties[i].concurrentKernels) if (_properties[i].concurrentKernels)
out << "Yes\n"; out << "Yes\n";
@ -513,7 +498,6 @@ void UCL_Device::print_all(std::ostream &out) {
out << "Yes\n"; out << "Yes\n";
else else
out << "No\n"; out << "No\n";
#endif
} }
} }

View File

@ -165,17 +165,11 @@ class UCL_Program {
class UCL_Kernel { class UCL_Kernel {
public: public:
UCL_Kernel() : _dimensions(1), _num_args(0) { UCL_Kernel() : _dimensions(1), _num_args(0) {
#if CUDA_VERSION < 4000
_param_size=0;
#endif
_num_blocks[0]=0; _num_blocks[0]=0;
} }
UCL_Kernel(UCL_Program &program, const char *function) : UCL_Kernel(UCL_Program &program, const char *function) :
_dimensions(1), _num_args(0) { _dimensions(1), _num_args(0) {
#if CUDA_VERSION < 4000
_param_size=0;
#endif
_num_blocks[0]=0; _num_blocks[0]=0;
set_function(program,function); set_function(program,function);
_cq=program._cq; _cq=program._cq;
@ -211,11 +205,7 @@ class UCL_Kernel {
if (index==_num_args) if (index==_num_args)
add_arg(arg); add_arg(arg);
else if (index<_num_args) else if (index<_num_args)
#if CUDA_VERSION >= 4000
_kernel_args[index]=arg; _kernel_args[index]=arg;
#else
CU_SAFE_CALL(cuParamSetv(_kernel, _offsets[index], arg, sizeof(dtype)));
#endif
else else
assert(0==1); // Must add kernel parameters in sequential order assert(0==1); // Must add kernel parameters in sequential order
} }
@ -242,15 +232,7 @@ class UCL_Kernel {
/// Add a kernel argument. /// Add a kernel argument.
inline void add_arg(const CUdeviceptr* const arg) { inline void add_arg(const CUdeviceptr* const arg) {
#if CUDA_VERSION >= 4000
_kernel_args[_num_args]=(void *)arg; _kernel_args[_num_args]=(void *)arg;
#else
void* ptr = (void*)(size_t)(*arg);
_param_size = (_param_size + __alignof(ptr) - 1) & ~(__alignof(ptr) - 1);
CU_SAFE_CALL(cuParamSetv(_kernel, _param_size, &ptr, sizeof(ptr)));
_offsets.push_back(_param_size);
_param_size+=sizeof(ptr);
#endif
_num_args++; _num_args++;
if (_num_args>UCL_MAX_KERNEL_ARGS) assert(0==1); if (_num_args>UCL_MAX_KERNEL_ARGS) assert(0==1);
} }
@ -258,14 +240,7 @@ class UCL_Kernel {
/// Add a kernel argument. /// Add a kernel argument.
template <class dtype> template <class dtype>
inline void add_arg(const dtype* const arg) { inline void add_arg(const dtype* const arg) {
#if CUDA_VERSION >= 4000
_kernel_args[_num_args]=const_cast<dtype *>(arg); _kernel_args[_num_args]=const_cast<dtype *>(arg);
#else
_param_size = (_param_size+__alignof(dtype)-1) & ~(__alignof(dtype)-1);
CU_SAFE_CALL(cuParamSetv(_kernel,_param_size,(void*)arg,sizeof(dtype)));
_offsets.push_back(_param_size);
_param_size+=sizeof(dtype);
#endif
_num_args++; _num_args++;
if (_num_args>UCL_MAX_KERNEL_ARGS) assert(0==1); if (_num_args>UCL_MAX_KERNEL_ARGS) assert(0==1);
} }
@ -298,13 +273,9 @@ class UCL_Kernel {
_num_blocks[0]=num_blocks; _num_blocks[0]=num_blocks;
_num_blocks[1]=1; _num_blocks[1]=1;
_num_blocks[2]=1; _num_blocks[2]=1;
#if CUDA_VERSION >= 4000
_block_size[0]=block_size; _block_size[0]=block_size;
_block_size[1]=1; _block_size[1]=1;
_block_size[2]=1; _block_size[2]=1;
#else
CU_SAFE_CALL(cuFuncSetBlockShape(_kernel,block_size,1,1));
#endif
} }
/// Set the number of thread blocks and the number of threads in each block /// Set the number of thread blocks and the number of threads in each block
@ -323,13 +294,9 @@ class UCL_Kernel {
_num_blocks[0]=num_blocks_x; _num_blocks[0]=num_blocks_x;
_num_blocks[1]=num_blocks_y; _num_blocks[1]=num_blocks_y;
_num_blocks[2]=1; _num_blocks[2]=1;
#if CUDA_VERSION >= 4000
_block_size[0]=block_size_x; _block_size[0]=block_size_x;
_block_size[1]=block_size_y; _block_size[1]=block_size_y;
_block_size[2]=1; _block_size[2]=1;
#else
CU_SAFE_CALL(cuFuncSetBlockShape(_kernel,block_size_x,block_size_y,1));
#endif
} }
/// Set the number of thread blocks and the number of threads in each block /// Set the number of thread blocks and the number of threads in each block
@ -350,14 +317,9 @@ class UCL_Kernel {
_num_blocks[0]=num_blocks_x; _num_blocks[0]=num_blocks_x;
_num_blocks[1]=num_blocks_y; _num_blocks[1]=num_blocks_y;
_num_blocks[2]=1; _num_blocks[2]=1;
#if CUDA_VERSION >= 4000
_block_size[0]=block_size_x; _block_size[0]=block_size_x;
_block_size[1]=block_size_y; _block_size[1]=block_size_y;
_block_size[2]=block_size_z; _block_size[2]=block_size_z;
#else
CU_SAFE_CALL(cuFuncSetBlockShape(_kernel,block_size_x,block_size_y,
block_size_z));
#endif
} }
/// Set the number of thread blocks and the number of threads in each block /// Set the number of thread blocks and the number of threads in each block
@ -373,23 +335,14 @@ class UCL_Kernel {
/// Run the kernel in the default command queue /// Run the kernel in the default command queue
inline void run() { inline void run() {
#if CUDA_VERSION >= 4000
CU_SAFE_CALL(cuLaunchKernel(_kernel,_num_blocks[0],_num_blocks[1], CU_SAFE_CALL(cuLaunchKernel(_kernel,_num_blocks[0],_num_blocks[1],
_num_blocks[2],_block_size[0],_block_size[1], _num_blocks[2],_block_size[0],_block_size[1],
_block_size[2],0,_cq,_kernel_args,nullptr)); _block_size[2],0,_cq,_kernel_args,nullptr));
#else
CU_SAFE_CALL(cuParamSetSize(_kernel,_param_size));
CU_SAFE_CALL(cuLaunchGridAsync(_kernel,_num_blocks[0],_num_blocks[1],_cq));
#endif
} }
/// Clear any arguments associated with the kernel /// Clear any arguments associated with the kernel
inline void clear_args() { inline void clear_args() {
_num_args=0; _num_args=0;
#if CUDA_VERSION < 4000
_offsets.clear();
_param_size=0;
#endif
} }
/// Return the default command queue/stream associated with this data /// Return the default command queue/stream associated with this data
@ -406,13 +359,8 @@ class UCL_Kernel {
unsigned _num_args; unsigned _num_args;
friend class UCL_Texture; friend class UCL_Texture;
#if CUDA_VERSION >= 4000
unsigned _block_size[3]; unsigned _block_size[3];
void * _kernel_args[UCL_MAX_KERNEL_ARGS]; void * _kernel_args[UCL_MAX_KERNEL_ARGS];
#else
std::vector<unsigned> _offsets;
unsigned _param_size;
#endif
}; };
} // namespace } // namespace

View File

@ -5,11 +5,7 @@
#include <cassert> #include <cassert>
#include <cuda.h> #include <cuda.h>
#if CUDA_VERSION >= 3020
#define CUDA_INT_TYPE size_t #define CUDA_INT_TYPE size_t
#else
#define CUDA_INT_TYPE unsigned
#endif
#ifdef MPI_GERYON #ifdef MPI_GERYON
#include "mpi.h" #include "mpi.h"

View File

@ -69,9 +69,6 @@ class UCL_Texture {
/// Make a texture reference available to kernel /// Make a texture reference available to kernel
inline void allow(UCL_Kernel &kernel) { inline void allow(UCL_Kernel &kernel) {
#if CUDA_VERSION < 4000
CU_SAFE_CALL(cuParamSetTexRef(kernel._kernel, CU_PARAM_TR_DEFAULT, _tex));
#endif
} }
private: private:

View File

@ -25,21 +25,8 @@
#ifndef UCL_NV_KERNEL_H #ifndef UCL_NV_KERNEL_H
#define UCL_NV_KERNEL_H #define UCL_NV_KERNEL_H
#if (__CUDA_ARCH__ < 200)
#define mul24 __mul24
#define MEM_THREADS 16
#else
#define mul24(X,Y) (X)*(Y) #define mul24(X,Y) (X)*(Y)
#define MEM_THREADS 32 #define MEM_THREADS 32
#endif
#ifdef CUDA_PRE_THREE
struct __builtin_align__(16) _double4
{
double x, y, z, w;
};
typedef struct _double4 double4;
#endif
#define GLOBAL_ID_X threadIdx.x+mul24(blockIdx.x,blockDim.x) #define GLOBAL_ID_X threadIdx.x+mul24(blockIdx.x,blockDim.x)
#define GLOBAL_ID_Y threadIdx.y+mul24(blockIdx.y,blockDim.y) #define GLOBAL_ID_Y threadIdx.y+mul24(blockIdx.y,blockDim.y)

View File

@ -58,49 +58,6 @@
#define MAX_BIO_SHARED_TYPES 128 #define MAX_BIO_SHARED_TYPES 128
#define PPPM_MAX_SPLINE 8 #define PPPM_MAX_SPLINE 8
// -------------------------------------------------------------------------
// LEGACY DEVICE CONFIGURATION
// -------------------------------------------------------------------------
#ifdef __CUDA_ARCH__
#if (__CUDA_ARCH__ < 200)
#undef CONFIG_ID
#define CONFIG_ID 101
#define MEM_THREADS 16
#undef THREADS_PER_ATOM
#define THREADS_PER_ATOM 1
#undef THREADS_PER_CHARGE
#define THREADS_PER_CHARGE 16
#undef BLOCK_PAIR
#define BLOCK_PAIR 64
#undef BLOCK_BIO_PAIR
#define BLOCK_BIO_PAIR 64
#undef BLOCK_NBOR_BUILD
#define BLOCK_NBOR_BUILD 64
#undef MAX_SHARED_TYPES
#define MAX_SHARED_TYPES 8
#undef SHUFFLE_AVAIL
#define SHUFFLE_AVAIL 0
#elseif (__CUDA_ARCH__ < 300)
#undef CONFIG_ID
#define CONFIG_ID 102
#undef BLOCK_PAIR
#define BLOCK_PAIR 128
#undef BLOCK_BIO_PAIR
#define BLOCK_BIO_PAIR 128
#undef MAX_SHARED_TYPES
#define MAX_SHARED_TYPES 8
#undef SHUFFLE_AVAIL
#define SHUFFLE_AVAIL 0
#endif
#endif
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// KERNEL MACROS // KERNEL MACROS
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -111,12 +68,6 @@
#define fast_mul(X,Y) (X)*(Y) #define fast_mul(X,Y) (X)*(Y)
#ifdef __CUDA_ARCH__
#if (__CUDA_ARCH__ < 200)
#define fast_mul __mul24
#endif
#endif
#define EVFLAG 1 #define EVFLAG 1
#define NOUNROLL #define NOUNROLL
#define GLOBAL_ID_X threadIdx.x+fast_mul(blockIdx.x,blockDim.x) #define GLOBAL_ID_X threadIdx.x+fast_mul(blockIdx.x,blockDim.x)
@ -220,14 +171,6 @@
// KERNEL MACROS - MATH // KERNEL MACROS - MATH
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
#ifdef CUDA_PRE_THREE
struct __builtin_align__(16) _double4
{
double x, y, z, w;
};
typedef struct _double4 double4;
#endif
#ifdef _DOUBLE_DOUBLE #ifdef _DOUBLE_DOUBLE
#define ucl_exp exp #define ucl_exp exp

View File

@ -34,12 +34,12 @@ make lib-meam args="-m ifort" # build MEAM lib with custom Makefile.ifort (usi
# settings # settings
version = "1.3.0" version = "1.3.2"
url = "https://github.com/MolSSI-MDI/MDI_Library/archive/v%s.tar.gz" % version url = "https://github.com/MolSSI-MDI/MDI_Library/archive/v%s.tar.gz" % version
# known checksums for different MDI versions. used to validate the download. # known checksums for different MDI versions. used to validate the download.
checksums = { \ checksums = { \
'1.3.0' : '8a8da217148bd9b700083b67d795af5e', \ '1.3.2' : '836f5da400d8cff0f0e4435640f9454f', \
} }
# print error message or help # print error message or help

18
src/.gitignore vendored
View File

@ -254,6 +254,21 @@
/pair_mesont_tpm.cpp /pair_mesont_tpm.cpp
/pair_mesont_tpm.h /pair_mesont_tpm.h
/atom_vec_bpm_sphere.cpp
/atom_vec_bpm_sphere.h
/bond_bpm.cpp
/bond_bpm.h
/bond_bpm_rotational.cpp
/bond_bpm_rotational.h
/bond_bpm_spring.cpp
/bond_bpm_spring.h
/compute_nbond_atom.cpp
/compute_nbond_atom.h
/fix_nve_bpm_sphere.cpp
/fix_nve_bpm_sphere.h
/pair_bpm_spring.cpp
/pair_bpm_spring.h
/compute_adf.cpp /compute_adf.cpp
/compute_adf.h /compute_adf.h
/compute_contact_atom.cpp /compute_contact_atom.cpp
@ -792,8 +807,6 @@
/fix_orient_eco.h /fix_orient_eco.h
/fix_orient_fcc.cpp /fix_orient_fcc.cpp
/fix_orient_fcc.h /fix_orient_fcc.h
/fix_pair_tracker.cpp
/fix_pair_tracker.h
/fix_peri_neigh.cpp /fix_peri_neigh.cpp
/fix_peri_neigh.h /fix_peri_neigh.h
/fix_phonon.cpp /fix_phonon.cpp
@ -1524,3 +1537,4 @@
/pair_smtbq.h /pair_smtbq.h
/pair_vashishta*.cpp /pair_vashishta*.cpp
/pair_vashishta*.h /pair_vashishta*.h

View File

@ -0,0 +1,245 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "atom_vec_bpm_sphere.h"
#include "atom.h"
#include "error.h"
#include "fix.h"
#include "fix_adapt.h"
#include "math_const.h"
#include "modify.h"
#include "utils.h"
#include <cstring>
using namespace LAMMPS_NS;
using MathConst::MY_PI;
/* ---------------------------------------------------------------------- */
AtomVecBPMSphere::AtomVecBPMSphere(LAMMPS *_lmp) : AtomVec(_lmp)
{
mass_type = PER_ATOM;
molecular = Atom::MOLECULAR;
bonds_allow = 1;
atom->molecule_flag = 1;
atom->sphere_flag = 1;
atom->radius_flag = atom->rmass_flag = atom->omega_flag = atom->torque_flag = atom->quat_flag = 1;
// strings with peratom variables to include in each AtomVec method
// strings cannot contain fields in corresponding AtomVec default strings
// order of fields in a string does not matter
// except: fields_data_atom & fields_data_vel must match data file
// clang-format off
fields_grow = (char *) "molecule num_bond bond_type bond_atom nspecial special radius rmass "
"omega torque quat";
fields_copy = (char *) "molecule num_bond bond_type bond_atom nspecial special radius rmass "
"omega quat";
fields_comm = (char *) "";
fields_comm_vel = (char *) "omega quat";
fields_reverse = (char *) "torque";
fields_border = (char *) "molecule radius rmass";
fields_border_vel = (char *) "molecule radius rmass omega quat";
fields_exchange = (char *) "molecule num_bond bond_type bond_atom nspecial special radius rmass "
"omega quat";
fields_restart = (char *) "molecule num_bond bond_type bond_atom radius rmass omega quat";
fields_create = (char *) "molecule num_bond nspecial radius rmass omega quat";
fields_data_atom = (char *) "id molecule type radius rmass x";
fields_data_vel = (char *) "id v omega";
// clang-format on
bond_per_atom = 0;
bond_negative = NULL;
}
/* ----------------------------------------------------------------------
process sub-style args
optional arg = 0/1 for static/dynamic particle radii
------------------------------------------------------------------------- */
void AtomVecBPMSphere::process_args(int narg, char **arg)
{
if (narg != 0 && narg != 1) error->all(FLERR, "Illegal atom_style bpm/sphere command");
radvary = 0;
if (narg == 1) {
radvary = utils::numeric(FLERR, arg[0], true, lmp);
if (radvary < 0 || radvary > 1) error->all(FLERR, "Illegal atom_style bpm/sphere command");
}
// dynamic particle radius and mass must be communicated every step
if (radvary) {
fields_comm = (char *) "radius rmass";
fields_comm_vel = (char *) "radius rmass omega";
}
// delay setting up of fields until now
setup_fields();
}
/* ---------------------------------------------------------------------- */
void AtomVecBPMSphere::init()
{
AtomVec::init();
// check if optional radvary setting should have been set to 1
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style, "adapt") == 0) {
FixAdapt *fix = (FixAdapt *) modify->fix[i];
if (fix->diamflag && radvary == 0)
error->all(FLERR, "Fix adapt changes atom radii but atom_style bpm/sphere is not dynamic");
}
}
/* ----------------------------------------------------------------------
set local copies of all grow ptrs used by this class, except defaults
needed in replicate when 2 atom classes exist and it calls pack_restart()
------------------------------------------------------------------------- */
void AtomVecBPMSphere::grow_pointers()
{
radius = atom->radius;
rmass = atom->rmass;
omega = atom->omega;
quat = atom->quat;
num_bond = atom->num_bond;
bond_type = atom->bond_type;
nspecial = atom->nspecial;
}
/* ----------------------------------------------------------------------
initialize non-zero atom quantities
------------------------------------------------------------------------- */
void AtomVecBPMSphere::create_atom_post(int ilocal)
{
radius[ilocal] = 0.5;
rmass[ilocal] = 4.0 * MY_PI / 3.0 * 0.5 * 0.5 * 0.5;
quat[ilocal][0] = 1.0;
quat[ilocal][1] = 0.0;
quat[ilocal][2] = 0.0;
quat[ilocal][3] = 0.0;
}
/* ----------------------------------------------------------------------
modify values for AtomVec::pack_restart() to pack
------------------------------------------------------------------------- */
void AtomVecBPMSphere::pack_restart_pre(int ilocal)
{
// insure bond_negative vector is needed length
if (bond_per_atom < atom->bond_per_atom) {
delete[] bond_negative;
bond_per_atom = atom->bond_per_atom;
bond_negative = new int[bond_per_atom];
}
// flip any negative types to positive and flag which ones
any_bond_negative = 0;
for (int m = 0; m < num_bond[ilocal]; m++) {
if (bond_type[ilocal][m] < 0) {
bond_negative[m] = 1;
bond_type[ilocal][m] = -bond_type[ilocal][m];
any_bond_negative = 1;
} else
bond_negative[m] = 0;
}
}
/* ----------------------------------------------------------------------
unmodify values packed by AtomVec::pack_restart()
------------------------------------------------------------------------- */
void AtomVecBPMSphere::pack_restart_post(int ilocal)
{
// restore the flagged types to their negative values
if (any_bond_negative) {
for (int m = 0; m < num_bond[ilocal]; m++)
if (bond_negative[m]) bond_type[ilocal][m] = -bond_type[ilocal][m];
}
}
/* ----------------------------------------------------------------------
initialize other atom quantities after AtomVec::unpack_restart()
------------------------------------------------------------------------- */
void AtomVecBPMSphere::unpack_restart_init(int ilocal)
{
nspecial[ilocal][0] = 0;
nspecial[ilocal][1] = 0;
nspecial[ilocal][2] = 0;
}
/* ----------------------------------------------------------------------
modify what AtomVec::data_atom() just unpacked
or initialize other atom quantities
------------------------------------------------------------------------- */
void AtomVecBPMSphere::data_atom_post(int ilocal)
{
radius_one = 0.5 * atom->radius[ilocal];
radius[ilocal] = radius_one;
if (radius_one > 0.0) rmass[ilocal] *= 4.0 * MY_PI / 3.0 * radius_one * radius_one * radius_one;
if (rmass[ilocal] <= 0.0) error->one(FLERR, "Invalid density in Atoms section of data file");
omega[ilocal][0] = 0.0;
omega[ilocal][1] = 0.0;
omega[ilocal][2] = 0.0;
quat[ilocal][0] = 1.0;
quat[ilocal][1] = 0.0;
quat[ilocal][2] = 0.0;
quat[ilocal][3] = 0.0;
num_bond[ilocal] = 0;
nspecial[ilocal][0] = 0;
nspecial[ilocal][1] = 0;
nspecial[ilocal][2] = 0;
}
/* ----------------------------------------------------------------------
modify values for AtomVec::pack_data() to pack
------------------------------------------------------------------------- */
void AtomVecBPMSphere::pack_data_pre(int ilocal)
{
radius_one = radius[ilocal];
rmass_one = rmass[ilocal];
radius[ilocal] *= 2.0;
if (radius_one != 0.0)
rmass[ilocal] = rmass_one / (4.0 * MY_PI / 3.0 * radius_one * radius_one * radius_one);
}
/* ----------------------------------------------------------------------
unmodify values packed by AtomVec::pack_data()
------------------------------------------------------------------------- */
void AtomVecBPMSphere::pack_data_post(int ilocal)
{
radius[ilocal] = radius_one;
rmass[ilocal] = rmass_one;
}

View File

@ -0,0 +1,82 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef ATOM_CLASS
// clang-format off
AtomStyle(bpm/sphere,AtomVecBPMSphere);
// clang-format on
#else
#ifndef LMP_ATOM_VEC_BPM_SPHERE_H
#define LMP_ATOM_VEC_BPM_SPHERE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecBPMSphere : public AtomVec {
public:
AtomVecBPMSphere(class LAMMPS *);
void process_args(int, char **) override;
void init() override;
void grow_pointers() override;
void create_atom_post(int) override;
void pack_restart_pre(int) override;
void pack_restart_post(int) override;
void unpack_restart_init(int) override;
void data_atom_post(int) override;
void pack_data_pre(int) override;
void pack_data_post(int) override;
private:
int *num_bond;
int **bond_type;
int **nspecial;
double *radius, *rmass;
double **omega, **torque, **quat;
int any_bond_negative;
int bond_per_atom;
int *bond_negative;
int radvary;
double radius_one, rmass_one;
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
E: Invalid radius in Atoms section of data file
Radius must be >= 0.0.
E: Invalid density in Atoms section of data file
Density value cannot be <= 0.0.
*/

415
src/BPM/bond_bpm.cpp Normal file
View File

@ -0,0 +1,415 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "bond_bpm.h"
#include "atom.h"
#include "domain.h"
#include "error.h"
#include "fix_bond_history.h"
#include "fix_store_local.h"
#include "fix_update_special_bonds.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "update.h"
#include <vector>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondBPM::BondBPM(LAMMPS *_lmp) :
Bond(_lmp), id_fix_dummy(nullptr), id_fix_dummy2(nullptr), id_fix_update(nullptr),
id_fix_bond_history(nullptr), id_fix_store_local(nullptr), id_fix_prop_atom(nullptr),
fix_store_local(nullptr), fix_bond_history(nullptr), fix_update_special_bonds(nullptr),
pack_choice(nullptr), output_data(nullptr)
{
overlay_flag = 0;
prop_atom_flag = 0;
nvalues = 0;
r0_max_estimate = 0.0;
max_stretch = 1.0;
// create dummy fix as placeholder for FixUpdateSpecialBonds & BondHistory
// this is so final order of Modify:fix will conform to input script
// BondHistory technically only needs this if updateflag = 1
id_fix_dummy = utils::strdup("BPM_DUMMY");
modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy));
id_fix_dummy2 = utils::strdup("BPM_DUMMY2");
modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy2));
}
/* ---------------------------------------------------------------------- */
BondBPM::~BondBPM()
{
delete[] pack_choice;
if (id_fix_dummy) modify->delete_fix(id_fix_dummy);
if (id_fix_dummy2) modify->delete_fix(id_fix_dummy2);
if (id_fix_update) modify->delete_fix(id_fix_update);
if (id_fix_bond_history) modify->delete_fix(id_fix_bond_history);
if (id_fix_store_local) modify->delete_fix(id_fix_store_local);
if (id_fix_prop_atom) modify->delete_fix(id_fix_prop_atom);
delete[] id_fix_dummy;
delete[] id_fix_dummy2;
delete[] id_fix_update;
delete[] id_fix_bond_history;
delete[] id_fix_store_local;
delete[] id_fix_prop_atom;
memory->destroy(output_data);
}
/* ---------------------------------------------------------------------- */
void BondBPM::init_style()
{
if (id_fix_store_local) {
auto ifix = modify->get_fix_by_id(id_fix_store_local);
if (!ifix) error->all(FLERR, "Cannot find fix store/local");
if (strcmp(ifix->style, "STORE_LOCAL") != 0)
error->all(FLERR, "Incorrect fix style matched, not store/local");
fix_store_local = dynamic_cast<FixStoreLocal *>(ifix);
fix_store_local->nvalues = nvalues;
}
if (overlay_flag) {
if (force->special_lj[1] != 1.0)
error->all(FLERR,
"With overlay/pair, BPM bond styles require special_bonds weight of 1.0 for "
"first neighbors");
if (id_fix_update) {
modify->delete_fix(id_fix_update);
delete[] id_fix_update;
id_fix_update = nullptr;
}
} else {
// Require atoms know about all of their bonds and if they break
if (force->newton_bond)
error->all(FLERR, "Without overlay/pair, BPM bond styles require Newton bond off");
// special lj must be 0 1 1 to censor pair forces between bonded particles
// special coulomb must be 1 1 1 to ensure all pairs are included in the
// neighbor list and 1-3 and 1-4 special bond lists are skipped
if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0)
error->all(FLERR,
"Without overlay/pair, BPM bond sytles requires special LJ weights = 0,1,1");
if (force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 ||
force->special_coul[3] != 1.0)
error->all(FLERR,
"Without overlay/pair, BPM bond sytles requires special Coulomb weights = 1,1,1");
if (id_fix_dummy) {
id_fix_update = utils::strdup("BPM_UPDATE_SPECIAL_BONDS");
fix_update_special_bonds = dynamic_cast<FixUpdateSpecialBonds *>(modify->replace_fix(
id_fix_dummy, fmt::format("{} all UPDATE_SPECIAL_BONDS", id_fix_update), 1));
delete[] id_fix_dummy;
id_fix_dummy = nullptr;
}
}
if (force->angle || force->dihedral || force->improper)
error->all(FLERR, "Bond style bpm cannot be used with 3,4-body interactions");
if (atom->molecular == 2)
error->all(FLERR, "Bond style bpm cannot be used with atom style template");
// special 1-3 and 1-4 weights must be 1 to prevent building 1-3 and 1-4 special bond lists
if (force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0 || force->special_coul[2] != 1.0 ||
force->special_coul[3] != 1.0)
error->all(FLERR, "Bond style bpm requires 1-3 and 1-4 special weights of 1.0");
}
/* ----------------------------------------------------------------------
global settings
All args before store/local command are saved for potential args
for specific bond BPM substyles
All args after optional store/local command are variables stored
in the compute store/local
------------------------------------------------------------------------- */
void BondBPM::settings(int narg, char **arg)
{
leftover_iarg.clear();
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg], "store/local") == 0) {
nvalues = 0;
id_fix_store_local = utils::strdup(arg[iarg + 1]);
store_local_freq = utils::inumeric(FLERR, arg[iarg + 2], false, lmp);
pack_choice = new FnPtrPack[narg - iarg - 1];
iarg += 3;
while (iarg < narg) {
if (strcmp(arg[iarg], "id1") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_id1;
} else if (strcmp(arg[iarg], "id2") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_id2;
} else if (strcmp(arg[iarg], "time") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_time;
} else if (strcmp(arg[iarg], "x") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_x;
} else if (strcmp(arg[iarg], "y") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_y;
} else if (strcmp(arg[iarg], "z") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_z;
} else if (strcmp(arg[iarg], "x/ref") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_x_ref;
prop_atom_flag = 1;
} else if (strcmp(arg[iarg], "y/ref") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_y_ref;
prop_atom_flag = 1;
} else if (strcmp(arg[iarg], "z/ref") == 0) {
pack_choice[nvalues++] = &BondBPM::pack_z_ref;
prop_atom_flag = 1;
} else {
break;
}
iarg++;
}
} else if (strcmp(arg[iarg], "overlay/pair") == 0) {
overlay_flag = 1;
iarg++;
} else {
leftover_iarg.push_back(iarg);
iarg++;
}
}
if (id_fix_store_local) {
if (nvalues == 0)
error->all(FLERR, "Storing local data must include at least one value to output");
memory->create(output_data, nvalues, "bond/bpm:output_data");
auto ifix = modify->get_fix_by_id(id_fix_store_local);
if (!ifix)
ifix = modify->add_fix(
fmt::format("{} all STORE_LOCAL {} {}", id_fix_store_local, store_local_freq, nvalues));
fix_store_local = dynamic_cast<FixStoreLocal *>(ifix);
// Use property/atom to save reference positions as it can transfer to ghost atoms
// This won't work for instances where bonds are added (e.g. fix pour) but in those cases
// a reference state isn't well defined
if (prop_atom_flag == 1) {
id_fix_prop_atom = utils::strdup("BPM_property_atom");
char *x_ref_id = utils::strdup("BPM_X_REF");
char *y_ref_id = utils::strdup("BPM_Y_REF");
char *z_ref_id = utils::strdup("BPM_Z_REF");
ifix = modify->get_fix_by_id(id_fix_prop_atom);
if (!ifix)
ifix = modify->add_fix(fmt::format("{} all property/atom {} {} {} ghost yes",
id_fix_prop_atom, x_ref_id, y_ref_id, z_ref_id));
int type_flag;
int col_flag;
index_x_ref = atom->find_custom(x_ref_id, type_flag, col_flag);
index_y_ref = atom->find_custom(y_ref_id, type_flag, col_flag);
index_z_ref = atom->find_custom(z_ref_id, type_flag, col_flag);
delete[] x_ref_id;
delete[] y_ref_id;
delete[] z_ref_id;
if (ifix->restart_reset) {
ifix->restart_reset = 0;
} else {
double *x_ref = atom->dvector[index_x_ref];
double *y_ref = atom->dvector[index_y_ref];
double *z_ref = atom->dvector[index_z_ref];
double **x = atom->x;
for (int i = 0; i < atom->nlocal; i++) {
x_ref[i] = x[i][0];
y_ref[i] = x[i][1];
z_ref[i] = x[i][2];
}
}
}
}
}
/* ----------------------------------------------------------------------
used to check bond communiction cutoff - not perfect, estimates based on local-local only
------------------------------------------------------------------------- */
double BondBPM::equilibrium_distance(int /*i*/)
{
// Ghost atoms may not yet be communicated, this may only be an estimate
if (r0_max_estimate == 0) {
int type, j;
double delx, dely, delz, r;
double **x = atom->x;
for (int i = 0; i < atom->nlocal; i++) {
for (int m = 0; m < atom->num_bond[i]; m++) {
type = atom->bond_type[i][m];
if (type == 0) continue;
j = atom->map(atom->bond_atom[i][m]);
if (j == -1) continue;
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
domain->minimum_image(delx, dely, delz);
r = sqrt(delx * delx + dely * dely + delz * delz);
if (r > r0_max_estimate) r0_max_estimate = r;
}
}
double temp;
MPI_Allreduce(&r0_max_estimate, &temp, 1, MPI_DOUBLE, MPI_MAX, world);
r0_max_estimate = temp;
}
// Divide out heuristic prefactor added in comm class
return max_stretch * r0_max_estimate / 1.5;
}
/* ---------------------------------------------------------------------- */
void BondBPM::process_broken(int i, int j)
{
if (fix_store_local) {
for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n, i, j);
fix_store_local->add_data(output_data, i, j);
}
if (fix_update_special_bonds) fix_update_special_bonds->add_broken_bond(i, j);
// Manually search and remove from atom arrays
// need to remove in case special bonds arrays rebuilt
int m, n;
int nlocal = atom->nlocal;
tagint *tag = atom->tag;
tagint **bond_atom = atom->bond_atom;
int **bond_type = atom->bond_type;
int *num_bond = atom->num_bond;
if (i < nlocal) {
for (m = 0; m < num_bond[i]; m++) {
if (bond_atom[i][m] == tag[j]) {
bond_type[i][m] = 0;
n = num_bond[i];
bond_type[i][m] = bond_type[i][n - 1];
bond_atom[i][m] = bond_atom[i][n - 1];
fix_bond_history->shift_history(i, m, n - 1);
fix_bond_history->delete_history(i, n - 1);
num_bond[i]--;
break;
}
}
}
if (j < nlocal) {
for (m = 0; m < num_bond[j]; m++) {
if (bond_atom[j][m] == tag[i]) {
bond_type[j][m] = 0;
n = num_bond[j];
bond_type[j][m] = bond_type[j][n - 1];
bond_atom[j][m] = bond_atom[j][n - 1];
fix_bond_history->shift_history(j, m, n - 1);
fix_bond_history->delete_history(j, n - 1);
num_bond[j]--;
break;
}
}
}
}
/* ----------------------------------------------------------------------
one method for every keyword bond bpm can output
the atom property is packed into array or vector
------------------------------------------------------------------------- */
void BondBPM::pack_id1(int n, int i, int /*j*/)
{
tagint *tag = atom->tag;
output_data[n] = tag[i];
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_id2(int n, int /*i*/, int j)
{
tagint *tag = atom->tag;
output_data[n] = tag[j];
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_time(int n, int /*i*/, int /*j*/)
{
bigint time = update->ntimestep;
output_data[n] = time;
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_x(int n, int i, int j)
{
double **x = atom->x;
output_data[n] = (x[i][0] + x[j][0]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_y(int n, int i, int j)
{
double **x = atom->x;
output_data[n] = (x[i][1] + x[j][1]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_z(int n, int i, int j)
{
double **x = atom->x;
output_data[n] = (x[i][2] + x[j][2]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_x_ref(int n, int i, int j)
{
double *x = atom->dvector[index_x_ref];
output_data[n] = (x[i] + x[j]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_y_ref(int n, int i, int j)
{
double *y = atom->dvector[index_y_ref];
output_data[n] = (y[i] + y[j]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void BondBPM::pack_z_ref(int n, int i, int j)
{
double *z = atom->dvector[index_z_ref];
output_data[n] = (z[i] + z[j]) * 0.5;
}

98
src/BPM/bond_bpm.h Normal file
View File

@ -0,0 +1,98 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_BOND_BPM_H
#define LMP_BOND_BPM_H
#include "bond.h"
#include <vector>
namespace LAMMPS_NS {
class BondBPM : public Bond {
public:
BondBPM(class LAMMPS *);
~BondBPM() override;
void compute(int, int) override = 0;
void coeff(int, char **) override = 0;
void init_style() override;
void settings(int, char **) override;
double equilibrium_distance(int) override;
void write_restart(FILE *) override{};
void read_restart(FILE *) override{};
void write_data(FILE *) override{};
double single(int, double, int, int, double &) override = 0;
protected:
double r0_max_estimate;
double max_stretch;
int store_local_freq;
std::vector<int> leftover_iarg;
char *id_fix_dummy, *id_fix_dummy2;
char *id_fix_update, *id_fix_bond_history;
char *id_fix_store_local, *id_fix_prop_atom;
class FixStoreLocal *fix_store_local;
class FixBondHistory *fix_bond_history;
class FixUpdateSpecialBonds *fix_update_special_bonds;
void process_broken(int, int);
typedef void (BondBPM::*FnPtrPack)(int, int, int);
FnPtrPack *pack_choice; // ptrs to pack functions
double *output_data;
int prop_atom_flag, nvalues, overlay_flag;
int index_x_ref, index_y_ref, index_z_ref;
void pack_id1(int, int, int);
void pack_id2(int, int, int);
void pack_time(int, int, int);
void pack_x(int, int, int);
void pack_y(int, int, int);
void pack_z(int, int, int);
void pack_x_ref(int, int, int);
void pack_y_ref(int, int, int);
void pack_z_ref(int, int, int);
};
} // namespace LAMMPS_NS
#endif
/* ERROR/WARNING messages:
E: Cannot find fix store/local
Fix id cannot be found.
E: Illegal bond_style command
Self-explanatory.
E: Bond style bpm must include at least one value to output
Must include at least one bond property to store in fix store/local
E: Bond style bpm cannot be used with 3,4-body interactions
No angle, dihedral, or improper styles can be defined when using
bond style bpm.
E: Bond style bpm cannot be used with atom style template
This bond style can change the bond topology which is not
allowed with this atom style.
*/

View File

@ -0,0 +1,796 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "bond_bpm_rotational.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "fix_bond_history.h"
#include "force.h"
#include "math_const.h"
#include "math_extra.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include <cmath>
#define EPSILON 1e-10
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondBPMRotational::BondBPMRotational(LAMMPS *_lmp) : BondBPM(_lmp)
{
Kr = nullptr;
Ks = nullptr;
Kt = nullptr;
Kb = nullptr;
Fcr = nullptr;
Fcs = nullptr;
Tct = nullptr;
Tcb = nullptr;
gnorm = nullptr;
gslide = nullptr;
groll = nullptr;
gtwist = nullptr;
partial_flag = 1;
smooth_flag = 1;
}
/* ---------------------------------------------------------------------- */
BondBPMRotational::~BondBPMRotational()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(Kr);
memory->destroy(Ks);
memory->destroy(Kt);
memory->destroy(Kb);
memory->destroy(Fcr);
memory->destroy(Fcs);
memory->destroy(Tct);
memory->destroy(Tcb);
memory->destroy(gnorm);
memory->destroy(gslide);
memory->destroy(groll);
memory->destroy(gtwist);
}
}
/* ---------------------------------------------------------------------- */
double BondBPMRotational::acos_limit(double c)
{
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
return acos(c);
}
/* ----------------------------------------------------------------------
Store data for a single bond - if bond added after LAMMPS init (e.g. pour)
------------------------------------------------------------------------- */
double BondBPMRotational::store_bond(int n, int i, int j)
{
double delx, dely, delz, r, rinv;
double **x = atom->x;
tagint *tag = atom->tag;
double **bondstore = fix_bond_history->bondstore;
if (tag[i] < tag[j]) {
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
} else {
delx = x[j][0] - x[i][0];
dely = x[j][1] - x[i][1];
delz = x[j][2] - x[i][2];
}
r = sqrt(delx * delx + dely * dely + delz * delz);
rinv = 1.0 / r;
bondstore[n][0] = r;
bondstore[n][1] = delx * rinv;
bondstore[n][2] = dely * rinv;
bondstore[n][3] = delz * rinv;
if (i < atom->nlocal) {
for (int m = 0; m < atom->num_bond[i]; m++) {
if (atom->bond_atom[i][m] == tag[j]) {
fix_bond_history->update_atom_value(i, m, 0, r);
fix_bond_history->update_atom_value(i, m, 1, delx * rinv);
fix_bond_history->update_atom_value(i, m, 2, dely * rinv);
fix_bond_history->update_atom_value(i, m, 3, delz * rinv);
}
}
}
if (j < atom->nlocal) {
for (int m = 0; m < atom->num_bond[j]; m++) {
if (atom->bond_atom[j][m] == tag[i]) {
fix_bond_history->update_atom_value(j, m, 0, r);
fix_bond_history->update_atom_value(j, m, 1, delx * rinv);
fix_bond_history->update_atom_value(j, m, 2, dely * rinv);
fix_bond_history->update_atom_value(j, m, 3, delz * rinv);
}
}
}
return r;
}
/* ----------------------------------------------------------------------
Store data for all bonds called once
------------------------------------------------------------------------- */
void BondBPMRotational::store_data()
{
int i, j, m, type;
double delx, dely, delz, r, rinv;
double **x = atom->x;
int **bond_type = atom->bond_type;
tagint *tag = atom->tag;
for (i = 0; i < atom->nlocal; i++) {
for (m = 0; m < atom->num_bond[i]; m++) {
type = bond_type[i][m];
//Skip if bond was turned off
if (type < 0) continue;
// map to find index n for tag
j = atom->map(atom->bond_atom[i][m]);
if (j == -1) error->one(FLERR, "Atom missing in BPM bond");
// Save orientation as pointing towards small tag
if (tag[i] < tag[j]) {
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
} else {
delx = x[j][0] - x[i][0];
dely = x[j][1] - x[i][1];
delz = x[j][2] - x[i][2];
}
// Get closest image in case bonded with ghost
domain->minimum_image(delx, dely, delz);
r = sqrt(delx * delx + dely * dely + delz * delz);
rinv = 1.0 / r;
fix_bond_history->update_atom_value(i, m, 0, r);
fix_bond_history->update_atom_value(i, m, 1, delx * rinv);
fix_bond_history->update_atom_value(i, m, 2, dely * rinv);
fix_bond_history->update_atom_value(i, m, 3, delz * rinv);
}
}
fix_bond_history->post_neighbor();
}
/* ----------------------------------------------------------------------
Calculate forces using formulation in:
1) Y. Wang Acta Geotechnica 2009
2) P. Mora & Y. Wang Advances in Geomcomputing 2009
---------------------------------------------------------------------- */
double BondBPMRotational::elastic_forces(int i1, int i2, int type, double &Fr, double r_mag,
double r0_mag, double r_mag_inv, double * /*rhat*/,
double *r, double *r0, double *force1on2,
double *torque1on2, double *torque2on1)
{
double breaking, temp, r0_dot_rb, c, gamma;
double psi, theta, cos_phi, sin_phi;
double mag_in_plane, mag_out_plane;
double Fs_mag, Tt_mag, Tb_mag;
double q1[4], q2[4];
double q2inv[4], mq[4], mqinv[4], qp21[4], q21[4], qtmp[4];
double rb[3], rb_x_r0[3], s[3], t[3];
double Fs[3], Fsp[3], F_rot[3], Ftmp[3];
double Ts[3], Tb[3], Tt[3], Tbp[3], Ttp[3], Tsp[3], T_rot[3], Ttmp[3];
double **quat = atom->quat;
q1[0] = quat[i1][0];
q1[1] = quat[i1][1];
q1[2] = quat[i1][2];
q1[3] = quat[i1][3];
q2[0] = quat[i2][0];
q2[1] = quat[i2][1];
q2[2] = quat[i2][2];
q2[3] = quat[i2][3];
// Calculate normal forces, rb = bond vector in particle 1's frame
MathExtra::qconjugate(q2, q2inv);
MathExtra::quatrotvec(q2inv, r, rb);
Fr = Kr[type] * (r_mag - r0_mag);
MathExtra::scale3(Fr * r_mag_inv, rb, F_rot);
// Calculate forces due to tangential displacements (no rotation)
r0_dot_rb = MathExtra::dot3(r0, rb);
c = r0_dot_rb * r_mag_inv / r0_mag;
gamma = acos_limit(c);
MathExtra::cross3(rb, r0, rb_x_r0);
MathExtra::cross3(rb, rb_x_r0, s);
MathExtra::norm3(s);
MathExtra::scale3(Ks[type] * r_mag * gamma, s, Fs);
// Calculate torque due to tangential displacements
MathExtra::cross3(r0, rb, t);
MathExtra::norm3(t);
MathExtra::scale3(0.5 * r_mag * Ks[type] * r_mag * gamma, t, Ts);
// Relative rotation force/torque
// Use representation of X'Y'Z' rotations from Wang, Mora 2009
temp = r_mag + rb[2];
if (temp < 0.0) temp = 0.0;
mq[0] = sqrt(2) * 0.5 * sqrt(temp * r_mag_inv);
temp = sqrt(rb[0] * rb[0] + rb[1] * rb[1]);
if (temp != 0.0) {
mq[1] = -sqrt(2) * 0.5 / temp;
temp = r_mag - rb[2];
if (temp < 0.0) temp = 0.0;
mq[1] *= sqrt(temp * r_mag_inv);
mq[2] = -mq[1];
mq[1] *= rb[1];
mq[2] *= rb[0];
} else {
// If aligned along z axis, x,y terms zero (r_mag-rb[2] = 0)
mq[1] = 0.0;
mq[2] = 0.0;
}
mq[3] = 0.0;
// qp21 = opposite of r^\circ_21 in Wang
// q21 = opposite of r_21 in Wang
MathExtra::quatquat(q2inv, q1, qp21);
MathExtra::qconjugate(mq, mqinv);
MathExtra::quatquat(mqinv, qp21, qtmp);
MathExtra::quatquat(qtmp, mq, q21);
temp = sqrt(q21[0] * q21[0] + q21[3] * q21[3]);
if (temp != 0.0) {
c = q21[0] / temp;
psi = 2.0 * acos_limit(c);
} else {
c = 0.0;
psi = 0.0;
}
// Map negative rotations
if (q21[3] < 0.0) // sin = q21[3]/temp
psi = -psi;
if (q21[3] == 0.0) psi = 0.0;
c = q21[0] * q21[0] - q21[1] * q21[1] - q21[2] * q21[2] + q21[3] * q21[3];
theta = acos_limit(c);
// Separately calculte magnitude of quaternion in x-y and out of x-y planes
// to avoid dividing by zero
mag_out_plane = (q21[0] * q21[0] + q21[3] * q21[3]);
mag_in_plane = (q21[1] * q21[1] + q21[2] * q21[2]);
if (mag_in_plane == 0.0) {
// No rotation => no bending/shear torque or extra shear force
// achieve by setting cos/sin = 0
cos_phi = 0.0;
sin_phi = 0.0;
} else if (mag_out_plane == 0.0) {
// Calculate angle in plane
cos_phi = q21[2] / sqrt(mag_in_plane);
sin_phi = -q21[1] / sqrt(mag_in_plane);
} else {
// Default equations in Mora, Wang 2009
cos_phi = q21[1] * q21[3] + q21[0] * q21[2];
sin_phi = q21[2] * q21[3] - q21[0] * q21[1];
cos_phi /= sqrt(mag_out_plane * mag_in_plane);
sin_phi /= sqrt(mag_out_plane * mag_in_plane);
}
Tbp[0] = -Kb[type] * theta * sin_phi;
Tbp[1] = Kb[type] * theta * cos_phi;
Tbp[2] = 0.0;
Ttp[0] = 0.0;
Ttp[1] = 0.0;
Ttp[2] = Kt[type] * psi;
Fsp[0] = -0.5 * Ks[type] * r_mag * theta * cos_phi;
Fsp[1] = -0.5 * Ks[type] * r_mag * theta * sin_phi;
Fsp[2] = 0.0;
Tsp[0] = 0.25 * Ks[type] * r_mag * r_mag * theta * sin_phi;
Tsp[1] = -0.25 * Ks[type] * r_mag * r_mag * theta * cos_phi;
Tsp[2] = 0.0;
// Rotate forces/torques back to 1st particle's frame
MathExtra::quatrotvec(mq, Fsp, Ftmp);
MathExtra::quatrotvec(mq, Tsp, Ttmp);
for (int m = 0; m < 3; m++) {
Fs[m] += Ftmp[m];
Ts[m] += Ttmp[m];
}
MathExtra::quatrotvec(mq, Tbp, Tb);
MathExtra::quatrotvec(mq, Ttp, Tt);
// Sum forces and calculate magnitudes
F_rot[0] += Fs[0];
F_rot[1] += Fs[1];
F_rot[2] += Fs[2];
MathExtra::quatrotvec(q2, F_rot, force1on2);
T_rot[0] = Ts[0] + Tt[0] + Tb[0];
T_rot[1] = Ts[1] + Tt[1] + Tb[1];
T_rot[2] = Ts[2] + Tt[2] + Tb[2];
MathExtra::quatrotvec(q2, T_rot, torque1on2);
T_rot[0] = Ts[0] - Tt[0] - Tb[0];
T_rot[1] = Ts[1] - Tt[1] - Tb[1];
T_rot[2] = Ts[2] - Tt[2] - Tb[2];
MathExtra::quatrotvec(q2, T_rot, torque2on1);
Fs_mag = MathExtra::len3(Fs);
Tt_mag = MathExtra::len3(Tt);
Tb_mag = MathExtra::len3(Tb);
breaking = Fr / Fcr[type] + Fs_mag / Fcs[type] + Tb_mag / Tcb[type] + Tt_mag / Tct[type];
if (breaking < 0.0) breaking = 0.0;
return breaking;
}
/* ----------------------------------------------------------------------
Calculate damping using formulation in
Y. Wang, F. Alonso-Marroquin, W. Guo 2015
Note: n points towards 1 vs pointing towards 2
---------------------------------------------------------------------- */
void BondBPMRotational::damping_forces(int i1, int i2, int type, double &Fr, double *rhat,
double *r, double *force1on2, double *torque1on2,
double *torque2on1)
{
double v1dotr, v2dotr, w1dotr, w2dotr;
double s1[3], s2[3], tdamp[3], tmp[3];
double vn1[3], vn2[3], vt1[3], vt2[3], vroll[3];
double wxn1[3], wxn2[3], wn1[3], wn2[3];
double **v = atom->v;
double **omega = atom->omega;
// Damp normal velocity difference
v1dotr = MathExtra::dot3(v[i1], rhat);
v2dotr = MathExtra::dot3(v[i2], rhat);
MathExtra::scale3(v1dotr, rhat, vn1);
MathExtra::scale3(v2dotr, rhat, vn2);
MathExtra::sub3(vn1, vn2, tmp);
MathExtra::scale3(gnorm[type], tmp);
Fr = MathExtra::lensq3(tmp);
MathExtra::add3(force1on2, tmp, force1on2);
// Damp tangential objective velocities
MathExtra::sub3(v[i1], vn1, vt1);
MathExtra::sub3(v[i2], vn2, vt2);
MathExtra::sub3(vt2, vt1, tmp);
MathExtra::scale3(0.5, tmp);
MathExtra::cross3(omega[i1], r, s1);
MathExtra::scale3(-0.5, s1);
MathExtra::sub3(s1, tmp, s1); // Eq 12
MathExtra::cross3(omega[i2], r, s2);
MathExtra::scale3(0.5, s2);
MathExtra::add3(s2, tmp, s2); // Eq 13
MathExtra::sub3(s1, s2, tmp);
MathExtra::scale3(gslide[type], tmp);
MathExtra::add3(force1on2, tmp, force1on2);
// Apply corresponding torque
MathExtra::cross3(r, tmp, tdamp);
MathExtra::scale3(0.5, tdamp);
MathExtra::add3(torque1on2, tdamp, torque1on2);
MathExtra::add3(torque2on1, tdamp, torque2on1);
// Damp rolling
MathExtra::cross3(omega[i1], rhat, wxn1);
MathExtra::cross3(omega[i2], rhat, wxn2);
MathExtra::sub3(wxn1, wxn2, vroll); // Eq. 31
MathExtra::cross3(r, vroll, tdamp);
MathExtra::scale3(0.5 * groll[type], tdamp);
MathExtra::add3(torque1on2, tdamp, torque1on2);
MathExtra::scale3(-1.0, tdamp);
MathExtra::add3(torque2on1, tdamp, torque2on1);
// Damp twist
w1dotr = MathExtra::dot3(omega[i1], rhat);
w2dotr = MathExtra::dot3(omega[i2], rhat);
MathExtra::scale3(w1dotr, rhat, wn1);
MathExtra::scale3(w2dotr, rhat, wn2);
MathExtra::sub3(wn1, wn2, tdamp); // Eq. 38
MathExtra::scale3(0.5 * gtwist[type], tdamp);
MathExtra::add3(torque1on2, tdamp, torque1on2);
MathExtra::scale3(-1.0, tdamp);
MathExtra::add3(torque2on1, tdamp, torque2on1);
}
/* ---------------------------------------------------------------------- */
void BondBPMRotational::compute(int eflag, int vflag)
{
if (!fix_bond_history->stored_flag) {
fix_bond_history->stored_flag = true;
store_data();
}
int i1, i2, itmp, n, type;
double r[3], r0[3], rhat[3];
double rsq, r0_mag, r_mag, r_mag_inv;
double Fr, breaking, smooth;
double force1on2[3], torque1on2[3], torque2on1[3];
ev_init(eflag, vflag);
double **x = atom->x;
double **f = atom->f;
double **torque = atom->torque;
tagint *tag = atom->tag;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
double **bondstore = fix_bond_history->bondstore;
for (n = 0; n < nbondlist; n++) {
// skip bond if already broken
if (bondlist[n][2] <= 0) continue;
i1 = bondlist[n][0];
i2 = bondlist[n][1];
type = bondlist[n][2];
r0_mag = bondstore[n][0];
// Ensure pair is always ordered such that r0 points in
// a consistent direction and to ensure numerical operations
// are identical to minimize the possibility that a bond straddling
// an mpi grid (newton off) doesn't break on one proc but not the other
if (tag[i2] < tag[i1]) {
itmp = i1;
i1 = i2;
i2 = itmp;
}
// If bond hasn't been set - should be initialized to zero
if (r0_mag < EPSILON || std::isnan(r0_mag)) r0_mag = store_bond(n, i1, i2);
r0[0] = bondstore[n][1];
r0[1] = bondstore[n][2];
r0[2] = bondstore[n][3];
MathExtra::scale3(r0_mag, r0);
// Note this is the reverse of Mora & Wang
MathExtra::sub3(x[i1], x[i2], r);
rsq = MathExtra::lensq3(r);
r_mag = sqrt(rsq);
r_mag_inv = 1.0 / r_mag;
MathExtra::scale3(r_mag_inv, r, rhat);
// ------------------------------------------------------//
// Calculate forces, check if bond breaks
// ------------------------------------------------------//
breaking = elastic_forces(i1, i2, type, Fr, r_mag, r0_mag, r_mag_inv, rhat, r, r0, force1on2,
torque1on2, torque2on1);
if (breaking >= 1.0) {
bondlist[n][2] = 0;
process_broken(i1, i2);
continue;
}
damping_forces(i1, i2, type, Fr, rhat, r, force1on2, torque1on2, torque2on1);
if (smooth_flag) {
smooth = breaking * breaking;
smooth = 1.0 - smooth * smooth;
} else {
smooth = 1.0;
}
// ------------------------------------------------------//
// Apply forces and torques to particles
// ------------------------------------------------------//
if (newton_bond || i1 < nlocal) {
f[i1][0] -= force1on2[0] * smooth;
f[i1][1] -= force1on2[1] * smooth;
f[i1][2] -= force1on2[2] * smooth;
torque[i1][0] += torque2on1[0] * smooth;
torque[i1][1] += torque2on1[1] * smooth;
torque[i1][2] += torque2on1[2] * smooth;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] += force1on2[0] * smooth;
f[i2][1] += force1on2[1] * smooth;
f[i2][2] += force1on2[2] * smooth;
torque[i2][0] += torque1on2[0] * smooth;
torque[i2][1] += torque1on2[1] * smooth;
torque[i2][2] += torque1on2[2] * smooth;
}
if (evflag) ev_tally(i1, i2, nlocal, newton_bond, 0.0, Fr * smooth, r[0], r[1], r[2]);
}
}
/* ---------------------------------------------------------------------- */
void BondBPMRotational::allocate()
{
allocated = 1;
const int np1 = atom->nbondtypes + 1;
memory->create(Kr, np1, "bond:Kr");
memory->create(Ks, np1, "bond:Ks");
memory->create(Kt, np1, "bond:Kt");
memory->create(Kb, np1, "bond:Kb");
memory->create(Fcr, np1, "bond:Fcr");
memory->create(Fcs, np1, "bond:Fcs");
memory->create(Tct, np1, "bond:Tct");
memory->create(Tcb, np1, "bond:Tcb");
memory->create(gnorm, np1, "bond:gnorm");
memory->create(gslide, np1, "bond:gslide");
memory->create(groll, np1, "bond:groll");
memory->create(gtwist, np1, "bond:gtwist");
memory->create(setflag, np1, "bond:setflag");
for (int i = 1; i < np1; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondBPMRotational::coeff(int narg, char **arg)
{
if (narg != 13) error->all(FLERR, "Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo, ihi;
utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error);
double Kr_one = utils::numeric(FLERR, arg[1], false, lmp);
double Ks_one = utils::numeric(FLERR, arg[2], false, lmp);
double Kt_one = utils::numeric(FLERR, arg[3], false, lmp);
double Kb_one = utils::numeric(FLERR, arg[4], false, lmp);
double Fcr_one = utils::numeric(FLERR, arg[5], false, lmp);
double Fcs_one = utils::numeric(FLERR, arg[6], false, lmp);
double Tct_one = utils::numeric(FLERR, arg[7], false, lmp);
double Tcb_one = utils::numeric(FLERR, arg[8], false, lmp);
double gnorm_one = utils::numeric(FLERR, arg[9], false, lmp);
double gslide_one = utils::numeric(FLERR, arg[10], false, lmp);
double groll_one = utils::numeric(FLERR, arg[11], false, lmp);
double gtwist_one = utils::numeric(FLERR, arg[12], false, lmp);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
Kr[i] = Kr_one;
Ks[i] = Ks_one;
Kt[i] = Kt_one;
Kb[i] = Kb_one;
Fcr[i] = Fcr_one;
Fcs[i] = Fcs_one;
Tct[i] = Tct_one;
Tcb[i] = Tcb_one;
gnorm[i] = gnorm_one;
gslide[i] = gslide_one;
groll[i] = groll_one;
gtwist[i] = gtwist_one;
setflag[i] = 1;
count++;
if (Fcr[i] / Kr[i] > max_stretch) max_stretch = Fcr[i] / Kr[i];
}
if (count == 0) error->all(FLERR, "Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
check for correct settings and create fix
------------------------------------------------------------------------- */
void BondBPMRotational::init_style()
{
BondBPM::init_style();
if (!atom->quat_flag || !atom->sphere_flag)
error->all(FLERR, "Bond bpm/rotational requires atom style bpm/sphere");
if (comm->ghost_velocity == 0)
error->all(FLERR, "Bond bpm/rotational requires ghost atoms store velocity");
if (domain->dimension == 2)
error->warning(FLERR, "Bond style bpm/rotational not intended for 2d use");
if (!id_fix_bond_history) {
id_fix_bond_history = utils::strdup("HISTORY_BPM_ROTATIONAL");
fix_bond_history = dynamic_cast<FixBondHistory *>(modify->replace_fix(
id_fix_dummy2, fmt::format("{} all BOND_HISTORY 0 4", id_fix_bond_history), 1));
delete[] id_fix_dummy2;
id_fix_dummy2 = nullptr;
}
}
/* ---------------------------------------------------------------------- */
void BondBPMRotational::settings(int narg, char **arg)
{
BondBPM::settings(narg, arg);
int iarg;
for (std::size_t i = 0; i < leftover_iarg.size(); i++) {
iarg = leftover_iarg[i];
if (strcmp(arg[iarg], "smooth") == 0) {
if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command");
smooth_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
i += 1;
} else {
error->all(FLERR, "Illegal bond_style command");
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondBPMRotational::write_restart(FILE *fp)
{
fwrite(&Kr[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Ks[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Kt[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Kb[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Fcr[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Fcs[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Tct[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&Tcb[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&gnorm[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&gslide[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&groll[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&gtwist[1], sizeof(double), atom->nbondtypes, fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondBPMRotational::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
utils::sfread(FLERR, &Kr[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Ks[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Kt[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Kb[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Fcr[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Fcs[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Tct[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &Tcb[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &gnorm[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &gslide[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &groll[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &gtwist[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
}
MPI_Bcast(&Kr[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Ks[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Kt[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Kb[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Fcr[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Fcs[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Tct[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&Tcb[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&gnorm[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&gslide[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&groll[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&gtwist[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
proc 0 writes to data file
------------------------------------------------------------------------- */
void BondBPMRotational::write_data(FILE *fp)
{
for (int i = 1; i <= atom->nbondtypes; i++)
fprintf(fp, "%d %g %g %g %g %g %g %g %g %g %g %g %g\n", i, Kr[i], Ks[i], Kt[i], Kb[i], Fcr[i],
Fcs[i], Tct[i], Tcb[i], gnorm[i], gslide[i], groll[i], gtwist[i]);
}
/* ---------------------------------------------------------------------- */
double BondBPMRotational::single(int type, double rsq, int i, int j, double &fforce)
{
// Not yet enabled
if (type <= 0) return 0.0;
int itmp;
if (atom->tag[j] < atom->tag[i]) {
itmp = i;
i = j;
j = itmp;
}
double r0_mag, r_mag, r_mag_inv;
double r0[3], r[3], rhat[3];
for (int n = 0; n < atom->num_bond[i]; n++) {
if (atom->bond_atom[i][n] == atom->tag[j]) {
r0_mag = fix_bond_history->get_atom_value(i, n, 0);
r0[0] = fix_bond_history->get_atom_value(i, n, 1);
r0[1] = fix_bond_history->get_atom_value(i, n, 2);
r0[2] = fix_bond_history->get_atom_value(i, n, 3);
}
}
double **x = atom->x;
MathExtra::scale3(r0_mag, r0);
MathExtra::sub3(x[i], x[j], r);
r_mag = sqrt(rsq);
r_mag_inv = 1.0 / r_mag;
MathExtra::scale3(r_mag_inv, r, rhat);
double breaking, smooth, Fr;
double force1on2[3], torque1on2[3], torque2on1[3];
breaking = elastic_forces(i, j, type, Fr, r_mag, r0_mag, r_mag_inv, rhat, r, r0, force1on2,
torque1on2, torque2on1);
fforce = Fr;
damping_forces(i, j, type, Fr, rhat, r, force1on2, torque1on2, torque2on1);
fforce += Fr;
if (smooth_flag) {
smooth = breaking * breaking;
smooth = 1.0 - smooth * smooth;
fforce *= smooth;
}
return 0.0;
}

View File

@ -0,0 +1,83 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef BOND_CLASS
// clang-format off
BondStyle(bpm/rotational,BondBPMRotational);
// clang-format on
#else
#ifndef LMP_BOND_BPM_ROTATIONAL_H
#define LMP_BOND_BPM_ROTATIONAL_H
#include "bond_bpm.h"
namespace LAMMPS_NS {
class BondBPMRotational : public BondBPM {
public:
BondBPMRotational(class LAMMPS *);
~BondBPMRotational() override;
void compute(int, int) override;
void coeff(int, char **) override;
void init_style() override;
void settings(int, char **) override;
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, double, int, int, double &) override;
protected:
double *Kr, *Ks, *Kt, *Kb, *gnorm, *gslide, *groll, *gtwist;
double *Fcr, *Fcs, *Tct, *Tcb;
int smooth_flag;
double acos_limit(double);
double elastic_forces(int, int, int, double &, double, double, double, double *, double *,
double *, double *, double *, double *);
void damping_forces(int, int, int, double &, double *, double *, double *, double *, double *);
void allocate();
void store_data();
double store_bond(int, int, int);
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Atom missing in BPM bond
Bonded atom cannot be found
E: Incorrect args for bond coefficients
Self-explanatory. Check the input script or data file.
E: Bond bpm/rotational requires atom style bpm/sphere
Self-explanatory.
E: Bond style bpm requires 1-3 and 1-4 special weights of 1.0
Self-explanatory.
W: Bond style bpm/rotational not intended for 2d use, may be inefficient
This bond style will perform a lot of unnecessary calculations in 2d
*/

380
src/BPM/bond_bpm_spring.cpp Normal file
View File

@ -0,0 +1,380 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "bond_bpm_spring.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "fix_bond_history.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#define EPSILON 1e-10
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondBPMSpring::BondBPMSpring(LAMMPS *_lmp) : BondBPM(_lmp), k(nullptr), ecrit(nullptr), gamma(nullptr)
{
partial_flag = 1;
smooth_flag = 1;
}
/* ---------------------------------------------------------------------- */
BondBPMSpring::~BondBPMSpring()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(ecrit);
memory->destroy(gamma);
}
}
/* ----------------------------------------------------------------------
Store data for a single bond - if bond added after LAMMPS init (e.g. pour)
------------------------------------------------------------------------- */
double BondBPMSpring::store_bond(int n, int i, int j)
{
double delx, dely, delz, r;
double **x = atom->x;
double **bondstore = fix_bond_history->bondstore;
tagint *tag = atom->tag;
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
r = sqrt(delx * delx + dely * dely + delz * delz);
bondstore[n][0] = r;
if (i < atom->nlocal) {
for (int m = 0; m < atom->num_bond[i]; m++) {
if (atom->bond_atom[i][m] == tag[j]) { fix_bond_history->update_atom_value(i, m, 0, r); }
}
}
if (j < atom->nlocal) {
for (int m = 0; m < atom->num_bond[j]; m++) {
if (atom->bond_atom[j][m] == tag[i]) { fix_bond_history->update_atom_value(j, m, 0, r); }
}
}
return r;
}
/* ----------------------------------------------------------------------
Store data for all bonds called once
------------------------------------------------------------------------- */
void BondBPMSpring::store_data()
{
int i, j, m, type;
double delx, dely, delz, r;
double **x = atom->x;
int **bond_type = atom->bond_type;
for (i = 0; i < atom->nlocal; i++) {
for (m = 0; m < atom->num_bond[i]; m++) {
type = bond_type[i][m];
//Skip if bond was turned off
if (type < 0) continue;
// map to find index n
j = atom->map(atom->bond_atom[i][m]);
if (j == -1) error->one(FLERR, "Atom missing in BPM bond");
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
// Get closest image in case bonded with ghost
domain->minimum_image(delx, dely, delz);
r = sqrt(delx * delx + dely * dely + delz * delz);
fix_bond_history->update_atom_value(i, m, 0, r);
}
}
fix_bond_history->post_neighbor();
}
/* ---------------------------------------------------------------------- */
void BondBPMSpring::compute(int eflag, int vflag)
{
if (!fix_bond_history->stored_flag) {
fix_bond_history->stored_flag = true;
store_data();
}
int i1, i2, itmp, n, type;
double delx, dely, delz, delvx, delvy, delvz;
double e, rsq, r, r0, rinv, smooth, fbond, dot;
ev_init(eflag, vflag);
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
tagint *tag = atom->tag;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
double **bondstore = fix_bond_history->bondstore;
for (n = 0; n < nbondlist; n++) {
// skip bond if already broken
if (bondlist[n][2] <= 0) continue;
i1 = bondlist[n][0];
i2 = bondlist[n][1];
type = bondlist[n][2];
r0 = bondstore[n][0];
// Ensure pair is always ordered to ensure numerical operations
// are identical to minimize the possibility that a bond straddling
// an mpi grid (newton off) doesn't break on one proc but not the other
if (tag[i2] < tag[i1]) {
itmp = i1;
i1 = i2;
i2 = itmp;
}
// If bond hasn't been set - should be initialized to zero
if (r0 < EPSILON || std::isnan(r0)) r0 = store_bond(n, i1, i2);
delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2];
rsq = delx * delx + dely * dely + delz * delz;
r = sqrt(rsq);
e = (r - r0) / r0;
if (fabs(e) > ecrit[type]) {
bondlist[n][2] = 0;
process_broken(i1, i2);
continue;
}
rinv = 1.0 / r;
fbond = k[type] * (r0 - r);
delvx = v[i1][0] - v[i2][0];
delvy = v[i1][1] - v[i2][1];
delvz = v[i1][2] - v[i2][2];
dot = delx * delvx + dely * delvy + delz * delvz;
fbond -= gamma[type] * dot * rinv;
fbond *= rinv;
if (smooth_flag) {
smooth = (r - r0) / (r0 * ecrit[type]);
smooth *= smooth;
smooth *= smooth;
smooth *= smooth;
smooth = 1 - smooth;
fbond *= smooth;
}
if (newton_bond || i1 < nlocal) {
f[i1][0] += delx * fbond;
f[i1][1] += dely * fbond;
f[i1][2] += delz * fbond;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx * fbond;
f[i2][1] -= dely * fbond;
f[i2][2] -= delz * fbond;
}
if (evflag) ev_tally(i1, i2, nlocal, newton_bond, 0.0, fbond, delx, dely, delz);
}
}
/* ---------------------------------------------------------------------- */
void BondBPMSpring::allocate()
{
allocated = 1;
const int np1 = atom->nbondtypes + 1;
memory->create(k, np1, "bond:k");
memory->create(ecrit, np1, "bond:ecrit");
memory->create(gamma, np1, "bond:gamma");
memory->create(setflag, np1, "bond:setflag");
for (int i = 1; i < np1; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondBPMSpring::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR, "Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo, ihi;
utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error);
double k_one = utils::numeric(FLERR, arg[1], false, lmp);
double ecrit_one = utils::numeric(FLERR, arg[2], false, lmp);
double gamma_one = utils::numeric(FLERR, arg[3], false, lmp);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
ecrit[i] = ecrit_one;
gamma[i] = gamma_one;
setflag[i] = 1;
count++;
if (1.0 + ecrit[i] > max_stretch) max_stretch = 1.0 + ecrit[i];
}
if (count == 0) error->all(FLERR, "Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
check for correct settings and create fix
------------------------------------------------------------------------- */
void BondBPMSpring::init_style()
{
BondBPM::init_style();
if (comm->ghost_velocity == 0)
error->all(FLERR, "Bond bpm/spring requires ghost atoms store velocity");
if (!id_fix_bond_history) {
id_fix_bond_history = utils::strdup("HISTORY_BPM_SPRING");
fix_bond_history = dynamic_cast<FixBondHistory *>(modify->replace_fix(
id_fix_dummy2, fmt::format("{} all BOND_HISTORY 0 1", id_fix_bond_history), 1));
delete[] id_fix_dummy2;
id_fix_dummy2 = nullptr;
}
}
/* ---------------------------------------------------------------------- */
void BondBPMSpring::settings(int narg, char **arg)
{
BondBPM::settings(narg, arg);
int iarg;
for (std::size_t i = 0; i < leftover_iarg.size(); i++) {
iarg = leftover_iarg[i];
if (strcmp(arg[iarg], "smooth") == 0) {
if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command");
smooth_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
i += 1;
} else {
error->all(FLERR, "Illegal bond_style command");
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondBPMSpring::write_restart(FILE *fp)
{
fwrite(&k[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&ecrit[1], sizeof(double), atom->nbondtypes, fp);
fwrite(&gamma[1], sizeof(double), atom->nbondtypes, fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondBPMSpring::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
utils::sfread(FLERR, &k[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &ecrit[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
utils::sfread(FLERR, &gamma[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
}
MPI_Bcast(&k[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&ecrit[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
MPI_Bcast(&gamma[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
proc 0 writes to data file
------------------------------------------------------------------------- */
void BondBPMSpring::write_data(FILE *fp)
{
for (int i = 1; i <= atom->nbondtypes; i++)
fprintf(fp, "%d %g %g %g\n", i, k[i], ecrit[i], gamma[i]);
}
/* ---------------------------------------------------------------------- */
double BondBPMSpring::single(int type, double rsq, int i, int j, double &fforce)
{
if (type <= 0) return 0.0;
double r0;
for (int n = 0; n < atom->num_bond[i]; n++) {
if (atom->bond_atom[i][n] == atom->tag[j]) r0 = fix_bond_history->get_atom_value(i, n, 0);
}
double r = sqrt(rsq);
double rinv = 1.0 / r;
fforce = k[type] * (r0 - r);
double **x = atom->x;
double **v = atom->v;
double delx = x[i][0] - x[j][0];
double dely = x[i][1] - x[j][1];
double delz = x[i][2] - x[j][2];
double delvx = v[i][0] - v[j][0];
double delvy = v[i][1] - v[j][1];
double delvz = v[i][2] - v[j][2];
double dot = delx * delvx + dely * delvy + delz * delvz;
fforce -= gamma[type] * dot * rinv;
fforce *= rinv;
if (smooth_flag) {
double smooth = (r - r0) / (r0 * ecrit[type]);
smooth *= smooth;
smooth *= smooth;
smooth *= smooth;
smooth = 1 - smooth;
fforce *= smooth;
}
return 0.0;
}

68
src/BPM/bond_bpm_spring.h Normal file
View File

@ -0,0 +1,68 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef BOND_CLASS
// clang-format off
BondStyle(bpm/spring,BondBPMSpring);
// clang-format on
#else
#ifndef LMP_BOND_BPM_SPRING_H
#define LMP_BOND_BPM_SPRING_H
#include "bond_bpm.h"
namespace LAMMPS_NS {
class BondBPMSpring : public BondBPM {
public:
BondBPMSpring(class LAMMPS *);
~BondBPMSpring() override;
void compute(int, int) override;
void coeff(int, char **) override;
void init_style() override;
void settings(int, char **) override;
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, double, int, int, double &) override;
protected:
double *k, *ecrit, *gamma;
int smooth_flag;
void allocate();
void store_data();
double store_bond(int, int, int);
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Atom missing in BPM bond
Bonded atom cannot be found
E: Incorrect args for bond coefficients
Self-explanatory. Check the input script or data file.
E: Bond style bpm requires 1-3 and 1-4 special weights of 1.0
Self-explanatory.
*/

View File

@ -0,0 +1,145 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "compute_nbond_atom.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "update.h"
#include <string.h>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeNBondAtom::ComputeNBondAtom(LAMMPS *_lmp, int narg, char **arg) :
Compute(_lmp, narg, arg), nbond(nullptr)
{
if (narg < 3) error->all(FLERR, "Illegal compute nbond/atom command");
peratom_flag = 1;
size_peratom_cols = 0;
peatomflag = 1;
timeflag = 1;
comm_reverse = 1;
nmax = 0;
}
/* ---------------------------------------------------------------------- */
ComputeNBondAtom::~ComputeNBondAtom()
{
memory->destroy(nbond);
}
/* ---------------------------------------------------------------------- */
void ComputeNBondAtom::compute_peratom()
{
invoked_peratom = update->ntimestep;
if (update->eflag_atom != invoked_peratom)
error->all(FLERR, "Per-atom nbond was not tallied on needed timestep");
// grow local nbond array if necessary
// needs to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(nbond);
nmax = atom->nmax;
memory->create(nbond, nmax, "nbond/atom:nbond");
vector_atom = nbond;
}
// npair includes ghosts if either newton flag is set
// b/c some bonds/dihedrals call pair::ev_tally with pairwise info
// nbond includes ghosts if newton_bond is set
// ntotal includes ghosts if either newton flag is set
// KSpace includes ghosts if tip4pflag is set
int nlocal = atom->nlocal;
tagint **bond_atom = atom->bond_atom;
int **bond_type = atom->bond_type;
int ntotal = nlocal;
if (force->newton) ntotal += atom->nghost;
// set local nbond array
int i, j, k;
int *num_bond = atom->num_bond;
int newton_bond = force->newton_bond;
for (i = 0; i < ntotal; i++) nbond[i] = 0;
for (i = 0; i < nlocal; i++) {
for (j = 0; j < num_bond[i]; j++) {
if (bond_type[i][j] <= 0) continue;
k = atom->map(bond_atom[i][j]);
if (k < 0) continue;
nbond[i] += 1;
if (newton_bond) nbond[k] += 1;
}
}
// communicate ghost nbond between neighbor procs
if (force->newton) comm->reverse_comm(this);
// zero nbond of atoms not in group
// only do this after comm since ghost contributions must be included
int *mask = atom->mask;
for (i = 0; i < nlocal; i++)
if (!(mask[i] & groupbit)) nbond[i] = 0.0;
}
/* ---------------------------------------------------------------------- */
int ComputeNBondAtom::pack_reverse_comm(int n, int first, double *buf)
{
int i, m, last;
m = 0;
last = first + n;
for (i = first; i < last; i++) buf[m++] = nbond[i];
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeNBondAtom::unpack_reverse_comm(int n, int *list, double *buf)
{
int i, j, m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
nbond[j] += buf[m++];
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeNBondAtom::memory_usage()
{
double bytes = nmax * sizeof(double);
return bytes;
}

View File

@ -0,0 +1,61 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(nbond/atom,ComputeNBondAtom);
// clang-format on
#else
#ifndef LMP_COMPUTE_NBOND_ATOM_H
#define LMP_COMPUTE_NBOND_ATOM_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeNBondAtom : public Compute {
public:
ComputeNBondAtom(class LAMMPS *, int, char **);
~ComputeNBondAtom() override;
void init() override {}
void compute_peratom() override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
double memory_usage() override;
private:
int nmax;
double *nbond;
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Per-atom energy was not tallied on needed timestep
You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
*/

View File

@ -0,0 +1,157 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "fix_nve_bpm_sphere.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "math_extra.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathExtra;
/* ---------------------------------------------------------------------- */
FixNVEBPMSphere::FixNVEBPMSphere(LAMMPS *_lmp, int narg, char **arg) : FixNVE(_lmp, narg, arg)
{
if (narg < 3) error->all(FLERR, "Illegal fix nve/bpm/sphere command");
time_integrate = 1;
// process extra keywords
// inertia = moment of inertia prefactor for sphere or disc
inertia = 0.4;
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg], "disc") == 0) {
inertia = 0.5;
if (domain->dimension != 2)
error->all(FLERR, "Fix nve/bpm/sphere disc requires 2d simulation");
iarg++;
} else
error->all(FLERR, "Illegal fix nve/bpm/sphere command");
}
inv_inertia = 1.0 / inertia;
// error checks
if (!atom->quat_flag || !atom->sphere_flag)
error->all(FLERR, "Fix nve/bpm/sphere requires atom style bpm/sphere");
}
/* ---------------------------------------------------------------------- */
void FixNVEBPMSphere::init()
{
FixNVE::init();
// check that all particles are finite-size spheres
// no point particles allowed
double *radius = atom->radius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
if (radius[i] == 0.0) error->one(FLERR, "Fix nve/bpm/sphere requires extended particles");
}
/* ---------------------------------------------------------------------- */
void FixNVEBPMSphere::initial_integrate(int /*vflag*/)
{
double dtq, dtfm, dtirotate, particle_inertia;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
double **quat = atom->quat;
double *radius = atom->radius;
double *rmass = atom->rmass;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
// set timestep here since dt may have changed or come via rRESPA
dtq = 0.5 * dtv;
// update v,x,omega,quat for all particles
// d_omega/dt = torque / inertia
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
particle_inertia = inertia * (radius[i] * radius[i] * rmass[i]);
dtirotate = dtf / particle_inertia;
omega[i][0] += dtirotate * torque[i][0];
omega[i][1] += dtirotate * torque[i][1];
omega[i][2] += dtirotate * torque[i][2];
MathExtra::richardson_sphere(quat[i], omega[i], dtq);
}
}
}
/* ---------------------------------------------------------------------- */
void FixNVEBPMSphere::final_integrate()
{
double dtfm, dtirotate, particle_inertia;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
double *rmass = atom->rmass;
double *radius = atom->radius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
// update v,omega for all particles
// d_omega/dt = torque / inertia
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
particle_inertia = inertia * (radius[i] * radius[i] * rmass[i]);
dtirotate = dtf / particle_inertia;
omega[i][0] += dtirotate * torque[i][0];
omega[i][1] += dtirotate * torque[i][1];
omega[i][2] += dtirotate * torque[i][2];
}
}

View File

@ -0,0 +1,71 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(nve/bpm/sphere,FixNVEBPMSphere);
// clang-format on
#else
#ifndef LMP_FIX_NVE_BPM_SPHERE_H
#define LMP_FIX_NVE_BPM_SPHERE_H
#include "fix_nve.h"
namespace LAMMPS_NS {
class FixNVEBPMSphere : public FixNVE {
public:
FixNVEBPMSphere(class LAMMPS *, int, char **);
void init() override;
void initial_integrate(int) override;
void final_integrate() override;
protected:
double inertia, inv_inertia;
int extra;
int dlm;
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Fix nve/bpm/sphere disc requires 2d simulation
UNDOCUMENTED
E: Fix nve/bpm/sphere requires atom style bpm/sphere
Self-explanatory.
E: Fix nve/bpm/sphere update dipole requires atom attribute mu
An atom style with this attribute is needed.
E: Fix nve/bpm/sphere requires extended particles
This fix can only be used for particles of a finite size.
*/

326
src/BPM/pair_bpm_spring.cpp Normal file
View File

@ -0,0 +1,326 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "pair_bpm_spring.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "neigh_list.h"
#include "neighbor.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairBPMSpring::PairBPMSpring(LAMMPS *_lmp) : Pair(_lmp)
{
writedata = 1;
}
/* ---------------------------------------------------------------------- */
PairBPMSpring::~PairBPMSpring()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(k);
memory->destroy(cut);
memory->destroy(gamma);
}
}
/* ---------------------------------------------------------------------- */
void PairBPMSpring::compute(int eflag, int vflag)
{
int i, j, ii, jj, inum, jnum, itype, jtype;
double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair;
double r, rsq, rinv, factor_lj;
int *ilist, *jlist, *numneigh, **firstneigh;
double vxtmp, vytmp, vztmp, delvx, delvy, delvz, dot, smooth;
evdwl = 0.0;
if (eflag || vflag)
ev_setup(eflag, vflag);
else
evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
double *special_lj = force->special_lj;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
vxtmp = v[i][0];
vytmp = v[i][1];
vztmp = v[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
if (factor_lj == 0) continue;
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx * delx + dely * dely + delz * delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
rinv = 1.0 / r;
fpair = k[itype][jtype] * (cut[itype][jtype] - r);
smooth = rsq / cutsq[itype][jtype];
smooth *= smooth;
smooth *= smooth;
smooth = 1.0 - smooth;
delvx = vxtmp - v[j][0];
delvy = vytmp - v[j][1];
delvz = vztmp - v[j][2];
dot = delx * delvx + dely * delvy + delz * delvz;
fpair -= gamma[itype][jtype] * dot * smooth * rinv;
fpair *= factor_lj * rinv;
if (eflag) evdwl = 0.0;
f[i][0] += delx * fpair;
f[i][1] += dely * fpair;
f[i][2] += delz * fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx * fpair;
f[j][1] -= dely * fpair;
f[j][2] -= delz * fpair;
}
if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, fpair, delx, dely, delz);
}
}
}
if (vflag_fdotr) virial_fdotr_compute();
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairBPMSpring::allocate()
{
allocated = 1;
const int np1 = atom->ntypes + 1;
memory->create(setflag, np1, np1, "pair:setflag");
for (int i = 1; i < np1; i++)
for (int j = i; j < np1; j++) setflag[i][j] = 0;
memory->create(cutsq, np1, np1, "pair:cutsq");
memory->create(k, np1, np1, "pair:k");
memory->create(cut, np1, np1, "pair:cut");
memory->create(gamma, np1, np1, "pair:gamma");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairBPMSpring::settings(int narg, char ** /*arg*/)
{
if (narg != 0) error->all(FLERR, "Illegal pair_style command");
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairBPMSpring::coeff(int narg, char **arg)
{
if (narg != 5) error->all(FLERR, "Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo, ihi, jlo, jhi;
utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error);
utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error);
double k_one = utils::numeric(FLERR, arg[2], false, lmp);
double cut_one = utils::numeric(FLERR, arg[3], false, lmp);
double gamma_one = utils::numeric(FLERR, arg[4], false, lmp);
if (cut_one <= 0.0) error->all(FLERR, "Incorrect args for pair coefficients");
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo, i); j <= jhi; j++) {
k[i][j] = k_one;
cut[i][j] = cut_one;
gamma[i][j] = gamma_one;
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairBPMSpring::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
cut[i][j] = mix_distance(cut[i][i], cut[j][j]);
k[i][j] = mix_energy(k[i][i], k[j][j], cut[i][i], cut[j][j]);
gamma[i][j] = mix_energy(gamma[i][i], gamma[j][j], cut[i][i], cut[j][j]);
}
cut[j][i] = cut[i][j];
k[j][i] = k[i][j];
gamma[j][i] = gamma[i][j];
return cut[i][j];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairBPMSpring::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i, j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j], sizeof(int), 1, fp);
if (setflag[i][j]) {
fwrite(&k[i][j], sizeof(double), 1, fp);
fwrite(&cut[i][j], sizeof(double), 1, fp);
fwrite(&gamma[i][j], sizeof(double), 1, fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairBPMSpring::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i, j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j], sizeof(int), 1, fp);
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
if (setflag[i][j]) {
if (me == 0) {
fread(&k[i][j], sizeof(double), 1, fp);
fread(&cut[i][j], sizeof(double), 1, fp);
fread(&gamma[i][j], sizeof(double), 1, fp);
}
MPI_Bcast(&k[i][j], 1, MPI_DOUBLE, 0, world);
MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world);
MPI_Bcast(&gamma[i][j], 1, MPI_DOUBLE, 0, world);
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to data file
------------------------------------------------------------------------- */
void PairBPMSpring::write_data(FILE *fp)
{
for (int i = 1; i <= atom->ntypes; i++)
fprintf(fp, "%d %g %g %g\n", i, k[i][i], cut[i][i], gamma[i][i]);
}
/* ----------------------------------------------------------------------
proc 0 writes all pairs to data file
------------------------------------------------------------------------- */
void PairBPMSpring::write_data_all(FILE *fp)
{
for (int i = 1; i <= atom->ntypes; i++)
for (int j = i; j <= atom->ntypes; j++)
fprintf(fp, "%d %d %g %g %g\n", i, j, k[i][j], cut[i][j], gamma[i][j]);
}
/* ---------------------------------------------------------------------- */
double PairBPMSpring::single(int i, int j, int itype, int jtype, double rsq, double /*factor_coul*/,
double factor_lj, double &fforce)
{
double fpair, r, rinv;
double delx, dely, delz, delvx, delvy, delvz, dot, smooth;
if (rsq > cutsq[itype][jtype]) return 0.0;
double **x = atom->x;
double **v = atom->v;
r = sqrt(rsq);
rinv = 1.0 / r;
fpair = k[itype][jtype] * (cut[itype][jtype] - r);
smooth = rsq / cutsq[itype][jtype];
smooth *= smooth;
smooth = 1.0 - smooth;
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
delvx = v[i][0] - v[j][0];
delvy = v[i][1] - v[j][1];
delvz = v[i][2] - v[j][2];
dot = delx * delvx + dely * delvy + delz * delvz;
fpair -= gamma[itype][jtype] * dot * rinv * smooth;
fpair *= factor_lj;
fforce = fpair;
return 0.0;
}

64
src/BPM/pair_bpm_spring.h Normal file
View File

@ -0,0 +1,64 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
// clang-format off
PairStyle(bpm/spring,PairBPMSpring);
// clang-format on
#else
#ifndef LMP_PAIR_BPM_SPRING_H
#define LMP_PAIR_BPM_SPRING_H
#include "pair.h"
namespace LAMMPS_NS {
class PairBPMSpring : public Pair {
public:
PairBPMSpring(class LAMMPS *);
~PairBPMSpring() override;
void compute(int, int) override;
void settings(int, char **) override;
void coeff(int, char **) override;
double init_one(int, int) override;
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void write_data_all(FILE *) override;
double single(int, int, int, int, double, double, double, double &) override;
protected:
double **k, **cut, **gamma;
void allocate();
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Incorrect args for pair coefficients
Self-explanatory. Check the input script or data file.
*/

View File

@ -136,8 +136,7 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Invalid atom type in fix pour mol command"); error->all(FLERR,"Invalid atom type in fix pour mol command");
if (atom->molecular == Atom::TEMPLATE && onemols != atom->avec->onemols) if (atom->molecular == Atom::TEMPLATE && onemols != atom->avec->onemols)
error->all(FLERR,"Fix pour molecule template ID must be same " error->all(FLERR,"Fix pour molecule template ID must be same as atom style template ID");
"as atom style template ID");
onemols[i]->check_attributes(0); onemols[i]->check_attributes(0);
// fix pour uses geoemetric center of molecule for insertion // fix pour uses geoemetric center of molecule for insertion

View File

@ -45,7 +45,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum; int i,j,ii,jj,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv; double radi,radj,radsum,rsq,r,rinv,rsqinv,factor_lj;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3; double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel; double vtr1,vtr2,vtr3,vrel;
@ -91,6 +91,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
double *special_lj = force->special_lj;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -114,8 +115,11 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
for (jj = 0; jj < jnum; jj++) { for (jj = 0; jj < jnum; jj++) {
j = jlist[jj]; j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK; j &= NEIGHMASK;
if (factor_lj == 0) continue;
delx = xtmp - x[j][0]; delx = xtmp - x[j][0];
dely = ytmp - x[j][1]; dely = ytmp - x[j][1];
delz = ztmp - x[j][2]; delz = ztmp - x[j][2];
@ -247,6 +251,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
fx = delx*ccel + fs1; fx = delx*ccel + fs1;
fy = dely*ccel + fs2; fy = dely*ccel + fs2;
fz = delz*ccel + fs3; fz = delz*ccel + fs3;
fx *= factor_lj;
fy *= factor_lj;
fz *= factor_lj;
f[i][0] += fx; f[i][0] += fx;
f[i][1] += fy; f[i][1] += fy;
f[i][2] += fz; f[i][2] += fz;
@ -254,6 +261,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
tor1 = rinv * (dely*fs3 - delz*fs2); tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3); tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1); tor3 = rinv * (delx*fs2 - dely*fs1);
tor1 *= factor_lj;
tor2 *= factor_lj;
tor3 *= factor_lj;
torque[i][0] -= radi*tor1; torque[i][0] -= radi*tor1;
torque[i][1] -= radi*tor2; torque[i][1] -= radi*tor2;
torque[i][2] -= radi*tor3; torque[i][2] -= radi*tor3;

View File

@ -42,7 +42,7 @@ void PairGranHooke::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum; int i,j,ii,jj,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv; double radi,radj,radsum,rsq,r,rinv,rsqinv,factor_lj;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3; double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel; double vtr1,vtr2,vtr3,vrel;
@ -82,6 +82,7 @@ void PairGranHooke::compute(int eflag, int vflag)
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
double *special_lj = force->special_lj;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -101,8 +102,11 @@ void PairGranHooke::compute(int eflag, int vflag)
for (jj = 0; jj < jnum; jj++) { for (jj = 0; jj < jnum; jj++) {
j = jlist[jj]; j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK; j &= NEIGHMASK;
if (factor_lj == 0) continue;
delx = xtmp - x[j][0]; delx = xtmp - x[j][0];
dely = ytmp - x[j][1]; dely = ytmp - x[j][1];
delz = ztmp - x[j][2]; delz = ztmp - x[j][2];
@ -187,6 +191,9 @@ void PairGranHooke::compute(int eflag, int vflag)
fx = delx*ccel + fs1; fx = delx*ccel + fs1;
fy = dely*ccel + fs2; fy = dely*ccel + fs2;
fz = delz*ccel + fs3; fz = delz*ccel + fs3;
fx *= factor_lj;
fy *= factor_lj;
fz *= factor_lj;
f[i][0] += fx; f[i][0] += fx;
f[i][1] += fy; f[i][1] += fy;
f[i][2] += fz; f[i][2] += fz;
@ -194,6 +201,9 @@ void PairGranHooke::compute(int eflag, int vflag)
tor1 = rinv * (dely*fs3 - delz*fs2); tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3); tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1); tor3 = rinv * (delx*fs2 - dely*fs1);
tor1 *= factor_lj;
tor2 *= factor_lj;
tor3 *= factor_lj;
torque[i][0] -= radi*tor1; torque[i][0] -= radi*tor1;
torque[i][1] -= radi*tor2; torque[i][1] -= radi*tor2;
torque[i][2] -= radi*tor3; torque[i][2] -= radi*tor3;

View File

@ -103,7 +103,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
{ {
int i, j, ii, jj, inum, jnum; int i, j, ii, jj, inum, jnum;
double xtmp, ytmp, ztmp, delx, dely, delz, fx, fy, fz; double xtmp, ytmp, ztmp, delx, dely, delz, fx, fy, fz;
double radi, radj, radsum, rsq, r, rinv, rsqinv; double radi, radj, radsum, rsq, r, rinv, rsqinv, factor_lj;
double vr1, vr2, vr3, vnnr, vn1, vn2, vn3, vt1, vt2, vt3; double vr1, vr2, vr3, vnnr, vn1, vn2, vn3, vt1, vt2, vt3;
double wr1, wr2, wr3; double wr1, wr2, wr3;
double vtr1, vtr2, vtr3, vrel; double vtr1, vtr2, vtr3, vrel;
@ -151,6 +151,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
double *special_lj = force->special_lj;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -174,8 +175,11 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
for (jj = 0; jj < jnum; jj++) { for (jj = 0; jj < jnum; jj++) {
j = jlist[jj]; j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK; j &= NEIGHMASK;
if (factor_lj == 0) continue;
delx = xtmp - x[j][0]; delx = xtmp - x[j][0];
dely = ytmp - x[j][1]; dely = ytmp - x[j][1];
delz = ztmp - x[j][2]; delz = ztmp - x[j][2];
@ -306,6 +310,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
fx = delx * ccel + fs1; fx = delx * ccel + fs1;
fy = dely * ccel + fs2; fy = dely * ccel + fs2;
fz = delz * ccel + fs3; fz = delz * ccel + fs3;
fx *= factor_lj;
fy *= factor_lj;
fz *= factor_lj;
f[i][0] += fx; f[i][0] += fx;
f[i][1] += fy; f[i][1] += fy;
f[i][2] += fz; f[i][2] += fz;
@ -313,6 +320,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
tor1 = rinv * (dely * fs3 - delz * fs2); tor1 = rinv * (dely * fs3 - delz * fs2);
tor2 = rinv * (delz * fs1 - delx * fs3); tor2 = rinv * (delz * fs1 - delx * fs3);
tor3 = rinv * (delx * fs2 - dely * fs1); tor3 = rinv * (delx * fs2 - dely * fs1);
tor1 *= factor_lj;
tor2 *= factor_lj;
tor3 *= factor_lj;
torque[i][0] -= radi * tor1; torque[i][0] -= radi * tor1;
torque[i][1] -= radi * tor2; torque[i][1] -= radi * tor2;
torque[i][2] -= radi * tor3; torque[i][2] -= radi * tor3;

View File

@ -150,7 +150,7 @@ void PairGranular::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz;
double radi,radj,radsum,rsq,r,rinv; double radi,radj,radsum,rsq,r,rinv,factor_lj;
double Reff, delta, dR, dR2, dist_to_contact; double Reff, delta, dR, dR2, dist_to_contact;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
@ -222,6 +222,7 @@ void PairGranular::compute(int eflag, int vflag)
double *rmass = atom->rmass; double *rmass = atom->rmass;
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -249,8 +250,11 @@ void PairGranular::compute(int eflag, int vflag)
for (jj = 0; jj < jnum; jj++) { for (jj = 0; jj < jnum; jj++) {
j = jlist[jj]; j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK; j &= NEIGHMASK;
if (factor_lj == 0) continue;
delx = xtmp - x[j][0]; delx = xtmp - x[j][0];
dely = ytmp - x[j][1]; dely = ytmp - x[j][1];
delz = ztmp - x[j][2]; delz = ztmp - x[j][2];
@ -651,6 +655,9 @@ void PairGranular::compute(int eflag, int vflag)
fx = nx*Fntot + fs1; fx = nx*Fntot + fs1;
fy = ny*Fntot + fs2; fy = ny*Fntot + fs2;
fz = nz*Fntot + fs3; fz = nz*Fntot + fs3;
fx *= factor_lj;
fy *= factor_lj;
fz *= factor_lj;
f[i][0] += fx; f[i][0] += fx;
f[i][1] += fy; f[i][1] += fy;
@ -659,6 +666,9 @@ void PairGranular::compute(int eflag, int vflag)
tor1 = ny*fs3 - nz*fs2; tor1 = ny*fs3 - nz*fs2;
tor2 = nz*fs1 - nx*fs3; tor2 = nz*fs1 - nx*fs3;
tor3 = nx*fs2 - ny*fs1; tor3 = nx*fs2 - ny*fs1;
tor1 *= factor_lj;
tor2 *= factor_lj;
tor3 *= factor_lj;
dist_to_contact = radi-0.5*delta; dist_to_contact = radi-0.5*delta;
torque[i][0] -= dist_to_contact*tor1; torque[i][0] -= dist_to_contact*tor1;
@ -666,9 +676,9 @@ void PairGranular::compute(int eflag, int vflag)
torque[i][2] -= dist_to_contact*tor3; torque[i][2] -= dist_to_contact*tor3;
if (twist_model[itype][jtype] != TWIST_NONE) { if (twist_model[itype][jtype] != TWIST_NONE) {
tortwist1 = magtortwist * nx; tortwist1 = magtortwist * nx * factor_lj;
tortwist2 = magtortwist * ny; tortwist2 = magtortwist * ny * factor_lj;
tortwist3 = magtortwist * nz; tortwist3 = magtortwist * nz * factor_lj;
torque[i][0] += tortwist1; torque[i][0] += tortwist1;
torque[i][1] += tortwist2; torque[i][1] += tortwist2;
@ -676,9 +686,9 @@ void PairGranular::compute(int eflag, int vflag)
} }
if (roll_model[itype][jtype] != ROLL_NONE) { if (roll_model[itype][jtype] != ROLL_NONE) {
torroll1 = Reff*(ny*fr3 - nz*fr2); // n cross fr torroll1 = Reff*(ny*fr3 - nz*fr2) * factor_lj; // n cross fr
torroll2 = Reff*(nz*fr1 - nx*fr3); torroll2 = Reff*(nz*fr1 - nx*fr3) * factor_lj;
torroll3 = Reff*(nx*fr2 - ny*fr1); torroll3 = Reff*(nx*fr2 - ny*fr1) * factor_lj;
torque[i][0] += torroll1; torque[i][0] += torroll1;
torque[i][1] += torroll2; torque[i][1] += torroll2;

View File

@ -78,8 +78,6 @@ void PairSWKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
eflag = eflag_in; eflag = eflag_in;
vflag = vflag_in; vflag = vflag_in;
if (neighflag == FULL) no_virial_fdotr_compute = 1;
ev_init(eflag,vflag,0); ev_init(eflag,vflag,0);
// reallocate per-atom arrays if necessary // reallocate per-atom arrays if necessary
@ -134,39 +132,27 @@ void PairSWKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
int max_neighs = d_neighbors.extent(1); int max_neighs = d_neighbors.extent(1);
if (((int) d_neighbors_short.extent(1) != max_neighs) || if (((int) d_neighbors_short.extent(1) < max_neighs) ||
((int) d_neighbors_short.extent(0) != ignum)) { ((int) d_neighbors_short.extent(0) < ignum)) {
d_neighbors_short = Kokkos::View<int**,DeviceType>("SW::neighbors_short",ignum,max_neighs); d_neighbors_short = Kokkos::View<int**,DeviceType>("SW::neighbors_short",ignum*1.2,max_neighs);
} }
if ((int)d_numneigh_short.extent(0)!=ignum) if ((int)d_numneigh_short.extent(0) < ignum)
d_numneigh_short = Kokkos::View<int*,DeviceType>("SW::numneighs_short",ignum); d_numneigh_short = Kokkos::View<int*,DeviceType>("SW::numneighs_short",ignum*1.2);
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType,TagPairSWComputeShortNeigh>(0,neighflag==FULL?ignum:inum), *this); Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType,TagPairSWComputeShortNeigh>(0,inum), *this);
// loop over neighbor list of my atoms // loop over neighbor list of my atoms
if (neighflag == HALF) { if (neighflag == HALF) {
if (evflag) if (evflag)
Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagPairSWComputeHalf<HALF,1> >(0,inum),*this,ev); Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagPairSWCompute<HALF,1> >(0,inum),*this,ev);
else else
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairSWComputeHalf<HALF,0> >(0,inum),*this); Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairSWCompute<HALF,0> >(0,inum),*this);
ev_all += ev; ev_all += ev;
} else if (neighflag == HALFTHREAD) { } else if (neighflag == HALFTHREAD) {
if (evflag) if (evflag)
Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagPairSWComputeHalf<HALFTHREAD,1> >(0,inum),*this,ev); Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagPairSWCompute<HALFTHREAD,1> >(0,inum),*this,ev);
else else
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairSWComputeHalf<HALFTHREAD,0> >(0,inum),*this); Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairSWCompute<HALFTHREAD,0> >(0,inum),*this);
ev_all += ev;
} else if (neighflag == FULL) {
if (evflag)
Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagPairSWComputeFullA<FULL,1> >(0,inum),*this,ev);
else
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairSWComputeFullA<FULL,0> >(0,inum),*this);
ev_all += ev;
if (evflag)
Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagPairSWComputeFullB<FULL,1> >(0,ignum),*this,ev);
else
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairSWComputeFullB<FULL,0> >(0,ignum),*this);
ev_all += ev; ev_all += ev;
} }
@ -216,6 +202,7 @@ template<class DeviceType>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeShortNeigh, const int& ii) const { void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeShortNeigh, const int& ii) const {
const int i = d_ilist[ii]; const int i = d_ilist[ii];
const int itype = d_map[type[i]];
const X_FLOAT xtmp = x(i,0); const X_FLOAT xtmp = x(i,0);
const X_FLOAT ytmp = x(i,1); const X_FLOAT ytmp = x(i,1);
const X_FLOAT ztmp = x(i,2); const X_FLOAT ztmp = x(i,2);
@ -225,18 +212,20 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeShortNeigh, const int&
for (int jj = 0; jj < jnum; jj++) { for (int jj = 0; jj < jnum; jj++) {
int j = d_neighbors(i,jj); int j = d_neighbors(i,jj);
j &= NEIGHMASK; j &= NEIGHMASK;
const int jtype = d_map[type[j]];
const X_FLOAT delx = xtmp - x(j,0); const X_FLOAT delx = xtmp - x(j,0);
const X_FLOAT dely = ytmp - x(j,1); const X_FLOAT dely = ytmp - x(j,1);
const X_FLOAT delz = ztmp - x(j,2); const X_FLOAT delz = ztmp - x(j,2);
const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; const F_FLOAT rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutmax*cutmax) { const int ijparam = d_elem3param(itype,jtype,jtype);
d_neighbors_short(i,inside) = j; if (rsq < d_params[ijparam].cutsq) {
d_neighbors_short(ii,inside) = j;
inside++; inside++;
} }
} }
d_numneigh_short(i) = inside; d_numneigh_short(ii) = inside;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -244,7 +233,7 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeShortNeigh, const int&
template<class DeviceType> template<class DeviceType>
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>, const int &ii, EV_FLOAT& ev) const { void PairSWKokkos<DeviceType>::operator()(TagPairSWCompute<NEIGHFLAG,EVFLAG>, const int &ii, EV_FLOAT& ev) const {
// The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial
@ -264,15 +253,14 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>
// two-body interactions, skip half of them // two-body interactions, skip half of them
const int jnum = d_numneigh_short[i]; const int jnum = d_numneigh_short[ii];
F_FLOAT fxtmpi = 0.0; F_FLOAT fxtmpi = 0.0;
F_FLOAT fytmpi = 0.0; F_FLOAT fytmpi = 0.0;
F_FLOAT fztmpi = 0.0; F_FLOAT fztmpi = 0.0;
for (int jj = 0; jj < jnum; jj++) { for (int jj = 0; jj < jnum; jj++) {
int j = d_neighbors_short(i,jj); int j = d_neighbors_short(ii,jj);
j &= NEIGHMASK;
const tagint jtag = tag[j]; const tagint jtag = tag[j];
if (itag > jtag) { if (itag > jtag) {
@ -293,7 +281,6 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>
const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; const F_FLOAT rsq = delx*delx + dely*dely + delz*delz;
const int ijparam = d_elem3param(itype,jtype,jtype); const int ijparam = d_elem3param(itype,jtype,jtype);
if (rsq >= d_params[ijparam].cutsq) continue;
twobody(d_params[ijparam],rsq,fpair,eflag,evdwl); twobody(d_params[ijparam],rsq,fpair,eflag,evdwl);
@ -313,23 +300,20 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>
const int jnumm1 = jnum - 1; const int jnumm1 = jnum - 1;
for (int jj = 0; jj < jnumm1; jj++) { for (int jj = 0; jj < jnumm1; jj++) {
int j = d_neighbors_short(i,jj); int j = d_neighbors_short(ii,jj);
j &= NEIGHMASK;
const int jtype = d_map[type[j]]; const int jtype = d_map[type[j]];
const int ijparam = d_elem3param(itype,jtype,jtype); const int ijparam = d_elem3param(itype,jtype,jtype);
delr1[0] = x(j,0) - xtmp; delr1[0] = x(j,0) - xtmp;
delr1[1] = x(j,1) - ytmp; delr1[1] = x(j,1) - ytmp;
delr1[2] = x(j,2) - ztmp; delr1[2] = x(j,2) - ztmp;
const F_FLOAT rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; const F_FLOAT rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
if (rsq1 >= d_params[ijparam].cutsq) continue;
F_FLOAT fxtmpj = 0.0; F_FLOAT fxtmpj = 0.0;
F_FLOAT fytmpj = 0.0; F_FLOAT fytmpj = 0.0;
F_FLOAT fztmpj = 0.0; F_FLOAT fztmpj = 0.0;
for (int kk = jj+1; kk < jnum; kk++) { for (int kk = jj+1; kk < jnum; kk++) {
int k = d_neighbors_short(i,kk); int k = d_neighbors_short(ii,kk);
k &= NEIGHMASK;
const int ktype = d_map[type[k]]; const int ktype = d_map[type[k]];
const int ikparam = d_elem3param(itype,ktype,ktype); const int ikparam = d_elem3param(itype,ktype,ktype);
const int ijkparam = d_elem3param(itype,jtype,ktype); const int ijkparam = d_elem3param(itype,jtype,ktype);
@ -339,8 +323,6 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>
delr2[2] = x(k,2) - ztmp; delr2[2] = x(k,2) - ztmp;
const F_FLOAT rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; const F_FLOAT rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 >= d_params[ikparam].cutsq) continue;
threebody_kk(d_params[ijparam],d_params[ikparam],d_params[ijkparam], threebody_kk(d_params[ijparam],d_params[ikparam],d_params[ijkparam],
rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl); rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl);
@ -373,203 +355,9 @@ void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>
template<class DeviceType> template<class DeviceType>
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>, const int &ii) const { void PairSWKokkos<DeviceType>::operator()(TagPairSWCompute<NEIGHFLAG,EVFLAG>, const int &ii) const {
EV_FLOAT ev; EV_FLOAT ev;
this->template operator()<NEIGHFLAG,EVFLAG>(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>(), ii, ev); this->template operator()<NEIGHFLAG,EVFLAG>(TagPairSWCompute<NEIGHFLAG,EVFLAG>(), ii, ev);
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeFullA<NEIGHFLAG,EVFLAG>, const int &ii, EV_FLOAT& ev) const {
F_FLOAT delr1[3],delr2[3],fj[3],fk[3];
F_FLOAT evdwl = 0.0;
F_FLOAT fpair = 0.0;
const int i = d_ilist[ii];
const int itype = d_map[type[i]];
const X_FLOAT xtmp = x(i,0);
const X_FLOAT ytmp = x(i,1);
const X_FLOAT ztmp = x(i,2);
// two-body interactions
const int jnum = d_numneigh_short[i];
F_FLOAT fxtmpi = 0.0;
F_FLOAT fytmpi = 0.0;
F_FLOAT fztmpi = 0.0;
for (int jj = 0; jj < jnum; jj++) {
int j = d_neighbors_short(i,jj);
j &= NEIGHMASK;
const int jtype = d_map[type[j]];
const X_FLOAT delx = xtmp - x(j,0);
const X_FLOAT dely = ytmp - x(j,1);
const X_FLOAT delz = ztmp - x(j,2);
const F_FLOAT rsq = delx*delx + dely*dely + delz*delz;
const int ijparam = d_elem3param(itype,jtype,jtype);
if (rsq >= d_params[ijparam].cutsq) continue;
twobody(d_params[ijparam],rsq,fpair,eflag,evdwl);
fxtmpi += delx*fpair;
fytmpi += dely*fpair;
fztmpi += delz*fpair;
if (EVFLAG) {
if (eflag) ev.evdwl += 0.5*evdwl;
if (vflag_either || eflag_atom) this->template ev_tally<NEIGHFLAG>(ev,i,j,evdwl,fpair,delx,dely,delz);
}
}
const int jnumm1 = jnum - 1;
for (int jj = 0; jj < jnumm1; jj++) {
int j = d_neighbors_short(i,jj);
j &= NEIGHMASK;
const int jtype = d_map[type[j]];
const int ijparam = d_elem3param(itype,jtype,jtype);
delr1[0] = x(j,0) - xtmp;
delr1[1] = x(j,1) - ytmp;
delr1[2] = x(j,2) - ztmp;
const F_FLOAT rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
if (rsq1 >= d_params[ijparam].cutsq) continue;
for (int kk = jj+1; kk < jnum; kk++) {
int k = d_neighbors_short(i,kk);
k &= NEIGHMASK;
const int ktype = d_map[type[k]];
const int ikparam = d_elem3param(itype,ktype,ktype);
const int ijkparam = d_elem3param(itype,jtype,ktype);
delr2[0] = x(k,0) - xtmp;
delr2[1] = x(k,1) - ytmp;
delr2[2] = x(k,2) - ztmp;
const F_FLOAT rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 >= d_params[ikparam].cutsq) continue;
threebody_kk(d_params[ijparam],d_params[ikparam],d_params[ijkparam],
rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl);
fxtmpi -= fj[0] + fk[0];
fytmpi -= fj[1] + fk[1];
fztmpi -= fj[2] + fk[2];
if (EVFLAG) {
if (eflag) ev.evdwl += evdwl;
if (vflag_either || eflag_atom) this->template ev_tally3<NEIGHFLAG>(ev,i,j,k,evdwl,0.0,fj,fk,delr1,delr2);
}
}
}
f(i,0) += fxtmpi;
f(i,1) += fytmpi;
f(i,2) += fztmpi;
}
template<class DeviceType>
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeFullA<NEIGHFLAG,EVFLAG>, const int &ii) const {
EV_FLOAT ev;
this->template operator()<NEIGHFLAG,EVFLAG>(TagPairSWComputeFullA<NEIGHFLAG,EVFLAG>(), ii, ev);
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeFullB<NEIGHFLAG,EVFLAG>, const int &ii, EV_FLOAT& ev) const {
F_FLOAT delr1[3],delr2[3],fj[3],fk[3];
F_FLOAT evdwl = 0.0;
const int i = d_ilist[ii];
const int itype = d_map[type[i]];
const X_FLOAT xtmpi = x(i,0);
const X_FLOAT ytmpi = x(i,1);
const X_FLOAT ztmpi = x(i,2);
const int jnum = d_numneigh_short[i];
F_FLOAT fxtmpi = 0.0;
F_FLOAT fytmpi = 0.0;
F_FLOAT fztmpi = 0.0;
for (int jj = 0; jj < jnum; jj++) {
int j = d_neighbors_short(i,jj);
j &= NEIGHMASK;
if (j >= nlocal) continue;
const int jtype = d_map[type[j]];
const int jiparam = d_elem3param(jtype,itype,itype);
const X_FLOAT xtmpj = x(j,0);
const X_FLOAT ytmpj = x(j,1);
const X_FLOAT ztmpj = x(j,2);
delr1[0] = xtmpi - xtmpj;
delr1[1] = ytmpi - ytmpj;
delr1[2] = ztmpi - ztmpj;
const F_FLOAT rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
if (rsq1 >= d_params[jiparam].cutsq) continue;
const int j_jnum = d_numneigh_short[j];
for (int kk = 0; kk < j_jnum; kk++) {
int k = d_neighbors_short(j,kk);
k &= NEIGHMASK;
if (k == i) continue;
const int ktype = d_map[type[k]];
const int jkparam = d_elem3param(jtype,ktype,ktype);
const int jikparam = d_elem3param(jtype,itype,ktype);
delr2[0] = x(k,0) - xtmpj;
delr2[1] = x(k,1) - ytmpj;
delr2[2] = x(k,2) - ztmpj;
const F_FLOAT rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 >= d_params[jkparam].cutsq) continue;
if (vflag_atom)
threebody_kk(d_params[jiparam],d_params[jkparam],d_params[jikparam],
rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl);
else
threebodyj(d_params[jiparam],d_params[jkparam],d_params[jikparam],
rsq1,rsq2,delr1,delr2,fj);
fxtmpi += fj[0];
fytmpi += fj[1];
fztmpi += fj[2];
if (EVFLAG)
if (vflag_atom || eflag_atom) ev_tally3_atom(ev,i,evdwl,0.0,fj,fk,delr1,delr2);
}
}
f(i,0) += fxtmpi;
f(i,1) += fytmpi;
f(i,2) += fztmpi;
}
template<class DeviceType>
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::operator()(TagPairSWComputeFullB<NEIGHFLAG,EVFLAG>, const int &ii) const {
EV_FLOAT ev;
this->template operator()<NEIGHFLAG,EVFLAG>(TagPairSWComputeFullB<NEIGHFLAG,EVFLAG>(), ii, ev);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -613,9 +401,9 @@ void PairSWKokkos<DeviceType>::init_style()
request->set_kokkos_host(std::is_same<DeviceType,LMPHostType>::value && request->set_kokkos_host(std::is_same<DeviceType,LMPHostType>::value &&
!std::is_same<DeviceType,LMPDeviceType>::value); !std::is_same<DeviceType,LMPDeviceType>::value);
request->set_kokkos_device(std::is_same<DeviceType,LMPDeviceType>::value); request->set_kokkos_device(std::is_same<DeviceType,LMPDeviceType>::value);
// always request a full neighbor list
request->enable_full(); if (neighflag == FULL)
if (neighflag == FULL) request->enable_ghost(); error->all(FLERR,"Must use half neighbor list style with pair sw/kk");
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -732,52 +520,6 @@ void PairSWKokkos<DeviceType>::threebody_kk(const Param& paramij, const Param& p
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void PairSWKokkos<DeviceType>::threebodyj(const Param& paramij, const Param& paramik, const Param& paramijk,
const F_FLOAT& rsq1, const F_FLOAT& rsq2, F_FLOAT *delr1, F_FLOAT *delr2, F_FLOAT *fj) const
{
F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1;
F_FLOAT r2, rainv2, gsrainv2, expgsrainv2;
F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1;
F_FLOAT facang,facang12,csfacang,csfac1;
r1 = sqrt(rsq1);
rinvsq1 = 1.0/rsq1;
rainv1 = 1.0/(r1 - paramij.cut);
gsrainv1 = paramij.sigma_gamma * rainv1;
gsrainvsq1 = gsrainv1*rainv1/r1;
expgsrainv1 = exp(gsrainv1);
r2 = sqrt(rsq2);
rainv2 = 1.0/(r2 - paramik.cut);
gsrainv2 = paramik.sigma_gamma * rainv2;
expgsrainv2 = exp(gsrainv2);
rinv12 = 1.0/(r1*r2);
cs = (delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2]) * rinv12;
delcs = cs - paramijk.costheta;
delcssq = delcs*delcs;
facexp = expgsrainv1*expgsrainv2;
// facrad = sqrt(paramij.lambda_epsilon*paramik.lambda_epsilon) *
// facexp*delcssq;
facrad = paramijk.lambda_epsilon * facexp*delcssq;
frad1 = facrad*gsrainvsq1;
facang = paramijk.lambda_epsilon2 * facexp*delcs;
facang12 = rinv12*facang;
csfacang = cs*facang;
csfac1 = rinvsq1*csfacang;
fj[0] = delr1[0]*(frad1+csfac1)-delr2[0]*facang12;
fj[1] = delr1[1]*(frad1+csfac1)-delr2[1]*facang12;
fj[2] = delr1[2]*(frad1+csfac1)-delr2[2]*facang12;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType> template<class DeviceType>
template<int NEIGHFLAG> template<int NEIGHFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
@ -785,7 +527,6 @@ void PairSWKokkos<DeviceType>::ev_tally(EV_FLOAT &ev, const int &i, const int &j
const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx,
const F_FLOAT &dely, const F_FLOAT &delz) const const F_FLOAT &dely, const F_FLOAT &delz) const
{ {
const int VFLAG = vflag_either;
// The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial
@ -798,11 +539,10 @@ void PairSWKokkos<DeviceType>::ev_tally(EV_FLOAT &ev, const int &i, const int &j
if (eflag_atom) { if (eflag_atom) {
const E_FLOAT epairhalf = 0.5 * epair; const E_FLOAT epairhalf = 0.5 * epair;
a_eatom[i] += epairhalf; a_eatom[i] += epairhalf;
if (NEIGHFLAG != FULL) a_eatom[j] += epairhalf;
a_eatom[j] += epairhalf;
} }
if (VFLAG) { if (vflag_either) {
const E_FLOAT v0 = delx*delx*fpair; const E_FLOAT v0 = delx*delx*fpair;
const E_FLOAT v1 = dely*dely*fpair; const E_FLOAT v1 = dely*dely*fpair;
const E_FLOAT v2 = delz*delz*fpair; const E_FLOAT v2 = delz*delz*fpair;
@ -811,21 +551,12 @@ void PairSWKokkos<DeviceType>::ev_tally(EV_FLOAT &ev, const int &i, const int &j
const E_FLOAT v5 = dely*delz*fpair; const E_FLOAT v5 = dely*delz*fpair;
if (vflag_global) { if (vflag_global) {
if (NEIGHFLAG != FULL) { ev.v[0] += v0;
ev.v[0] += v0; ev.v[1] += v1;
ev.v[1] += v1; ev.v[2] += v2;
ev.v[2] += v2; ev.v[3] += v3;
ev.v[3] += v3; ev.v[4] += v4;
ev.v[4] += v4; ev.v[5] += v5;
ev.v[5] += v5;
} else {
ev.v[0] += 0.5*v0;
ev.v[1] += 0.5*v1;
ev.v[2] += 0.5*v2;
ev.v[3] += 0.5*v3;
ev.v[4] += 0.5*v4;
ev.v[5] += 0.5*v5;
}
} }
if (vflag_atom) { if (vflag_atom) {
@ -836,14 +567,12 @@ void PairSWKokkos<DeviceType>::ev_tally(EV_FLOAT &ev, const int &i, const int &j
a_vatom(i,4) += 0.5*v4; a_vatom(i,4) += 0.5*v4;
a_vatom(i,5) += 0.5*v5; a_vatom(i,5) += 0.5*v5;
if (NEIGHFLAG != FULL) { a_vatom(j,0) += 0.5*v0;
a_vatom(j,0) += 0.5*v0; a_vatom(j,1) += 0.5*v1;
a_vatom(j,1) += 0.5*v1; a_vatom(j,2) += 0.5*v2;
a_vatom(j,2) += 0.5*v2; a_vatom(j,3) += 0.5*v3;
a_vatom(j,3) += 0.5*v3; a_vatom(j,4) += 0.5*v4;
a_vatom(j,4) += 0.5*v4; a_vatom(j,5) += 0.5*v5;
a_vatom(j,5) += 0.5*v5;
}
} }
} }
} }
@ -863,8 +592,6 @@ void PairSWKokkos<DeviceType>::ev_tally3(EV_FLOAT &ev, const int &i, const int &
{ {
F_FLOAT epairthird,v[6]; F_FLOAT epairthird,v[6];
const int VFLAG = vflag_either;
// The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial
auto v_eatom = ScatterViewHelper<NeedDup_v<NEIGHFLAG,DeviceType>,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); auto v_eatom = ScatterViewHelper<NeedDup_v<NEIGHFLAG,DeviceType>,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom);
@ -876,13 +603,11 @@ void PairSWKokkos<DeviceType>::ev_tally3(EV_FLOAT &ev, const int &i, const int &
if (eflag_atom) { if (eflag_atom) {
epairthird = THIRD * (evdwl + ecoul); epairthird = THIRD * (evdwl + ecoul);
a_eatom[i] += epairthird; a_eatom[i] += epairthird;
if (NEIGHFLAG != FULL) { a_eatom[j] += epairthird;
a_eatom[j] += epairthird; a_eatom[k] += epairthird;
a_eatom[k] += epairthird;
}
} }
if (VFLAG) { if (vflag_either) {
v[0] = drji[0]*fj[0] + drki[0]*fk[0]; v[0] = drji[0]*fj[0] + drki[0]*fk[0];
v[1] = drji[1]*fj[1] + drki[1]*fk[1]; v[1] = drji[1]*fj[1] + drki[1]*fk[1];
v[2] = drji[2]*fj[2] + drki[2]*fk[2]; v[2] = drji[2]*fj[2] + drki[2]*fk[2];
@ -904,15 +629,13 @@ void PairSWKokkos<DeviceType>::ev_tally3(EV_FLOAT &ev, const int &i, const int &
a_vatom(i,2) += THIRD*v[2]; a_vatom(i,3) += THIRD*v[3]; a_vatom(i,2) += THIRD*v[2]; a_vatom(i,3) += THIRD*v[3];
a_vatom(i,4) += THIRD*v[4]; a_vatom(i,5) += THIRD*v[5]; a_vatom(i,4) += THIRD*v[4]; a_vatom(i,5) += THIRD*v[5];
if (NEIGHFLAG != FULL) { a_vatom(j,0) += THIRD*v[0]; a_vatom(j,1) += THIRD*v[1];
a_vatom(j,0) += THIRD*v[0]; a_vatom(j,1) += THIRD*v[1]; a_vatom(j,2) += THIRD*v[2]; a_vatom(j,3) += THIRD*v[3];
a_vatom(j,2) += THIRD*v[2]; a_vatom(j,3) += THIRD*v[3]; a_vatom(j,4) += THIRD*v[4]; a_vatom(j,5) += THIRD*v[5];
a_vatom(j,4) += THIRD*v[4]; a_vatom(j,5) += THIRD*v[5];
a_vatom(k,0) += THIRD*v[0]; a_vatom(k,1) += THIRD*v[1]; a_vatom(k,0) += THIRD*v[0]; a_vatom(k,1) += THIRD*v[1];
a_vatom(k,2) += THIRD*v[2]; a_vatom(k,3) += THIRD*v[3]; a_vatom(k,2) += THIRD*v[2]; a_vatom(k,3) += THIRD*v[3];
a_vatom(k,4) += THIRD*v[4]; a_vatom(k,5) += THIRD*v[5]; a_vatom(k,4) += THIRD*v[4]; a_vatom(k,5) += THIRD*v[5];
}
} }
} }
} }
@ -931,14 +654,12 @@ void PairSWKokkos<DeviceType>::ev_tally3_atom(EV_FLOAT & /*ev*/, const int &i,
{ {
F_FLOAT epairthird,v[6]; F_FLOAT epairthird,v[6];
const int VFLAG = vflag_either;
if (eflag_atom) { if (eflag_atom) {
epairthird = THIRD * (evdwl + ecoul); epairthird = THIRD * (evdwl + ecoul);
d_eatom[i] += epairthird; d_eatom[i] += epairthird;
} }
if (VFLAG) { if (vflag_either) {
v[0] = drji[0]*fj[0] + drki[0]*fk[0]; v[0] = drji[0]*fj[0] + drki[0]*fk[0];
v[1] = drji[1]*fj[1] + drki[1]*fk[1]; v[1] = drji[1]*fj[1] + drki[1]*fk[1];
v[2] = drji[2]*fj[2] + drki[2]*fk[2]; v[2] = drji[2]*fj[2] + drki[2]*fk[2];

View File

@ -27,13 +27,7 @@ PairStyle(sw/kk/host,PairSWKokkos<LMPHostType>);
#include "pair_kokkos.h" #include "pair_kokkos.h"
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
struct TagPairSWComputeHalf{}; struct TagPairSWCompute{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairSWComputeFullA{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairSWComputeFullB{};
struct TagPairSWComputeShortNeigh{}; struct TagPairSWComputeShortNeigh{};
@ -42,7 +36,7 @@ namespace LAMMPS_NS {
template<class DeviceType> template<class DeviceType>
class PairSWKokkos : public PairSW { class PairSWKokkos : public PairSW {
public: public:
enum {EnabledNeighFlags=FULL}; enum {EnabledNeighFlags=HALF|HALFTHREAD};
enum {COUL_FLAG=0}; enum {COUL_FLAG=0};
typedef DeviceType device_type; typedef DeviceType device_type;
typedef ArrayTypes<DeviceType> AT; typedef ArrayTypes<DeviceType> AT;
@ -56,27 +50,11 @@ class PairSWKokkos : public PairSW {
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const; void operator()(TagPairSWCompute<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeHalf<NEIGHFLAG,EVFLAG>, const int&) const; void operator()(TagPairSWCompute<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeFullA<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeFullA<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeFullB<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeFullB<NEIGHFLAG,EVFLAG>, const int&) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairSWComputeShortNeigh, const int&) const; void operator()(TagPairSWComputeShortNeigh, const int&) const;
@ -121,10 +99,6 @@ class PairSWKokkos : public PairSW {
void threebody_kk(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, void threebody_kk(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *,
F_FLOAT *, F_FLOAT *, const int&, F_FLOAT&) const; F_FLOAT *, F_FLOAT *, const int&, F_FLOAT&) const;
KOKKOS_INLINE_FUNCTION
void threebodyj(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *,
F_FLOAT *) const;
typename AT::t_x_array_randomread x; typename AT::t_x_array_randomread x;
typename AT::t_f_array f; typename AT::t_f_array f;
typename AT::t_tagint_1d tag; typename AT::t_tagint_1d tag;
@ -180,7 +154,7 @@ class PairSWKokkos : public PairSW {
/* ERROR/WARNING messages: /* ERROR/WARNING messages:
E: Cannot use chosen neighbor list style with pair sw/kk E: Must use half neighbor list style with pair sw/kk
Self-explanatory. Self-explanatory.

File diff suppressed because it is too large Load Diff

View File

@ -30,20 +30,14 @@ PairStyle(tersoff/kk/host,PairTersoffKokkos<LMPHostType>);
namespace LAMMPS_NS { namespace LAMMPS_NS {
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffComputeHalf{}; struct TagPairTersoffCompute{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffComputeFullA{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffComputeFullB{};
struct TagPairTersoffComputeShortNeigh{}; struct TagPairTersoffComputeShortNeigh{};
template<class DeviceType> template<class DeviceType>
class PairTersoffKokkos : public PairTersoff { class PairTersoffKokkos : public PairTersoff {
public: public:
enum {EnabledNeighFlags=FULL}; enum {EnabledNeighFlags=HALF|HALFTHREAD};
enum {COUL_FLAG=0}; enum {COUL_FLAG=0};
typedef DeviceType device_type; typedef DeviceType device_type;
typedef ArrayTypes<DeviceType> AT; typedef ArrayTypes<DeviceType> AT;
@ -52,90 +46,75 @@ class PairTersoffKokkos : public PairTersoff {
PairTersoffKokkos(class LAMMPS *); PairTersoffKokkos(class LAMMPS *);
~PairTersoffKokkos() override; ~PairTersoffKokkos() override;
void compute(int, int) override; void compute(int, int) override;
void coeff(int, char **) override;
void init_style() override; void init_style() override;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeHalf<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const; void operator()(TagPairTersoffCompute<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeHalf<NEIGHFLAG,EVFLAG>, const int&) const; void operator()(TagPairTersoffCompute<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeFullA<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeFullA<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeFullB<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeFullB<NEIGHFLAG,EVFLAG>, const int&) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffComputeShortNeigh, const int&) const; void operator()(TagPairTersoffComputeShortNeigh, const int&) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_fc_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_fc_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dfc(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_dfc(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_fc_k_and_ters_dfc(const int &i, const int &j, const int &k, const F_FLOAT &r, double &fc, double &dfc) const; void ters_fc_k_and_ters_dfc(const Param& param, const F_FLOAT &r, double &fc, double &dfc) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_fa_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_fa_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dfa(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_dfa(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_fa_k_and_ters_dfa(const int &i, const int &j, const int &k, const F_FLOAT &r, double &fa, double &dfa) const; void ters_fa_k_and_ters_dfa(const Param& param, const F_FLOAT &r, double &fa, double &dfa) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_bij_k(const int &i, const int &j, const int &k, const F_FLOAT &bo) const; double ters_bij_k(const Param& param, const F_FLOAT &bo) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dbij(const int &i, const int &j, const int &k, const F_FLOAT &bo) const; double ters_dbij(const Param& param, const F_FLOAT &bo) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_bij_k_and_ters_dbij(const int &i, const int &j, const int &k, const F_FLOAT &bo, double &bij, double &prefactor) const; void ters_bij_k_and_ters_dbij(const Param& param, const F_FLOAT &bo, double &bij, double &prefactor) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double bondorder(const int &i, const int &j, const int &k, double bondorder(const Param& param,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2) const; const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_gijk(const int &i, const int &j, const int &k, const F_FLOAT &cos) const; double ters_gijk(const Param& param, const F_FLOAT &cos) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dgijk(const int &i, const int &j, const int &k, const F_FLOAT &cos) const; double ters_dgijk(const Param& param, const F_FLOAT &cos) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_gijk_and_ters_dgijk(const int &i, const int &j, const int &k, const F_FLOAT &cos, double& gijk, double& dgijk) const; void ters_gijk_and_ters_dgijk(const Param& param, const F_FLOAT &cos, double& gijk, double& dgijk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthb(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthb(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk) const; F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthbj(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthbj(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fj, F_FLOAT *fk) const; F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthbk(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthbk(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fk) const; F_FLOAT *fk) const;
@ -163,17 +142,6 @@ class PairTersoffKokkos : public PairTersoff {
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
int sbmask(const int& j) const; int sbmask(const int& j) const;
struct params_ters{
KOKKOS_INLINE_FUNCTION
params_ters() {powerm=0;gamma=0;lam3=0;c=0;d=0;h=0;powern=0;beta=0;lam2=0;bigb=0;
bigr=0;bigd=0;lam1=0;biga=0;cutsq=0;c1=0;c2=0;c3=0;c4=0;};
KOKKOS_INLINE_FUNCTION
params_ters(int /*i*/) {powerm=0;gamma=0;lam3=0;c=0;d=0;h=0;powern=0;beta=0;lam2=0;bigb=0;
bigr=0;bigd=0;lam1=0;biga=0;cutsq=0;c1=0;c2=0;c3=0;c4=0;};
F_FLOAT powerm, gamma, lam3, c, d, h, powern, beta, lam2, bigb, bigr,
bigd, lam1, biga, cutsq, c1, c2, c3, c4;
};
template<int NEIGHFLAG> template<int NEIGHFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ev_tally(EV_FLOAT &ev, const int &i, const int &j, void ev_tally(EV_FLOAT &ev, const int &i, const int &j,
@ -189,16 +157,21 @@ class PairTersoffKokkos : public PairTersoff {
void v_tally3_atom(EV_FLOAT &ev, const int &i, const int &j, const int &k, void v_tally3_atom(EV_FLOAT &ev, const int &i, const int &j, const int &k,
F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const; F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const;
void allocate() override;
void setup_params() override; void setup_params() override;
protected: protected:
typedef Kokkos::DualView<int***,DeviceType> tdual_int_3d; typedef Kokkos::DualView<int***,DeviceType> tdual_int_3d;
Kokkos::DualView<params_ters***,Kokkos::LayoutRight,DeviceType> k_params; typedef typename tdual_int_3d::t_dev_const_randomread t_int_3d_randomread;
typename Kokkos::DualView<params_ters***, typedef typename tdual_int_3d::t_host t_host_int_3d;
Kokkos::LayoutRight,DeviceType>::t_dev_const_um paramskk;
// hardwired to space for 12 atom types t_int_3d_randomread d_elem3param;
//params_ters m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename AT::t_int_1d_randomread d_map;
typedef Kokkos::DualView<Param*,DeviceType> tdual_param_1d;
typedef typename tdual_param_1d::t_dev t_param_1d;
typedef typename tdual_param_1d::t_host t_host_param_1d;
t_param_1d d_params;
int inum; int inum;
typename AT::t_x_array_randomread x; typename AT::t_x_array_randomread x;
@ -254,11 +227,7 @@ class PairTersoffKokkos : public PairTersoff {
/* ERROR/WARNING messages: /* ERROR/WARNING messages:
E: Cannot (yet) use full neighbor list style with tersoff/kk E: Must use half neighbor list style with pair tersoff/kk
Self-explanatory.
E: Cannot use chosen neighbor list style with tersoff/kk
Self-explanatory. Self-explanatory.

File diff suppressed because it is too large Load Diff

View File

@ -30,20 +30,14 @@ PairStyle(tersoff/mod/kk/host,PairTersoffMODKokkos<LMPHostType>);
namespace LAMMPS_NS { namespace LAMMPS_NS {
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffMODComputeHalf{}; struct TagPairTersoffMODCompute{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffMODComputeFullA{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffMODComputeFullB{};
struct TagPairTersoffMODComputeShortNeigh{}; struct TagPairTersoffMODComputeShortNeigh{};
template<class DeviceType> template<class DeviceType>
class PairTersoffMODKokkos : public PairTersoffMOD { class PairTersoffMODKokkos : public PairTersoffMOD {
public: public:
enum {EnabledNeighFlags=FULL}; enum {EnabledNeighFlags=HALF|HALFTHREAD};
enum {COUL_FLAG=0}; enum {COUL_FLAG=0};
typedef DeviceType device_type; typedef DeviceType device_type;
typedef ArrayTypes<DeviceType> AT; typedef ArrayTypes<DeviceType> AT;
@ -52,81 +46,66 @@ class PairTersoffMODKokkos : public PairTersoffMOD {
PairTersoffMODKokkos(class LAMMPS *); PairTersoffMODKokkos(class LAMMPS *);
~PairTersoffMODKokkos() override; ~PairTersoffMODKokkos() override;
void compute(int, int) override; void compute(int, int) override;
void coeff(int, char **) override;
void init_style() override; void init_style() override;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeHalf<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const; void operator()(TagPairTersoffMODCompute<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeHalf<NEIGHFLAG,EVFLAG>, const int&) const; void operator()(TagPairTersoffMODCompute<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeFullA<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeFullA<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeFullB<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeFullB<NEIGHFLAG,EVFLAG>, const int&) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffMODComputeShortNeigh, const int&) const; void operator()(TagPairTersoffMODComputeShortNeigh, const int&) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_fc_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_fc_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dfc(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_dfc(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_fa_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_fa_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dfa(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_dfa(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_bij_k(const int &i, const int &j, const int &k, const F_FLOAT &bo) const; double ters_bij_k(const Param& param, const F_FLOAT &bo) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dbij(const int &i, const int &j, const int &k, const F_FLOAT &bo) const; double ters_dbij(const Param& param, const F_FLOAT &bo) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double bondorder(const int &i, const int &j, const int &k, double bondorder(const Param& param,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2) const; const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_gijk(const int &i, const int &j, const int &k, const F_FLOAT &cos) const; double ters_gijk(const Param& param, const F_FLOAT &cos) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dgijk(const int &i, const int &j, const int &k, const F_FLOAT &cos) const; double ters_dgijk(const Param& param, const F_FLOAT &cos) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthb(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthb(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk) const; F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthbj(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthbj(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fj, F_FLOAT *fk) const; F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthbk(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthbk(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fk) const; F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double vec3_dot(const F_FLOAT x[3], const double y[3]) const { double vec3_dot(const F_FLOAT x[3], const double y[3]) const {
@ -151,17 +130,6 @@ class PairTersoffMODKokkos : public PairTersoffMOD {
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
int sbmask(const int& j) const; int sbmask(const int& j) const;
struct params_ters {
KOKKOS_INLINE_FUNCTION
params_ters() {powerm=0;lam3=0;h=0;powern=0;beta=0;lam2=0;bigb=0;bigr=0;bigd=0;
lam1=0;biga=0;powern_del=0;cutsq=0;c1=0;c2=0;c3=0;c4=0;c5=0;ca1=0;ca4=0;};
KOKKOS_INLINE_FUNCTION
params_ters(int /*i*/) {powerm=0;lam3=0;h=0;powern=0;beta=0;lam2=0;bigb=0;bigr=0;bigd=0;
lam1=0;biga=0;powern_del=0;cutsq=0;c1=0;c2=0;c3=0;c4=0;c5=0;ca1=0;ca4=0;};
F_FLOAT powerm, lam3, h, powern, beta, lam2, bigb, bigr, bigd,
lam1, biga, powern_del, cutsq, c1, c2, c3, c4, c5, ca1, ca4;
};
template<int NEIGHFLAG> template<int NEIGHFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ev_tally(EV_FLOAT &ev, const int &i, const int &j, void ev_tally(EV_FLOAT &ev, const int &i, const int &j,
@ -171,24 +139,27 @@ class PairTersoffMODKokkos : public PairTersoffMOD {
template<int NEIGHFLAG> template<int NEIGHFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void v_tally3(EV_FLOAT &ev, const int &i, const int &j, const int &k, void v_tally3(EV_FLOAT &ev, const int &i, const int &j, const int &k,
F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drij, F_FLOAT *drik) const; F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drij, F_FLOAT *drik) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void v_tally3_atom(EV_FLOAT &ev, const int &i, const int &j, const int &k, void v_tally3_atom(EV_FLOAT &ev, const int &i, const int &j, const int &k,
F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const; F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const;
void allocate() override;
void setup_params() override; void setup_params() override;
protected: protected:
using KKDeviceType = typename KKDevice<DeviceType>::value;
typedef Kokkos::DualView<int***,DeviceType> tdual_int_3d; typedef Kokkos::DualView<int***,DeviceType> tdual_int_3d;
Kokkos::DualView<params_ters***,Kokkos::LayoutRight,DeviceType> k_params; typedef typename tdual_int_3d::t_dev_const_randomread t_int_3d_randomread;
typename Kokkos::DualView<params_ters***, typedef typename tdual_int_3d::t_host t_host_int_3d;
Kokkos::LayoutRight,DeviceType>::t_dev_const_um paramskk;
// hardwired to space for 12 atom types t_int_3d_randomread d_elem3param;
//params_ters m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename AT::t_int_1d_randomread d_map;
typedef Kokkos::DualView<Param*,DeviceType> tdual_param_1d;
typedef typename tdual_param_1d::t_dev t_param_1d;
typedef typename tdual_param_1d::t_host t_host_param_1d;
t_param_1d d_params;
int inum; int inum;
typename AT::t_x_array_randomread x; typename AT::t_x_array_randomread x;
@ -203,6 +174,7 @@ class PairTersoffMODKokkos : public PairTersoffMOD {
int need_dup; int need_dup;
using KKDeviceType = typename KKDevice<DeviceType>::value;
template<typename DataType, typename Layout> template<typename DataType, typename Layout>
using DupScatterView = KKScatterView<DataType, Layout, KKDeviceType, KKScatterSum, KKScatterDuplicated>; using DupScatterView = KKScatterView<DataType, Layout, KKDeviceType, KKScatterSum, KKScatterDuplicated>;
@ -213,6 +185,7 @@ class PairTersoffMODKokkos : public PairTersoffMOD {
DupScatterView<F_FLOAT*[3], typename DAT::t_f_array::array_layout> dup_f; DupScatterView<F_FLOAT*[3], typename DAT::t_f_array::array_layout> dup_f;
DupScatterView<E_FLOAT*, typename DAT::t_efloat_1d::array_layout> dup_eatom; DupScatterView<E_FLOAT*, typename DAT::t_efloat_1d::array_layout> dup_eatom;
DupScatterView<F_FLOAT*[6], typename DAT::t_virial_array::array_layout> dup_vatom; DupScatterView<F_FLOAT*[6], typename DAT::t_virial_array::array_layout> dup_vatom;
NonDupScatterView<F_FLOAT*[3], typename DAT::t_f_array::array_layout> ndup_f; NonDupScatterView<F_FLOAT*[3], typename DAT::t_f_array::array_layout> ndup_f;
NonDupScatterView<E_FLOAT*, typename DAT::t_efloat_1d::array_layout> ndup_eatom; NonDupScatterView<E_FLOAT*, typename DAT::t_efloat_1d::array_layout> ndup_eatom;
NonDupScatterView<F_FLOAT*[6], typename DAT::t_virial_array::array_layout> ndup_vatom; NonDupScatterView<F_FLOAT*[6], typename DAT::t_virial_array::array_layout> ndup_vatom;
@ -242,11 +215,7 @@ class PairTersoffMODKokkos : public PairTersoffMOD {
/* ERROR/WARNING messages: /* ERROR/WARNING messages:
E: Cannot (yet) use full neighbor list style with tersoff/mod/kk E: Must use half neighbor list style with pair tersoff/mod/kk
Self-explanatory.
E: Cannot use chosen neighbor list style with tersoff/mod/kk
Self-explanatory. Self-explanatory.

File diff suppressed because it is too large Load Diff

View File

@ -30,20 +30,14 @@ PairStyle(tersoff/zbl/kk/host,PairTersoffZBLKokkos<LMPHostType>);
namespace LAMMPS_NS { namespace LAMMPS_NS {
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffZBLComputeHalf{}; struct TagPairTersoffZBLCompute{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffZBLComputeFullA{};
template<int NEIGHFLAG, int EVFLAG>
struct TagPairTersoffZBLComputeFullB{};
struct TagPairTersoffZBLComputeShortNeigh{}; struct TagPairTersoffZBLComputeShortNeigh{};
template<class DeviceType> template<class DeviceType>
class PairTersoffZBLKokkos : public PairTersoffZBL { class PairTersoffZBLKokkos : public PairTersoffZBL {
public: public:
enum {EnabledNeighFlags=FULL}; enum {EnabledNeighFlags=HALF|HALFTHREAD};
enum {COUL_FLAG=0}; enum {COUL_FLAG=0};
typedef DeviceType device_type; typedef DeviceType device_type;
typedef ArrayTypes<DeviceType> AT; typedef ArrayTypes<DeviceType> AT;
@ -52,80 +46,66 @@ class PairTersoffZBLKokkos : public PairTersoffZBL {
PairTersoffZBLKokkos(class LAMMPS *); PairTersoffZBLKokkos(class LAMMPS *);
~PairTersoffZBLKokkos() override; ~PairTersoffZBLKokkos() override;
void compute(int, int) override; void compute(int, int) override;
void coeff(int, char **) override;
void init_style() override; void init_style() override;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeHalf<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const; void operator()(TagPairTersoffZBLCompute<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG> template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeHalf<NEIGHFLAG,EVFLAG>, const int&) const; void operator()(TagPairTersoffZBLCompute<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeFullA<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeFullA<NEIGHFLAG,EVFLAG>, const int&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeFullB<NEIGHFLAG,EVFLAG>, const int&, EV_FLOAT&) const;
template<int NEIGHFLAG, int EVFLAG>
KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeFullB<NEIGHFLAG,EVFLAG>, const int&) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void operator()(TagPairTersoffZBLComputeShortNeigh, const int&) const; void operator()(TagPairTersoffZBLComputeShortNeigh, const int&) const;
KOKKOS_INLINE_FUNCTION
double ters_fc_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dfc(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_fc_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_fa_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_dfc(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dfa(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double ters_fa_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_bij_k(const int &i, const int &j, const int &k, const F_FLOAT &bo) const; double ters_dfa(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dbij(const int &i, const int &j, const int &k, const F_FLOAT &bo) const; double ters_bij_k(const Param& param, const F_FLOAT &bo) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double bondorder(const int &i, const int &j, const int &k, double ters_dbij(const Param& param, const F_FLOAT &bo) const;
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_gijk(const int &i, const int &j, const int &k, const F_FLOAT &cos) const; double bondorder(const Param& param,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double ters_dgijk(const int &i, const int &j, const int &k, const F_FLOAT &cos) const; double ters_gijk(const Param& param, const F_FLOAT &cos) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthb(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, double ters_dgijk(const Param& param, const F_FLOAT &cos) const;
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthbj(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthb(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fj, F_FLOAT *fk) const; F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ters_dthbk(const int &i, const int &j, const int &k, const F_FLOAT &prefactor, void ters_dthbj(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1, const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2, const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fk) const; F_FLOAT *fj, F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION
void ters_dthbk(const Param& param, const F_FLOAT &prefactor,
const F_FLOAT &rij, const F_FLOAT &dx1, const F_FLOAT &dy1, const F_FLOAT &dz1,
const F_FLOAT &rik, const F_FLOAT &dx2, const F_FLOAT &dy2, const F_FLOAT &dz2,
F_FLOAT *fk) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double vec3_dot(const F_FLOAT x[3], const double y[3]) const { double vec3_dot(const F_FLOAT x[3], const double y[3]) const {
@ -150,17 +130,6 @@ class PairTersoffZBLKokkos : public PairTersoffZBL {
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
int sbmask(const int& j) const; int sbmask(const int& j) const;
struct params_ters {
KOKKOS_INLINE_FUNCTION
params_ters() {powerm=0;gamma=0;lam3=0;c=0;d=0;h=0;powern=0;beta=0;lam2=0;bigb=0;
bigr=0;bigd=0;lam1=0;biga=0;cutsq=0;c1=0;c2=0;c3=0;c4=0;Z_i=0;Z_j=0;ZBLcut=0;ZBLexpscale=0;};
KOKKOS_INLINE_FUNCTION
params_ters(int /*i*/) {powerm=0;gamma=0;lam3=0;c=0;d=0;h=0;powern=0;beta=0;lam2=0;bigb=0;
bigr=0;bigd=0;lam1=0;biga=0;cutsq=0;c1=0;c2=0;c3=0;c4=0;Z_i=0;Z_j=0;ZBLcut=0;ZBLexpscale=0;};
F_FLOAT powerm, gamma, lam3, c, d, h, powern, beta, lam2, bigb, bigr,
bigd, lam1, biga, cutsq, c1, c2, c3, c4, Z_i, Z_j, ZBLcut, ZBLexpscale;
};
template<int NEIGHFLAG> template<int NEIGHFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void ev_tally(EV_FLOAT &ev, const int &i, const int &j, void ev_tally(EV_FLOAT &ev, const int &i, const int &j,
@ -170,28 +139,33 @@ class PairTersoffZBLKokkos : public PairTersoffZBL {
template<int NEIGHFLAG> template<int NEIGHFLAG>
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void v_tally3(EV_FLOAT &ev, const int &i, const int &j, const int &k, void v_tally3(EV_FLOAT &ev, const int &i, const int &j, const int &k,
F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drij, F_FLOAT *drik) const; F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drij, F_FLOAT *drik) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
void v_tally3_atom(EV_FLOAT &ev, const int &i, const int &j, const int &k, void v_tally3_atom(EV_FLOAT &ev, const int &i, const int &j, const int &k,
F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const; F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const;
void allocate() override;
void setup_params() override; void setup_params() override;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double fermi_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double fermi_k(const Param& param, const F_FLOAT &r) const;
KOKKOS_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
double fermi_d_k(const int &i, const int &j, const int &k, const F_FLOAT &r) const; double fermi_d_k(const Param& param, const F_FLOAT &r) const;
protected: protected:
typedef Kokkos::DualView<int***,DeviceType> tdual_int_3d; typedef Kokkos::DualView<int***,DeviceType> tdual_int_3d;
Kokkos::DualView<params_ters***,Kokkos::LayoutRight,DeviceType> k_params; typedef typename tdual_int_3d::t_dev_const_randomread t_int_3d_randomread;
typename Kokkos::DualView<params_ters***, typedef typename tdual_int_3d::t_host t_host_int_3d;
Kokkos::LayoutRight,DeviceType>::t_dev_const_um paramskk;
// hardwired to space for 12 atom types t_int_3d_randomread d_elem3param;
//params_ters m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename AT::t_int_1d_randomread d_map;
typedef Kokkos::DualView<Param*,DeviceType> tdual_param_1d;
typedef typename tdual_param_1d::t_dev t_param_1d;
typedef typename tdual_param_1d::t_host t_host_param_1d;
t_param_1d d_params;
int inum; int inum;
typename AT::t_x_array_randomread x; typename AT::t_x_array_randomread x;
@ -238,7 +212,7 @@ class PairTersoffZBLKokkos : public PairTersoffZBL {
Kokkos::View<int*,DeviceType> d_numneigh_short; Kokkos::View<int*,DeviceType> d_numneigh_short;
// ZBL // ZBL
F_FLOAT global_a_0; // Bohr radius for Coulomb repulsion F_FLOAT global_a_0; // Bohr radius for Coulomb repulsion
F_FLOAT global_epsilon_0; // permittivity of vacuum for Coulomb repulsion F_FLOAT global_epsilon_0; // permittivity of vacuum for Coulomb repulsion
F_FLOAT global_e; // proton charge (negative of electron charge) F_FLOAT global_e; // proton charge (negative of electron charge)
@ -256,11 +230,7 @@ E: Pair tersoff/zbl/kk requires metal or real units
This is a current restriction of this pair potential. This is a current restriction of this pair potential.
E: Cannot (yet) use full neighbor list style with tersoff/zbl/kk E: Must use half neighbor list style with pair tersoff/zlb/kk
Self-explanatory.
E: Cannot use chosen neighbor list style with tersoff/zbl/kk
Self-explanatory. Self-explanatory.

View File

@ -38,7 +38,6 @@ class PairTersoff : public Pair {
static constexpr int NPARAMS_PER_LINE = 17; static constexpr int NPARAMS_PER_LINE = 17;
protected:
struct Param { struct Param {
double lam1, lam2, lam3; double lam1, lam2, lam3;
double c, d, h; double c, d, h;
@ -56,6 +55,7 @@ class PairTersoff : public Pair {
double c0; // added for TersoffMODC double c0; // added for TersoffMODC
}; };
protected:
Param *params; // parameter set for an I-J-K interaction Param *params; // parameter set for an I-J-K interaction
double cutmax; // max cutoff for all elements double cutmax; // max cutoff for all elements
int maxshort; // size of short neighbor list array int maxshort; // size of short neighbor list array

View File

@ -19,11 +19,14 @@
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
#include "memory.h" #include "memory.h"
#include "modify.h"
#include "neighbor.h" #include "neighbor.h"
#include "random_mars.h" #include "random_mars.h"
#include "respa.h" #include "respa.h"
#include "update.h" #include "update.h"
#include "fix_bond_history.h"
#include <cstring> #include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -258,6 +261,10 @@ void FixBondBreak::post_integrate()
commflag = 1; commflag = 1;
comm->forward_comm(this,2); comm->forward_comm(this,2);
// find instances of bond history to delete data
auto histories = modify->get_fix_by_style("BOND_HISTORY");
int n_histories = histories.size();
// break bonds // break bonds
// if both atoms list each other as winning bond partner // if both atoms list each other as winning bond partner
// and probability constraint is satisfied // and probability constraint is satisfied
@ -292,7 +299,13 @@ void FixBondBreak::post_integrate()
for (k = m; k < num_bond[i]-1; k++) { for (k = m; k < num_bond[i]-1; k++) {
bond_atom[i][k] = bond_atom[i][k+1]; bond_atom[i][k] = bond_atom[i][k+1];
bond_type[i][k] = bond_type[i][k+1]; bond_type[i][k] = bond_type[i][k+1];
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->shift_history(i,k,k+1);
} }
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i,num_bond[i]-1);
num_bond[i]--; num_bond[i]--;
break; break;
} }

View File

@ -17,21 +17,15 @@
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "fix_bond_create_angle.h" #include "fix_bond_create_angle.h"
#include "atom.h" #include "atom.h"
#include <cmath> #include <cmath>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixBondCreateAngle::FixBondCreateAngle(LAMMPS *lmp, int narg, char **arg) :
FixBondCreate(lmp, narg, arg)
{
}
/* ---------------------------------------------------------------------- */
int FixBondCreateAngle::constrain(int i, int j, double amin, double amax) int FixBondCreateAngle::constrain(int i, int j, double amin, double amax)
{ {
double **x = atom->x; double **x = atom->x;

View File

@ -26,7 +26,7 @@ namespace LAMMPS_NS {
class FixBondCreateAngle : public FixBondCreate { class FixBondCreateAngle : public FixBondCreate {
public: public:
FixBondCreateAngle(class LAMMPS *, int, char **); FixBondCreateAngle(LAMMPS *_lmp, int narg, char **arg) : FixBondCreate(_lmp, narg, arg) {}
private: private:
int constrain(int, int, double, double) override; int constrain(int, int, double, double) override;

View File

@ -22,6 +22,7 @@
#include "compute.h" #include "compute.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_bond_history.h"
#include "force.h" #include "force.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
@ -446,6 +447,10 @@ void FixBondSwap::post_integrate()
if (!accept) return; if (!accept) return;
naccept++; naccept++;
// find instances of bond/history to reset history
auto histories = modify->get_fix_by_style("BOND_HISTORY");
int n_histories = histories.size();
// change bond partners of affected atoms // change bond partners of affected atoms
// on atom i: bond i-inext changes to i-jnext // on atom i: bond i-inext changes to i-jnext
// on atom j: bond j-jnext changes to j-inext // on atom j: bond j-jnext changes to j-inext
@ -453,13 +458,33 @@ void FixBondSwap::post_integrate()
// on atom jnext: bond jnext-j changes to jnext-i // on atom jnext: bond jnext-j changes to jnext-i
for (ibond = 0; ibond < num_bond[i]; ibond++) for (ibond = 0; ibond < num_bond[i]; ibond++)
if (bond_atom[i][ibond] == tag[inext]) bond_atom[i][ibond] = tag[jnext]; if (bond_atom[i][ibond] == tag[inext]) {
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i,ibond);
bond_atom[i][ibond] = tag[jnext];
}
for (jbond = 0; jbond < num_bond[j]; jbond++) for (jbond = 0; jbond < num_bond[j]; jbond++)
if (bond_atom[j][jbond] == tag[jnext]) bond_atom[j][jbond] = tag[inext]; if (bond_atom[j][jbond] == tag[jnext]) {
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(j,jbond);
bond_atom[j][jbond] = tag[inext];
}
for (ibond = 0; ibond < num_bond[inext]; ibond++) for (ibond = 0; ibond < num_bond[inext]; ibond++)
if (bond_atom[inext][ibond] == tag[i]) bond_atom[inext][ibond] = tag[j]; if (bond_atom[inext][ibond] == tag[i]) {
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(inext,ibond);
bond_atom[inext][ibond] = tag[j];
}
for (jbond = 0; jbond < num_bond[jnext]; jbond++) for (jbond = 0; jbond < num_bond[jnext]; jbond++)
if (bond_atom[jnext][jbond] == tag[j]) bond_atom[jnext][jbond] = tag[i]; if (bond_atom[jnext][jbond] == tag[j]) {
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(jnext,jbond);
bond_atom[jnext][jbond] = tag[i];
}
// set global tags of 4 atoms in bonds // set global tags of 4 atoms in bonds

View File

@ -29,7 +29,7 @@ enum { NATIVE, REAL, METAL }; // LAMMPS units which MDI supports
FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
{ {
if (narg > 4) error->all(FLERR, "Illegal fix mdi/aimd command"); if (narg != 3) error->all(FLERR, "Illegal fix mdi/aimd command");
scalar_flag = 1; scalar_flag = 1;
global_freq = 1; global_freq = 1;
@ -38,16 +38,6 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
virial_global_flag = 1; virial_global_flag = 1;
thermo_energy = thermo_virial = 1; thermo_energy = thermo_virial = 1;
// check for plugin arg
plugin = 0;
if (narg == 4) {
if (strcmp(arg[3], "plugin") == 0)
plugin = 1;
else
error->all(FLERR, "Illegal fix mdi/aimd command");
}
// check requirements for LAMMPS to work with MDI as an engine // check requirements for LAMMPS to work with MDI as an engine
if (atom->tag_enable == 0) error->all(FLERR, "Cannot use MDI engine without atom IDs"); if (atom->tag_enable == 0) error->all(FLERR, "Cannot use MDI engine without atom IDs");
@ -62,6 +52,11 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
if (role != MDI_DRIVER) if (role != MDI_DRIVER)
error->all(FLERR, "Must invoke LAMMPS as an MDI driver to use fix mdi/aimd"); error->all(FLERR, "Must invoke LAMMPS as an MDI driver to use fix mdi/aimd");
// mdicomm will be one-time initialized in init()
// cannot be done here for a plugin library, b/c mdi plugin command is later
mdicomm = MDI_COMM_NULL;
// storage for all atoms // storage for all atoms
buf3 = buf3all = nullptr; buf3 = buf3all = nullptr;
@ -78,13 +73,6 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
unit_conversions(); unit_conversions();
// connect to MDI engine, only if engine is stand-alone code
if (!plugin) {
MDI_Accept_communicator(&mdicomm);
if (mdicomm <= 0) error->all(FLERR, "Unable to connect to MDI engine");
}
nprocs = comm->nprocs; nprocs = comm->nprocs;
} }
@ -92,7 +80,8 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
FixMDIAimd::~FixMDIAimd() FixMDIAimd::~FixMDIAimd()
{ {
// send exit command to engine, only if engine is stand-alone code // send exit command to engine if it is a stand-alone code
// for plugin, this happens in MDIPlugin::plugin_wrapper()
if (!plugin) { if (!plugin) {
int ierr = MDI_Send_command("EXIT", mdicomm); int ierr = MDI_Send_command("EXIT", mdicomm);
@ -118,6 +107,30 @@ int FixMDIAimd::setmask()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void FixMDIAimd::init()
{
if (mdicomm != MDI_COMM_NULL) return;
// one-time auto-detect whether engine is stand-alone code or plugin library
// also initializes mdicomm
// plugin = 0/1 for engine = stand-alone code vs plugin library
MDI_Get_communicator(&mdicomm, 0);
if (mdicomm == MDI_COMM_NULL) {
plugin = 0;
MDI_Accept_communicator(&mdicomm);
if (mdicomm == MDI_COMM_NULL) error->all(FLERR, "MDI unable to connect to stand-alone engine");
} else {
plugin = 1;
int method;
MDI_Get_method(&method, mdicomm);
if (method != MDI_PLUGIN) error->all(FLERR, "MDI internal error for plugin engine");
}
}
/* ---------------------------------------------------------------------- */
void FixMDIAimd::setup(int vflag) void FixMDIAimd::setup(int vflag)
{ {
post_force(vflag); post_force(vflag);

View File

@ -27,14 +27,11 @@ namespace LAMMPS_NS {
class FixMDIAimd : public Fix { class FixMDIAimd : public Fix {
public: public:
// MDI communicator, public so that LAMMPS can work with a plugin
MDI_Comm mdicomm;
FixMDIAimd(class LAMMPS *, int, char **); FixMDIAimd(class LAMMPS *, int, char **);
~FixMDIAimd(); ~FixMDIAimd();
int setmask(); int setmask();
void init();
void setup(int); void setup(int);
void setup_pre_reverse(int, int); void setup_pre_reverse(int, int);
void pre_reverse(int, int); void pre_reverse(int, int);
@ -46,6 +43,8 @@ class FixMDIAimd : public Fix {
int nprocs; int nprocs;
int plugin; int plugin;
MDI_Comm mdicomm;
int eflag_caller; int eflag_caller;
double engine_energy; double engine_energy;
int lmpunits; int lmpunits;

View File

@ -601,7 +601,8 @@ void MDIEngine::mdi_md()
// delete the instance before this method returns // delete the instance before this method returns
modify->add_fix("MDI_ENGINE_INTERNAL all MDI/ENGINE"); modify->add_fix("MDI_ENGINE_INTERNAL all MDI/ENGINE");
FixMDIEngine *mdi_fix = dynamic_cast<FixMDIEngine *>( modify->get_fix_by_id("MDI_ENGINE_INTERNAL")); FixMDIEngine *mdi_fix =
dynamic_cast<FixMDIEngine *>(modify->get_fix_by_id("MDI_ENGINE_INTERNAL"));
mdi_fix->mdi_engine = this; mdi_fix->mdi_engine = this;
// initialize LAMMPS and setup() the simulation // initialize LAMMPS and setup() the simulation
@ -723,7 +724,8 @@ void MDIEngine::mdi_optg()
// delete the instance before this method returns // delete the instance before this method returns
modify->add_fix("MDI_ENGINE_INTERNAL all MDI/ENGINE"); modify->add_fix("MDI_ENGINE_INTERNAL all MDI/ENGINE");
FixMDIEngine *mdi_fix = dynamic_cast<FixMDIEngine *>( modify->get_fix_by_id("MDI_ENGINE_INTERNAL")); FixMDIEngine *mdi_fix =
dynamic_cast<FixMDIEngine *>(modify->get_fix_by_id("MDI_ENGINE_INTERNAL"));
mdi_fix->mdi_engine = this; mdi_fix->mdi_engine = this;
// initialize LAMMPS and setup() the simulation // initialize LAMMPS and setup() the simulation
@ -956,7 +958,8 @@ void MDIEngine::create_system()
// optionally set charges if specified by ">CHARGES" // optionally set charges if specified by ">CHARGES"
if (flag_velocities) if (flag_velocities)
lammps_create_atoms(lmp, sys_natoms, nullptr, sys_types, sys_coords, sys_velocities, nullptr, 1); lammps_create_atoms(lmp, sys_natoms, nullptr, sys_types, sys_coords, sys_velocities, nullptr,
1);
else else
lammps_create_atoms(lmp, sys_natoms, nullptr, sys_types, sys_coords, nullptr, nullptr, 1); lammps_create_atoms(lmp, sys_natoms, nullptr, sys_types, sys_coords, nullptr, nullptr, 1);

View File

@ -92,11 +92,6 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp)
strcat(plugin_args, extra_arg); strcat(plugin_args, extra_arg);
} }
// find FixMDIAimd instance so can reset its mdicomm
// NOTE: this is a kludge - need better way to handle this
fixptr = modify->get_fix_by_style("mdi/aimd")[0];
// launch the MDI plugin library // launch the MDI plugin library
// path for lib was specified in -mdi command-line arg when LAMMPS started // path for lib was specified in -mdi command-line arg when LAMMPS started
// this calls back to plugin_wrapper, which must issue MDI EXIT at end // this calls back to plugin_wrapper, which must issue MDI EXIT at end
@ -108,8 +103,7 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp)
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
callback function from MDI_Launch_plugin() callback function from MDI_Launch_plugin()
this function must wrap entire interaction of LAMMPS as a driver this function wraps entire interaction of LAMMPS driver with the plugin
with the plugin
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
int MDIPlugin::plugin_wrapper(void * /*pmpicomm*/, MDI_Comm mdicomm, void *vptr) int MDIPlugin::plugin_wrapper(void * /*pmpicomm*/, MDI_Comm mdicomm, void *vptr)
@ -118,11 +112,6 @@ int MDIPlugin::plugin_wrapper(void * /*pmpicomm*/, MDI_Comm mdicomm, void *vptr)
LAMMPS *lammps = ptr->lmp; LAMMPS *lammps = ptr->lmp;
char *lammps_command = ptr->lammps_command; char *lammps_command = ptr->lammps_command;
// set FixMDIAimd mdicomm to driver's mdicomm passed to this callback
auto aimdptr = dynamic_cast<FixMDIAimd *> (ptr->fixptr);
aimdptr->mdicomm = mdicomm;
// invoke the specified LAMMPS command // invoke the specified LAMMPS command
// that operation will issue MDI commands to the plugin engine // that operation will issue MDI commands to the plugin engine

View File

@ -25,7 +25,6 @@ class MDIPlugin : protected Pointers {
private: private:
char *lammps_command; char *lammps_command;
class Fix *fixptr;
static int plugin_wrapper(void *, MDI_Comm, void *); static int plugin_wrapper(void *, MDI_Comm, void *);
}; };

View File

@ -1,350 +0,0 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/ Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "fix_pair_tracker.h"
#include "atom.h"
#include "error.h"
#include "memory.h"
#include "tokenizer.h"
#include "update.h"
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;
#define DELTA 1000
/* ---------------------------------------------------------------------- */
FixPairTracker::FixPairTracker(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), nvalues(0), vector(nullptr), array(nullptr), pack_choice(nullptr)
{
if (narg < 3) error->all(FLERR, "Illegal fix pair/tracker command");
local_flag = 1;
nevery = utils::inumeric(FLERR, arg[3], false, lmp);
if (nevery <= 0) error->all(FLERR, "Illegal fix pair/tracker command");
local_freq = nevery;
// If optional arguments included, this will be oversized
nvalues = narg - 4;
pack_choice = new FnPtrPack[nvalues];
tmin = -1;
type_filter = nullptr;
int iarg = 4;
nvalues = 0;
while (iarg < narg) {
if (strcmp(arg[iarg], "id1") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_id1;
} else if (strcmp(arg[iarg], "id2") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_id2;
} else if (strcmp(arg[iarg], "time/created") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_time_created;
} else if (strcmp(arg[iarg], "time/broken") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_time_broken;
} else if (strcmp(arg[iarg], "time/total") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_time_total;
} else if (strcmp(arg[iarg], "x") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_x;
} else if (strcmp(arg[iarg], "y") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_y;
} else if (strcmp(arg[iarg], "z") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_z;
} else if (strcmp(arg[iarg], "r/min") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_rmin;
} else if (strcmp(arg[iarg], "r/ave") == 0) {
pack_choice[nvalues++] = &FixPairTracker::pack_rave;
} else if (strcmp(arg[iarg], "time/min") == 0) {
if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in fix pair/tracker command");
tmin = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg++;
} else if (strcmp(arg[iarg], "type/include") == 0) {
if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in fix pair/tracker command");
int ntypes = atom->ntypes;
int i, j, itype, jtype;
int inlo, inhi, jnlo, jnhi;
if (!type_filter) {
memory->create(type_filter, ntypes + 1, ntypes + 1, "fix/pair/tracker:type_filter");
for (i = 0; i <= ntypes; i++) {
for (j = 0; j <= ntypes; j++) type_filter[i][j] = 0;
}
}
auto iwords = Tokenizer(arg[iarg + 1], ",").as_vector();
auto jwords = Tokenizer(arg[iarg + 2], ",").as_vector();
for (const auto &ifield : iwords) {
utils::bounds(FLERR, ifield, 1, ntypes, inlo, inhi, error);
for (const auto &jfield : jwords) {
utils::bounds(FLERR, jfield, 1, ntypes, jnlo, jnhi, error);
for (itype = inlo; itype <= inhi; itype++) {
for (jtype = jnlo; jtype <= jnhi; jtype++) {
type_filter[itype][jtype] = 1;
type_filter[jtype][itype] = 1;
}
}
}
}
iarg += 2;
} else
error->all(FLERR, "Invalid keyword in fix pair/tracker command");
iarg++;
}
if (nvalues == 1)
size_local_cols = 0;
else
size_local_cols = nvalues;
nmax = 0;
ncount = 0;
vector = nullptr;
array = nullptr;
}
/* ---------------------------------------------------------------------- */
FixPairTracker::~FixPairTracker()
{
delete[] pack_choice;
memory->destroy(vector);
memory->destroy(array);
memory->destroy(type_filter);
}
/* ---------------------------------------------------------------------- */
int FixPairTracker::setmask()
{
int mask = 0;
mask |= POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::init()
{
// Set size of array/vector
ncount = 0;
if (ncount > nmax) reallocate(ncount);
size_local_rows = ncount;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::lost_contact(int i, int j, double time_tmp, double nstep_tmp, double rsum_tmp,
double rmin_tmp)
{
double time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
if ((time - time_tmp) < tmin) return;
if (type_filter) {
int *type = atom->type;
if (type_filter[type[i]][type[j]] == 0) return;
}
int *mask = atom->mask;
if (!(mask[i] & groupbit)) return;
if (!(mask[j] & groupbit)) return;
if (ncount == nmax) reallocate(ncount);
index_i = i;
index_j = j;
rmin = rmin_tmp;
rsum = rsum_tmp;
time_initial = time_tmp;
nstep_initial = nstep_tmp;
// fill vector or array with local values
if (nvalues == 1) {
(this->*pack_choice[0])(0);
} else {
for (int k = 0; k < nvalues; k++) { (this->*pack_choice[k])(k); }
}
ncount += 1;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::post_force(int /*vflag*/)
{
if (update->ntimestep % nevery == 0) {
size_local_rows = ncount;
ncount = 0;
}
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::reallocate(int n)
{
// grow vector or array
while (nmax <= n) nmax += DELTA;
if (nvalues == 1) {
memory->grow(vector, nmax, "fix_pair_tracker:vector");
vector_local = vector;
} else {
memory->grow(array, nmax, nvalues, "fix_pair_tracker:array");
array_local = array;
}
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
double FixPairTracker::memory_usage()
{
double bytes = nmax * (double) nvalues * sizeof(double);
bytes += nmax * 2 * sizeof(int);
return bytes;
}
/* ----------------------------------------------------------------------
one method for every keyword fix pair/tracker can output
the atom property is packed into a local vector or array
------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_time_created(int n)
{
if (nvalues == 1)
vector[ncount] = time_initial;
else
array[ncount][n] = time_initial;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_time_broken(int n)
{
double time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
if (nvalues == 1)
vector[ncount] = time;
else
array[ncount][n] = time;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_time_total(int n)
{
double time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
if (nvalues == 1)
vector[ncount] = time - time_initial;
else
array[ncount][n] = time - time_initial;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_id1(int n)
{
tagint *tag = atom->tag;
if (nvalues == 1)
vector[ncount] = tag[index_i];
else
array[ncount][n] = tag[index_i];
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_id2(int n)
{
tagint *tag = atom->tag;
if (nvalues == 1)
vector[ncount] = tag[index_j];
else
array[ncount][n] = tag[index_j];
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_x(int n)
{
double **x = atom->x;
if (nvalues == 1)
vector[ncount] = (x[index_i][0] + x[index_j][0]) / 2;
else
array[ncount][n] = (x[index_i][0] + x[index_j][0]) / 2;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_y(int n)
{
double **x = atom->x;
if (nvalues == 1)
vector[ncount] = (x[index_i][1] + x[index_j][1]) / 2;
else
array[ncount][n] = (x[index_i][1] + x[index_j][1]) / 2;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_z(int n)
{
double **x = atom->x;
if (nvalues == 1)
vector[ncount] = (x[index_i][2] + x[index_j][2]) / 2;
else
array[ncount][n] = (x[index_i][2] + x[index_j][2]) / 2;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_rmin(int n)
{
if (nvalues == 1)
vector[ncount] = rmin;
else
array[ncount][n] = rmin;
}
/* ---------------------------------------------------------------------- */
void FixPairTracker::pack_rave(int n)
{
if (nvalues == 1)
vector[ncount] = rsum / (update->ntimestep - nstep_initial);
else
array[ncount][n] = rsum / (update->ntimestep - nstep_initial);
}

View File

@ -19,39 +19,41 @@
#include "fix.h" #include "fix.h"
#include "fix_dummy.h" #include "fix_dummy.h"
#include "fix_neigh_history.h" #include "fix_neigh_history.h"
#include "fix_pair_tracker.h" #include "fix_store_local.h"
#include "force.h" #include "force.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
#include "neigh_list.h" #include "neigh_list.h"
#include "neighbor.h" #include "neighbor.h"
#include "tokenizer.h"
#include "update.h" #include "update.h"
#include "utils.h"
#include <cmath>
#include <cstring> #include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
PairTracker::PairTracker(LAMMPS *lmp) : Pair(lmp) PairTracker::PairTracker(LAMMPS *lmp) :
Pair(lmp), onerad_dynamic(nullptr), onerad_frozen(nullptr), maxrad_dynamic(nullptr),
maxrad_frozen(nullptr), id_fix_store_local(nullptr), fix_dummy(nullptr), fix_history(nullptr),
fix_store_local(nullptr), type_filter(nullptr), output_data(nullptr), pack_choice(nullptr)
{ {
single_enable = 1; single_enable = 1;
no_virial_fdotr_compute = 1; no_virial_fdotr_compute = 1;
neighprev = 0; neighprev = 0;
history = 1; history = 1;
size_history = 4; size_history = 3;
nondefault_history_transfer = 1; nondefault_history_transfer = 1;
finitecutflag = 0; finitecutflag = 0;
tmin = -1;
// create dummy fix as placeholder for FixNeighHistory // create dummy fix as placeholder for FixNeighHistory
// this is so final order of Modify:fix will conform to input script // this is so final order of Modify:fix will conform to input script
fix_dummy = dynamic_cast<FixDummy *>(modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY"));
fix_history = nullptr;
modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY");
fix_dummy = dynamic_cast<FixDummy *>( modify->fix[modify->nfix - 1]);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -62,6 +64,7 @@ PairTracker::~PairTracker()
modify->delete_fix("NEIGH_HISTORY_TRACK_DUMMY"); modify->delete_fix("NEIGH_HISTORY_TRACK_DUMMY");
else else
modify->delete_fix("NEIGH_HISTORY_TRACK"); modify->delete_fix("NEIGH_HISTORY_TRACK");
if (id_fix_store_local) modify->delete_fix(id_fix_store_local);
if (allocated) { if (allocated) {
memory->destroy(setflag); memory->destroy(setflag);
@ -73,6 +76,12 @@ PairTracker::~PairTracker()
delete[] maxrad_dynamic; delete[] maxrad_dynamic;
delete[] maxrad_frozen; delete[] maxrad_frozen;
} }
delete[] pack_choice;
delete[] id_fix_store_local;
memory->destroy(output_data);
memory->destroy(type_filter);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -80,7 +89,7 @@ PairTracker::~PairTracker()
void PairTracker::compute(int eflag, int vflag) void PairTracker::compute(int eflag, int vflag)
{ {
int i, j, ii, jj, inum, jnum, itype, jtype; int i, j, ii, jj, inum, jnum, itype, jtype;
double xtmp, ytmp, ztmp, delx, dely, delz, time; double xtmp, ytmp, ztmp, delx, dely, delz;
double radi, radj, radsum, rsq, r; double radi, radj, radsum, rsq, r;
int *ilist, *jlist, *numneigh, **firstneigh; int *ilist, *jlist, *numneigh, **firstneigh;
int *touch, **firsttouch; int *touch, **firsttouch;
@ -131,27 +140,23 @@ void PairTracker::compute(int eflag, int vflag)
if (rsq >= radsum * radsum) { if (rsq >= radsum * radsum) {
data = &alldata[size_history * jj]; data = &alldata[size_history * jj];
if (touch[jj] == 1) { if (touch[jj] == 1) process_data(i, j, data);
fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]);
}
touch[jj] = 0; touch[jj] = 0;
data[0] = 0.0; // initial time data[0] = 0.0; // initial timestep
data[1] = 0.0; // initial timestep data[1] = 0.0; // sum of r, may be inaccurate over long times
data[2] = 0.0; // sum of r, may overflow data[2] = 0.0; // min of r
data[3] = 0.0; // min of r
} else { } else {
data = &alldata[size_history * jj]; data = &alldata[size_history * jj];
if (touch[jj] == 0) { if (touch[jj] == 0) {
time = update->atime + (update->ntimestep - update->atimestep) * update->dt; data[0] = (double) update->ntimestep;
data[0] = time; data[1] = r;
data[1] = (double) update->ntimestep;
data[2] = r; data[2] = r;
data[3] = r;
} else if (updateflag) { } else if (updateflag) {
data[2] += r; data[1] += r;
if (data[3] > r) data[3] = r; if (data[2] > r) data[2] = r;
} }
touch[jj] = 1; touch[jj] = 1;
} }
@ -160,28 +165,23 @@ void PairTracker::compute(int eflag, int vflag)
if (rsq >= cutsq[itype][jtype]) { if (rsq >= cutsq[itype][jtype]) {
data = &alldata[size_history * jj]; data = &alldata[size_history * jj];
if (touch[jj] == 1) { if (touch[jj] == 1) process_data(i, j, data);
fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]);
}
touch[jj] = 0; touch[jj] = 0;
data[0] = 0.0; // initial time data[0] = 0.0; // initial timestep
data[1] = 0.0; // initial timestep data[1] = 0.0; // sum of r, may be inaccurate over long times
data[2] = 0.0; // sum of r, may overflow data[2] = 0.0; // min of r
data[3] = 0.0; // min of r
} else { } else {
data = &alldata[size_history * jj]; data = &alldata[size_history * jj];
if (touch[jj] == 0) { if (touch[jj] == 0) {
time = update->atime + (update->ntimestep - update->atimestep) * update->dt; data[0] = (double) update->ntimestep;
data[0] = time; data[1] = r;
data[1] = (double) update->ntimestep;
data[2] = r; data[2] = r;
data[3] = r;
} else if (updateflag) { } else if (updateflag) {
data[2] += r; data[1] += r;
if (data[3] > r) data[3] = r; if (data[2] > r) data[2] = r;
} }
touch[jj] = 1; touch[jj] = 1;
} }
@ -218,14 +218,89 @@ void PairTracker::allocate()
void PairTracker::settings(int narg, char **arg) void PairTracker::settings(int narg, char **arg)
{ {
if (narg != 0 && narg != 1) error->all(FLERR, "Illegal pair_style command"); if (narg < 2) error->all(FLERR, "Illegal pair_style command");
if (narg == 1) { id_fix_store_local = utils::strdup(arg[0]);
if (strcmp(arg[0], "finite") == 0) store_local_freq = utils::inumeric(FLERR, arg[1], false, lmp);
// If optional arguments included, this will be oversized
pack_choice = new FnPtrPack[narg - 1];
nvalues = 0;
int iarg = 2;
while (iarg < narg) {
if (strcmp(arg[iarg], "finite") == 0) {
finitecutflag = 1; finitecutflag = 1;
else } else if (strcmp(arg[iarg], "id1") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_id1;
} else if (strcmp(arg[iarg], "id2") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_id2;
} else if (strcmp(arg[iarg], "time/created") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_time_created;
} else if (strcmp(arg[iarg], "time/broken") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_time_broken;
} else if (strcmp(arg[iarg], "time/total") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_time_total;
} else if (strcmp(arg[iarg], "x") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_x;
} else if (strcmp(arg[iarg], "y") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_y;
} else if (strcmp(arg[iarg], "z") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_z;
} else if (strcmp(arg[iarg], "r/min") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_rmin;
} else if (strcmp(arg[iarg], "r/ave") == 0) {
pack_choice[nvalues++] = &PairTracker::pack_rave;
} else if (strcmp(arg[iarg], "time/min") == 0) {
if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in pair tracker command");
tmin = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg++;
} else if (strcmp(arg[iarg], "type/include") == 0) {
if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in pair tracker command");
int ntypes = atom->ntypes;
int i, j, itype, jtype;
int inlo, inhi, jnlo, jnhi;
if (!type_filter) {
memory->create(type_filter, ntypes + 1, ntypes + 1, "pair/tracker:type_filter");
for (i = 0; i <= ntypes; i++) {
for (j = 0; j <= ntypes; j++) type_filter[i][j] = 0;
}
}
auto iwords = Tokenizer(arg[iarg + 1], ",").as_vector();
auto jwords = Tokenizer(arg[iarg + 2], ",").as_vector();
for (const auto &ifield : iwords) {
utils::bounds(FLERR, ifield, 1, ntypes, inlo, inhi, error);
for (const auto &jfield : jwords) {
utils::bounds(FLERR, jfield, 1, ntypes, jnlo, jnhi, error);
for (itype = inlo; itype <= inhi; itype++) {
for (jtype = jnlo; jtype <= jnhi; jtype++) {
type_filter[itype][jtype] = 1;
type_filter[jtype][itype] = 1;
}
}
}
}
iarg += 2;
} else {
error->all(FLERR, "Illegal pair_style command"); error->all(FLERR, "Illegal pair_style command");
}
iarg++;
} }
if (nvalues == 0) error->all(FLERR, "Must request at least one value to output");
memory->create(output_data, nvalues, "pair/tracker:output_data");
fix_store_local = dynamic_cast<FixStoreLocal *>(modify->get_fix_by_id(id_fix_store_local));
if (!fix_store_local)
fix_store_local = dynamic_cast<FixStoreLocal *>(modify->add_fix(
fmt::format("{} all STORE_LOCAL {} {}", id_fix_store_local, store_local_freq, nvalues)));
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -263,8 +338,6 @@ void PairTracker::coeff(int narg, char **arg)
void PairTracker::init_style() void PairTracker::init_style()
{ {
int i;
// error and warning checks // error and warning checks
if (!atom->radius_flag && finitecutflag) if (!atom->radius_flag && finitecutflag)
@ -283,44 +356,49 @@ void PairTracker::init_style()
if (fix_history == nullptr) { if (fix_history == nullptr) {
modify->replace_fix("NEIGH_HISTORY_TRACK_DUMMY", modify->replace_fix("NEIGH_HISTORY_TRACK_DUMMY",
fmt::format("NEIGH_HISTORY_TRACK all NEIGH_HISTORY {}", size_history), 1); fmt::format("NEIGH_HISTORY_TRACK all NEIGH_HISTORY {}", size_history), 1);
fix_history = dynamic_cast<FixNeighHistory *>( modify->get_fix_by_id("NEIGH_HISTORY_TRACK")); fix_history = dynamic_cast<FixNeighHistory *>(modify->get_fix_by_id("NEIGH_HISTORY_TRACK"));
fix_history->pair = this; fix_history->pair = this;
fix_history->use_bit_flag = 0; fix_history->use_bit_flag = 0;
} else { } else {
fix_history = dynamic_cast<FixNeighHistory *>( modify->get_fix_by_id("NEIGH_HISTORY_TRACK")); fix_history = dynamic_cast<FixNeighHistory *>(modify->get_fix_by_id("NEIGH_HISTORY_TRACK"));
if (!fix_history) error->all(FLERR, "Could not find pair fix neigh history ID"); if (!fix_history) error->all(FLERR, "Could not find pair fix neigh history ID");
} }
if (finitecutflag) { if (finitecutflag) {
if (force->pair->beyond_contact) if (force->pair->beyond_contact)
error->all(FLERR, error->all(FLERR,
"Pair tracker incompatible with granular pairstyles that extend beyond contact"); "Pair tracker incompatible with granular pairstyles that extend beyond contact");
// check for FixFreeze and set freeze_group_bit
auto fixlist = modify->get_fix_by_style("^freeze");
if (fixlist.size() == 0)
freeze_group_bit = 0;
else if (fixlist.size() > 1)
error->all(FLERR, "Only one fix freeze command at a time allowed");
else
freeze_group_bit = fixlist.front()->groupbit;
// check for FixPour and FixDeposit so can extract particle radii // check for FixPour and FixDeposit so can extract particle radii
int ipour; auto pours = modify->get_fix_by_style("^pour");
for (ipour = 0; ipour < modify->nfix; ipour++) auto deps = modify->get_fix_by_style("^deposit");
if (strcmp(modify->fix[ipour]->style, "pour") == 0) break;
if (ipour == modify->nfix) ipour = -1;
int idep;
for (idep = 0; idep < modify->nfix; idep++)
if (strcmp(modify->fix[idep]->style, "deposit") == 0) break;
if (idep == modify->nfix) idep = -1;
// set maxrad_dynamic and maxrad_frozen for each type // set maxrad_dynamic and maxrad_frozen for each type
// include future FixPour and FixDeposit particles as dynamic // include future FixPour and FixDeposit particles as dynamic
int itype; int itype = 0;
for (i = 1; i <= atom->ntypes; i++) { for (int i = 1; i <= atom->ntypes; i++) {
onerad_dynamic[i] = onerad_frozen[i] = 0.0; onerad_dynamic[i] = onerad_frozen[i] = 0.0;
if (ipour >= 0) { for (auto &ipour : pours) {
itype = i; itype = i;
onerad_dynamic[i] = *((double *) modify->fix[ipour]->extract("radius", itype)); double maxrad = *((double *) ipour->extract("radius", itype));
if (maxrad > 0.0) onerad_dynamic[i] = maxrad;
} }
if (idep >= 0) { for (auto &idep : deps) {
itype = i; itype = i;
onerad_dynamic[i] = *((double *) modify->fix[idep]->extract("radius", itype)); double maxrad = *((double *) idep->extract("radius", itype));
if (maxrad > 0.0) onerad_dynamic[i] = maxrad;
} }
} }
@ -329,7 +407,7 @@ void PairTracker::init_style()
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++) for (int i = 0; i < nlocal; i++)
if (mask[i] & freeze_group_bit) if (mask[i] & freeze_group_bit)
onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]], radius[i]); onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]], radius[i]);
else else
@ -338,11 +416,6 @@ void PairTracker::init_style()
MPI_Allreduce(&onerad_dynamic[1], &maxrad_dynamic[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world); MPI_Allreduce(&onerad_dynamic[1], &maxrad_dynamic[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world);
MPI_Allreduce(&onerad_frozen[1], &maxrad_frozen[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world); MPI_Allreduce(&onerad_frozen[1], &maxrad_frozen[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world);
} }
auto trackfixes = modify->get_fix_by_style("pair/tracker");
if (trackfixes.size() != 1)
error->all(FLERR, "Must use exactly one fix pair/tracker command with pair style tracker");
fix_pair_tracker = dynamic_cast<FixPairTracker *>( trackfixes.front());
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -354,8 +427,7 @@ double PairTracker::init_one(int i, int j)
if (!allocated) allocate(); if (!allocated) allocate();
// always mix prefactors geometrically // always mix prefactors geometrically
if (setflag[i][j] == 0) cut[i][j] = mix_distance(cut[i][i], cut[j][j]);
if (setflag[i][j] == 0) { cut[i][j] = mix_distance(cut[i][i], cut[j][j]); }
cut[j][i] = cut[i][j]; cut[j][i] = cut[i][j];
@ -384,7 +456,7 @@ void PairTracker::write_restart(FILE *fp)
for (i = 1; i <= atom->ntypes; i++) for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) { for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j], sizeof(int), 1, fp); fwrite(&setflag[i][j], sizeof(int), 1, fp);
if (setflag[i][j]) { fwrite(&cut[i][j], sizeof(double), 1, fp); } if (setflag[i][j]) fwrite(&cut[i][j], sizeof(double), 1, fp);
} }
} }
@ -404,7 +476,7 @@ void PairTracker::read_restart(FILE *fp)
if (me == 0) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error); if (me == 0) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error);
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world); MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
if (setflag[i][j]) { if (setflag[i][j]) {
if (me == 0) { utils::sfread(FLERR, &cut[i][j], sizeof(double), 1, fp, nullptr, error); } if (me == 0) utils::sfread(FLERR, &cut[i][j], sizeof(double), 1, fp, nullptr, error);
MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world); MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world);
} }
} }
@ -466,3 +538,91 @@ double PairTracker::radii2cut(double r1, double r2)
double cut = r1 + r2; double cut = r1 + r2;
return cut; return cut;
} }
/* ---------------------------------------------------------------------- */
void PairTracker::process_data(int i, int j, double *input_data)
{
if ((update->ntimestep - input_data[0]) < tmin) return;
if (type_filter) {
int *type = atom->type;
if (type_filter[type[i]][type[j]] == 0) return;
}
for (int k = 0; k < nvalues; k++) (this->*pack_choice[k])(k, i, j, input_data);
fix_store_local->add_data(output_data, i, j);
}
/* ----------------------------------------------------------------------
one method for every keyword fix pair/tracker can output
the atom property is packed into a local vector or array
------------------------------------------------------------------------- */
void PairTracker::pack_time_created(int n, int /*i*/, int /*j*/, double *data)
{
output_data[n] = data[0];
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_time_broken(int n, int /*i*/, int /*j*/, double * /*data*/)
{
output_data[n] = update->ntimestep;
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_time_total(int n, int /*i*/, int /*j*/, double *data)
{
output_data[n] = update->ntimestep - data[0];
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_id1(int n, int i, int /*j*/, double * /*data*/)
{
output_data[n] = atom->tag[i];
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_id2(int n, int /*i*/, int j, double * /*data*/)
{
output_data[n] = atom->tag[j];
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_x(int n, int i, int j, double * /*data*/)
{
output_data[n] = (atom->x[i][0] + atom->x[j][0]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_y(int n, int i, int j, double * /*data*/)
{
output_data[n] = (atom->x[i][1] + atom->x[j][1]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_z(int n, int i, int j, double * /*data*/)
{
output_data[n] = (atom->x[i][2] + atom->x[j][2]) * 0.5;
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_rmin(int n, int /*i*/, int /*j*/, double *data)
{
output_data[n] = data[2];
}
/* ---------------------------------------------------------------------- */
void PairTracker::pack_rave(int n, int /*i*/, int /*j*/, double *data)
{
output_data[n] = data[1] / (update->ntimestep - data[0]);
}

View File

@ -40,6 +40,7 @@ class PairTracker : public Pair {
double single(int, int, int, int, double, double, double, double &) override; double single(int, int, int, int, double, double, double, double &) override;
double atom2cut(int) override; double atom2cut(int) override;
double radii2cut(double, double) override; double radii2cut(double, double) override;
void transfer_history(double *, double *) override;
protected: protected:
int sizeflag; int sizeflag;
@ -50,12 +51,33 @@ class PairTracker : public Pair {
double *onerad_dynamic, *onerad_frozen; double *onerad_dynamic, *onerad_frozen;
double *maxrad_dynamic, *maxrad_frozen; double *maxrad_dynamic, *maxrad_frozen;
int freeze_group_bit; int freeze_group_bit;
int store_local_freq;
char *id_fix_store_local;
class FixDummy *fix_dummy; class FixDummy *fix_dummy;
class FixNeighHistory *fix_history; class FixNeighHistory *fix_history;
class FixPairTracker *fix_pair_tracker; class FixStoreLocal *fix_store_local;
void transfer_history(double *, double *) override; int **type_filter;
double tmin;
int nvalues, ncount;
double *output_data;
typedef void (PairTracker::*FnPtrPack)(int, int, int, double *);
FnPtrPack *pack_choice; // ptrs to pack functions
void pack_id1(int, int, int, double *);
void pack_id2(int, int, int, double *);
void pack_time_created(int, int, int, double *);
void pack_time_broken(int, int, int, double *);
void pack_time_total(int, int, int, double *);
void pack_x(int, int, int, double *);
void pack_y(int, int, int, double *);
void pack_z(int, int, int, double *);
void pack_rmin(int, int, int, double *);
void pack_rave(int, int, int, double *);
void process_data(int, int, double *);
void allocate(); void allocate();
}; };
@ -72,20 +94,37 @@ Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line. command-line option when running LAMMPS to see the offending line.
E: Invalid keyword in pair tracker command
Self-explanatory.
E: Incorrect args for pair coefficients E: Incorrect args for pair coefficients
Self-explanatory. Check the input script or data file. Self-explanatory. Check the input script or data file.
E: Must request at least one value to output
Must include at least one bond property to store in fix store/local
E: Pair tracker requires atom attribute radius for finite cutoffs E: Pair tracker requires atom attribute radius for finite cutoffs
The atom style defined does not have these attributes. The atom style defined does not have these attributes.
E: Pair tracker incompatible with granular pairstyles that extend beyond contact
Self-explanatory.
E: Could not find pair fix neigh history ID E: Could not find pair fix neigh history ID
The associated fix neigh/history is missing The associated fix neigh/history is missing
E: Cannot use pair tracker without fix pair/tracker E: Cannot use pair tracker without fix store/local
This pairstyle requires one to define a pair/tracker fix The associated fix store/local does not exist
E: Inconsistent number of output variables in fix store/local
The number of values specified in fix store/local disagrees with
the number of values requested in pair tracker
*/ */

Some files were not shown because too many files have changed in this diff Show More