Merge pull request #2906 from jtclemm/BPM
Adding package for bonded particle models
This commit is contained in:
@ -172,6 +172,7 @@ set(STANDARD_PACKAGES
|
||||
AWPMD
|
||||
BOCS
|
||||
BODY
|
||||
BPM
|
||||
BROWNIAN
|
||||
CG-DNA
|
||||
CG-SDK
|
||||
|
||||
@ -8,6 +8,7 @@ set(ALL_PACKAGES
|
||||
AWPMD
|
||||
BOCS
|
||||
BODY
|
||||
BPM
|
||||
BROWNIAN
|
||||
CG-DNA
|
||||
CG-SDK
|
||||
|
||||
@ -10,6 +10,7 @@ set(ALL_PACKAGES
|
||||
AWPMD
|
||||
BOCS
|
||||
BODY
|
||||
BPM
|
||||
BROWNIAN
|
||||
CG-DNA
|
||||
CG-SDK
|
||||
|
||||
@ -4,6 +4,7 @@ set(WIN_PACKAGES
|
||||
AWPMD
|
||||
BOCS
|
||||
BODY
|
||||
BPM
|
||||
BROWNIAN
|
||||
CG-DNA
|
||||
CG-SDK
|
||||
|
||||
@ -6,6 +6,7 @@ set(ALL_PACKAGES
|
||||
ASPHERE
|
||||
BOCS
|
||||
BODY
|
||||
BPM
|
||||
BROWNIAN
|
||||
CG-DNA
|
||||
CG-SDK
|
||||
|
||||
@ -2,6 +2,7 @@ set(WIN_PACKAGES
|
||||
ASPHERE
|
||||
BOCS
|
||||
BODY
|
||||
BPM
|
||||
BROWNIAN
|
||||
CG-DNA
|
||||
CG-SDK
|
||||
|
||||
@ -32,6 +32,8 @@ OPT.
|
||||
*
|
||||
*
|
||||
*
|
||||
* :doc:`bpm/rotational <bond_bpm_rotational>`
|
||||
* :doc:`bpm/spring <bond_bpm_spring>`
|
||||
* :doc:`class2 (ko) <bond_class2>`
|
||||
* :doc:`fene (iko) <bond_fene>`
|
||||
* :doc:`fene/expand (o) <bond_fene_expand>`
|
||||
|
||||
@ -91,6 +91,7 @@ KOKKOS, o = OPENMP, t = OPT.
|
||||
* :doc:`msd <compute_msd>`
|
||||
* :doc:`msd/chunk <compute_msd_chunk>`
|
||||
* :doc:`msd/nongauss <compute_msd_nongauss>`
|
||||
* :doc:`nbond/atom <compute_nbond_atom>`
|
||||
* :doc:`omega/chunk <compute_omega_chunk>`
|
||||
* :doc:`orientorder/atom (k) <compute_orientorder_atom>`
|
||||
* :doc:`pair <compute_pair>`
|
||||
|
||||
@ -141,6 +141,7 @@ OPT.
|
||||
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>`
|
||||
* :doc:`nve/noforce <fix_nve_noforce>`
|
||||
* :doc:`nve/sphere (ko) <fix_nve_sphere>`
|
||||
* :doc:`nve/bpm/sphere <fix_nve_bpm_sphere>`
|
||||
* :doc:`nve/spin <fix_nve_spin>`
|
||||
* :doc:`nve/tri <fix_nve_tri>`
|
||||
* :doc:`nvk <fix_nvk>`
|
||||
@ -158,7 +159,6 @@ OPT.
|
||||
* :doc:`orient/fcc <fix_orient>`
|
||||
* :doc:`orient/eco <fix_orient_eco>`
|
||||
* :doc:`pafi <fix_pafi>`
|
||||
* :doc:`pair/tracker <fix_pair_tracker>`
|
||||
* :doc:`phonon <fix_phonon>`
|
||||
* :doc:`pimd <fix_pimd>`
|
||||
* :doc:`planeforce <fix_planeforce>`
|
||||
|
||||
@ -53,6 +53,7 @@ OPT.
|
||||
* :doc:`born/coul/msm (o) <pair_born>`
|
||||
* :doc:`born/coul/wolf (go) <pair_born>`
|
||||
* :doc:`born/coul/wolf/cs (g) <pair_cs>`
|
||||
* :doc:`bpm/spring <pair_bpm_spring>`
|
||||
* :doc:`brownian (o) <pair_brownian>`
|
||||
* :doc:`brownian/poly (o) <pair_brownian>`
|
||||
* :doc:`buck (giko) <pair_buck>`
|
||||
|
||||
@ -54,6 +54,8 @@ Lowercase directories
|
||||
+-------------+------------------------------------------------------------------+
|
||||
| body | body particles, 2d system |
|
||||
+-------------+------------------------------------------------------------------+
|
||||
| bpm | BPM simulations of pouring elastic grains and plate impact |
|
||||
+-------------+------------------------------------------------------------------+
|
||||
| cmap | CMAP 5-body contributions to CHARMM force field |
|
||||
+-------------+------------------------------------------------------------------+
|
||||
| colloid | big colloid particles in a small particle solvent, 2d system |
|
||||
|
||||
@ -23,6 +23,8 @@ General howto
|
||||
Howto_library
|
||||
Howto_couple
|
||||
Howto_mdi
|
||||
Howto_bpm
|
||||
Howto_broken_bonds
|
||||
|
||||
Settings howto
|
||||
==============
|
||||
|
||||
124
doc/src/Howto_bpm.rst
Normal file
124
doc/src/Howto_bpm.rst
Normal 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.
|
||||
48
doc/src/Howto_broken_bonds.rst
Normal file
48
doc/src/Howto_broken_bonds.rst
Normal 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.
|
||||
@ -32,6 +32,7 @@ page gives those details.
|
||||
* :ref:`AWPMD <PKG-AWPMD>`
|
||||
* :ref:`BOCS <PKG-BOCS>`
|
||||
* :ref:`BODY <PKG-BODY>`
|
||||
* :ref:`BPM <PKG-BPM>`
|
||||
* :ref:`BROWNIAN <PKG-BROWNIAN>`
|
||||
* :ref:`CG-DNA <PKG-CG-DNA>`
|
||||
* :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:
|
||||
|
||||
BROWNIAN package
|
||||
@ -1545,7 +1573,6 @@ listing, "ls src/MISC", to see the list of commands.
|
||||
* :doc:`pair_style list <pair_list>`
|
||||
* :doc:`pair_style srp <pair_srp>`
|
||||
* :doc:`pair_style tracker <pair_tracker>`
|
||||
* :doc:`fix pair/tracker <fix_pair_tracker>`
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -58,6 +58,11 @@ whether an extra library is needed to build and use the package:
|
||||
- :doc:`Howto body <Howto_body>`
|
||||
- body
|
||||
- no
|
||||
* - :ref:`BPM <PKG-BPM>`
|
||||
- bonded particle models
|
||||
- :doc:`Howto bpm <Howto_bpm>`
|
||||
- bpm
|
||||
- no
|
||||
* - :ref:`BROWNIAN <PKG-BROWNIAN>`
|
||||
- Brownian dynamics, self-propelled particles
|
||||
- :doc:`fix brownian <fix_brownian>`, :doc:`fix propel/self <fix_propel_self>`
|
||||
|
||||
@ -10,7 +10,7 @@ Syntax
|
||||
|
||||
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::
|
||||
|
||||
@ -21,6 +21,7 @@ Syntax
|
||||
see the :doc:`Howto body <Howto_body>` doc
|
||||
page for details
|
||||
*sphere* arg = 0/1 (optional) for static/dynamic particle radii
|
||||
*bpm/sphere* arg = 0/1 (optional) for static/dynamic particle radii
|
||||
*tdpd* arg = Nspecies
|
||||
Nspecies = # of chemical species
|
||||
*template* arg = template-ID
|
||||
@ -120,6 +121,8 @@ quantities.
|
||||
+--------------+-----------------------------------------------------+--------------------------------------+
|
||||
| *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 |
|
||||
+--------------+-----------------------------------------------------+--------------------------------------+
|
||||
| *tdpd* | chemical concentration | tDPD particles |
|
||||
@ -141,8 +144,9 @@ quantities.
|
||||
output the custom values.
|
||||
|
||||
All of the above styles define point particles, except the *sphere*,
|
||||
*ellipsoid*, *electron*, *peri*, *wavepacket*, *line*, *tri*, and
|
||||
*body* styles, which define finite-size particles. See the :doc:`Howto spherical <Howto_spherical>` page for an overview of using
|
||||
*bpm/sphere*, *ellipsoid*, *electron*, *peri*, *wavepacket*, *line*,
|
||||
*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.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
nve/sphere <fix_nve_sphere>`, :doc:`fix nvt/sphere <fix_nvt_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
|
||||
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
|
||||
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
|
||||
@ -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
|
||||
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
|
||||
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
|
||||
|
||||
258
doc/src/bond_bpm_rotational.rst
Normal file
258
doc/src/bond_bpm_rotational.rst
Normal 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
202
doc/src/bond_bpm_spring.rst
Normal 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).
|
||||
@ -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
|
||||
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
|
||||
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
|
||||
subtracts the pairwise interaction as part of the bond computation.
|
||||
|
||||
@ -84,6 +84,8 @@ accelerated styles exist.
|
||||
* :doc:`zero <bond_zero>` - topology but no 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:`fene <bond_fene>` - FENE (finite-extensible non-linear elastic) bond
|
||||
* :doc:`fene/expand <bond_fene_expand>` - FENE bonds with variable size particles
|
||||
|
||||
@ -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/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:`nbond/atom <compute_nbond_atom>` - calculates number of bonds per atom
|
||||
* :doc:`omega/chunk <compute_omega_chunk>` - angular velocity for each chunk
|
||||
* :doc:`orientorder/atom <compute_orientorder_atom>` - Steinhardt bond orientational order parameters Ql
|
||||
* :doc:`pair <compute_pair>` - values computed by a pair style
|
||||
|
||||
52
doc/src/compute_nbond_atom.rst
Normal file
52
doc/src/compute_nbond_atom.rst
Normal 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
|
||||
@ -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
|
||||
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
|
||||
require the information typically written to the header.
|
||||
data produced by :doc:`pair tracker <pair_tracker>` or
|
||||
:doc:`bpm bond styles <Howto_bpm>` which may not require the
|
||||
information typically written to the header.
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -284,6 +284,7 @@ accelerated styles exist.
|
||||
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>` -
|
||||
* :doc:`nve/noforce <fix_nve_noforce>` - NVE without forces (v only)
|
||||
* :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/tri <fix_nve_tri>` - NVE for triangles
|
||||
* :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/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:`pair/tracker <fix_pair_tracker>` - track properties of pairwise interactions
|
||||
* :doc:`phonon <fix_phonon>` - calculate dynamical matrix from MD simulations
|
||||
* :doc:`pimd <fix_pimd>` - Feynman path integral molecular dynamics
|
||||
* :doc:`planeforce <fix_planeforce>` - constrain atoms to move in a plane
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
87
doc/src/fix_nve_bpm_sphere.rst
Normal file
87
doc/src/fix_nve_bpm_sphere.rst
Normal 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
|
||||
|
||||
@ -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
114
doc/src/pair_bpm_spring.rst
Normal 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
|
||||
@ -131,6 +131,7 @@ accelerated styles exist.
|
||||
* :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/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/poly <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics with polydispersity
|
||||
* :doc:`buck <pair_buck>` - Buckingham potential
|
||||
|
||||
@ -8,89 +8,182 @@ Syntax
|
||||
|
||||
.. 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
|
||||
* keyword = *finite*
|
||||
* fix_ID = ID of associated internal fix to store data
|
||||
* 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::
|
||||
|
||||
*finite* value = none
|
||||
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
|
||||
""""""""
|
||||
|
||||
.. 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_style hybrid/overlay tracker finite ...
|
||||
pair_style hybrid/overlay tracker myfix 1000 finite x y z time/min 100 granular
|
||||
pair_coeff * * tracker
|
||||
|
||||
fix 1 all pair/tracker 1000 time/created time/broken
|
||||
dump 1 all local 1000 dump.local f_1[1] f_1[2]
|
||||
dump 1 all local 1000 dump.local f_myfix[1] f_myfix[2] f_myfix[3]
|
||||
dump_modify 1 write_header no
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
|
||||
Style *tracker* monitors information about pairwise interactions.
|
||||
It does not calculate any forces on atoms.
|
||||
:doc:`Pair hybrid/overlay <pair_hybrid>` can be used to combine this pair
|
||||
style with another pair style. Style *tracker* must be used in conjunction
|
||||
with about :doc:`fix pair_tracker <fix_pair_tracker>` which contains
|
||||
information on what data can be output.
|
||||
Style *tracker* monitors information about pairwise interactions. It
|
||||
does not calculate any forces on atoms. :doc:`Pair hybrid/overlay
|
||||
<pair_hybrid>` can be used to combine this pair style with any other
|
||||
pair style, as shown in the examples above.
|
||||
|
||||
If the *finite* keyword is not defined, 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:
|
||||
At each timestep, if two neighboring atoms move beyond the interaction
|
||||
cutoff, pairwise data is processed and transferred to an internal fix
|
||||
labeled *fix_ID*. This allows the local data to be accessed by other
|
||||
LAMMPS commands. Additional
|
||||
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)
|
||||
|
||||
If the *finite* keyword is defined, no coefficients may be defined.
|
||||
Interaction cutoffs are alternatively calculated based on the
|
||||
diameter of finite particles.
|
||||
If the *finite* keyword is used, there are no additional coefficients
|
||||
to set for each pair of atom types via the
|
||||
: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
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
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
|
||||
*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.
|
||||
distance for this pair style can be mixed. The cutoff 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 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 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.
|
||||
|
||||
The :doc:`pair_modify <pair_modify>` shift, table, and tail options
|
||||
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
|
||||
""""""""""""
|
||||
|
||||
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
|
||||
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
|
||||
""""""""""""""""
|
||||
|
||||
:doc:`fix pair_tracker <fix_pair_tracker>`
|
||||
|
||||
Default
|
||||
"""""""
|
||||
|
||||
|
||||
@ -650,6 +650,8 @@ of analysis.
|
||||
- atom-ID atom-type rho esph cv x y z
|
||||
* - sphere
|
||||
- atom-ID atom-type diameter density x y z
|
||||
* - bpm/sphere
|
||||
- atom-ID molecule-ID atom-type diameter density x y z
|
||||
* - spin
|
||||
- atom-ID atom-type x y z spx spy spz sp
|
||||
* - tdpd
|
||||
|
||||
@ -328,6 +328,8 @@ boxzlo
|
||||
bp
|
||||
bpclermont
|
||||
bpls
|
||||
bpm
|
||||
BPM
|
||||
br
|
||||
Branduardi
|
||||
Branicio
|
||||
@ -1149,8 +1151,10 @@ gdot
|
||||
GeC
|
||||
Geier
|
||||
gencode
|
||||
Geocomputing
|
||||
georg
|
||||
Georg
|
||||
Geotechnica
|
||||
germain
|
||||
Germann
|
||||
Germano
|
||||
@ -1320,6 +1324,7 @@ Holm
|
||||
holonomic
|
||||
Homebrew
|
||||
hooke
|
||||
hookean
|
||||
Hookean
|
||||
hostname
|
||||
hotpink
|
||||
@ -2074,6 +2079,7 @@ monopole
|
||||
monovalent
|
||||
Montalenti
|
||||
Montero
|
||||
Mora
|
||||
Morefoo
|
||||
Morfill
|
||||
Mori
|
||||
@ -2203,6 +2209,7 @@ Nbin
|
||||
Nbins
|
||||
nbody
|
||||
Nbody
|
||||
nbond
|
||||
nbonds
|
||||
nbondtype
|
||||
Nbondtype
|
||||
@ -3174,6 +3181,7 @@ Steinhauser
|
||||
Stepaniants
|
||||
stepwise
|
||||
Stesmans
|
||||
stiffnesses
|
||||
Stillinger
|
||||
stk
|
||||
stochastically
|
||||
|
||||
3173
examples/bpm/impact/brokenDump
Normal file
3173
examples/bpm/impact/brokenDump
Normal file
File diff suppressed because it is too large
Load Diff
51
examples/bpm/impact/in.bpm.impact.rotational
Normal file
51
examples/bpm/impact/in.bpm.impact.rotational
Normal 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
|
||||
53
examples/bpm/impact/in.bpm.impact.spring
Normal file
53
examples/bpm/impact/in.bpm.impact.spring
Normal 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
|
||||
219
examples/bpm/impact/log.17Feb2022.impact.rotational.g++.4
Normal file
219
examples/bpm/impact/log.17Feb2022.impact.rotational.g++.4
Normal 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
|
||||
221
examples/bpm/impact/log.17Feb2022.impact.spring.g++.4
Normal file
221
examples/bpm/impact/log.17Feb2022.impact.spring.g++.4
Normal 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
|
||||
35
examples/bpm/pour/in.bpm.pour
Normal file
35
examples/bpm/pour/in.bpm.pour
Normal 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
|
||||
1091
examples/bpm/pour/log.17Feb2022.pour.g++.4
Normal file
1091
examples/bpm/pour/log.17Feb2022.pour.g++.4
Normal file
File diff suppressed because it is too large
Load Diff
568
examples/bpm/pour/rect.mol
Normal file
568
examples/bpm/pour/rect.mol
Normal 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
|
||||
18
src/.gitignore
vendored
18
src/.gitignore
vendored
@ -254,6 +254,21 @@
|
||||
/pair_mesont_tpm.cpp
|
||||
/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.h
|
||||
/compute_contact_atom.cpp
|
||||
@ -792,8 +807,6 @@
|
||||
/fix_orient_eco.h
|
||||
/fix_orient_fcc.cpp
|
||||
/fix_orient_fcc.h
|
||||
/fix_pair_tracker.cpp
|
||||
/fix_pair_tracker.h
|
||||
/fix_peri_neigh.cpp
|
||||
/fix_peri_neigh.h
|
||||
/fix_phonon.cpp
|
||||
@ -1524,3 +1537,4 @@
|
||||
/pair_smtbq.h
|
||||
/pair_vashishta*.cpp
|
||||
/pair_vashishta*.h
|
||||
|
||||
|
||||
245
src/BPM/atom_vec_bpm_sphere.cpp
Normal file
245
src/BPM/atom_vec_bpm_sphere.cpp
Normal 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;
|
||||
}
|
||||
82
src/BPM/atom_vec_bpm_sphere.h
Normal file
82
src/BPM/atom_vec_bpm_sphere.h
Normal 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
415
src/BPM/bond_bpm.cpp
Normal 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
98
src/BPM/bond_bpm.h
Normal 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.
|
||||
|
||||
*/
|
||||
796
src/BPM/bond_bpm_rotational.cpp
Normal file
796
src/BPM/bond_bpm_rotational.cpp
Normal 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(>wist[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, >wist[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(>wist[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;
|
||||
}
|
||||
83
src/BPM/bond_bpm_rotational.h
Normal file
83
src/BPM/bond_bpm_rotational.h
Normal 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
380
src/BPM/bond_bpm_spring.cpp
Normal 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
68
src/BPM/bond_bpm_spring.h
Normal 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.
|
||||
|
||||
*/
|
||||
145
src/BPM/compute_nbond_atom.cpp
Normal file
145
src/BPM/compute_nbond_atom.cpp
Normal 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;
|
||||
}
|
||||
61
src/BPM/compute_nbond_atom.h
Normal file
61
src/BPM/compute_nbond_atom.h
Normal 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.
|
||||
|
||||
*/
|
||||
157
src/BPM/fix_nve_bpm_sphere.cpp
Normal file
157
src/BPM/fix_nve_bpm_sphere.cpp
Normal 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];
|
||||
}
|
||||
}
|
||||
71
src/BPM/fix_nve_bpm_sphere.h
Normal file
71
src/BPM/fix_nve_bpm_sphere.h
Normal 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
326
src/BPM/pair_bpm_spring.cpp
Normal 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
64
src/BPM/pair_bpm_spring.h
Normal 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.
|
||||
|
||||
*/
|
||||
@ -136,8 +136,7 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
|
||||
error->all(FLERR,"Invalid atom type in fix pour mol command");
|
||||
|
||||
if (atom->molecular == Atom::TEMPLATE && onemols != atom->avec->onemols)
|
||||
error->all(FLERR,"Fix pour molecule template ID must be same "
|
||||
"as atom style template ID");
|
||||
error->all(FLERR,"Fix pour molecule template ID must be same as atom style template ID");
|
||||
onemols[i]->check_attributes(0);
|
||||
|
||||
// fix pour uses geoemetric center of molecule for insertion
|
||||
|
||||
@ -45,7 +45,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum;
|
||||
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 wr1,wr2,wr3;
|
||||
double vtr1,vtr2,vtr3,vrel;
|
||||
@ -91,6 +91,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
int newton_pair = force->newton_pair;
|
||||
double *special_lj = force->special_lj;
|
||||
|
||||
inum = list->inum;
|
||||
ilist = list->ilist;
|
||||
@ -114,8 +115,11 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_lj = special_lj[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
if (factor_lj == 0) continue;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
@ -247,6 +251,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
||||
fx = delx*ccel + fs1;
|
||||
fy = dely*ccel + fs2;
|
||||
fz = delz*ccel + fs3;
|
||||
fx *= factor_lj;
|
||||
fy *= factor_lj;
|
||||
fz *= factor_lj;
|
||||
f[i][0] += fx;
|
||||
f[i][1] += fy;
|
||||
f[i][2] += fz;
|
||||
@ -254,6 +261,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
||||
tor1 = rinv * (dely*fs3 - delz*fs2);
|
||||
tor2 = rinv * (delz*fs1 - delx*fs3);
|
||||
tor3 = rinv * (delx*fs2 - dely*fs1);
|
||||
tor1 *= factor_lj;
|
||||
tor2 *= factor_lj;
|
||||
tor3 *= factor_lj;
|
||||
torque[i][0] -= radi*tor1;
|
||||
torque[i][1] -= radi*tor2;
|
||||
torque[i][2] -= radi*tor3;
|
||||
|
||||
@ -42,7 +42,7 @@ void PairGranHooke::compute(int eflag, int vflag)
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum;
|
||||
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 wr1,wr2,wr3;
|
||||
double vtr1,vtr2,vtr3,vrel;
|
||||
@ -82,6 +82,7 @@ void PairGranHooke::compute(int eflag, int vflag)
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
int newton_pair = force->newton_pair;
|
||||
double *special_lj = force->special_lj;
|
||||
|
||||
inum = list->inum;
|
||||
ilist = list->ilist;
|
||||
@ -101,8 +102,11 @@ void PairGranHooke::compute(int eflag, int vflag)
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_lj = special_lj[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
if (factor_lj == 0) continue;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
@ -187,6 +191,9 @@ void PairGranHooke::compute(int eflag, int vflag)
|
||||
fx = delx*ccel + fs1;
|
||||
fy = dely*ccel + fs2;
|
||||
fz = delz*ccel + fs3;
|
||||
fx *= factor_lj;
|
||||
fy *= factor_lj;
|
||||
fz *= factor_lj;
|
||||
f[i][0] += fx;
|
||||
f[i][1] += fy;
|
||||
f[i][2] += fz;
|
||||
@ -194,6 +201,9 @@ void PairGranHooke::compute(int eflag, int vflag)
|
||||
tor1 = rinv * (dely*fs3 - delz*fs2);
|
||||
tor2 = rinv * (delz*fs1 - delx*fs3);
|
||||
tor3 = rinv * (delx*fs2 - dely*fs1);
|
||||
tor1 *= factor_lj;
|
||||
tor2 *= factor_lj;
|
||||
tor3 *= factor_lj;
|
||||
torque[i][0] -= radi*tor1;
|
||||
torque[i][1] -= radi*tor2;
|
||||
torque[i][2] -= radi*tor3;
|
||||
|
||||
@ -103,7 +103,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
||||
{
|
||||
int i, j, ii, jj, inum, jnum;
|
||||
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 wr1, wr2, wr3;
|
||||
double vtr1, vtr2, vtr3, vrel;
|
||||
@ -151,6 +151,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
int newton_pair = force->newton_pair;
|
||||
double *special_lj = force->special_lj;
|
||||
|
||||
inum = list->inum;
|
||||
ilist = list->ilist;
|
||||
@ -174,8 +175,11 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_lj = special_lj[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
if (factor_lj == 0) continue;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
@ -306,6 +310,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
||||
fx = delx * ccel + fs1;
|
||||
fy = dely * ccel + fs2;
|
||||
fz = delz * ccel + fs3;
|
||||
fx *= factor_lj;
|
||||
fy *= factor_lj;
|
||||
fz *= factor_lj;
|
||||
f[i][0] += fx;
|
||||
f[i][1] += fy;
|
||||
f[i][2] += fz;
|
||||
@ -313,6 +320,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
||||
tor1 = rinv * (dely * fs3 - delz * fs2);
|
||||
tor2 = rinv * (delz * fs1 - delx * fs3);
|
||||
tor3 = rinv * (delx * fs2 - dely * fs1);
|
||||
tor1 *= factor_lj;
|
||||
tor2 *= factor_lj;
|
||||
tor3 *= factor_lj;
|
||||
torque[i][0] -= radi * tor1;
|
||||
torque[i][1] -= radi * tor2;
|
||||
torque[i][2] -= radi * tor3;
|
||||
|
||||
@ -150,7 +150,7 @@ void PairGranular::compute(int eflag, int vflag)
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||
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 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;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
double *special_lj = force->special_lj;
|
||||
|
||||
inum = list->inum;
|
||||
ilist = list->ilist;
|
||||
@ -249,8 +250,11 @@ void PairGranular::compute(int eflag, int vflag)
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_lj = special_lj[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
if (factor_lj == 0) continue;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
@ -651,6 +655,9 @@ void PairGranular::compute(int eflag, int vflag)
|
||||
fx = nx*Fntot + fs1;
|
||||
fy = ny*Fntot + fs2;
|
||||
fz = nz*Fntot + fs3;
|
||||
fx *= factor_lj;
|
||||
fy *= factor_lj;
|
||||
fz *= factor_lj;
|
||||
|
||||
f[i][0] += fx;
|
||||
f[i][1] += fy;
|
||||
@ -659,6 +666,9 @@ void PairGranular::compute(int eflag, int vflag)
|
||||
tor1 = ny*fs3 - nz*fs2;
|
||||
tor2 = nz*fs1 - nx*fs3;
|
||||
tor3 = nx*fs2 - ny*fs1;
|
||||
tor1 *= factor_lj;
|
||||
tor2 *= factor_lj;
|
||||
tor3 *= factor_lj;
|
||||
|
||||
dist_to_contact = radi-0.5*delta;
|
||||
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;
|
||||
|
||||
if (twist_model[itype][jtype] != TWIST_NONE) {
|
||||
tortwist1 = magtortwist * nx;
|
||||
tortwist2 = magtortwist * ny;
|
||||
tortwist3 = magtortwist * nz;
|
||||
tortwist1 = magtortwist * nx * factor_lj;
|
||||
tortwist2 = magtortwist * ny * factor_lj;
|
||||
tortwist3 = magtortwist * nz * factor_lj;
|
||||
|
||||
torque[i][0] += tortwist1;
|
||||
torque[i][1] += tortwist2;
|
||||
@ -676,9 +686,9 @@ void PairGranular::compute(int eflag, int vflag)
|
||||
}
|
||||
|
||||
if (roll_model[itype][jtype] != ROLL_NONE) {
|
||||
torroll1 = Reff*(ny*fr3 - nz*fr2); // n cross fr
|
||||
torroll2 = Reff*(nz*fr1 - nx*fr3);
|
||||
torroll3 = Reff*(nx*fr2 - ny*fr1);
|
||||
torroll1 = Reff*(ny*fr3 - nz*fr2) * factor_lj; // n cross fr
|
||||
torroll2 = Reff*(nz*fr1 - nx*fr3) * factor_lj;
|
||||
torroll3 = Reff*(nx*fr2 - ny*fr1) * factor_lj;
|
||||
|
||||
torque[i][0] += torroll1;
|
||||
torque[i][1] += torroll2;
|
||||
|
||||
@ -19,11 +19,14 @@
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
#include "memory.h"
|
||||
#include "modify.h"
|
||||
#include "neighbor.h"
|
||||
#include "random_mars.h"
|
||||
#include "respa.h"
|
||||
#include "update.h"
|
||||
|
||||
#include "fix_bond_history.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
@ -258,6 +261,10 @@ void FixBondBreak::post_integrate()
|
||||
commflag = 1;
|
||||
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
|
||||
// if both atoms list each other as winning bond partner
|
||||
// and probability constraint is satisfied
|
||||
@ -292,7 +299,13 @@ void FixBondBreak::post_integrate()
|
||||
for (k = m; k < num_bond[i]-1; k++) {
|
||||
bond_atom[i][k] = bond_atom[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]--;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -17,21 +17,15 @@
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "fix_bond_create_angle.h"
|
||||
|
||||
#include "atom.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
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)
|
||||
{
|
||||
double **x = atom->x;
|
||||
|
||||
@ -26,7 +26,7 @@ namespace LAMMPS_NS {
|
||||
|
||||
class FixBondCreateAngle : public FixBondCreate {
|
||||
public:
|
||||
FixBondCreateAngle(class LAMMPS *, int, char **);
|
||||
FixBondCreateAngle(LAMMPS *_lmp, int narg, char **arg) : FixBondCreate(_lmp, narg, arg) {}
|
||||
|
||||
private:
|
||||
int constrain(int, int, double, double) override;
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "compute.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "fix_bond_history.h"
|
||||
#include "force.h"
|
||||
#include "memory.h"
|
||||
#include "modify.h"
|
||||
@ -446,6 +447,10 @@ void FixBondSwap::post_integrate()
|
||||
if (!accept) return;
|
||||
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
|
||||
// on atom i: bond i-inext changes to i-jnext
|
||||
// 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
|
||||
|
||||
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++)
|
||||
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++)
|
||||
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++)
|
||||
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
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -19,39 +19,41 @@
|
||||
#include "fix.h"
|
||||
#include "fix_dummy.h"
|
||||
#include "fix_neigh_history.h"
|
||||
#include "fix_pair_tracker.h"
|
||||
#include "fix_store_local.h"
|
||||
#include "force.h"
|
||||
#include "memory.h"
|
||||
#include "modify.h"
|
||||
#include "neigh_list.h"
|
||||
#include "neighbor.h"
|
||||
#include "tokenizer.h"
|
||||
#include "update.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
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;
|
||||
no_virial_fdotr_compute = 1;
|
||||
|
||||
neighprev = 0;
|
||||
history = 1;
|
||||
size_history = 4;
|
||||
size_history = 3;
|
||||
nondefault_history_transfer = 1;
|
||||
|
||||
finitecutflag = 0;
|
||||
tmin = -1;
|
||||
|
||||
// create dummy fix as placeholder for FixNeighHistory
|
||||
// this is so final order of Modify:fix will conform to input script
|
||||
|
||||
fix_history = nullptr;
|
||||
modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY");
|
||||
fix_dummy = dynamic_cast<FixDummy *>( modify->fix[modify->nfix - 1]);
|
||||
fix_dummy = dynamic_cast<FixDummy *>(modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY"));
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -62,6 +64,7 @@ PairTracker::~PairTracker()
|
||||
modify->delete_fix("NEIGH_HISTORY_TRACK_DUMMY");
|
||||
else
|
||||
modify->delete_fix("NEIGH_HISTORY_TRACK");
|
||||
if (id_fix_store_local) modify->delete_fix(id_fix_store_local);
|
||||
|
||||
if (allocated) {
|
||||
memory->destroy(setflag);
|
||||
@ -73,6 +76,12 @@ PairTracker::~PairTracker()
|
||||
delete[] maxrad_dynamic;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
int *ilist, *jlist, *numneigh, **firstneigh;
|
||||
int *touch, **firsttouch;
|
||||
@ -131,27 +140,23 @@ void PairTracker::compute(int eflag, int vflag)
|
||||
if (rsq >= radsum * radsum) {
|
||||
|
||||
data = &alldata[size_history * jj];
|
||||
if (touch[jj] == 1) {
|
||||
fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
if (touch[jj] == 1) process_data(i, j, data);
|
||||
|
||||
touch[jj] = 0;
|
||||
data[0] = 0.0; // initial time
|
||||
data[1] = 0.0; // initial timestep
|
||||
data[2] = 0.0; // sum of r, may overflow
|
||||
data[3] = 0.0; // min of r
|
||||
data[0] = 0.0; // initial timestep
|
||||
data[1] = 0.0; // sum of r, may be inaccurate over long times
|
||||
data[2] = 0.0; // min of r
|
||||
|
||||
} else {
|
||||
|
||||
data = &alldata[size_history * jj];
|
||||
if (touch[jj] == 0) {
|
||||
time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
|
||||
data[0] = time;
|
||||
data[1] = (double) update->ntimestep;
|
||||
data[0] = (double) update->ntimestep;
|
||||
data[1] = r;
|
||||
data[2] = r;
|
||||
data[3] = r;
|
||||
} else if (updateflag) {
|
||||
data[2] += r;
|
||||
if (data[3] > r) data[3] = r;
|
||||
data[1] += r;
|
||||
if (data[2] > r) data[2] = r;
|
||||
}
|
||||
touch[jj] = 1;
|
||||
}
|
||||
@ -160,28 +165,23 @@ void PairTracker::compute(int eflag, int vflag)
|
||||
if (rsq >= cutsq[itype][jtype]) {
|
||||
|
||||
data = &alldata[size_history * jj];
|
||||
if (touch[jj] == 1) {
|
||||
fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
if (touch[jj] == 1) process_data(i, j, data);
|
||||
|
||||
touch[jj] = 0;
|
||||
data[0] = 0.0; // initial time
|
||||
data[1] = 0.0; // initial timestep
|
||||
data[2] = 0.0; // sum of r, may overflow
|
||||
data[3] = 0.0; // min of r
|
||||
data[0] = 0.0; // initial timestep
|
||||
data[1] = 0.0; // sum of r, may be inaccurate over long times
|
||||
data[2] = 0.0; // min of r
|
||||
|
||||
} else {
|
||||
|
||||
data = &alldata[size_history * jj];
|
||||
if (touch[jj] == 0) {
|
||||
time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
|
||||
data[0] = time;
|
||||
data[1] = (double) update->ntimestep;
|
||||
data[0] = (double) update->ntimestep;
|
||||
data[1] = r;
|
||||
data[2] = r;
|
||||
data[3] = r;
|
||||
} else if (updateflag) {
|
||||
data[2] += r;
|
||||
if (data[3] > r) data[3] = r;
|
||||
data[1] += r;
|
||||
if (data[2] > r) data[2] = r;
|
||||
}
|
||||
touch[jj] = 1;
|
||||
}
|
||||
@ -218,14 +218,89 @@ void PairTracker::allocate()
|
||||
|
||||
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) {
|
||||
if (strcmp(arg[0], "finite") == 0)
|
||||
id_fix_store_local = utils::strdup(arg[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;
|
||||
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");
|
||||
}
|
||||
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()
|
||||
{
|
||||
int i;
|
||||
|
||||
// error and warning checks
|
||||
|
||||
if (!atom->radius_flag && finitecutflag)
|
||||
@ -292,35 +365,40 @@ void PairTracker::init_style()
|
||||
}
|
||||
|
||||
if (finitecutflag) {
|
||||
|
||||
if (force->pair->beyond_contact)
|
||||
error->all(FLERR,
|
||||
"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
|
||||
|
||||
int ipour;
|
||||
for (ipour = 0; ipour < modify->nfix; ipour++)
|
||||
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;
|
||||
auto pours = modify->get_fix_by_style("^pour");
|
||||
auto deps = modify->get_fix_by_style("^deposit");
|
||||
|
||||
// set maxrad_dynamic and maxrad_frozen for each type
|
||||
// include future FixPour and FixDeposit particles as dynamic
|
||||
|
||||
int itype;
|
||||
for (i = 1; i <= atom->ntypes; i++) {
|
||||
int itype = 0;
|
||||
for (int i = 1; i <= atom->ntypes; i++) {
|
||||
onerad_dynamic[i] = onerad_frozen[i] = 0.0;
|
||||
if (ipour >= 0) {
|
||||
for (auto &ipour : pours) {
|
||||
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;
|
||||
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 nlocal = atom->nlocal;
|
||||
|
||||
for (i = 0; i < nlocal; i++)
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & freeze_group_bit)
|
||||
onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]], radius[i]);
|
||||
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_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();
|
||||
|
||||
// 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];
|
||||
|
||||
@ -384,7 +456,7 @@ void PairTracker::write_restart(FILE *fp)
|
||||
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(&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);
|
||||
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -466,3 +538,91 @@ double PairTracker::radii2cut(double r1, double r2)
|
||||
double cut = r1 + r2;
|
||||
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]);
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ class PairTracker : public Pair {
|
||||
double single(int, int, int, int, double, double, double, double &) override;
|
||||
double atom2cut(int) override;
|
||||
double radii2cut(double, double) override;
|
||||
void transfer_history(double *, double *) override;
|
||||
|
||||
protected:
|
||||
int sizeflag;
|
||||
@ -50,12 +51,33 @@ class PairTracker : public Pair {
|
||||
double *onerad_dynamic, *onerad_frozen;
|
||||
double *maxrad_dynamic, *maxrad_frozen;
|
||||
int freeze_group_bit;
|
||||
int store_local_freq;
|
||||
|
||||
char *id_fix_store_local;
|
||||
class FixDummy *fix_dummy;
|
||||
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();
|
||||
};
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
@ -36,6 +36,7 @@ using MathConst::MY_CUBEROOT2;
|
||||
BondQuartic::BondQuartic(LAMMPS *_lmp) :
|
||||
Bond(_lmp), k(nullptr), b1(nullptr), b2(nullptr), rc(nullptr), u0(nullptr)
|
||||
{
|
||||
partial_flag = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -54,6 +54,7 @@ PACKAGE = \
|
||||
awpmd \
|
||||
bocs \
|
||||
body \
|
||||
bpm \
|
||||
brownian \
|
||||
cg-dna \
|
||||
cg-sdk \
|
||||
@ -147,6 +148,7 @@ PACKMOST = \
|
||||
asphere \
|
||||
bocs \
|
||||
body \
|
||||
bpm \
|
||||
brownian \
|
||||
cg-dna \
|
||||
cg-sdk \
|
||||
|
||||
@ -578,7 +578,7 @@ void FixNeighHistoryOMP::post_neighbor()
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
rflag = sbmask(j);
|
||||
rflag = histmask(j);
|
||||
j &= NEIGHMASK;
|
||||
jlist[jj] = j;
|
||||
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_bin_newtoff_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
#include "npair_omp.h"
|
||||
@ -40,8 +43,10 @@ NPairHalfSizeBinNewtoffOmp::NPairHalfSizeBinNewtoffOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
|
||||
@ -50,7 +55,8 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,ibin;
|
||||
int i,j,jh,k,n,ibin,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutsq;
|
||||
int *neighptr;
|
||||
@ -61,7 +67,14 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -81,6 +94,11 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
ibin = atom2bin[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over all atoms in surrounding bins in stencil including self
|
||||
// only store pair if i < j
|
||||
@ -100,10 +118,23 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
||||
cutsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_bin_newton_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
#include "npair_omp.h"
|
||||
@ -39,8 +42,10 @@ NPairHalfSizeBinNewtonOmp::NPairHalfSizeBinNewtonOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
|
||||
@ -49,7 +54,8 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,ibin;
|
||||
int i,j,jh,k,n,ibin,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutsq;
|
||||
int *neighptr;
|
||||
@ -58,7 +64,14 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -77,6 +90,11 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over rest of atoms in i's bin, ghosts are at end of linked list
|
||||
// if j is owned atom, store it, since j is beyond i in linked list
|
||||
@ -101,10 +119,23 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||
cutsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,10 +154,23 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||
cutsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_bin_newton_tri_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
#include "npair_omp.h"
|
||||
@ -39,8 +42,10 @@ NPairHalfSizeBinNewtonTriOmp::NPairHalfSizeBinNewtonTriOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -48,7 +53,8 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,ibin;
|
||||
int i,j,jh,k,n,ibin,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutsq;
|
||||
int *neighptr;
|
||||
@ -59,7 +65,14 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -78,6 +91,11 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over all atoms in bins in stencil
|
||||
// pairs for atoms j "below" i are excluded
|
||||
@ -107,10 +125,23 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
||||
cutsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_multi_newtoff_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neighbor.h"
|
||||
#include "neigh_list.h"
|
||||
@ -41,8 +44,10 @@ NPairHalfSizeMultiNewtoffOmp::NPairHalfSizeMultiNewtoffOmp(LAMMPS *lmp) : NPair(
|
||||
void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -50,7 +55,9 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns;
|
||||
int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns;
|
||||
int which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutdistsq;
|
||||
int *neighptr,*s;
|
||||
@ -63,7 +70,14 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -84,6 +98,11 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
ibin = atom2bin[i];
|
||||
|
||||
@ -119,10 +138,23 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_multi_newton_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neighbor.h"
|
||||
#include "neigh_list.h"
|
||||
@ -40,8 +43,10 @@ NPairHalfSizeMultiNewtonOmp::NPairHalfSizeMultiNewtonOmp(LAMMPS *lmp) : NPair(lm
|
||||
void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -49,7 +54,9 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns;
|
||||
int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns;
|
||||
int which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutdistsq;
|
||||
int *neighptr,*s;
|
||||
@ -62,7 +69,14 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -83,6 +97,11 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
ibin = atom2bin[i];
|
||||
|
||||
@ -129,10 +148,23 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,9 +193,21 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
j = j ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = j;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = j;
|
||||
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
|
||||
} else neighptr[n++] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_multi_newton_tri_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neighbor.h"
|
||||
#include "neigh_list.h"
|
||||
@ -41,8 +44,10 @@ NPairHalfSizeMultiNewtonTriOmp::NPairHalfSizeMultiNewtonTriOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -50,7 +55,9 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns;
|
||||
int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns;
|
||||
int which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutdistsq;
|
||||
int *neighptr,*s;
|
||||
@ -63,7 +70,14 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -84,6 +98,11 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
ibin = atom2bin[i];
|
||||
|
||||
@ -134,10 +153,23 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,8 +13,12 @@
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "npair_half_size_multi_old_newtoff_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
#include "npair_omp.h"
|
||||
@ -39,8 +43,10 @@ NPairHalfSizeMultiOldNewtoffOmp::NPairHalfSizeMultiOldNewtoffOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -48,7 +54,8 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,itype,jtype,ibin,ns;
|
||||
int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutdistsq;
|
||||
int *neighptr,*s;
|
||||
@ -58,7 +65,14 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -78,6 +92,11 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over all atoms in other bins in stencil including self
|
||||
// only store pair if i < j
|
||||
@ -106,10 +125,23 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_multi_old_newton_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
#include "npair_omp.h"
|
||||
@ -39,8 +42,10 @@ NPairHalfSizeMultiOldNewtonOmp::NPairHalfSizeMultiOldNewtonOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -48,7 +53,8 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,itype,jtype,ibin,ns;
|
||||
int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutdistsq;
|
||||
int *neighptr,*s;
|
||||
@ -58,7 +64,14 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -78,6 +91,11 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over rest of atoms in i's bin, ghosts are at end of linked list
|
||||
// if j is owned atom, store it, since j is beyond i in linked list
|
||||
@ -102,10 +120,23 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,10 +163,23 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_multi_old_newton_tri_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
#include "npair_omp.h"
|
||||
@ -39,8 +42,10 @@ NPairHalfSizeMultiOldNewtonTriOmp::NPairHalfSizeMultiOldNewtonTriOmp(LAMMPS *lmp
|
||||
void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
#if defined(_OPENMP)
|
||||
@ -48,7 +53,8 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,k,n,itype,jtype,ibin,ns;
|
||||
int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutdistsq;
|
||||
int *neighptr,*s;
|
||||
@ -58,7 +64,14 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
@ -78,6 +91,11 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over all atoms in bins, including self, in stencil
|
||||
// skip if i,j neighbor cutoff is less than bin distance
|
||||
@ -115,10 +133,23 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutdistsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_nsq_newtoff_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "group.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
@ -42,8 +45,10 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
|
||||
@ -52,7 +57,8 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,n;
|
||||
int i,j,jh,n,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutsq;
|
||||
int *neighptr;
|
||||
@ -61,9 +67,17 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
||||
double *radius = atom->radius;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *tag = atom->tag;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int nall = atom->nlocal + atom->nghost;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
int *numneigh = list->numneigh;
|
||||
int **firstneigh = list->firstneigh;
|
||||
@ -81,6 +95,11 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over remaining atoms, owned and ghost
|
||||
|
||||
@ -96,10 +115,23 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
||||
cutsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
#include "npair_half_size_nsq_newton_omp.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "molecule.h"
|
||||
#include "group.h"
|
||||
#include "my_page.h"
|
||||
#include "neigh_list.h"
|
||||
@ -42,9 +45,11 @@ NPairHalfSizeNsqNewtonOmp::NPairHalfSizeNsqNewtonOmp(LAMMPS *lmp) :
|
||||
void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
||||
{
|
||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
||||
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;;
|
||||
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
|
||||
const int molecular = atom->molecular;
|
||||
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
|
||||
const int history = list->history;
|
||||
const int mask_history = 3 << SBBITS;
|
||||
const int mask_history = 1 << HISTBITS;
|
||||
|
||||
NPAIR_OMP_INIT;
|
||||
|
||||
@ -53,7 +58,8 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
||||
#endif
|
||||
NPAIR_OMP_SETUP(nlocal);
|
||||
|
||||
int i,j,n,itag,jtag;
|
||||
int i,j,jh,n,itag,jtag,which,imol,iatom;
|
||||
tagint tagprev;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||
double radi,radsum,cutsq;
|
||||
int *neighptr;
|
||||
@ -64,6 +70,13 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
tagint *molecule = atom->molecule;
|
||||
tagint **special = atom->special;
|
||||
int **nspecial = atom->nspecial;
|
||||
|
||||
int *molindex = atom->molindex;
|
||||
int *molatom = atom->molatom;
|
||||
Molecule **onemols = atom->avec->onemols;
|
||||
|
||||
int nall = atom->nlocal + atom->nghost;
|
||||
|
||||
int *ilist = list->ilist;
|
||||
@ -84,6 +97,11 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
radi = radius[i];
|
||||
if (moltemplate) {
|
||||
imol = molindex[i];
|
||||
iatom = molatom[i];
|
||||
tagprev = tag[i] - iatom - 1;
|
||||
}
|
||||
|
||||
// loop over remaining atoms, owned and ghost
|
||||
|
||||
@ -115,10 +133,23 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
||||
cutsq = (radsum+skin) * (radsum+skin);
|
||||
|
||||
if (rsq <= cutsq) {
|
||||
jh = j;
|
||||
if (history && rsq < radsum*radsum)
|
||||
neighptr[n++] = j ^ mask_history;
|
||||
else
|
||||
neighptr[n++] = j;
|
||||
jh = jh ^ mask_history;
|
||||
|
||||
if (molecular != Atom::ATOMIC) {
|
||||
if (!moltemplate)
|
||||
which = find_special(special[i],nspecial[i],tag[j]);
|
||||
else if (imol >=0)
|
||||
which = find_special(onemols[imol]->special[iatom],
|
||||
onemols[imol]->nspecial[iatom],
|
||||
tag[j]-tagprev);
|
||||
else which = 0;
|
||||
if (which == 0) neighptr[n++] = jh;
|
||||
else if (domain->minimum_image_check(delx,dely,delz))
|
||||
neighptr[n++] = jh;
|
||||
else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS);
|
||||
} else neighptr[n++] = jh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ Contributing Author: Jacob Gissinger (jacob.r.gissinger@gmail.com)
|
||||
#include "comm.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "fix_bond_history.h"
|
||||
#include "force.h"
|
||||
#include "group.h"
|
||||
#include "input.h"
|
||||
@ -3093,6 +3094,10 @@ void FixBondReact::update_everything()
|
||||
// next let's update bond info
|
||||
// cool thing is, newton_bond issues are already taken care of in templates
|
||||
// same with class2 improper issues, which is why this fix started in the first place
|
||||
// also need to find any instances of bond history to update histories
|
||||
auto histories = modify->get_fix_by_style("BOND_HISTORY");
|
||||
int n_histories = histories.size();
|
||||
|
||||
for (int i = 0; i < update_num_mega; i++) {
|
||||
rxnID = update_mega_glove[0][i];
|
||||
twomol = atom->molecules[reacted_mol[rxnID]];
|
||||
@ -3102,6 +3107,14 @@ void FixBondReact::update_everything()
|
||||
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
|
||||
if (landlocked_atoms[j][rxnID] == 1) {
|
||||
delta_bonds -= num_bond[atom->map(update_mega_glove[jj+1][i])];
|
||||
// If deleting all bonds, first cache then remove all histories
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories) {
|
||||
for (int n = 0; n < num_bond[atom->map(update_mega_glove[jj+1][i])]; n++)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->cache_history(atom->map(update_mega_glove[jj+1][i]), n);
|
||||
for (int n = 0; n < num_bond[atom->map(update_mega_glove[jj+1][i])]; n++)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(atom->map(update_mega_glove[jj+1][i]), 0);
|
||||
}
|
||||
num_bond[atom->map(update_mega_glove[jj+1][i])] = 0;
|
||||
}
|
||||
if (landlocked_atoms[j][rxnID] == 0) {
|
||||
@ -3109,10 +3122,21 @@ void FixBondReact::update_everything()
|
||||
for (int n = 0; n < twomol->natoms; n++) {
|
||||
int nn = equivalences[n][1][rxnID]-1;
|
||||
if (n!=j && bond_atom[atom->map(update_mega_glove[jj+1][i])][p] == update_mega_glove[nn+1][i] && landlocked_atoms[n][rxnID] == 1) {
|
||||
// Cache history information, shift history, then delete final element
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->cache_history(atom->map(update_mega_glove[jj+1][i]), p);
|
||||
for (int m = p; m < num_bond[atom->map(update_mega_glove[jj+1][i])]-1; m++) {
|
||||
bond_type[atom->map(update_mega_glove[jj+1][i])][m] = bond_type[atom->map(update_mega_glove[jj+1][i])][m+1];
|
||||
bond_atom[atom->map(update_mega_glove[jj+1][i])][m] = bond_atom[atom->map(update_mega_glove[jj+1][i])][m+1];
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->shift_history(atom->map(update_mega_glove[jj+1][i]),m,m+1);
|
||||
}
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(atom->map(update_mega_glove[jj+1][i]),
|
||||
num_bond[atom->map(update_mega_glove[jj+1][i])]-1);
|
||||
num_bond[atom->map(update_mega_glove[jj+1][i])]--;
|
||||
delta_bonds--;
|
||||
}
|
||||
@ -3131,6 +3155,10 @@ void FixBondReact::update_everything()
|
||||
for (int p = 0; p < twomol->num_bond[j]; p++) {
|
||||
bond_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->bond_type[j][p];
|
||||
bond_atom[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->bond_atom[j][p]-1][1][rxnID]][i];
|
||||
// Check cached history data to see if bond regenerated
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->check_cache(atom->map(update_mega_glove[jj+1][i]), p);
|
||||
}
|
||||
}
|
||||
if (landlocked_atoms[j][rxnID] == 0) {
|
||||
@ -3139,6 +3167,10 @@ void FixBondReact::update_everything()
|
||||
insert_num = num_bond[atom->map(update_mega_glove[jj+1][i])];
|
||||
bond_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->bond_type[j][p];
|
||||
bond_atom[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->bond_atom[j][p]-1][1][rxnID]][i];
|
||||
// Check cached history data to see if bond regenerated
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->check_cache(atom->map(update_mega_glove[jj+1][i]), insert_num);
|
||||
num_bond[atom->map(update_mega_glove[jj+1][i])]++;
|
||||
if (num_bond[atom->map(update_mega_glove[jj+1][i])] > atom->bond_per_atom)
|
||||
error->one(FLERR,"Bond/react topology/atom exceed system topology/atom");
|
||||
@ -3150,6 +3182,10 @@ void FixBondReact::update_everything()
|
||||
}
|
||||
}
|
||||
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories)
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->clear_cache();
|
||||
|
||||
// Angles! First let's delete all angle info:
|
||||
if (force->angle && twomol->angleflag) {
|
||||
int *num_angle = atom->num_angle;
|
||||
|
||||
31
src/atom.cpp
31
src/atom.cpp
@ -128,6 +128,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
|
||||
omega = angmom = torque = nullptr;
|
||||
radius = rmass = nullptr;
|
||||
ellipsoid = line = tri = body = nullptr;
|
||||
quat = nullptr;
|
||||
|
||||
// molecular systems
|
||||
|
||||
@ -426,6 +427,10 @@ void Atom::peratom_create()
|
||||
add_peratom("tri",&tri,INT,0);
|
||||
add_peratom("body",&body,INT,0);
|
||||
|
||||
// BPM package
|
||||
|
||||
add_peratom("quat",&quat,DOUBLE,4);
|
||||
|
||||
// MOLECULE package
|
||||
|
||||
add_peratom("molecule",&molecule,tagintsize,0);
|
||||
@ -646,6 +651,7 @@ void Atom::set_atomflag_defaults()
|
||||
// identical list as 2nd customization in atom.h
|
||||
|
||||
sphere_flag = ellipsoid_flag = line_flag = tri_flag = body_flag = 0;
|
||||
quat_flag = 0;
|
||||
peri_flag = electron_flag = 0;
|
||||
wavepacket_flag = sph_flag = 0;
|
||||
molecule_flag = molindex_flag = molatom_flag = 0;
|
||||
@ -1889,8 +1895,7 @@ void Atom::add_molecule(int narg, char **arg)
|
||||
int index = 1;
|
||||
while (true) {
|
||||
molecules = (Molecule **)
|
||||
memory->srealloc(molecules,(nmolecule+1)*sizeof(Molecule *),
|
||||
"atom::molecules");
|
||||
memory->srealloc(molecules,(nmolecule+1)*sizeof(Molecule *), "atom::molecules");
|
||||
molecules[nmolecule] = new Molecule(lmp,narg,arg,index);
|
||||
molecules[nmolecule]->nset = 0;
|
||||
molecules[nmolecule-ifile+1]->nset++;
|
||||
@ -1920,8 +1925,7 @@ int Atom::find_molecule(char *id)
|
||||
called by fixes and commands that add molecules
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Atom::add_molecule_atom(Molecule *onemol, int iatom,
|
||||
int ilocal, tagint offset)
|
||||
void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint offset)
|
||||
{
|
||||
if (onemol->qflag && q_flag) q[ilocal] = onemol->q[iatom];
|
||||
if (onemol->radiusflag && radius_flag) radius[ilocal] = onemol->radius[iatom];
|
||||
@ -1936,6 +1940,19 @@ void Atom::add_molecule_atom(Molecule *onemol, int iatom,
|
||||
onemol->avec_body->set_quat(ilocal,onemol->quat_external);
|
||||
}
|
||||
|
||||
// initialize custom per-atom properties to zero if present
|
||||
|
||||
for (int i = 0; i < nivector; ++i)
|
||||
ivector[i][ilocal] = 0;
|
||||
for (int i = 0; i < ndvector; ++i)
|
||||
dvector[i][ilocal] = 0.0;
|
||||
for (int i = 0; i < niarray; ++i)
|
||||
for (int j = 0; j < icols[i]; ++j)
|
||||
iarray[i][ilocal][j] = 0;
|
||||
for (int i = 0; i < ndarray; ++i)
|
||||
for (int j = 0; j < dcols[i]; ++j)
|
||||
darray[i][ilocal][j] = 0.0;
|
||||
|
||||
if (molecular != Atom::MOLECULAR) return;
|
||||
|
||||
// add bond topology info
|
||||
@ -2614,6 +2631,10 @@ length of the data area, and a short description.
|
||||
- int
|
||||
- 1
|
||||
- 1 if the particle is a body particle, 0 if not
|
||||
* - quat
|
||||
- double
|
||||
- 4
|
||||
- four quaternion components of the particles
|
||||
* - i_name
|
||||
- int
|
||||
- 1
|
||||
@ -2669,6 +2690,7 @@ void *Atom::extract(const char *name)
|
||||
if (strcmp(name,"line") == 0) return (void *) line;
|
||||
if (strcmp(name,"tri") == 0) return (void *) tri;
|
||||
if (strcmp(name,"body") == 0) return (void *) body;
|
||||
if (strcmp(name,"quat") == 0) return (void *) quat;
|
||||
|
||||
if (strcmp(name,"vfrac") == 0) return (void *) vfrac;
|
||||
if (strcmp(name,"s0") == 0) return (void *) s0;
|
||||
@ -2791,6 +2813,7 @@ int Atom::extract_datatype(const char *name)
|
||||
if (strcmp(name,"line") == 0) return LAMMPS_INT;
|
||||
if (strcmp(name,"tri") == 0) return LAMMPS_INT;
|
||||
if (strcmp(name,"body") == 0) return LAMMPS_INT;
|
||||
if (strcmp(name,"quat") == 0) return LAMMPS_DOUBLE_2D;
|
||||
|
||||
if (strcmp(name,"vfrac") == 0) return LAMMPS_DOUBLE;
|
||||
if (strcmp(name,"s0") == 0) return LAMMPS_DOUBLE;
|
||||
|
||||
@ -79,6 +79,7 @@ class Atom : protected Pointers {
|
||||
double *radius;
|
||||
double **omega, **angmom, **torque;
|
||||
int *ellipsoid, *line, *tri, *body;
|
||||
double **quat;
|
||||
|
||||
// molecular systems
|
||||
|
||||
@ -180,7 +181,7 @@ class Atom : protected Pointers {
|
||||
|
||||
int molecule_flag, molindex_flag, molatom_flag;
|
||||
int q_flag, mu_flag;
|
||||
int rmass_flag, radius_flag, omega_flag, torque_flag, angmom_flag;
|
||||
int rmass_flag, radius_flag, omega_flag, torque_flag, angmom_flag, quat_flag;
|
||||
int vfrac_flag, spin_flag, eradius_flag, ervel_flag, erforce_flag;
|
||||
int cs_flag, csforce_flag, vforce_flag, ervelforce_flag, etag_flag;
|
||||
int rho_flag, esph_flag, cv_flag, vest_flag;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributead under
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
|
||||
@ -27,6 +27,10 @@ using namespace LAMMPS_NS;
|
||||
|
||||
enum { NONE, LINEAR, SPLINE };
|
||||
|
||||
// allocate space for static class instance variable and initialize it
|
||||
|
||||
int Bond::instance_total = 0;
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
set bond contribution to Vdwl energy to 0.0
|
||||
a particular bond style can override this
|
||||
@ -34,12 +38,17 @@ enum { NONE, LINEAR, SPLINE };
|
||||
|
||||
Bond::Bond(LAMMPS *_lmp) : Pointers(_lmp)
|
||||
{
|
||||
instance_me = instance_total++;
|
||||
|
||||
energy = 0.0;
|
||||
virial[0] = virial[1] = virial[2] = virial[3] = virial[4] = virial[5] = 0.0;
|
||||
writedata = 1;
|
||||
|
||||
comm_forward = comm_reverse = comm_reverse_off = 0;
|
||||
|
||||
allocated = 0;
|
||||
suffix_flag = Suffix::NONE;
|
||||
partial_flag = 0;
|
||||
|
||||
maxeatom = maxvatom = 0;
|
||||
eatom = nullptr;
|
||||
|
||||
12
src/bond.h
12
src/bond.h
@ -23,13 +23,20 @@ class Bond : protected Pointers {
|
||||
friend class FixOMP;
|
||||
|
||||
public:
|
||||
static int instance_total; // # of Bond classes ever instantiated
|
||||
|
||||
int allocated;
|
||||
int *setflag;
|
||||
int partial_flag; // 1 if bond type can be set to 0 and deleted
|
||||
int writedata; // 1 if writes coeffs to data file
|
||||
double energy; // accumulated energies
|
||||
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
||||
double *eatom, **vatom; // accumulated per-atom energy/virial
|
||||
|
||||
int comm_forward; // size of forward communication (0 if none)
|
||||
int comm_reverse; // size of reverse communication (0 if none)
|
||||
int comm_reverse_off; // size of reverse comm even if newton off
|
||||
|
||||
int reinitflag; // 1 if compatible with fix adapt and alike
|
||||
|
||||
// KOKKOS host/device flag and data masks
|
||||
@ -55,10 +62,15 @@ class Bond : protected Pointers {
|
||||
virtual double memory_usage();
|
||||
virtual void *extract(const char *, int &) { return nullptr; }
|
||||
virtual void reinit();
|
||||
virtual int pack_forward_comm(int, int *, double *, int, int *) {return 0;}
|
||||
virtual void unpack_forward_comm(int, int, double *) {}
|
||||
virtual int pack_reverse_comm(int, int, double *) {return 0;}
|
||||
virtual void unpack_reverse_comm(int, int *, double *) {}
|
||||
|
||||
void write_file(int, char **);
|
||||
|
||||
protected:
|
||||
int instance_me; // which Bond class instantiation I am
|
||||
int suffix_flag; // suffix compatibility flag
|
||||
|
||||
int evflag;
|
||||
|
||||
@ -218,6 +218,9 @@ void Comm::init()
|
||||
if (force->pair) maxforward = MAX(maxforward,force->pair->comm_forward);
|
||||
if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse);
|
||||
|
||||
if (force->bond) maxforward = MAX(maxforward,force->bond->comm_forward);
|
||||
if (force->bond) maxreverse = MAX(maxreverse,force->bond->comm_reverse);
|
||||
|
||||
for (const auto &fix : fix_list) {
|
||||
maxforward = MAX(maxforward,fix->comm_forward);
|
||||
maxreverse = MAX(maxreverse,fix->comm_reverse);
|
||||
@ -235,6 +238,7 @@ void Comm::init()
|
||||
|
||||
if (force->newton == 0) maxreverse = 0;
|
||||
if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse_off);
|
||||
if (force->bond) maxreverse = MAX(maxreverse,force->bond->comm_reverse_off);
|
||||
|
||||
// maxexchange_atom = size of an exchanged atom, set by AtomVec
|
||||
// only needs to be set if size > BUFEXTRA
|
||||
|
||||
@ -80,10 +80,12 @@ class Comm : protected Pointers {
|
||||
virtual void exchange() = 0; // move atoms to new procs
|
||||
virtual void borders() = 0; // setup list of atoms to comm
|
||||
|
||||
// forward/reverse comm from a Pair, Fix, Compute, Dump
|
||||
// forward/reverse comm from a Pair, Bond, Fix, Compute, Dump
|
||||
|
||||
virtual void forward_comm(class Pair *) = 0;
|
||||
virtual void reverse_comm(class Pair *) = 0;
|
||||
virtual void forward_comm(class Bond *) = 0;
|
||||
virtual void reverse_comm(class Bond *) = 0;
|
||||
virtual void forward_comm(class Fix *, int size = 0) = 0;
|
||||
virtual void reverse_comm(class Fix *, int size = 0) = 0;
|
||||
virtual void reverse_comm_variable(class Fix *) = 0;
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "bond.h"
|
||||
#include "compute.h"
|
||||
#include "domain.h"
|
||||
#include "dump.h"
|
||||
@ -490,8 +491,7 @@ void CommBrick::setup()
|
||||
return how many procs away are needed to encompass cutghost away from loc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int CommBrick::updown(int dim, int dir, int loc,
|
||||
double prd, int periodicity, double *split)
|
||||
int CommBrick::updown(int dim, int dir, int loc, double prd, int periodicity, double *split)
|
||||
{
|
||||
int index,count;
|
||||
double frac,delta;
|
||||
@ -552,19 +552,15 @@ void CommBrick::forward_comm(int /*dummy*/)
|
||||
if (comm_x_only) {
|
||||
if (size_forward_recv[iswap]) {
|
||||
buf = x[firstrecv[iswap]];
|
||||
MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE,
|
||||
recvproc[iswap],0,world,&request);
|
||||
MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
}
|
||||
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
} else if (ghost_velocity) {
|
||||
if (size_forward_recv[iswap])
|
||||
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
|
||||
recvproc[iswap],0,world,&request);
|
||||
n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_recv);
|
||||
@ -572,8 +568,7 @@ void CommBrick::forward_comm(int /*dummy*/)
|
||||
if (size_forward_recv[iswap])
|
||||
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
|
||||
recvproc[iswap],0,world,&request);
|
||||
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_recv);
|
||||
@ -585,12 +580,10 @@ void CommBrick::forward_comm(int /*dummy*/)
|
||||
avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
||||
x[firstrecv[iswap]],pbc_flag[iswap],pbc[iswap]);
|
||||
} else if (ghost_velocity) {
|
||||
avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||
} else {
|
||||
avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||
}
|
||||
}
|
||||
@ -618,18 +611,15 @@ void CommBrick::reverse_comm()
|
||||
if (sendproc[iswap] != me) {
|
||||
if (comm_f_only) {
|
||||
if (size_reverse_recv[iswap])
|
||||
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,
|
||||
sendproc[iswap],0,world,&request);
|
||||
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
if (size_reverse_send[iswap]) {
|
||||
buf = f[firstrecv[iswap]];
|
||||
MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE,
|
||||
recvproc[iswap],0,world);
|
||||
MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
}
|
||||
if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
} else {
|
||||
if (size_reverse_recv[iswap])
|
||||
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,
|
||||
sendproc[iswap],0,world,&request);
|
||||
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
n = avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -639,8 +629,7 @@ void CommBrick::reverse_comm()
|
||||
} else {
|
||||
if (comm_f_only) {
|
||||
if (sendnum[iswap])
|
||||
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],
|
||||
f[firstrecv[iswap]]);
|
||||
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],f[firstrecv[iswap]]);
|
||||
} else {
|
||||
avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],buf_send);
|
||||
@ -733,25 +722,21 @@ void CommBrick::exchange()
|
||||
if (procgrid[dim] == 1) nrecv = 0;
|
||||
else {
|
||||
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0,
|
||||
&nrecv1,1,MPI_INT,procneigh[dim][1],0,world,
|
||||
MPI_STATUS_IGNORE);
|
||||
&nrecv1,1,MPI_INT,procneigh[dim][1],0,world,MPI_STATUS_IGNORE);
|
||||
nrecv = nrecv1;
|
||||
if (procgrid[dim] > 2) {
|
||||
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
|
||||
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,
|
||||
MPI_STATUS_IGNORE);
|
||||
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE);
|
||||
nrecv += nrecv2;
|
||||
}
|
||||
if (nrecv > maxrecv) grow_recv(nrecv);
|
||||
|
||||
MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request);
|
||||
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
|
||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
|
||||
if (procgrid[dim] > 2) {
|
||||
MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,
|
||||
world,&request);
|
||||
MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request);
|
||||
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
|
||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
}
|
||||
@ -925,11 +910,9 @@ void CommBrick::borders()
|
||||
|
||||
if (nsend*size_border > maxsend) grow_send(nsend*size_border,0);
|
||||
if (ghost_velocity)
|
||||
n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send,
|
||||
pbc_flag[iswap],pbc[iswap]);
|
||||
n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
else
|
||||
n = avec->pack_border(nsend,sendlist[iswap],buf_send,
|
||||
pbc_flag[iswap],pbc[iswap]);
|
||||
n = avec->pack_border(nsend,sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
|
||||
// swap atoms with other proc
|
||||
// no MPI calls except SendRecv if nsend/nrecv = 0
|
||||
@ -938,8 +921,7 @@ void CommBrick::borders()
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
MPI_Sendrecv(&nsend,1,MPI_INT,sendproc[iswap],0,
|
||||
&nrecv,1,MPI_INT,recvproc[iswap],0,world,
|
||||
MPI_STATUS_IGNORE);
|
||||
&nrecv,1,MPI_INT,recvproc[iswap],0,world,MPI_STATUS_IGNORE);
|
||||
if (nrecv*size_border > maxrecv) grow_recv(nrecv*size_border);
|
||||
if (nrecv) MPI_Irecv(buf_recv,nrecv*size_border,MPI_DOUBLE,
|
||||
recvproc[iswap],0,world,&request);
|
||||
@ -1013,16 +995,14 @@ void CommBrick::forward_comm(Pair *pair)
|
||||
|
||||
// pack buffer
|
||||
|
||||
n = pair->pack_forward_comm(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
n = pair->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
|
||||
// exchange with another proc
|
||||
// if self, set recv buffer to send buffer
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (recvnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,
|
||||
recvproc[iswap],0,world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
if (sendnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1059,8 +1039,7 @@ void CommBrick::reverse_comm(Pair *pair)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (sendnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
if (recvnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1073,6 +1052,80 @@ void CommBrick::reverse_comm(Pair *pair)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
forward communication invoked by a Bond
|
||||
nsize used only to set recv buffer limit
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void CommBrick::forward_comm(Bond *bond)
|
||||
{
|
||||
int iswap,n;
|
||||
double *buf;
|
||||
MPI_Request request;
|
||||
|
||||
int nsize = bond->comm_forward;
|
||||
|
||||
for (iswap = 0; iswap < nswap; iswap++) {
|
||||
|
||||
// pack buffer
|
||||
|
||||
n = bond->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
|
||||
// exchange with another proc
|
||||
// if self, set recv buffer to send buffer
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (recvnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
if (sendnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
buf = buf_recv;
|
||||
} else buf = buf_send;
|
||||
|
||||
// unpack buffer
|
||||
|
||||
bond->unpack_forward_comm(recvnum[iswap],firstrecv[iswap],buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
reverse communication invoked by a Bond
|
||||
nsize used only to set recv buffer limit
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void CommBrick::reverse_comm(Bond *bond)
|
||||
{
|
||||
int iswap,n;
|
||||
double *buf;
|
||||
MPI_Request request;
|
||||
|
||||
int nsize = MAX(bond->comm_reverse,bond->comm_reverse_off);
|
||||
|
||||
for (iswap = nswap-1; iswap >= 0; iswap--) {
|
||||
|
||||
// pack buffer
|
||||
|
||||
n = bond->pack_reverse_comm(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||
|
||||
// exchange with another proc
|
||||
// if self, set recv buffer to send buffer
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (sendnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
if (recvnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
buf = buf_recv;
|
||||
} else buf = buf_send;
|
||||
|
||||
// unpack buffer
|
||||
|
||||
bond->unpack_reverse_comm(sendnum[iswap],sendlist[iswap],buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
forward communication invoked by a Fix
|
||||
size/nsize used only to set recv buffer limit
|
||||
@ -1095,16 +1148,14 @@ void CommBrick::forward_comm(Fix *fix, int size)
|
||||
|
||||
// pack buffer
|
||||
|
||||
n = fix->pack_forward_comm(sendnum[iswap],sendlist[iswap],
|
||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
n = fix->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||
|
||||
// exchange with another proc
|
||||
// if self, set recv buffer to send buffer
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (recvnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
if (sendnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1146,8 +1197,7 @@ void CommBrick::reverse_comm(Fix *fix, int size)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (sendnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
if (recvnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1185,13 +1235,11 @@ void CommBrick::reverse_comm_variable(Fix *fix)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
MPI_Sendrecv(&nsend,1,MPI_INT,recvproc[iswap],0,
|
||||
&nrecv,1,MPI_INT,sendproc[iswap],0,world,
|
||||
MPI_STATUS_IGNORE);
|
||||
&nrecv,1,MPI_INT,sendproc[iswap],0,world,MPI_STATUS_IGNORE);
|
||||
|
||||
if (sendnum[iswap]) {
|
||||
if (nrecv > maxrecv) grow_recv(nrecv);
|
||||
MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
}
|
||||
if (recvnum[iswap])
|
||||
MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
@ -1230,8 +1278,7 @@ void CommBrick::forward_comm(Compute *compute)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (recvnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
if (sendnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1268,8 +1315,7 @@ void CommBrick::reverse_comm(Compute *compute)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (sendnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
if (recvnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1307,8 +1353,7 @@ void CommBrick::forward_comm(Dump *dump)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (recvnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
if (sendnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1345,8 +1390,7 @@ void CommBrick::reverse_comm(Dump *dump)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (sendnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||
if (recvnum[iswap])
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
@ -1394,11 +1438,9 @@ void CommBrick::forward_comm_array(int nsize, double **array)
|
||||
|
||||
if (sendproc[iswap] != me) {
|
||||
if (recvnum[iswap])
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
||||
world,&request);
|
||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||
if (sendnum[iswap])
|
||||
MPI_Send(buf_send,nsize*sendnum[iswap],MPI_DOUBLE,
|
||||
sendproc[iswap],0,world);
|
||||
MPI_Send(buf_send,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world);
|
||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
buf = buf_recv;
|
||||
} else buf = buf_send;
|
||||
@ -1444,21 +1486,18 @@ int CommBrick::exchange_variable(int n, double *inbuf, double *&outbuf)
|
||||
nrecv += nrecv1;
|
||||
if (procgrid[dim] > 2) {
|
||||
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
|
||||
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,
|
||||
MPI_STATUS_IGNORE);
|
||||
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE);
|
||||
nrecv += nrecv2;
|
||||
} else nrecv2 = 0;
|
||||
|
||||
if (nrecv > maxrecv) grow_recv(nrecv);
|
||||
|
||||
MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0,
|
||||
world,&request);
|
||||
MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request);
|
||||
MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
|
||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
|
||||
if (procgrid[dim] > 2) {
|
||||
MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,
|
||||
world,&request);
|
||||
MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request);
|
||||
MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
|
||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ class CommBrick : public Comm {
|
||||
public:
|
||||
CommBrick(class LAMMPS *);
|
||||
CommBrick(class LAMMPS *, class Comm *);
|
||||
|
||||
~CommBrick() override;
|
||||
|
||||
void init() override;
|
||||
@ -33,6 +34,8 @@ class CommBrick : public Comm {
|
||||
|
||||
void forward_comm(class Pair *) override; // forward comm from a Pair
|
||||
void reverse_comm(class Pair *) override; // reverse comm from a Pair
|
||||
void forward_comm(class Bond *) override; // forward comm from a Bond
|
||||
void reverse_comm(class Bond *) override; // reverse comm from a Bond
|
||||
void forward_comm(class Fix *, int size = 0) override; // forward comm from a Fix
|
||||
void reverse_comm(class Fix *, int size = 0) override; // reverse comm from a Fix
|
||||
void reverse_comm_variable(class Fix *) override; // variable size reverse comm from a Fix
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "bond.h"
|
||||
#include "compute.h"
|
||||
#include "domain.h"
|
||||
#include "dump.h"
|
||||
@ -512,16 +513,14 @@ void CommTiled::setup()
|
||||
MIN(sbox_multi[3+idim]+cutghostmulti[icollection][idim],subhi[idim]);
|
||||
else
|
||||
sbox_multi[3+idim] =
|
||||
MIN(sbox_multi[3+idim]-prd[idim]+cutghostmulti[icollection][idim],
|
||||
subhi[idim]);
|
||||
MIN(sbox_multi[3+idim]-prd[idim]+cutghostmulti[icollection][idim],subhi[idim]);
|
||||
} else {
|
||||
if (i < noverlap1)
|
||||
sbox_multi[idim] =
|
||||
MAX(sbox_multi[idim]-cutghostmulti[icollection][idim],sublo[idim]);
|
||||
else
|
||||
sbox_multi[idim] =
|
||||
MAX(sbox_multi[idim]+prd[idim]-cutghostmulti[icollection][idim],
|
||||
sublo[idim]);
|
||||
MAX(sbox_multi[idim]+prd[idim]-cutghostmulti[icollection][idim],sublo[idim]);
|
||||
sbox_multi[3+idim] = subhi[idim];
|
||||
}
|
||||
|
||||
@ -588,16 +587,14 @@ void CommTiled::setup()
|
||||
MIN(sbox_multiold[3+idim]+cutghostmultiold[itype][idim],subhi[idim]);
|
||||
else
|
||||
sbox_multiold[3+idim] =
|
||||
MIN(sbox_multiold[3+idim]-prd[idim]+cutghostmultiold[itype][idim],
|
||||
subhi[idim]);
|
||||
MIN(sbox_multiold[3+idim]-prd[idim]+cutghostmultiold[itype][idim],subhi[idim]);
|
||||
} else {
|
||||
if (i < noverlap1)
|
||||
sbox_multiold[idim] =
|
||||
MAX(sbox_multiold[idim]-cutghostmultiold[itype][idim],sublo[idim]);
|
||||
else
|
||||
sbox_multiold[idim] =
|
||||
MAX(sbox_multiold[idim]+prd[idim]-cutghostmultiold[itype][idim],
|
||||
sublo[idim]);
|
||||
MAX(sbox_multiold[idim]+prd[idim]-cutghostmultiold[itype][idim],sublo[idim]);
|
||||
sbox_multiold[3+idim] = subhi[idim];
|
||||
}
|
||||
|
||||
@ -747,8 +744,7 @@ void CommTiled::forward_comm(int /*dummy*/)
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
x[firstrecv[iswap][nrecv]],pbc_flag[iswap][nsend],
|
||||
pbc[iswap][nsend]);
|
||||
x[firstrecv[iswap][nrecv]],pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
}
|
||||
if (recvother[iswap]) MPI_Waitall(nrecv,requests,MPI_STATUS_IGNORE);
|
||||
|
||||
@ -756,8 +752,7 @@ void CommTiled::forward_comm(int /*dummy*/)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]],
|
||||
size_forward_recv[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
size_forward_recv[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
@ -769,15 +764,13 @@ void CommTiled::forward_comm(int /*dummy*/)
|
||||
if (sendself[iswap]) {
|
||||
avec->pack_comm_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
avec->unpack_comm_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
avec->unpack_comm_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
avec->unpack_comm_vel(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[size_forward*
|
||||
forward_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[size_forward*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,8 +778,7 @@ void CommTiled::forward_comm(int /*dummy*/)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]],
|
||||
size_forward_recv[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
size_forward_recv[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
@ -798,15 +790,13 @@ void CommTiled::forward_comm(int /*dummy*/)
|
||||
if (sendself[iswap]) {
|
||||
avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
avec->unpack_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
avec->unpack_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
avec->unpack_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[size_forward*
|
||||
forward_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[size_forward*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -839,8 +829,7 @@ void CommTiled::reverse_comm()
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]],
|
||||
size_reverse_recv[iswap][i],MPI_DOUBLE,
|
||||
sendproc[iswap][i],0,world,&requests[i]);
|
||||
size_reverse_recv[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
@ -856,8 +845,7 @@ void CommTiled::reverse_comm()
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[size_reverse*
|
||||
reverse_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[size_reverse*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,28 +853,23 @@ void CommTiled::reverse_comm()
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++)
|
||||
MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]],
|
||||
size_reverse_recv[iswap][i],MPI_DOUBLE,
|
||||
sendproc[iswap][i],0,world,&requests[i]);
|
||||
size_reverse_recv[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
n = avec->pack_reverse(recvnum[iswap][i],firstrecv[iswap][i],
|
||||
buf_send);
|
||||
n = avec->pack_reverse(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
avec->pack_reverse(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
avec->unpack_reverse(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send);
|
||||
avec->pack_reverse(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
avec->unpack_reverse(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[size_reverse*
|
||||
reverse_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[size_reverse*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -989,8 +972,7 @@ void CommTiled::exchange()
|
||||
if (!nexch) continue;
|
||||
|
||||
for (m = 0; m < nexch; m++)
|
||||
MPI_Irecv(&exchnum[dim][m],1,MPI_INT,
|
||||
exchproc[dim][m],0,world,&requests[m]);
|
||||
MPI_Irecv(&exchnum[dim][m],1,MPI_INT,exchproc[dim][m],0,world,&requests[m]);
|
||||
for (m = 0; m < nexch; m++)
|
||||
MPI_Send(&nsend,1,MPI_INT,exchproc[dim][m],0,world);
|
||||
MPI_Waitall(nexch,requests,MPI_STATUS_IGNORE);
|
||||
@ -1001,8 +983,7 @@ void CommTiled::exchange()
|
||||
|
||||
offset = 0;
|
||||
for (m = 0; m < nexch; m++) {
|
||||
MPI_Irecv(&buf_recv[offset],exchnum[dim][m],
|
||||
MPI_DOUBLE,exchproc[dim][m],0,world,&requests[m]);
|
||||
MPI_Irecv(&buf_recv[offset],exchnum[dim][m],MPI_DOUBLE,exchproc[dim][m],0,world,&requests[m]);
|
||||
offset += exchnum[dim][m];
|
||||
}
|
||||
for (m = 0; m < nexch; m++)
|
||||
@ -1233,8 +1214,7 @@ void CommTiled::borders()
|
||||
|
||||
if (recvother[iswap])
|
||||
for (m = 0; m < nrecv; m++)
|
||||
MPI_Irecv(&recvnum[iswap][m],1,MPI_INT,
|
||||
recvproc[iswap][m],0,world,&requests[m]);
|
||||
MPI_Irecv(&recvnum[iswap][m],1,MPI_INT,recvproc[iswap][m],0,world,&requests[m]);
|
||||
if (sendother[iswap])
|
||||
for (m = 0; m < nsend; m++)
|
||||
MPI_Send(&sendnum[iswap][m],1,MPI_INT,sendproc[iswap][m],0,world);
|
||||
@ -1294,17 +1274,14 @@ void CommTiled::borders()
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
avec->pack_border_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],
|
||||
pbc[iswap][nsend]);
|
||||
avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
||||
avec->unpack_border_vel(recvnum[iswap][m],firstrecv[iswap][m],
|
||||
&buf_recv[size_border*
|
||||
forward_recv_offset[iswap][m]]);
|
||||
&buf_recv[size_border*forward_recv_offset[iswap][m]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1325,15 +1302,13 @@ void CommTiled::borders()
|
||||
if (sendself[iswap]) {
|
||||
avec->pack_border(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
||||
avec->unpack_border(recvnum[iswap][m],firstrecv[iswap][m],
|
||||
&buf_recv[size_border*
|
||||
forward_recv_offset[iswap][m]]);
|
||||
&buf_recv[size_border*forward_recv_offset[iswap][m]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1351,10 +1326,8 @@ void CommTiled::borders()
|
||||
// For molecular systems we lose some bits for local atom indices due
|
||||
// to encoding of special pairs in neighbor lists. Check for overflows.
|
||||
|
||||
if ((atom->molecular != Atom::ATOMIC)
|
||||
&& ((atom->nlocal + atom->nghost) > NEIGHMASK))
|
||||
error->one(FLERR,"Per-processor number of atoms is too large for "
|
||||
"molecular neighbor lists");
|
||||
if ((atom->molecular != Atom::ATOMIC) && ((atom->nlocal + atom->nghost) > NEIGHMASK))
|
||||
error->one(FLERR,"Per-processor number of atoms is too large for molecular neighbor lists");
|
||||
|
||||
// insure send/recv buffers are long enough for all forward & reverse comm
|
||||
// send buf is for one forward or reverse sends to one proc
|
||||
@ -1388,8 +1361,7 @@ void CommTiled::forward_comm(Pair *pair)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||
nsize*recvnum[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
|
||||
if (sendother[iswap]) {
|
||||
@ -1402,17 +1374,14 @@ void CommTiled::forward_comm(Pair *pair)
|
||||
|
||||
if (sendself[iswap]) {
|
||||
pair->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],
|
||||
pbc[iswap][nsend]);
|
||||
pair->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
pair->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
pair->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
forward_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1436,28 +1405,107 @@ void CommTiled::reverse_comm(Pair *pair)
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
||||
sendproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
n = pair->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
||||
buf_send);
|
||||
n = pair->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
pair->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
pair->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send);
|
||||
pair->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
pair->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
pair->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
reverse_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
forward communication invoked by a Bond
|
||||
nsize used only to set recv buffer limit
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void CommTiled::forward_comm(Bond *bond)
|
||||
{
|
||||
int i,irecv,n,nsend,nrecv;
|
||||
|
||||
int nsize = bond->comm_forward;
|
||||
|
||||
for (int iswap = 0; iswap < nswap; iswap++) {
|
||||
nsend = nsendproc[iswap] - sendself[iswap];
|
||||
nrecv = nrecvproc[iswap] - sendself[iswap];
|
||||
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
n = bond->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
||||
buf_send,pbc_flag[iswap][i],pbc[iswap][i]);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
|
||||
if (sendself[iswap]) {
|
||||
bond->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
bond->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
bond->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
reverse communication invoked by a Bond
|
||||
nsize used only to set recv buffer limit
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void CommTiled::reverse_comm(Bond *bond)
|
||||
{
|
||||
int i,irecv,n,nsend,nrecv;
|
||||
|
||||
int nsize = MAX(bond->comm_reverse,bond->comm_reverse_off);
|
||||
|
||||
for (int iswap = nswap-1; iswap >= 0; iswap--) {
|
||||
nsend = nsendproc[iswap] - sendself[iswap];
|
||||
nrecv = nrecvproc[iswap] - sendself[iswap];
|
||||
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
n = bond->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
bond->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
bond->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
bond->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1486,8 +1534,7 @@ void CommTiled::forward_comm(Fix *fix, int size)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||
nsize*recvnum[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
@ -1498,17 +1545,14 @@ void CommTiled::forward_comm(Fix *fix, int size)
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
fix->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],
|
||||
pbc[iswap][nsend]);
|
||||
fix->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
fix->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
fix->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
forward_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1537,28 +1581,23 @@ void CommTiled::reverse_comm(Fix *fix, int size)
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
||||
sendproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
n = fix->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
||||
buf_send);
|
||||
n = fix->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
fix->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
fix->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send);
|
||||
fix->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
fix->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
fix->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
reverse_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1594,31 +1633,26 @@ void CommTiled::forward_comm(Compute *compute)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||
nsize*recvnum[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
n = compute->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
||||
buf_send,pbc_flag[iswap][i],
|
||||
pbc[iswap][i]);
|
||||
buf_send,pbc_flag[iswap][i],pbc[iswap][i]);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
compute->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],
|
||||
pbc[iswap][nsend]);
|
||||
compute->unpack_forward_comm(recvnum[iswap][nrecv],
|
||||
firstrecv[iswap][nrecv],buf_send);
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
compute->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
compute->
|
||||
unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
forward_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1642,29 +1676,24 @@ void CommTiled::reverse_comm(Compute *compute)
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
||||
sendproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
n = compute->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
||||
buf_send);
|
||||
n = compute->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
compute->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
compute->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send);
|
||||
compute->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
compute->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
compute->
|
||||
unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
reverse_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1688,21 +1717,18 @@ void CommTiled::forward_comm(Dump *dump)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||
nsize*recvnum[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
n = dump->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
||||
buf_send,pbc_flag[iswap][i],
|
||||
pbc[iswap][i]);
|
||||
buf_send,pbc_flag[iswap][i],pbc[iswap][i]);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
dump->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send,pbc_flag[iswap][nsend],
|
||||
pbc[iswap][nsend]);
|
||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||
dump->unpack_forward_comm(recvnum[iswap][nrecv],
|
||||
firstrecv[iswap][nrecv],buf_send);
|
||||
}
|
||||
@ -1710,8 +1736,7 @@ void CommTiled::forward_comm(Dump *dump)
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
dump->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
forward_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1735,28 +1760,23 @@ void CommTiled::reverse_comm(Dump *dump)
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
||||
sendproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
n = dump->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
||||
buf_send);
|
||||
n = dump->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
dump->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
||||
buf_send);
|
||||
dump->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||
buf_send);
|
||||
dump->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||
dump->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||
dump->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||
&buf_recv[nsize*
|
||||
reverse_recv_offset[iswap][irecv]]);
|
||||
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1788,8 +1808,7 @@ void CommTiled::forward_comm_array(int nsize, double **array)
|
||||
if (recvother[iswap]) {
|
||||
for (i = 0; i < nrecv; i++)
|
||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||
nsize*recvnum[iswap][i],
|
||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||
}
|
||||
if (sendother[iswap]) {
|
||||
for (i = 0; i < nsend; i++) {
|
||||
@ -1799,8 +1818,7 @@ void CommTiled::forward_comm_array(int nsize, double **array)
|
||||
for (k = 0; k < nsize; k++)
|
||||
buf_send[m++] = array[j][k];
|
||||
}
|
||||
MPI_Send(buf_send,nsize*sendnum[iswap][i],
|
||||
MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||
MPI_Send(buf_send,nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||
}
|
||||
}
|
||||
if (sendself[iswap]) {
|
||||
@ -1919,8 +1937,7 @@ void CommTiled::box_drop_tiled(int /*idim*/, double *lo, double *hi, int &indexm
|
||||
box_drop_tiled_recurse(lo,hi,0,nprocs-1,indexme);
|
||||
}
|
||||
|
||||
void CommTiled::box_drop_tiled_recurse(double *lo, double *hi,
|
||||
int proclower, int procupper,
|
||||
void CommTiled::box_drop_tiled_recurse(double *lo, double *hi, int proclower, int procupper,
|
||||
int &indexme)
|
||||
{
|
||||
// end recursion when partition is a single proc
|
||||
@ -1958,8 +1975,7 @@ void CommTiled::box_drop_tiled_recurse(double *lo, double *hi,
|
||||
return other box owned by proc as lo/hi corner pts
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void CommTiled::box_other_brick(int idim, int idir,
|
||||
int proc, double *lo, double *hi)
|
||||
void CommTiled::box_other_brick(int idim, int idir, int proc, double *lo, double *hi)
|
||||
{
|
||||
lo[0] = sublo[0]; lo[1] = sublo[1]; lo[2] = sublo[2];
|
||||
hi[0] = subhi[0]; hi[1] = subhi[1]; hi[2] = subhi[2];
|
||||
@ -2006,8 +2022,7 @@ void CommTiled::box_other_brick(int idim, int idir,
|
||||
return other box owned by proc as lo/hi corner pts
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void CommTiled::box_other_tiled(int /*idim*/, int /*idir*/,
|
||||
int proc, double *lo, double *hi)
|
||||
void CommTiled::box_other_tiled(int /*idim*/, int /*idir*/, int proc, double *lo, double *hi)
|
||||
{
|
||||
double (*split)[2] = rcbinfo[proc].mysplit;
|
||||
|
||||
@ -2136,8 +2151,7 @@ int CommTiled::point_drop_tiled(int idim, double *x)
|
||||
recursive point drop thru RCB tree
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int CommTiled::point_drop_tiled_recurse(double *x,
|
||||
int proclower, int procupper)
|
||||
int CommTiled::point_drop_tiled_recurse(double *x, int proclower, int procupper)
|
||||
{
|
||||
// end recursion when partition is a single proc
|
||||
// return proc
|
||||
@ -2195,8 +2209,7 @@ void CommTiled::coord2proc_setup()
|
||||
memcpy(&rcbone.mysplit[0][0],&mysplit[0][0],6*sizeof(double));
|
||||
rcbone.cutfrac = rcbcutfrac;
|
||||
rcbone.dim = rcbcutdim;
|
||||
MPI_Allgather(&rcbone,sizeof(RCBinfo),MPI_CHAR,
|
||||
rcbinfo,sizeof(RCBinfo),MPI_CHAR,world);
|
||||
MPI_Allgather(&rcbone,sizeof(RCBinfo),MPI_CHAR,rcbinfo,sizeof(RCBinfo),MPI_CHAR,world);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -22,6 +22,7 @@ class CommTiled : public Comm {
|
||||
public:
|
||||
CommTiled(class LAMMPS *);
|
||||
CommTiled(class LAMMPS *, class Comm *);
|
||||
|
||||
~CommTiled() override;
|
||||
|
||||
void init() override;
|
||||
@ -33,6 +34,8 @@ class CommTiled : public Comm {
|
||||
|
||||
void forward_comm(class Pair *) override; // forward comm from a Pair
|
||||
void reverse_comm(class Pair *) override; // reverse comm from a Pair
|
||||
void forward_comm(class Bond *) override; // forward comm from a Bond
|
||||
void reverse_comm(class Bond *) override; // reverse comm from a Bond
|
||||
void forward_comm(class Fix *, int size = 0) override; // forward comm from a Fix
|
||||
void reverse_comm(class Fix *, int size = 0) override; // reverse comm from a Fix
|
||||
void reverse_comm_variable(class Fix *) override; // variable size reverse comm from a Fix
|
||||
|
||||
@ -231,25 +231,25 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
} else if (strcmp(arg[iarg],"quatw") == 0) {
|
||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
||||
if (!avec_ellipsoid && !avec_body)
|
||||
if (!avec_ellipsoid && !avec_body && !atom->quat_flag)
|
||||
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_quatw;
|
||||
} else if (strcmp(arg[iarg],"quati") == 0) {
|
||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
||||
if (!avec_ellipsoid && !avec_body)
|
||||
if (!avec_ellipsoid && !avec_body && !atom->quat_flag)
|
||||
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_quati;
|
||||
} else if (strcmp(arg[iarg],"quatj") == 0) {
|
||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
||||
if (!avec_ellipsoid && !avec_body)
|
||||
if (!avec_ellipsoid && !avec_body && !atom->quat_flag)
|
||||
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_quatj;
|
||||
} else if (strcmp(arg[iarg],"quatk") == 0) {
|
||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
||||
if (!avec_ellipsoid && !avec_body)
|
||||
if (!avec_ellipsoid && !avec_body && !atom->quat_flag)
|
||||
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_quatk;
|
||||
|
||||
@ -1334,7 +1334,7 @@ void ComputePropertyAtom::pack_quatw(int n)
|
||||
n += nvalues;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (avec_body) {
|
||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||
int *body = atom->body;
|
||||
int *mask = atom->mask;
|
||||
@ -1346,6 +1346,17 @@ void ComputePropertyAtom::pack_quatw(int n)
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
} else {
|
||||
double **quat = atom->quat;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit)
|
||||
buf[n] = quat[i][0];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1366,7 +1377,7 @@ void ComputePropertyAtom::pack_quati(int n)
|
||||
n += nvalues;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (avec_body) {
|
||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||
int *body = atom->body;
|
||||
int *mask = atom->mask;
|
||||
@ -1378,6 +1389,17 @@ void ComputePropertyAtom::pack_quati(int n)
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
} else {
|
||||
double **quat = atom->quat;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit)
|
||||
buf[n] = quat[i][1];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1398,7 +1420,7 @@ void ComputePropertyAtom::pack_quatj(int n)
|
||||
n += nvalues;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (avec_body) {
|
||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||
int *body = atom->body;
|
||||
int *mask = atom->mask;
|
||||
@ -1410,6 +1432,17 @@ void ComputePropertyAtom::pack_quatj(int n)
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
} else {
|
||||
double **quat = atom->quat;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit)
|
||||
buf[n] = quat[i][2];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1430,7 +1463,7 @@ void ComputePropertyAtom::pack_quatk(int n)
|
||||
n += nvalues;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (avec_body) {
|
||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||
int *body = atom->body;
|
||||
int *mask = atom->mask;
|
||||
@ -1442,6 +1475,17 @@ void ComputePropertyAtom::pack_quatk(int n)
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
} else {
|
||||
double **quat = atom->quat;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit)
|
||||
buf[n] = quat[i][3];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,10 @@
|
||||
#include "comm.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "fix_bond_history.h"
|
||||
#include "force.h"
|
||||
#include "group.h"
|
||||
#include "modify.h"
|
||||
#include "special.h"
|
||||
|
||||
#include <cstring>
|
||||
@ -116,6 +118,10 @@ void DeleteBonds::command(int narg, char **arg)
|
||||
iarg++;
|
||||
}
|
||||
|
||||
// find instances of bond history to delete data
|
||||
auto histories = modify->get_fix_by_style("BOND_HISTORY");
|
||||
int n_histories = histories.size();
|
||||
|
||||
// border swap to insure type and mask is current for off-proc atoms
|
||||
// enforce PBC before in case atoms are outside box
|
||||
|
||||
@ -331,6 +337,11 @@ void DeleteBonds::command(int narg, char **arg)
|
||||
n = atom->num_bond[i];
|
||||
atom->bond_type[i][m] = atom->bond_type[i][n-1];
|
||||
atom->bond_atom[i][m] = atom->bond_atom[i][n-1];
|
||||
if (n_histories > 0)
|
||||
for (auto &ihistory: histories) {
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->shift_history(i,m,n-1);
|
||||
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i,n-1);
|
||||
}
|
||||
atom->num_bond[i]--;
|
||||
} else m++;
|
||||
} else m++;
|
||||
@ -431,32 +442,28 @@ void DeleteBonds::command(int narg, char **arg)
|
||||
if (atom->avec->bonds_allow) {
|
||||
bigint nbonds = 0;
|
||||
for (i = 0; i < nlocal; i++) nbonds += atom->num_bond[i];
|
||||
MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT,
|
||||
MPI_SUM,world);
|
||||
MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
if (force->newton_bond == 0) atom->nbonds /= 2;
|
||||
}
|
||||
|
||||
if (atom->avec->angles_allow) {
|
||||
bigint nangles = 0;
|
||||
for (i = 0; i < nlocal; i++) nangles += atom->num_angle[i];
|
||||
MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT,
|
||||
MPI_SUM,world);
|
||||
MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
if (force->newton_bond == 0) atom->nangles /= 3;
|
||||
}
|
||||
|
||||
if (atom->avec->dihedrals_allow) {
|
||||
bigint ndihedrals = 0;
|
||||
for (i = 0; i < nlocal; i++) ndihedrals += atom->num_dihedral[i];
|
||||
MPI_Allreduce(&ndihedrals,&atom->ndihedrals,
|
||||
1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
MPI_Allreduce(&ndihedrals,&atom->ndihedrals,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
if (force->newton_bond == 0) atom->ndihedrals /= 4;
|
||||
}
|
||||
|
||||
if (atom->avec->impropers_allow) {
|
||||
bigint nimpropers = 0;
|
||||
for (i = 0; i < nlocal; i++) nimpropers += atom->num_improper[i];
|
||||
MPI_Allreduce(&nimpropers,&atom->nimpropers,
|
||||
1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
MPI_Allreduce(&nimpropers,&atom->nimpropers,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
if (force->newton_bond == 0) atom->nimpropers /= 4;
|
||||
}
|
||||
|
||||
@ -535,21 +542,18 @@ void DeleteBonds::command(int narg, char **arg)
|
||||
}
|
||||
|
||||
if (comm->me == 0) {
|
||||
constexpr auto fmtstr = " {} total {}, {} turned on, {} turned off\n";
|
||||
if (atom->avec->bonds_allow)
|
||||
utils::logmesg(lmp," {} total bonds, {} turned on, {} turned off\n",
|
||||
atom->nbonds,bond_on,bond_off);
|
||||
utils::logmesg(lmp,fmtstr,atom->nbonds,"bonds",bond_on,bond_off);
|
||||
|
||||
if (atom->avec->angles_allow)
|
||||
utils::logmesg(lmp," {} total angles, {} turned on, {} turned off\n",
|
||||
atom->nangles,angle_on,angle_off);
|
||||
utils::logmesg(lmp,fmtstr,atom->nangles,"angles",angle_on,angle_off);
|
||||
|
||||
if (atom->avec->dihedrals_allow)
|
||||
utils::logmesg(lmp," {} total dihedrals, {} turned on, {} turned off\n",
|
||||
atom->ndihedrals,dihedral_on,dihedral_off);
|
||||
utils::logmesg(lmp,fmtstr,atom->ndihedrals,"dihedrals",dihedral_on,dihedral_off);
|
||||
|
||||
if (atom->avec->impropers_allow)
|
||||
utils::logmesg(lmp," {} total impropers, {} turned on, {} turned off\n",
|
||||
atom->nimpropers,improper_on,improper_off);
|
||||
utils::logmesg(lmp,fmtstr,atom->nimpropers,"impropers",improper_on,improper_off);
|
||||
}
|
||||
|
||||
// re-compute special list if requested
|
||||
|
||||
@ -1181,7 +1181,7 @@ void Dump::modify_params(int narg, char **arg)
|
||||
|
||||
} else if (strcmp(arg[iarg],"header") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
header_flag = utils::logical(FLERR,arg[iarg+1],false,lmp);
|
||||
write_header_flag = utils::logical(FLERR,arg[iarg+1],false,lmp);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"maxfiles") == 0) {
|
||||
|
||||
@ -66,7 +66,6 @@ class Dump : protected Pointers {
|
||||
char *multiname; // filename with % converted to cluster ID
|
||||
MPI_Comm clustercomm; // MPI communicator within my cluster of procs
|
||||
|
||||
int header_flag; // 0 = item, 2 = xyz
|
||||
int flush_flag; // 0 if no flush, 1 if flush every dump
|
||||
int sort_flag; // 1 if sorted output
|
||||
int balance_flag; // 1 if load balanced output
|
||||
|
||||
365
src/fix_bond_history.cpp
Normal file
365
src/fix_bond_history.cpp
Normal file
@ -0,0 +1,365 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
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_bond_history.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "comm.h"
|
||||
#include "error.h"
|
||||
#include "group.h"
|
||||
#include "memory.h"
|
||||
#include "modify.h"
|
||||
#include "neighbor.h"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
#define LB_FACTOR 1.5
|
||||
#define DELTA 8192
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixBondHistory::FixBondHistory(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg), bondstore(nullptr), id_fix(nullptr), id_array(nullptr)
|
||||
|
||||
{
|
||||
if (narg != 5) error->all(FLERR, "Illegal fix bond/history command");
|
||||
update_flag = utils::inumeric(FLERR, arg[3], false, lmp);
|
||||
ndata = utils::inumeric(FLERR, arg[4], false, lmp);
|
||||
nbond = atom->bond_per_atom;
|
||||
|
||||
if (nbond == 0) error->all(FLERR, "Cannot store bond variables without any bonds");
|
||||
|
||||
stored_flag = false;
|
||||
restart_global = 1;
|
||||
create_attribute = 1;
|
||||
|
||||
// Flag whether bond arrays are updated such that data may need to be
|
||||
// copied to atom arrays before exchanging atoms
|
||||
// Prevents sequential calls to pre_exchange() without post_neighbor()
|
||||
updated_bond_flag = 0;
|
||||
|
||||
maxbond = 0;
|
||||
allocate();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixBondHistory::~FixBondHistory()
|
||||
{
|
||||
if (id_fix && modify->nfix) modify->delete_fix(id_fix);
|
||||
delete[] id_fix;
|
||||
delete[] id_array;
|
||||
|
||||
memory->destroy(bondstore);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int FixBondHistory::setmask()
|
||||
{
|
||||
int mask = 0;
|
||||
mask |= PRE_EXCHANGE;
|
||||
mask |= POST_NEIGHBOR;
|
||||
return mask;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::post_constructor()
|
||||
{
|
||||
// Store saved bond quantities for each atom using fix property atom
|
||||
|
||||
id_fix = utils::strdup(id + std::string("_FIX_PROP_ATOM"));
|
||||
id_array = utils::strdup(std::string("d2_") + id);
|
||||
modify->add_fix(fmt::format("{} {} property/atom {} {}", id_fix, group->names[igroup], id_array,
|
||||
nbond * ndata));
|
||||
int tmp1, tmp2;
|
||||
index = atom->find_custom(&id_array[3], tmp1, tmp2);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::update_atom_value(int i, int m, int idata, double value)
|
||||
{
|
||||
if (idata >= ndata || m > nbond) error->all(FLERR, "Index exceeded in fix bond history");
|
||||
atom->darray[index][i][m * ndata + idata] = value;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
double FixBondHistory::get_atom_value(int i, int m, int idata)
|
||||
{
|
||||
if (idata >= ndata || m > nbond) error->all(FLERR, "Index exceeded in fix bond history");
|
||||
return atom->darray[index][i][m * ndata + idata];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::setup_pre_exchange()
|
||||
{
|
||||
pre_exchange();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
If stored values are updated, need to copy to atom arrays before exchanging
|
||||
If bondstore array has been allocated, call before nlist rebuild
|
||||
Also call prior to irregular communication in other fixes (e.g. deform)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::pre_exchange()
|
||||
{
|
||||
if (!update_flag) return;
|
||||
if (!stored_flag) return;
|
||||
if (!updated_bond_flag) return;
|
||||
|
||||
int i1, i2, n, m, idata;
|
||||
int **bondlist = neighbor->bondlist;
|
||||
int nbondlist = neighbor->nbondlist;
|
||||
double **stored = atom->darray[index];
|
||||
|
||||
int nlocal = atom->nlocal;
|
||||
tagint **bond_atom = atom->bond_atom;
|
||||
int *num_bond = atom->num_bond;
|
||||
tagint *tag = atom->tag;
|
||||
|
||||
for (n = 0; n < nbondlist; n++) {
|
||||
i1 = bondlist[n][0];
|
||||
i2 = bondlist[n][1];
|
||||
|
||||
// skip bond if already broken
|
||||
if (bondlist[n][2] <= 0) { continue; }
|
||||
|
||||
if (i1 < nlocal) {
|
||||
for (m = 0; m < num_bond[i1]; m++) {
|
||||
if (bond_atom[i1][m] == tag[i2]) {
|
||||
for (idata = 0; idata < ndata; idata++) {
|
||||
stored[i1][m * ndata + idata] = bondstore[n][idata];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i2 < nlocal) {
|
||||
for (m = 0; m < num_bond[i2]; m++) {
|
||||
if (bond_atom[i2][m] == tag[i1]) {
|
||||
for (idata = 0; idata < ndata; idata++) {
|
||||
stored[i2][m * ndata + idata] = bondstore[n][idata];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updated_bond_flag = 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::allocate()
|
||||
{
|
||||
//Ideally would just ask ntopo for maxbond, but protected
|
||||
if (comm->nprocs == 1)
|
||||
maxbond = atom->nbonds;
|
||||
else
|
||||
maxbond = static_cast<int>(LB_FACTOR * atom->nbonds / comm->nprocs);
|
||||
memory->create(bondstore, maxbond, ndata, "fix_bond_store:bondstore");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::setup_post_neighbor()
|
||||
{
|
||||
//Grow array if number of bonds has increased
|
||||
while (neighbor->nbondlist >= maxbond) {
|
||||
maxbond += DELTA;
|
||||
memory->grow(bondstore, maxbond, ndata, "fix_bond_store:bondstore");
|
||||
}
|
||||
|
||||
pre_exchange();
|
||||
post_neighbor();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
called after neighbor list is build
|
||||
build array of stored bond quantities from fix property atom
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::post_neighbor()
|
||||
{
|
||||
//Grow array if number of bonds has increased
|
||||
while (neighbor->nbondlist >= maxbond) {
|
||||
maxbond += DELTA;
|
||||
memory->grow(bondstore, maxbond, ndata, "fix_bond_store:bondstore");
|
||||
}
|
||||
|
||||
int i1, i2, n, m, idata;
|
||||
int **bondlist = neighbor->bondlist;
|
||||
int nbondlist = neighbor->nbondlist;
|
||||
double **stored = atom->darray[index];
|
||||
|
||||
int nlocal = atom->nlocal;
|
||||
tagint **bond_atom = atom->bond_atom;
|
||||
int *num_bond = atom->num_bond;
|
||||
tagint *tag = atom->tag;
|
||||
|
||||
for (n = 0; n < nbondlist; n++) {
|
||||
i1 = bondlist[n][0];
|
||||
i2 = bondlist[n][1];
|
||||
|
||||
// skip bond if already broken
|
||||
if (bondlist[n][2] <= 0) { continue; }
|
||||
|
||||
if (i1 < nlocal) {
|
||||
for (m = 0; m < num_bond[i1]; m++) {
|
||||
if (bond_atom[i1][m] == tag[i2]) {
|
||||
for (idata = 0; idata < ndata; idata++) {
|
||||
bondstore[n][idata] = stored[i1][m * ndata + idata];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i2 < nlocal) {
|
||||
for (m = 0; m < num_bond[i2]; m++) {
|
||||
if (bond_atom[i2][m] == tag[i1]) {
|
||||
for (idata = 0; idata < ndata; idata++) {
|
||||
bondstore[n][idata] = stored[i2][m * ndata + idata];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updated_bond_flag = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
double FixBondHistory::memory_usage()
|
||||
{
|
||||
return maxbond * ndata * sizeof(double);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::write_restart(FILE *fp)
|
||||
{
|
||||
int n = 0;
|
||||
double list[1];
|
||||
list[n++] = stored_flag;
|
||||
|
||||
if (comm->me == 0) {
|
||||
int size = n * sizeof(double);
|
||||
fwrite(&size, sizeof(int), 1, fp);
|
||||
fwrite(list, sizeof(double), n, fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::restart(char *buf)
|
||||
{
|
||||
int n = 0;
|
||||
double *list = (double *) buf;
|
||||
stored_flag = static_cast<int>(list[n++]);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
initialize bond values to zero, called when atom is created
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::set_arrays(int i)
|
||||
{
|
||||
double **stored = atom->darray[index];
|
||||
for (int m = 0; m < nbond; m++)
|
||||
for (int idata = 0; idata < ndata; idata++) stored[i][m * ndata + idata] = 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Delete bond by zeroing data
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::delete_history(int i, int m)
|
||||
{
|
||||
double **stored = atom->darray[index];
|
||||
for (int idata = 0; idata < ndata; idata++) stored[i][m * ndata + idata] = 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Shift bond data to a new location
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::shift_history(int i, int m, int k)
|
||||
{
|
||||
if (m == k) return;
|
||||
|
||||
double **stored = atom->darray[index];
|
||||
for (int idata = 0; idata < ndata; idata++)
|
||||
stored[i][m * ndata + idata] = stored[i][k * ndata + idata];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Temporarily caches history for a deleted bond which
|
||||
could be recreated before the cache is emptied
|
||||
NOTE: the cache methods still need to be tested, need an example first
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::cache_history(int i, int m)
|
||||
{
|
||||
// Order tags to create a unique key pair
|
||||
tagint max_tag = MAX(atom->tag[i], atom->bond_atom[i][m]);
|
||||
tagint min_tag = MIN(atom->tag[i], atom->bond_atom[i][m]);
|
||||
auto key = std::make_pair(min_tag, max_tag);
|
||||
|
||||
// Copy data to vector
|
||||
double **stored = atom->darray[index];
|
||||
std::vector<double> data;
|
||||
for (int idata = 0; idata < ndata; idata++) data.push_back(stored[i][m * ndata + idata]);
|
||||
|
||||
// Add data to cache
|
||||
cached_histories.insert(std::make_pair(key, data));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Checks to see if a newly created bond has cached history
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::check_cache(int i, int m)
|
||||
{
|
||||
// Order tags to create a unique key pair
|
||||
tagint max_tag = MAX(atom->tag[i], atom->bond_atom[i][m]);
|
||||
tagint min_tag = MIN(atom->tag[i], atom->bond_atom[i][m]);
|
||||
auto key = std::make_pair(min_tag, max_tag);
|
||||
|
||||
// Check if it exists, if so, copy data
|
||||
double **stored = atom->darray[index];
|
||||
std::vector<double> data;
|
||||
auto pos = cached_histories.find(key);
|
||||
if (pos != cached_histories.end()) {
|
||||
data = pos->second;
|
||||
for (int idata = 0; idata < ndata; idata++) stored[i][m * ndata + idata] = data[idata];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Delete saved memory
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondHistory::clear_cache()
|
||||
{
|
||||
cached_histories.clear();
|
||||
}
|
||||
94
src/fix_bond_history.h
Normal file
94
src/fix_bond_history.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* -*- 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(BOND_HISTORY,FixBondHistory);
|
||||
// clang-format on
|
||||
#else
|
||||
|
||||
#ifndef LMP_FIX_BOND_HISTORY_H
|
||||
#define LMP_FIX_BOND_HISTORY_H
|
||||
|
||||
#include "fix.h"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class FixBondHistory : public Fix {
|
||||
public:
|
||||
FixBondHistory(class LAMMPS *, int, char **);
|
||||
~FixBondHistory() override;
|
||||
int setmask() override;
|
||||
void post_constructor() override;
|
||||
void setup_post_neighbor() override;
|
||||
void setup_pre_exchange() override;
|
||||
void post_neighbor() override;
|
||||
void pre_exchange() override;
|
||||
double memory_usage() override;
|
||||
void write_restart(FILE *fp) override;
|
||||
void restart(char *buf) override;
|
||||
void set_arrays(int);
|
||||
|
||||
void update_atom_value(int, int, int, double);
|
||||
double get_atom_value(int, int, int);
|
||||
|
||||
// methods to reorder/delete elements of atom->bond_atom
|
||||
void delete_history(int, int);
|
||||
void shift_history(int, int, int);
|
||||
void cache_history(int, int);
|
||||
void check_cache(int, int);
|
||||
void clear_cache();
|
||||
|
||||
// if data is temporarily stored while the bond_atom array
|
||||
// is being reordered, use map of vectors with pairs for keys
|
||||
// to enable quick look up
|
||||
std::map<std::pair<tagint, tagint>, std::vector<double>> cached_histories;
|
||||
|
||||
double **bondstore;
|
||||
int stored_flag;
|
||||
|
||||
protected:
|
||||
void allocate();
|
||||
|
||||
int update_flag; //Flag whether history values can evolve
|
||||
int updated_bond_flag;
|
||||
int nbond, maxbond, ndata;
|
||||
int index;
|
||||
char *id_fix;
|
||||
char *id_array;
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ERROR/WARNING messages:
|
||||
|
||||
E: Illegal ... command
|
||||
|
||||
UNDOCUMENTED
|
||||
|
||||
E: Index exceeded in fix bond history
|
||||
|
||||
Bond requested non-existant data
|
||||
|
||||
E: Cannot store bond variables without any bonds
|
||||
|
||||
Atoms must have a nonzero number of bonds to store data
|
||||
|
||||
*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user