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
|
AWPMD
|
||||||
BOCS
|
BOCS
|
||||||
BODY
|
BODY
|
||||||
|
BPM
|
||||||
BROWNIAN
|
BROWNIAN
|
||||||
CG-DNA
|
CG-DNA
|
||||||
CG-SDK
|
CG-SDK
|
||||||
|
|||||||
@ -8,6 +8,7 @@ set(ALL_PACKAGES
|
|||||||
AWPMD
|
AWPMD
|
||||||
BOCS
|
BOCS
|
||||||
BODY
|
BODY
|
||||||
|
BPM
|
||||||
BROWNIAN
|
BROWNIAN
|
||||||
CG-DNA
|
CG-DNA
|
||||||
CG-SDK
|
CG-SDK
|
||||||
|
|||||||
@ -10,6 +10,7 @@ set(ALL_PACKAGES
|
|||||||
AWPMD
|
AWPMD
|
||||||
BOCS
|
BOCS
|
||||||
BODY
|
BODY
|
||||||
|
BPM
|
||||||
BROWNIAN
|
BROWNIAN
|
||||||
CG-DNA
|
CG-DNA
|
||||||
CG-SDK
|
CG-SDK
|
||||||
|
|||||||
@ -4,6 +4,7 @@ set(WIN_PACKAGES
|
|||||||
AWPMD
|
AWPMD
|
||||||
BOCS
|
BOCS
|
||||||
BODY
|
BODY
|
||||||
|
BPM
|
||||||
BROWNIAN
|
BROWNIAN
|
||||||
CG-DNA
|
CG-DNA
|
||||||
CG-SDK
|
CG-SDK
|
||||||
|
|||||||
@ -6,6 +6,7 @@ set(ALL_PACKAGES
|
|||||||
ASPHERE
|
ASPHERE
|
||||||
BOCS
|
BOCS
|
||||||
BODY
|
BODY
|
||||||
|
BPM
|
||||||
BROWNIAN
|
BROWNIAN
|
||||||
CG-DNA
|
CG-DNA
|
||||||
CG-SDK
|
CG-SDK
|
||||||
|
|||||||
@ -2,6 +2,7 @@ set(WIN_PACKAGES
|
|||||||
ASPHERE
|
ASPHERE
|
||||||
BOCS
|
BOCS
|
||||||
BODY
|
BODY
|
||||||
|
BPM
|
||||||
BROWNIAN
|
BROWNIAN
|
||||||
CG-DNA
|
CG-DNA
|
||||||
CG-SDK
|
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:`class2 (ko) <bond_class2>`
|
||||||
* :doc:`fene (iko) <bond_fene>`
|
* :doc:`fene (iko) <bond_fene>`
|
||||||
* :doc:`fene/expand (o) <bond_fene_expand>`
|
* :doc:`fene/expand (o) <bond_fene_expand>`
|
||||||
|
|||||||
@ -91,6 +91,7 @@ KOKKOS, o = OPENMP, t = OPT.
|
|||||||
* :doc:`msd <compute_msd>`
|
* :doc:`msd <compute_msd>`
|
||||||
* :doc:`msd/chunk <compute_msd_chunk>`
|
* :doc:`msd/chunk <compute_msd_chunk>`
|
||||||
* :doc:`msd/nongauss <compute_msd_nongauss>`
|
* :doc:`msd/nongauss <compute_msd_nongauss>`
|
||||||
|
* :doc:`nbond/atom <compute_nbond_atom>`
|
||||||
* :doc:`omega/chunk <compute_omega_chunk>`
|
* :doc:`omega/chunk <compute_omega_chunk>`
|
||||||
* :doc:`orientorder/atom (k) <compute_orientorder_atom>`
|
* :doc:`orientorder/atom (k) <compute_orientorder_atom>`
|
||||||
* :doc:`pair <compute_pair>`
|
* :doc:`pair <compute_pair>`
|
||||||
|
|||||||
@ -141,6 +141,7 @@ OPT.
|
|||||||
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>`
|
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>`
|
||||||
* :doc:`nve/noforce <fix_nve_noforce>`
|
* :doc:`nve/noforce <fix_nve_noforce>`
|
||||||
* :doc:`nve/sphere (ko) <fix_nve_sphere>`
|
* :doc:`nve/sphere (ko) <fix_nve_sphere>`
|
||||||
|
* :doc:`nve/bpm/sphere <fix_nve_bpm_sphere>`
|
||||||
* :doc:`nve/spin <fix_nve_spin>`
|
* :doc:`nve/spin <fix_nve_spin>`
|
||||||
* :doc:`nve/tri <fix_nve_tri>`
|
* :doc:`nve/tri <fix_nve_tri>`
|
||||||
* :doc:`nvk <fix_nvk>`
|
* :doc:`nvk <fix_nvk>`
|
||||||
@ -158,7 +159,6 @@ OPT.
|
|||||||
* :doc:`orient/fcc <fix_orient>`
|
* :doc:`orient/fcc <fix_orient>`
|
||||||
* :doc:`orient/eco <fix_orient_eco>`
|
* :doc:`orient/eco <fix_orient_eco>`
|
||||||
* :doc:`pafi <fix_pafi>`
|
* :doc:`pafi <fix_pafi>`
|
||||||
* :doc:`pair/tracker <fix_pair_tracker>`
|
|
||||||
* :doc:`phonon <fix_phonon>`
|
* :doc:`phonon <fix_phonon>`
|
||||||
* :doc:`pimd <fix_pimd>`
|
* :doc:`pimd <fix_pimd>`
|
||||||
* :doc:`planeforce <fix_planeforce>`
|
* :doc:`planeforce <fix_planeforce>`
|
||||||
|
|||||||
@ -53,6 +53,7 @@ OPT.
|
|||||||
* :doc:`born/coul/msm (o) <pair_born>`
|
* :doc:`born/coul/msm (o) <pair_born>`
|
||||||
* :doc:`born/coul/wolf (go) <pair_born>`
|
* :doc:`born/coul/wolf (go) <pair_born>`
|
||||||
* :doc:`born/coul/wolf/cs (g) <pair_cs>`
|
* :doc:`born/coul/wolf/cs (g) <pair_cs>`
|
||||||
|
* :doc:`bpm/spring <pair_bpm_spring>`
|
||||||
* :doc:`brownian (o) <pair_brownian>`
|
* :doc:`brownian (o) <pair_brownian>`
|
||||||
* :doc:`brownian/poly (o) <pair_brownian>`
|
* :doc:`brownian/poly (o) <pair_brownian>`
|
||||||
* :doc:`buck (giko) <pair_buck>`
|
* :doc:`buck (giko) <pair_buck>`
|
||||||
|
|||||||
@ -54,6 +54,8 @@ Lowercase directories
|
|||||||
+-------------+------------------------------------------------------------------+
|
+-------------+------------------------------------------------------------------+
|
||||||
| body | body particles, 2d system |
|
| body | body particles, 2d system |
|
||||||
+-------------+------------------------------------------------------------------+
|
+-------------+------------------------------------------------------------------+
|
||||||
|
| bpm | BPM simulations of pouring elastic grains and plate impact |
|
||||||
|
+-------------+------------------------------------------------------------------+
|
||||||
| cmap | CMAP 5-body contributions to CHARMM force field |
|
| cmap | CMAP 5-body contributions to CHARMM force field |
|
||||||
+-------------+------------------------------------------------------------------+
|
+-------------+------------------------------------------------------------------+
|
||||||
| colloid | big colloid particles in a small particle solvent, 2d system |
|
| colloid | big colloid particles in a small particle solvent, 2d system |
|
||||||
|
|||||||
@ -23,6 +23,8 @@ General howto
|
|||||||
Howto_library
|
Howto_library
|
||||||
Howto_couple
|
Howto_couple
|
||||||
Howto_mdi
|
Howto_mdi
|
||||||
|
Howto_bpm
|
||||||
|
Howto_broken_bonds
|
||||||
|
|
||||||
Settings howto
|
Settings howto
|
||||||
==============
|
==============
|
||||||
|
|||||||
124
doc/src/Howto_bpm.rst
Normal file
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:`AWPMD <PKG-AWPMD>`
|
||||||
* :ref:`BOCS <PKG-BOCS>`
|
* :ref:`BOCS <PKG-BOCS>`
|
||||||
* :ref:`BODY <PKG-BODY>`
|
* :ref:`BODY <PKG-BODY>`
|
||||||
|
* :ref:`BPM <PKG-BPM>`
|
||||||
* :ref:`BROWNIAN <PKG-BROWNIAN>`
|
* :ref:`BROWNIAN <PKG-BROWNIAN>`
|
||||||
* :ref:`CG-DNA <PKG-CG-DNA>`
|
* :ref:`CG-DNA <PKG-CG-DNA>`
|
||||||
* :ref:`CG-SDK <PKG-CG-SDK>`
|
* :ref:`CG-SDK <PKG-CG-SDK>`
|
||||||
@ -283,6 +284,33 @@ overview.
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
.. _PKG-BPM:
|
||||||
|
|
||||||
|
BPM package
|
||||||
|
------------
|
||||||
|
|
||||||
|
**Contents:**
|
||||||
|
|
||||||
|
Pair styles, bond styles, fixes, and computes for bonded particle
|
||||||
|
models for mesoscale simulations of solids and fracture. See the
|
||||||
|
:doc:`Howto bpm <Howto_bpm>` page for an overview.
|
||||||
|
|
||||||
|
**Authors:** Joel T. Clemmer (Sandia National Labs)
|
||||||
|
|
||||||
|
**Supporting info:**
|
||||||
|
|
||||||
|
* src/BPM filenames -> commands
|
||||||
|
* :doc:`Howto_bpm <Howto_bpm>`
|
||||||
|
* :doc:`atom_style bpm/sphere <atom_style>`
|
||||||
|
* :doc:`bond_style bpm/rotational <bond_bpm_rotational>`
|
||||||
|
* :doc:`bond_style bpm/spring <bond_bpm_spring>`
|
||||||
|
* :doc:`compute nbond/atom <compute_nbond_atom>`
|
||||||
|
* :doc:`fix nve/bpm/sphere <fix_nve_bpm_sphere>`
|
||||||
|
* :doc:`pair_style bpm/spring <pair_bpm_spring>`
|
||||||
|
* examples/bpm
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
.. _PKG-BROWNIAN:
|
.. _PKG-BROWNIAN:
|
||||||
|
|
||||||
BROWNIAN package
|
BROWNIAN package
|
||||||
@ -1545,7 +1573,6 @@ listing, "ls src/MISC", to see the list of commands.
|
|||||||
* :doc:`pair_style list <pair_list>`
|
* :doc:`pair_style list <pair_list>`
|
||||||
* :doc:`pair_style srp <pair_srp>`
|
* :doc:`pair_style srp <pair_srp>`
|
||||||
* :doc:`pair_style tracker <pair_tracker>`
|
* :doc:`pair_style tracker <pair_tracker>`
|
||||||
* :doc:`fix pair/tracker <fix_pair_tracker>`
|
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,11 @@ whether an extra library is needed to build and use the package:
|
|||||||
- :doc:`Howto body <Howto_body>`
|
- :doc:`Howto body <Howto_body>`
|
||||||
- body
|
- body
|
||||||
- no
|
- no
|
||||||
|
* - :ref:`BPM <PKG-BPM>`
|
||||||
|
- bonded particle models
|
||||||
|
- :doc:`Howto bpm <Howto_bpm>`
|
||||||
|
- bpm
|
||||||
|
- no
|
||||||
* - :ref:`BROWNIAN <PKG-BROWNIAN>`
|
* - :ref:`BROWNIAN <PKG-BROWNIAN>`
|
||||||
- Brownian dynamics, self-propelled particles
|
- Brownian dynamics, self-propelled particles
|
||||||
- :doc:`fix brownian <fix_brownian>`, :doc:`fix propel/self <fix_propel_self>`
|
- :doc:`fix brownian <fix_brownian>`, :doc:`fix propel/self <fix_propel_self>`
|
||||||
|
|||||||
@ -10,7 +10,7 @@ Syntax
|
|||||||
|
|
||||||
atom_style style args
|
atom_style style args
|
||||||
|
|
||||||
* style = *angle* or *atomic* or *body* or *bond* or *charge* or *dipole* or *dpd* or *edpd* or *electron* or *ellipsoid* or *full* or *line* or *mdpd* or *molecular* or *oxdna* or *peri* or *smd* or *sph* or *sphere* or *spin* or *tdpd* or *tri* or *template* or *hybrid*
|
* style = *angle* or *atomic* or *body* or *bond* or *charge* or *dipole* or *dpd* or *edpd* or *electron* or *ellipsoid* or *full* or *line* or *mdpd* or *molecular* or *oxdna* or *peri* or *smd* or *sph* or *sphere* or *bpm/sphere* or *spin* or *tdpd* or *tri* or *template* or *hybrid*
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ Syntax
|
|||||||
see the :doc:`Howto body <Howto_body>` doc
|
see the :doc:`Howto body <Howto_body>` doc
|
||||||
page for details
|
page for details
|
||||||
*sphere* arg = 0/1 (optional) for static/dynamic particle radii
|
*sphere* arg = 0/1 (optional) for static/dynamic particle radii
|
||||||
|
*bpm/sphere* arg = 0/1 (optional) for static/dynamic particle radii
|
||||||
*tdpd* arg = Nspecies
|
*tdpd* arg = Nspecies
|
||||||
Nspecies = # of chemical species
|
Nspecies = # of chemical species
|
||||||
*template* arg = template-ID
|
*template* arg = template-ID
|
||||||
@ -120,6 +121,8 @@ quantities.
|
|||||||
+--------------+-----------------------------------------------------+--------------------------------------+
|
+--------------+-----------------------------------------------------+--------------------------------------+
|
||||||
| *sphere* | diameter, mass, angular velocity | granular models |
|
| *sphere* | diameter, mass, angular velocity | granular models |
|
||||||
+--------------+-----------------------------------------------------+--------------------------------------+
|
+--------------+-----------------------------------------------------+--------------------------------------+
|
||||||
|
| *bpm/sphere* | diameter, mass, angular velocity, quaternion | granular bonded particle models (BPM)|
|
||||||
|
+--------------+-----------------------------------------------------+--------------------------------------+
|
||||||
| *spin* | magnetic moment | system with magnetic particles |
|
| *spin* | magnetic moment | system with magnetic particles |
|
||||||
+--------------+-----------------------------------------------------+--------------------------------------+
|
+--------------+-----------------------------------------------------+--------------------------------------+
|
||||||
| *tdpd* | chemical concentration | tDPD particles |
|
| *tdpd* | chemical concentration | tDPD particles |
|
||||||
@ -141,8 +144,9 @@ quantities.
|
|||||||
output the custom values.
|
output the custom values.
|
||||||
|
|
||||||
All of the above styles define point particles, except the *sphere*,
|
All of the above styles define point particles, except the *sphere*,
|
||||||
*ellipsoid*, *electron*, *peri*, *wavepacket*, *line*, *tri*, and
|
*bpm/sphere*, *ellipsoid*, *electron*, *peri*, *wavepacket*, *line*,
|
||||||
*body* styles, which define finite-size particles. See the :doc:`Howto spherical <Howto_spherical>` page for an overview of using
|
*tri*, and *body* styles, which define finite-size particles. See the
|
||||||
|
:doc:`Howto spherical <Howto_spherical>` page for an overview of using
|
||||||
finite-size particle models with LAMMPS.
|
finite-size particle models with LAMMPS.
|
||||||
|
|
||||||
All of the point-particle styles assign mass to particles on a
|
All of the point-particle styles assign mass to particles on a
|
||||||
@ -150,15 +154,15 @@ per-type basis, using the :doc:`mass <mass>` command, The finite-size
|
|||||||
particle styles assign mass to individual particles on a per-particle
|
particle styles assign mass to individual particles on a per-particle
|
||||||
basis.
|
basis.
|
||||||
|
|
||||||
For the *sphere* style, the particles are spheres and each stores a
|
For the *sphere* and *bpm/sphere* styles, the particles are spheres and each stores a
|
||||||
per-particle diameter and mass. If the diameter > 0.0, the particle
|
per-particle diameter and mass. If the diameter > 0.0, the particle
|
||||||
is a finite-size sphere. If the diameter = 0.0, it is a point
|
is a finite-size sphere. If the diameter = 0.0, it is a point
|
||||||
particle. Note that by use of the *disc* keyword with the :doc:`fix
|
particle. Note that by use of the *disc* keyword with the :doc:`fix
|
||||||
nve/sphere <fix_nve_sphere>`, :doc:`fix nvt/sphere <fix_nvt_sphere>`,
|
nve/sphere <fix_nve_sphere>`, :doc:`fix nvt/sphere <fix_nvt_sphere>`,
|
||||||
:doc:`fix nph/sphere <fix_nph_sphere>`, :doc:`fix npt/sphere
|
:doc:`fix nph/sphere <fix_nph_sphere>`, :doc:`fix npt/sphere
|
||||||
<fix_npt_sphere>` commands, spheres can be effectively treated as 2d
|
<fix_npt_sphere>` commands for the *sphere* style, spheres can be effectively treated as 2d
|
||||||
discs for a 2d simulation if desired. See also the :doc:`set
|
discs for a 2d simulation if desired. See also the :doc:`set
|
||||||
density/disc <set>` command. The *sphere* style takes an optional 0
|
density/disc <set>` command. The *sphere* and *bpm/sphere* styles take an optional 0
|
||||||
or 1 argument. A value of 0 means the radius of each sphere is
|
or 1 argument. A value of 0 means the radius of each sphere is
|
||||||
constant for the duration of the simulation. A value of 1 means the
|
constant for the duration of the simulation. A value of 1 means the
|
||||||
radii may vary dynamically during the simulation, e.g. due to use of
|
radii may vary dynamically during the simulation, e.g. due to use of
|
||||||
@ -195,6 +199,8 @@ position, which is represented by the eradius = electron size.
|
|||||||
For the *peri* style, the particles are spherical and each stores a
|
For the *peri* style, the particles are spherical and each stores a
|
||||||
per-particle mass and volume.
|
per-particle mass and volume.
|
||||||
|
|
||||||
|
The *bpm/sphere* style is part of the BPM package.
|
||||||
|
|
||||||
The *oxdna* style is for coarse-grained nucleotides and stores the
|
The *oxdna* style is for coarse-grained nucleotides and stores the
|
||||||
3'-to-5' polarity of the nucleotide strand, which is set through
|
3'-to-5' polarity of the nucleotide strand, which is set through
|
||||||
the bond topology in the data file. The first (second) atom in a
|
the bond topology in the data file. The first (second) atom in a
|
||||||
|
|||||||
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
|
the bond, which means two things. First, the bond potential is turned
|
||||||
off by setting its type to 0, and is no longer computed. Second, a
|
off by setting its type to 0, and is no longer computed. Second, a
|
||||||
pairwise interaction between the two atoms is turned on, since they
|
pairwise interaction between the two atoms is turned on, since they
|
||||||
are no longer bonded.
|
are no longer bonded. See the :doc:`Howto <Howto_broken_bonds>` page
|
||||||
|
on broken bonds for more information.
|
||||||
|
|
||||||
LAMMPS does the second task via a computational sleight-of-hand. It
|
LAMMPS does the second task via a computational sleight-of-hand. It
|
||||||
subtracts the pairwise interaction as part of the bond computation.
|
subtracts the pairwise interaction as part of the bond computation.
|
||||||
|
|||||||
@ -84,6 +84,8 @@ accelerated styles exist.
|
|||||||
* :doc:`zero <bond_zero>` - topology but no interactions
|
* :doc:`zero <bond_zero>` - topology but no interactions
|
||||||
* :doc:`hybrid <bond_hybrid>` - define multiple styles of bond interactions
|
* :doc:`hybrid <bond_hybrid>` - define multiple styles of bond interactions
|
||||||
|
|
||||||
|
* :doc:`bpm/rotational <bond_bpm_rotational>` - breakable bond with forces and torques based on deviation from reference state
|
||||||
|
* :doc:`bpm/spring <bond_bpm_spring>` - breakable bond with forces based on deviation from reference length
|
||||||
* :doc:`class2 <bond_class2>` - COMPASS (class 2) bond
|
* :doc:`class2 <bond_class2>` - COMPASS (class 2) bond
|
||||||
* :doc:`fene <bond_fene>` - FENE (finite-extensible non-linear elastic) bond
|
* :doc:`fene <bond_fene>` - FENE (finite-extensible non-linear elastic) bond
|
||||||
* :doc:`fene/expand <bond_fene_expand>` - FENE bonds with variable size particles
|
* :doc:`fene/expand <bond_fene_expand>` - FENE bonds with variable size particles
|
||||||
|
|||||||
@ -236,6 +236,7 @@ The individual style names on the :doc:`Commands compute <Commands_compute>` pag
|
|||||||
* :doc:`msd <compute_msd>` - mean-squared displacement of group of atoms
|
* :doc:`msd <compute_msd>` - mean-squared displacement of group of atoms
|
||||||
* :doc:`msd/chunk <compute_msd_chunk>` - mean-squared displacement for each chunk
|
* :doc:`msd/chunk <compute_msd_chunk>` - mean-squared displacement for each chunk
|
||||||
* :doc:`msd/nongauss <compute_msd_nongauss>` - MSD and non-Gaussian parameter of group of atoms
|
* :doc:`msd/nongauss <compute_msd_nongauss>` - MSD and non-Gaussian parameter of group of atoms
|
||||||
|
* :doc:`nbond/atom <compute_nbond_atom>` - calculates number of bonds per atom
|
||||||
* :doc:`omega/chunk <compute_omega_chunk>` - angular velocity for each chunk
|
* :doc:`omega/chunk <compute_omega_chunk>` - angular velocity for each chunk
|
||||||
* :doc:`orientorder/atom <compute_orientorder_atom>` - Steinhardt bond orientational order parameters Ql
|
* :doc:`orientorder/atom <compute_orientorder_atom>` - Steinhardt bond orientational order parameters Ql
|
||||||
* :doc:`pair <compute_pair>` - values computed by a pair style
|
* :doc:`pair <compute_pair>` - values computed by a pair style
|
||||||
|
|||||||
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
|
The *header* keyword toggles whether the dump file will include a
|
||||||
header. Excluding a header will reduce the size of the dump file for
|
header. Excluding a header will reduce the size of the dump file for
|
||||||
fixes such as :doc:`fix pair/tracker <fix_pair_tracker>` which do not
|
data produced by :doc:`pair tracker <pair_tracker>` or
|
||||||
require the information typically written to the header.
|
:doc:`bpm bond styles <Howto_bpm>` which may not require the
|
||||||
|
information typically written to the header.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|||||||
@ -284,6 +284,7 @@ accelerated styles exist.
|
|||||||
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>` -
|
* :doc:`nve/manifold/rattle <fix_nve_manifold_rattle>` -
|
||||||
* :doc:`nve/noforce <fix_nve_noforce>` - NVE without forces (v only)
|
* :doc:`nve/noforce <fix_nve_noforce>` - NVE without forces (v only)
|
||||||
* :doc:`nve/sphere <fix_nve_sphere>` - NVE for spherical particles
|
* :doc:`nve/sphere <fix_nve_sphere>` - NVE for spherical particles
|
||||||
|
* :doc:`nve/bpm/sphere <fix_nve_bpm_sphere>` - NVE for spherical particles used in the BPM package
|
||||||
* :doc:`nve/spin <fix_nve_spin>` - NVE for a spin or spin-lattice system
|
* :doc:`nve/spin <fix_nve_spin>` - NVE for a spin or spin-lattice system
|
||||||
* :doc:`nve/tri <fix_nve_tri>` - NVE for triangles
|
* :doc:`nve/tri <fix_nve_tri>` - NVE for triangles
|
||||||
* :doc:`nvk <fix_nvk>` - constant kinetic energy time integration
|
* :doc:`nvk <fix_nvk>` - constant kinetic energy time integration
|
||||||
@ -301,7 +302,6 @@ accelerated styles exist.
|
|||||||
* :doc:`orient/fcc <fix_orient>` - add grain boundary migration force for FCC
|
* :doc:`orient/fcc <fix_orient>` - add grain boundary migration force for FCC
|
||||||
* :doc:`orient/eco <fix_orient_eco>` - add generalized grain boundary migration force
|
* :doc:`orient/eco <fix_orient_eco>` - add generalized grain boundary migration force
|
||||||
* :doc:`pafi <fix_pafi>` - constrained force averages on hyper-planes to compute free energies (PAFI)
|
* :doc:`pafi <fix_pafi>` - constrained force averages on hyper-planes to compute free energies (PAFI)
|
||||||
* :doc:`pair/tracker <fix_pair_tracker>` - track properties of pairwise interactions
|
|
||||||
* :doc:`phonon <fix_phonon>` - calculate dynamical matrix from MD simulations
|
* :doc:`phonon <fix_phonon>` - calculate dynamical matrix from MD simulations
|
||||||
* :doc:`pimd <fix_pimd>` - Feynman path integral molecular dynamics
|
* :doc:`pimd <fix_pimd>` - Feynman path integral molecular dynamics
|
||||||
* :doc:`planeforce <fix_planeforce>` - constrain atoms to move in a plane
|
* :doc:`planeforce <fix_planeforce>` - constrain atoms to move in a plane
|
||||||
|
|||||||
@ -113,6 +113,9 @@ You can dump out snapshots of the current bond topology via the :doc:`dump local
|
|||||||
may need to thermostat your system to compensate for energy changes
|
may need to thermostat your system to compensate for energy changes
|
||||||
resulting from broken bonds (and angles, dihedrals, impropers).
|
resulting from broken bonds (and angles, dihedrals, impropers).
|
||||||
|
|
||||||
|
See the :doc:`Howto <Howto_broken_bonds>` page on broken bonds for more
|
||||||
|
information on related features in LAMMPS.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Restart, fix_modify, output, run start/stop, minimize info
|
Restart, fix_modify, output, run start/stop, minimize info
|
||||||
|
|||||||
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/msm <pair_born>` - Born with long-range MSM Coulomb
|
||||||
* :doc:`born/coul/wolf <pair_born>` - Born with Wolf potential for Coulomb
|
* :doc:`born/coul/wolf <pair_born>` - Born with Wolf potential for Coulomb
|
||||||
* :doc:`born/coul/wolf/cs <pair_cs>` - Born with Wolf potential for Coulomb and core/shell model
|
* :doc:`born/coul/wolf/cs <pair_cs>` - Born with Wolf potential for Coulomb and core/shell model
|
||||||
|
* :doc:`bpm/spring <pair_bpm_spring>` - repulsive harmonic force with damping
|
||||||
* :doc:`brownian <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics
|
* :doc:`brownian <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics
|
||||||
* :doc:`brownian/poly <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics with polydispersity
|
* :doc:`brownian/poly <pair_brownian>` - Brownian potential for Fast Lubrication Dynamics with polydispersity
|
||||||
* :doc:`buck <pair_buck>` - Buckingham potential
|
* :doc:`buck <pair_buck>` - Buckingham potential
|
||||||
|
|||||||
@ -8,89 +8,182 @@ Syntax
|
|||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
pair_style tracker keyword
|
pair_style tracker fix_ID N keyword values attribute1 attribute2 ...
|
||||||
|
|
||||||
* zero or more keyword/arg pairs may be appended
|
* fix_ID = ID of associated internal fix to store data
|
||||||
* keyword = *finite*
|
* N = prepare data for output every this many timesteps
|
||||||
|
* zero or more keywords may be appended
|
||||||
|
* keyword = *finite* or *time/min* or *type/include*
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
*finite* value = none
|
*finite* value = none
|
||||||
pair style uses atomic diameters to identify contacts
|
pair style uses atomic diameters to identify contacts
|
||||||
|
*time/min* value = T
|
||||||
|
T = minimum number of timesteps of interaction
|
||||||
|
*type/include* value = list1 list2
|
||||||
|
list1,list2 = separate lists of types (see below)
|
||||||
|
|
||||||
|
* one or more attributes may be appended
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
possible attributes = id1 id2 time/created time/broken time/total
|
||||||
|
r/min r/ave x y z
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
id1, id2 = IDs of the 2 atoms in each pair interaction
|
||||||
|
time/created = the timestep that the 2 atoms began interacting
|
||||||
|
time/broken = the timestep that the 2 atoms stopped interacting
|
||||||
|
time/total = the total number of timesteps the 2 atoms interacted
|
||||||
|
r/min = the minimum radial distance between the 2 atoms during the interaction (distance units)
|
||||||
|
r/ave = the average radial distance between the 2 atoms during the interaction (distance units)
|
||||||
|
x, y, z = the center of mass position of the 2 atoms when they stopped interacting (distance units)
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
""""""""
|
""""""""
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
pair_style hybrid/overlay tracker ...
|
pair_style hybrid/overlay tracker myfix 1000 id1 id2 type/include 1 * type/include 2 3,4 lj/cut 2.5
|
||||||
pair_coeff 1 1 tracker 2.0
|
pair_coeff 1 1 tracker 2.0
|
||||||
|
|
||||||
pair_style hybrid/overlay tracker finite ...
|
pair_style hybrid/overlay tracker myfix 1000 finite x y z time/min 100 granular
|
||||||
pair_coeff * * tracker
|
pair_coeff * * tracker
|
||||||
|
|
||||||
fix 1 all pair/tracker 1000 time/created time/broken
|
dump 1 all local 1000 dump.local f_myfix[1] f_myfix[2] f_myfix[3]
|
||||||
dump 1 all local 1000 dump.local f_1[1] f_1[2]
|
|
||||||
dump_modify 1 write_header no
|
dump_modify 1 write_header no
|
||||||
|
|
||||||
Description
|
Description
|
||||||
"""""""""""
|
"""""""""""
|
||||||
|
|
||||||
Style *tracker* monitors information about pairwise interactions.
|
Style *tracker* monitors information about pairwise interactions. It
|
||||||
It does not calculate any forces on atoms.
|
does not calculate any forces on atoms. :doc:`Pair hybrid/overlay
|
||||||
:doc:`Pair hybrid/overlay <pair_hybrid>` can be used to combine this pair
|
<pair_hybrid>` can be used to combine this pair style with any other
|
||||||
style with another pair style. Style *tracker* must be used in conjunction
|
pair style, as shown in the examples above.
|
||||||
with about :doc:`fix pair_tracker <fix_pair_tracker>` which contains
|
|
||||||
information on what data can be output.
|
|
||||||
|
|
||||||
If the *finite* keyword is not defined, the following coefficients must be
|
At each timestep, if two neighboring atoms move beyond the interaction
|
||||||
defined for each pair of atom types via the :doc:`pair_coeff <pair_coeff>`
|
cutoff, pairwise data is processed and transferred to an internal fix
|
||||||
command as in the examples above, or in the data file or restart files
|
labeled *fix_ID*. This allows the local data to be accessed by other
|
||||||
read by the :doc:`read_data <read_data>` or :doc:`read_restart <read_restart>`
|
LAMMPS commands. Additional
|
||||||
commands, or by mixing as described below:
|
filters can be applied using the *time/min* or *type/include* keywords
|
||||||
|
described below. Note that this is the interaction cutoff defined by
|
||||||
|
this pair style, not the short-range cutoff defined by the pair style
|
||||||
|
that is calculating forces on atoms.
|
||||||
|
|
||||||
|
Following any optional keyword/value arguments, a list of one or more
|
||||||
|
attributes is specified. These include the IDs of the two atoms in
|
||||||
|
the pair. The other attributes for the pair of atoms are the
|
||||||
|
duration of time they were "interacting" or at the point in time they
|
||||||
|
started or stopped interacting. In this context, "interacting" means
|
||||||
|
the time window during which the two atoms were closer than the
|
||||||
|
interaction cutoff distance. The attributes for time/* refer to
|
||||||
|
timesteps.
|
||||||
|
|
||||||
|
Data is continuously accumulated by the internal fix over intervals of *N*
|
||||||
|
timesteps. At the end of each interval, all of the saved accumulated
|
||||||
|
data is deleted to make room for new data. Individual datum may
|
||||||
|
therefore persist anywhere between *1* to *N* timesteps depending on
|
||||||
|
when they are saved. This data can be accessed using the *fix_ID* and a
|
||||||
|
:doc:`dump local <dump>` command. To ensure all data is output,
|
||||||
|
the dump frequency should correspond to the same interval of *N*
|
||||||
|
timesteps. A dump frequency of an integer multiple of *N* can be used
|
||||||
|
to regularly output a sample of the accumulated data.
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
The following optional keywords may be used.
|
||||||
|
|
||||||
|
If the *finite* keyword is not used, the following coefficients must
|
||||||
|
be defined for each pair of atom types via the :doc:`pair_coeff
|
||||||
|
<pair_coeff>` command as in the examples above, or in the data file or
|
||||||
|
restart files read by the :doc:`read_data <read_data>` or
|
||||||
|
:doc:`read_restart <read_restart>` commands, or by mixing as described
|
||||||
|
below:
|
||||||
|
|
||||||
* cutoff (distance units)
|
* cutoff (distance units)
|
||||||
|
|
||||||
If the *finite* keyword is defined, no coefficients may be defined.
|
If the *finite* keyword is used, there are no additional coefficients
|
||||||
Interaction cutoffs are alternatively calculated based on the
|
to set for each pair of atom types via the
|
||||||
diameter of finite particles.
|
:doc:`pair_coeff <pair_coeff>` command. Interaction cutoffs are
|
||||||
|
instead calculated based on the diameter of finite particles. However
|
||||||
|
you must still use the :doc:`pair_coeff <pair_coeff>` for all atom
|
||||||
|
types. For example the command
|
||||||
|
|
||||||
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
|
pair_coeff * *
|
||||||
|
|
||||||
|
should be used.
|
||||||
|
|
||||||
|
The *time/min* keyword sets a minimum amount of time that an
|
||||||
|
interaction must persist to be included. This setting can be used to
|
||||||
|
censor short-lived interactions.
|
||||||
|
|
||||||
|
The *type/include* keyword filters interactions based on the types of
|
||||||
|
the two atoms. Data is only saved for interactions between atoms
|
||||||
|
whose two atom types appear in *list1* and *list2*. Atom type 1 must
|
||||||
|
be in list1 and atom type 2 in list2. Or vice versa.
|
||||||
|
|
||||||
|
Each type list consists of a series of type ranges separated by
|
||||||
|
commas. Each range can be specified as a single numeric value, or a
|
||||||
|
wildcard asterisk can be used to specify a range of values. This
|
||||||
|
takes the form "\*" or "\*n" or "n\*" or "m\*n". For example, if M =
|
||||||
|
the number of atom types, then an asterisk with no numeric values
|
||||||
|
means all types from 1 to M. A leading asterisk means all types from
|
||||||
|
1 to n (inclusive). A trailing asterisk means all types from n to M
|
||||||
|
(inclusive). A middle asterisk means all types from m to n
|
||||||
|
(inclusive). Note that the *type/include* keyword can be specified
|
||||||
|
multiple times.
|
||||||
|
|
||||||
Mixing, shift, table, tail correction, restart, rRESPA info
|
Mixing, shift, table, tail correction, restart, rRESPA info
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
For atom type pairs I,J and I != J, the cutoff coefficient and cutoff
|
For atom type pairs I,J and I != J, the cutoff coefficient and cutoff
|
||||||
distance for this pair style can be mixed. The cutoff is always mixed via a
|
distance for this pair style can be mixed. The cutoff is always mixed
|
||||||
*geometric* rule. The cutoff is mixed according to the pair_modify
|
via a *geometric* rule. The cutoff is mixed according to the
|
||||||
mix value. The default mix value is *geometric*\ . See the
|
pair_modify mix value. The default mix value is *geometric*\ . See
|
||||||
"pair_modify" command for details.
|
the "pair_modify" command for details.
|
||||||
|
|
||||||
This pair style writes its information to :doc:`binary restart files <restart>`, so
|
This pair style writes its information to :doc:`binary restart files
|
||||||
pair_style and pair_coeff commands do not need
|
<restart>`, so pair_style and pair_coeff commands do not need to be
|
||||||
to be specified in an input script that reads a restart file.
|
specified in an input script that reads a restart file.
|
||||||
|
|
||||||
The :doc:`pair_modify <pair_modify>` shift, table, and tail options
|
The :doc:`pair_modify <pair_modify>` shift, table, and tail options
|
||||||
are not relevant for this pair style.
|
are not relevant for this pair style.
|
||||||
|
|
||||||
|
The accumulated data is not written to restart files and should be
|
||||||
|
output before a restart file is written to avoid missing data.
|
||||||
|
|
||||||
|
The internal fix calculates a local vector or local array depending on the
|
||||||
|
number of input values. The length of the vector or number of rows in
|
||||||
|
the array is the number of recorded, lost interactions. If a single
|
||||||
|
input is specified, a local vector is produced. If two or more inputs
|
||||||
|
are specified, a local array is produced where the number of columns =
|
||||||
|
the number of inputs. The vector or array can be accessed by any
|
||||||
|
command that uses local values from a compute as input. See the
|
||||||
|
:doc:`Howto output <Howto_output>` page for an overview of LAMMPS
|
||||||
|
output options.
|
||||||
|
|
||||||
|
The vector or array will be floating point values that correspond to
|
||||||
|
the specified attribute.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Restrictions
|
Restrictions
|
||||||
""""""""""""
|
""""""""""""
|
||||||
|
|
||||||
A corresponding :doc:`fix pair_tracker <fix_pair_tracker>` must be defined
|
|
||||||
to use this pair style.
|
|
||||||
|
|
||||||
This pair style is currently incompatible with granular pair styles that extend
|
|
||||||
beyond the contact (e.g. JKR and DMT).
|
|
||||||
|
|
||||||
This fix is part of the MISC package. It is only enabled if LAMMPS
|
This fix is part of the MISC package. It is only enabled if LAMMPS
|
||||||
was built with that package. See the :doc:`Build package <Build_package>` page for more info.
|
was built with that package. See the :doc:`Build package
|
||||||
|
<Build_package>` page for more info.
|
||||||
|
|
||||||
|
This pair style is currently incompatible with granular pair styles
|
||||||
|
that extend beyond the contact (e.g. JKR and DMT).
|
||||||
|
|
||||||
Related commands
|
Related commands
|
||||||
""""""""""""""""
|
""""""""""""""""
|
||||||
|
|
||||||
:doc:`fix pair_tracker <fix_pair_tracker>`
|
|
||||||
|
|
||||||
Default
|
Default
|
||||||
"""""""
|
"""""""
|
||||||
|
|
||||||
|
|||||||
@ -650,6 +650,8 @@ of analysis.
|
|||||||
- atom-ID atom-type rho esph cv x y z
|
- atom-ID atom-type rho esph cv x y z
|
||||||
* - sphere
|
* - sphere
|
||||||
- atom-ID atom-type diameter density x y z
|
- atom-ID atom-type diameter density x y z
|
||||||
|
* - bpm/sphere
|
||||||
|
- atom-ID molecule-ID atom-type diameter density x y z
|
||||||
* - spin
|
* - spin
|
||||||
- atom-ID atom-type x y z spx spy spz sp
|
- atom-ID atom-type x y z spx spy spz sp
|
||||||
* - tdpd
|
* - tdpd
|
||||||
|
|||||||
@ -328,6 +328,8 @@ boxzlo
|
|||||||
bp
|
bp
|
||||||
bpclermont
|
bpclermont
|
||||||
bpls
|
bpls
|
||||||
|
bpm
|
||||||
|
BPM
|
||||||
br
|
br
|
||||||
Branduardi
|
Branduardi
|
||||||
Branicio
|
Branicio
|
||||||
@ -1149,8 +1151,10 @@ gdot
|
|||||||
GeC
|
GeC
|
||||||
Geier
|
Geier
|
||||||
gencode
|
gencode
|
||||||
|
Geocomputing
|
||||||
georg
|
georg
|
||||||
Georg
|
Georg
|
||||||
|
Geotechnica
|
||||||
germain
|
germain
|
||||||
Germann
|
Germann
|
||||||
Germano
|
Germano
|
||||||
@ -1320,6 +1324,7 @@ Holm
|
|||||||
holonomic
|
holonomic
|
||||||
Homebrew
|
Homebrew
|
||||||
hooke
|
hooke
|
||||||
|
hookean
|
||||||
Hookean
|
Hookean
|
||||||
hostname
|
hostname
|
||||||
hotpink
|
hotpink
|
||||||
@ -2074,6 +2079,7 @@ monopole
|
|||||||
monovalent
|
monovalent
|
||||||
Montalenti
|
Montalenti
|
||||||
Montero
|
Montero
|
||||||
|
Mora
|
||||||
Morefoo
|
Morefoo
|
||||||
Morfill
|
Morfill
|
||||||
Mori
|
Mori
|
||||||
@ -2203,6 +2209,7 @@ Nbin
|
|||||||
Nbins
|
Nbins
|
||||||
nbody
|
nbody
|
||||||
Nbody
|
Nbody
|
||||||
|
nbond
|
||||||
nbonds
|
nbonds
|
||||||
nbondtype
|
nbondtype
|
||||||
Nbondtype
|
Nbondtype
|
||||||
@ -3174,6 +3181,7 @@ Steinhauser
|
|||||||
Stepaniants
|
Stepaniants
|
||||||
stepwise
|
stepwise
|
||||||
Stesmans
|
Stesmans
|
||||||
|
stiffnesses
|
||||||
Stillinger
|
Stillinger
|
||||||
stk
|
stk
|
||||||
stochastically
|
stochastically
|
||||||
|
|||||||
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.cpp
|
||||||
/pair_mesont_tpm.h
|
/pair_mesont_tpm.h
|
||||||
|
|
||||||
|
/atom_vec_bpm_sphere.cpp
|
||||||
|
/atom_vec_bpm_sphere.h
|
||||||
|
/bond_bpm.cpp
|
||||||
|
/bond_bpm.h
|
||||||
|
/bond_bpm_rotational.cpp
|
||||||
|
/bond_bpm_rotational.h
|
||||||
|
/bond_bpm_spring.cpp
|
||||||
|
/bond_bpm_spring.h
|
||||||
|
/compute_nbond_atom.cpp
|
||||||
|
/compute_nbond_atom.h
|
||||||
|
/fix_nve_bpm_sphere.cpp
|
||||||
|
/fix_nve_bpm_sphere.h
|
||||||
|
/pair_bpm_spring.cpp
|
||||||
|
/pair_bpm_spring.h
|
||||||
|
|
||||||
/compute_adf.cpp
|
/compute_adf.cpp
|
||||||
/compute_adf.h
|
/compute_adf.h
|
||||||
/compute_contact_atom.cpp
|
/compute_contact_atom.cpp
|
||||||
@ -792,8 +807,6 @@
|
|||||||
/fix_orient_eco.h
|
/fix_orient_eco.h
|
||||||
/fix_orient_fcc.cpp
|
/fix_orient_fcc.cpp
|
||||||
/fix_orient_fcc.h
|
/fix_orient_fcc.h
|
||||||
/fix_pair_tracker.cpp
|
|
||||||
/fix_pair_tracker.h
|
|
||||||
/fix_peri_neigh.cpp
|
/fix_peri_neigh.cpp
|
||||||
/fix_peri_neigh.h
|
/fix_peri_neigh.h
|
||||||
/fix_phonon.cpp
|
/fix_phonon.cpp
|
||||||
@ -1524,3 +1537,4 @@
|
|||||||
/pair_smtbq.h
|
/pair_smtbq.h
|
||||||
/pair_vashishta*.cpp
|
/pair_vashishta*.cpp
|
||||||
/pair_vashishta*.h
|
/pair_vashishta*.h
|
||||||
|
|
||||||
|
|||||||
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");
|
error->all(FLERR,"Invalid atom type in fix pour mol command");
|
||||||
|
|
||||||
if (atom->molecular == Atom::TEMPLATE && onemols != atom->avec->onemols)
|
if (atom->molecular == Atom::TEMPLATE && onemols != atom->avec->onemols)
|
||||||
error->all(FLERR,"Fix pour molecule template ID must be same "
|
error->all(FLERR,"Fix pour molecule template ID must be same as atom style template ID");
|
||||||
"as atom style template ID");
|
|
||||||
onemols[i]->check_attributes(0);
|
onemols[i]->check_attributes(0);
|
||||||
|
|
||||||
// fix pour uses geoemetric center of molecule for insertion
|
// fix pour uses geoemetric center of molecule for insertion
|
||||||
|
|||||||
@ -45,7 +45,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
|||||||
{
|
{
|
||||||
int i,j,ii,jj,inum,jnum;
|
int i,j,ii,jj,inum,jnum;
|
||||||
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
|
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
|
||||||
double radi,radj,radsum,rsq,r,rinv,rsqinv;
|
double radi,radj,radsum,rsq,r,rinv,rsqinv,factor_lj;
|
||||||
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
|
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
|
||||||
double wr1,wr2,wr3;
|
double wr1,wr2,wr3;
|
||||||
double vtr1,vtr2,vtr3,vrel;
|
double vtr1,vtr2,vtr3,vrel;
|
||||||
@ -91,6 +91,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
|||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
int newton_pair = force->newton_pair;
|
int newton_pair = force->newton_pair;
|
||||||
|
double *special_lj = force->special_lj;
|
||||||
|
|
||||||
inum = list->inum;
|
inum = list->inum;
|
||||||
ilist = list->ilist;
|
ilist = list->ilist;
|
||||||
@ -114,8 +115,11 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
|||||||
|
|
||||||
for (jj = 0; jj < jnum; jj++) {
|
for (jj = 0; jj < jnum; jj++) {
|
||||||
j = jlist[jj];
|
j = jlist[jj];
|
||||||
|
factor_lj = special_lj[sbmask(j)];
|
||||||
j &= NEIGHMASK;
|
j &= NEIGHMASK;
|
||||||
|
|
||||||
|
if (factor_lj == 0) continue;
|
||||||
|
|
||||||
delx = xtmp - x[j][0];
|
delx = xtmp - x[j][0];
|
||||||
dely = ytmp - x[j][1];
|
dely = ytmp - x[j][1];
|
||||||
delz = ztmp - x[j][2];
|
delz = ztmp - x[j][2];
|
||||||
@ -247,6 +251,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
|||||||
fx = delx*ccel + fs1;
|
fx = delx*ccel + fs1;
|
||||||
fy = dely*ccel + fs2;
|
fy = dely*ccel + fs2;
|
||||||
fz = delz*ccel + fs3;
|
fz = delz*ccel + fs3;
|
||||||
|
fx *= factor_lj;
|
||||||
|
fy *= factor_lj;
|
||||||
|
fz *= factor_lj;
|
||||||
f[i][0] += fx;
|
f[i][0] += fx;
|
||||||
f[i][1] += fy;
|
f[i][1] += fy;
|
||||||
f[i][2] += fz;
|
f[i][2] += fz;
|
||||||
@ -254,6 +261,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag)
|
|||||||
tor1 = rinv * (dely*fs3 - delz*fs2);
|
tor1 = rinv * (dely*fs3 - delz*fs2);
|
||||||
tor2 = rinv * (delz*fs1 - delx*fs3);
|
tor2 = rinv * (delz*fs1 - delx*fs3);
|
||||||
tor3 = rinv * (delx*fs2 - dely*fs1);
|
tor3 = rinv * (delx*fs2 - dely*fs1);
|
||||||
|
tor1 *= factor_lj;
|
||||||
|
tor2 *= factor_lj;
|
||||||
|
tor3 *= factor_lj;
|
||||||
torque[i][0] -= radi*tor1;
|
torque[i][0] -= radi*tor1;
|
||||||
torque[i][1] -= radi*tor2;
|
torque[i][1] -= radi*tor2;
|
||||||
torque[i][2] -= radi*tor3;
|
torque[i][2] -= radi*tor3;
|
||||||
|
|||||||
@ -42,7 +42,7 @@ void PairGranHooke::compute(int eflag, int vflag)
|
|||||||
{
|
{
|
||||||
int i,j,ii,jj,inum,jnum;
|
int i,j,ii,jj,inum,jnum;
|
||||||
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
|
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
|
||||||
double radi,radj,radsum,rsq,r,rinv,rsqinv;
|
double radi,radj,radsum,rsq,r,rinv,rsqinv,factor_lj;
|
||||||
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
|
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
|
||||||
double wr1,wr2,wr3;
|
double wr1,wr2,wr3;
|
||||||
double vtr1,vtr2,vtr3,vrel;
|
double vtr1,vtr2,vtr3,vrel;
|
||||||
@ -82,6 +82,7 @@ void PairGranHooke::compute(int eflag, int vflag)
|
|||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
int newton_pair = force->newton_pair;
|
int newton_pair = force->newton_pair;
|
||||||
|
double *special_lj = force->special_lj;
|
||||||
|
|
||||||
inum = list->inum;
|
inum = list->inum;
|
||||||
ilist = list->ilist;
|
ilist = list->ilist;
|
||||||
@ -101,8 +102,11 @@ void PairGranHooke::compute(int eflag, int vflag)
|
|||||||
|
|
||||||
for (jj = 0; jj < jnum; jj++) {
|
for (jj = 0; jj < jnum; jj++) {
|
||||||
j = jlist[jj];
|
j = jlist[jj];
|
||||||
|
factor_lj = special_lj[sbmask(j)];
|
||||||
j &= NEIGHMASK;
|
j &= NEIGHMASK;
|
||||||
|
|
||||||
|
if (factor_lj == 0) continue;
|
||||||
|
|
||||||
delx = xtmp - x[j][0];
|
delx = xtmp - x[j][0];
|
||||||
dely = ytmp - x[j][1];
|
dely = ytmp - x[j][1];
|
||||||
delz = ztmp - x[j][2];
|
delz = ztmp - x[j][2];
|
||||||
@ -187,6 +191,9 @@ void PairGranHooke::compute(int eflag, int vflag)
|
|||||||
fx = delx*ccel + fs1;
|
fx = delx*ccel + fs1;
|
||||||
fy = dely*ccel + fs2;
|
fy = dely*ccel + fs2;
|
||||||
fz = delz*ccel + fs3;
|
fz = delz*ccel + fs3;
|
||||||
|
fx *= factor_lj;
|
||||||
|
fy *= factor_lj;
|
||||||
|
fz *= factor_lj;
|
||||||
f[i][0] += fx;
|
f[i][0] += fx;
|
||||||
f[i][1] += fy;
|
f[i][1] += fy;
|
||||||
f[i][2] += fz;
|
f[i][2] += fz;
|
||||||
@ -194,6 +201,9 @@ void PairGranHooke::compute(int eflag, int vflag)
|
|||||||
tor1 = rinv * (dely*fs3 - delz*fs2);
|
tor1 = rinv * (dely*fs3 - delz*fs2);
|
||||||
tor2 = rinv * (delz*fs1 - delx*fs3);
|
tor2 = rinv * (delz*fs1 - delx*fs3);
|
||||||
tor3 = rinv * (delx*fs2 - dely*fs1);
|
tor3 = rinv * (delx*fs2 - dely*fs1);
|
||||||
|
tor1 *= factor_lj;
|
||||||
|
tor2 *= factor_lj;
|
||||||
|
tor3 *= factor_lj;
|
||||||
torque[i][0] -= radi*tor1;
|
torque[i][0] -= radi*tor1;
|
||||||
torque[i][1] -= radi*tor2;
|
torque[i][1] -= radi*tor2;
|
||||||
torque[i][2] -= radi*tor3;
|
torque[i][2] -= radi*tor3;
|
||||||
|
|||||||
@ -103,7 +103,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
|||||||
{
|
{
|
||||||
int i, j, ii, jj, inum, jnum;
|
int i, j, ii, jj, inum, jnum;
|
||||||
double xtmp, ytmp, ztmp, delx, dely, delz, fx, fy, fz;
|
double xtmp, ytmp, ztmp, delx, dely, delz, fx, fy, fz;
|
||||||
double radi, radj, radsum, rsq, r, rinv, rsqinv;
|
double radi, radj, radsum, rsq, r, rinv, rsqinv, factor_lj;
|
||||||
double vr1, vr2, vr3, vnnr, vn1, vn2, vn3, vt1, vt2, vt3;
|
double vr1, vr2, vr3, vnnr, vn1, vn2, vn3, vt1, vt2, vt3;
|
||||||
double wr1, wr2, wr3;
|
double wr1, wr2, wr3;
|
||||||
double vtr1, vtr2, vtr3, vrel;
|
double vtr1, vtr2, vtr3, vrel;
|
||||||
@ -151,6 +151,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
|||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
int newton_pair = force->newton_pair;
|
int newton_pair = force->newton_pair;
|
||||||
|
double *special_lj = force->special_lj;
|
||||||
|
|
||||||
inum = list->inum;
|
inum = list->inum;
|
||||||
ilist = list->ilist;
|
ilist = list->ilist;
|
||||||
@ -174,8 +175,11 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
|||||||
|
|
||||||
for (jj = 0; jj < jnum; jj++) {
|
for (jj = 0; jj < jnum; jj++) {
|
||||||
j = jlist[jj];
|
j = jlist[jj];
|
||||||
|
factor_lj = special_lj[sbmask(j)];
|
||||||
j &= NEIGHMASK;
|
j &= NEIGHMASK;
|
||||||
|
|
||||||
|
if (factor_lj == 0) continue;
|
||||||
|
|
||||||
delx = xtmp - x[j][0];
|
delx = xtmp - x[j][0];
|
||||||
dely = ytmp - x[j][1];
|
dely = ytmp - x[j][1];
|
||||||
delz = ztmp - x[j][2];
|
delz = ztmp - x[j][2];
|
||||||
@ -306,6 +310,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
|||||||
fx = delx * ccel + fs1;
|
fx = delx * ccel + fs1;
|
||||||
fy = dely * ccel + fs2;
|
fy = dely * ccel + fs2;
|
||||||
fz = delz * ccel + fs3;
|
fz = delz * ccel + fs3;
|
||||||
|
fx *= factor_lj;
|
||||||
|
fy *= factor_lj;
|
||||||
|
fz *= factor_lj;
|
||||||
f[i][0] += fx;
|
f[i][0] += fx;
|
||||||
f[i][1] += fy;
|
f[i][1] += fy;
|
||||||
f[i][2] += fz;
|
f[i][2] += fz;
|
||||||
@ -313,6 +320,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag)
|
|||||||
tor1 = rinv * (dely * fs3 - delz * fs2);
|
tor1 = rinv * (dely * fs3 - delz * fs2);
|
||||||
tor2 = rinv * (delz * fs1 - delx * fs3);
|
tor2 = rinv * (delz * fs1 - delx * fs3);
|
||||||
tor3 = rinv * (delx * fs2 - dely * fs1);
|
tor3 = rinv * (delx * fs2 - dely * fs1);
|
||||||
|
tor1 *= factor_lj;
|
||||||
|
tor2 *= factor_lj;
|
||||||
|
tor3 *= factor_lj;
|
||||||
torque[i][0] -= radi * tor1;
|
torque[i][0] -= radi * tor1;
|
||||||
torque[i][1] -= radi * tor2;
|
torque[i][1] -= radi * tor2;
|
||||||
torque[i][2] -= radi * tor3;
|
torque[i][2] -= radi * tor3;
|
||||||
|
|||||||
@ -150,7 +150,7 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
{
|
{
|
||||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||||
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz;
|
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz;
|
||||||
double radi,radj,radsum,rsq,r,rinv;
|
double radi,radj,radsum,rsq,r,rinv,factor_lj;
|
||||||
double Reff, delta, dR, dR2, dist_to_contact;
|
double Reff, delta, dR, dR2, dist_to_contact;
|
||||||
|
|
||||||
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
|
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
|
||||||
@ -222,6 +222,7 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
double *rmass = atom->rmass;
|
double *rmass = atom->rmass;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
double *special_lj = force->special_lj;
|
||||||
|
|
||||||
inum = list->inum;
|
inum = list->inum;
|
||||||
ilist = list->ilist;
|
ilist = list->ilist;
|
||||||
@ -249,8 +250,11 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
|
|
||||||
for (jj = 0; jj < jnum; jj++) {
|
for (jj = 0; jj < jnum; jj++) {
|
||||||
j = jlist[jj];
|
j = jlist[jj];
|
||||||
|
factor_lj = special_lj[sbmask(j)];
|
||||||
j &= NEIGHMASK;
|
j &= NEIGHMASK;
|
||||||
|
|
||||||
|
if (factor_lj == 0) continue;
|
||||||
|
|
||||||
delx = xtmp - x[j][0];
|
delx = xtmp - x[j][0];
|
||||||
dely = ytmp - x[j][1];
|
dely = ytmp - x[j][1];
|
||||||
delz = ztmp - x[j][2];
|
delz = ztmp - x[j][2];
|
||||||
@ -651,6 +655,9 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
fx = nx*Fntot + fs1;
|
fx = nx*Fntot + fs1;
|
||||||
fy = ny*Fntot + fs2;
|
fy = ny*Fntot + fs2;
|
||||||
fz = nz*Fntot + fs3;
|
fz = nz*Fntot + fs3;
|
||||||
|
fx *= factor_lj;
|
||||||
|
fy *= factor_lj;
|
||||||
|
fz *= factor_lj;
|
||||||
|
|
||||||
f[i][0] += fx;
|
f[i][0] += fx;
|
||||||
f[i][1] += fy;
|
f[i][1] += fy;
|
||||||
@ -659,6 +666,9 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
tor1 = ny*fs3 - nz*fs2;
|
tor1 = ny*fs3 - nz*fs2;
|
||||||
tor2 = nz*fs1 - nx*fs3;
|
tor2 = nz*fs1 - nx*fs3;
|
||||||
tor3 = nx*fs2 - ny*fs1;
|
tor3 = nx*fs2 - ny*fs1;
|
||||||
|
tor1 *= factor_lj;
|
||||||
|
tor2 *= factor_lj;
|
||||||
|
tor3 *= factor_lj;
|
||||||
|
|
||||||
dist_to_contact = radi-0.5*delta;
|
dist_to_contact = radi-0.5*delta;
|
||||||
torque[i][0] -= dist_to_contact*tor1;
|
torque[i][0] -= dist_to_contact*tor1;
|
||||||
@ -666,9 +676,9 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
torque[i][2] -= dist_to_contact*tor3;
|
torque[i][2] -= dist_to_contact*tor3;
|
||||||
|
|
||||||
if (twist_model[itype][jtype] != TWIST_NONE) {
|
if (twist_model[itype][jtype] != TWIST_NONE) {
|
||||||
tortwist1 = magtortwist * nx;
|
tortwist1 = magtortwist * nx * factor_lj;
|
||||||
tortwist2 = magtortwist * ny;
|
tortwist2 = magtortwist * ny * factor_lj;
|
||||||
tortwist3 = magtortwist * nz;
|
tortwist3 = magtortwist * nz * factor_lj;
|
||||||
|
|
||||||
torque[i][0] += tortwist1;
|
torque[i][0] += tortwist1;
|
||||||
torque[i][1] += tortwist2;
|
torque[i][1] += tortwist2;
|
||||||
@ -676,9 +686,9 @@ void PairGranular::compute(int eflag, int vflag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (roll_model[itype][jtype] != ROLL_NONE) {
|
if (roll_model[itype][jtype] != ROLL_NONE) {
|
||||||
torroll1 = Reff*(ny*fr3 - nz*fr2); // n cross fr
|
torroll1 = Reff*(ny*fr3 - nz*fr2) * factor_lj; // n cross fr
|
||||||
torroll2 = Reff*(nz*fr1 - nx*fr3);
|
torroll2 = Reff*(nz*fr1 - nx*fr3) * factor_lj;
|
||||||
torroll3 = Reff*(nx*fr2 - ny*fr1);
|
torroll3 = Reff*(nx*fr2 - ny*fr1) * factor_lj;
|
||||||
|
|
||||||
torque[i][0] += torroll1;
|
torque[i][0] += torroll1;
|
||||||
torque[i][1] += torroll2;
|
torque[i][1] += torroll2;
|
||||||
|
|||||||
@ -19,11 +19,14 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "modify.h"
|
||||||
#include "neighbor.h"
|
#include "neighbor.h"
|
||||||
#include "random_mars.h"
|
#include "random_mars.h"
|
||||||
#include "respa.h"
|
#include "respa.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
|
||||||
|
#include "fix_bond_history.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
@ -258,6 +261,10 @@ void FixBondBreak::post_integrate()
|
|||||||
commflag = 1;
|
commflag = 1;
|
||||||
comm->forward_comm(this,2);
|
comm->forward_comm(this,2);
|
||||||
|
|
||||||
|
// find instances of bond history to delete data
|
||||||
|
auto histories = modify->get_fix_by_style("BOND_HISTORY");
|
||||||
|
int n_histories = histories.size();
|
||||||
|
|
||||||
// break bonds
|
// break bonds
|
||||||
// if both atoms list each other as winning bond partner
|
// if both atoms list each other as winning bond partner
|
||||||
// and probability constraint is satisfied
|
// and probability constraint is satisfied
|
||||||
@ -292,7 +299,13 @@ void FixBondBreak::post_integrate()
|
|||||||
for (k = m; k < num_bond[i]-1; k++) {
|
for (k = m; k < num_bond[i]-1; k++) {
|
||||||
bond_atom[i][k] = bond_atom[i][k+1];
|
bond_atom[i][k] = bond_atom[i][k+1];
|
||||||
bond_type[i][k] = bond_type[i][k+1];
|
bond_type[i][k] = bond_type[i][k+1];
|
||||||
|
if (n_histories > 0)
|
||||||
|
for (auto &ihistory: histories)
|
||||||
|
dynamic_cast<FixBondHistory *>(ihistory)->shift_history(i,k,k+1);
|
||||||
}
|
}
|
||||||
|
if (n_histories > 0)
|
||||||
|
for (auto &ihistory: histories)
|
||||||
|
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i,num_bond[i]-1);
|
||||||
num_bond[i]--;
|
num_bond[i]--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,21 +17,15 @@
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "fix_bond_create_angle.h"
|
#include "fix_bond_create_angle.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixBondCreateAngle::FixBondCreateAngle(LAMMPS *lmp, int narg, char **arg) :
|
|
||||||
FixBondCreate(lmp, narg, arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
int FixBondCreateAngle::constrain(int i, int j, double amin, double amax)
|
int FixBondCreateAngle::constrain(int i, int j, double amin, double amax)
|
||||||
{
|
{
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace LAMMPS_NS {
|
|||||||
|
|
||||||
class FixBondCreateAngle : public FixBondCreate {
|
class FixBondCreateAngle : public FixBondCreate {
|
||||||
public:
|
public:
|
||||||
FixBondCreateAngle(class LAMMPS *, int, char **);
|
FixBondCreateAngle(LAMMPS *_lmp, int narg, char **arg) : FixBondCreate(_lmp, narg, arg) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int constrain(int, int, double, double) override;
|
int constrain(int, int, double, double) override;
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "compute.h"
|
#include "compute.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "fix_bond_history.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "modify.h"
|
#include "modify.h"
|
||||||
@ -446,6 +447,10 @@ void FixBondSwap::post_integrate()
|
|||||||
if (!accept) return;
|
if (!accept) return;
|
||||||
naccept++;
|
naccept++;
|
||||||
|
|
||||||
|
// find instances of bond/history to reset history
|
||||||
|
auto histories = modify->get_fix_by_style("BOND_HISTORY");
|
||||||
|
int n_histories = histories.size();
|
||||||
|
|
||||||
// change bond partners of affected atoms
|
// change bond partners of affected atoms
|
||||||
// on atom i: bond i-inext changes to i-jnext
|
// on atom i: bond i-inext changes to i-jnext
|
||||||
// on atom j: bond j-jnext changes to j-inext
|
// on atom j: bond j-jnext changes to j-inext
|
||||||
@ -453,13 +458,33 @@ void FixBondSwap::post_integrate()
|
|||||||
// on atom jnext: bond jnext-j changes to jnext-i
|
// on atom jnext: bond jnext-j changes to jnext-i
|
||||||
|
|
||||||
for (ibond = 0; ibond < num_bond[i]; ibond++)
|
for (ibond = 0; ibond < num_bond[i]; ibond++)
|
||||||
if (bond_atom[i][ibond] == tag[inext]) bond_atom[i][ibond] = tag[jnext];
|
if (bond_atom[i][ibond] == tag[inext]) {
|
||||||
|
if (n_histories > 0)
|
||||||
|
for (auto &ihistory: histories)
|
||||||
|
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i,ibond);
|
||||||
|
bond_atom[i][ibond] = tag[jnext];
|
||||||
|
}
|
||||||
for (jbond = 0; jbond < num_bond[j]; jbond++)
|
for (jbond = 0; jbond < num_bond[j]; jbond++)
|
||||||
if (bond_atom[j][jbond] == tag[jnext]) bond_atom[j][jbond] = tag[inext];
|
if (bond_atom[j][jbond] == tag[jnext]) {
|
||||||
|
if (n_histories > 0)
|
||||||
|
for (auto &ihistory: histories)
|
||||||
|
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(j,jbond);
|
||||||
|
bond_atom[j][jbond] = tag[inext];
|
||||||
|
}
|
||||||
for (ibond = 0; ibond < num_bond[inext]; ibond++)
|
for (ibond = 0; ibond < num_bond[inext]; ibond++)
|
||||||
if (bond_atom[inext][ibond] == tag[i]) bond_atom[inext][ibond] = tag[j];
|
if (bond_atom[inext][ibond] == tag[i]) {
|
||||||
|
if (n_histories > 0)
|
||||||
|
for (auto &ihistory: histories)
|
||||||
|
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(inext,ibond);
|
||||||
|
bond_atom[inext][ibond] = tag[j];
|
||||||
|
}
|
||||||
for (jbond = 0; jbond < num_bond[jnext]; jbond++)
|
for (jbond = 0; jbond < num_bond[jnext]; jbond++)
|
||||||
if (bond_atom[jnext][jbond] == tag[j]) bond_atom[jnext][jbond] = tag[i];
|
if (bond_atom[jnext][jbond] == tag[j]) {
|
||||||
|
if (n_histories > 0)
|
||||||
|
for (auto &ihistory: histories)
|
||||||
|
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(jnext,jbond);
|
||||||
|
bond_atom[jnext][jbond] = tag[i];
|
||||||
|
}
|
||||||
|
|
||||||
// set global tags of 4 atoms in bonds
|
// set global tags of 4 atoms in bonds
|
||||||
|
|
||||||
|
|||||||
@ -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.h"
|
||||||
#include "fix_dummy.h"
|
#include "fix_dummy.h"
|
||||||
#include "fix_neigh_history.h"
|
#include "fix_neigh_history.h"
|
||||||
#include "fix_pair_tracker.h"
|
#include "fix_store_local.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "modify.h"
|
#include "modify.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "neighbor.h"
|
#include "neighbor.h"
|
||||||
|
#include "tokenizer.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
PairTracker::PairTracker(LAMMPS *lmp) : Pair(lmp)
|
PairTracker::PairTracker(LAMMPS *lmp) :
|
||||||
|
Pair(lmp), onerad_dynamic(nullptr), onerad_frozen(nullptr), maxrad_dynamic(nullptr),
|
||||||
|
maxrad_frozen(nullptr), id_fix_store_local(nullptr), fix_dummy(nullptr), fix_history(nullptr),
|
||||||
|
fix_store_local(nullptr), type_filter(nullptr), output_data(nullptr), pack_choice(nullptr)
|
||||||
{
|
{
|
||||||
single_enable = 1;
|
single_enable = 1;
|
||||||
no_virial_fdotr_compute = 1;
|
no_virial_fdotr_compute = 1;
|
||||||
|
|
||||||
neighprev = 0;
|
neighprev = 0;
|
||||||
history = 1;
|
history = 1;
|
||||||
size_history = 4;
|
size_history = 3;
|
||||||
nondefault_history_transfer = 1;
|
nondefault_history_transfer = 1;
|
||||||
|
|
||||||
finitecutflag = 0;
|
finitecutflag = 0;
|
||||||
|
tmin = -1;
|
||||||
|
|
||||||
// create dummy fix as placeholder for FixNeighHistory
|
// create dummy fix as placeholder for FixNeighHistory
|
||||||
// this is so final order of Modify:fix will conform to input script
|
// this is so final order of Modify:fix will conform to input script
|
||||||
|
fix_dummy = dynamic_cast<FixDummy *>(modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY"));
|
||||||
fix_history = nullptr;
|
|
||||||
modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY");
|
|
||||||
fix_dummy = dynamic_cast<FixDummy *>( modify->fix[modify->nfix - 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -62,6 +64,7 @@ PairTracker::~PairTracker()
|
|||||||
modify->delete_fix("NEIGH_HISTORY_TRACK_DUMMY");
|
modify->delete_fix("NEIGH_HISTORY_TRACK_DUMMY");
|
||||||
else
|
else
|
||||||
modify->delete_fix("NEIGH_HISTORY_TRACK");
|
modify->delete_fix("NEIGH_HISTORY_TRACK");
|
||||||
|
if (id_fix_store_local) modify->delete_fix(id_fix_store_local);
|
||||||
|
|
||||||
if (allocated) {
|
if (allocated) {
|
||||||
memory->destroy(setflag);
|
memory->destroy(setflag);
|
||||||
@ -73,6 +76,12 @@ PairTracker::~PairTracker()
|
|||||||
delete[] maxrad_dynamic;
|
delete[] maxrad_dynamic;
|
||||||
delete[] maxrad_frozen;
|
delete[] maxrad_frozen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] pack_choice;
|
||||||
|
delete[] id_fix_store_local;
|
||||||
|
|
||||||
|
memory->destroy(output_data);
|
||||||
|
memory->destroy(type_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -80,7 +89,7 @@ PairTracker::~PairTracker()
|
|||||||
void PairTracker::compute(int eflag, int vflag)
|
void PairTracker::compute(int eflag, int vflag)
|
||||||
{
|
{
|
||||||
int i, j, ii, jj, inum, jnum, itype, jtype;
|
int i, j, ii, jj, inum, jnum, itype, jtype;
|
||||||
double xtmp, ytmp, ztmp, delx, dely, delz, time;
|
double xtmp, ytmp, ztmp, delx, dely, delz;
|
||||||
double radi, radj, radsum, rsq, r;
|
double radi, radj, radsum, rsq, r;
|
||||||
int *ilist, *jlist, *numneigh, **firstneigh;
|
int *ilist, *jlist, *numneigh, **firstneigh;
|
||||||
int *touch, **firsttouch;
|
int *touch, **firsttouch;
|
||||||
@ -131,27 +140,23 @@ void PairTracker::compute(int eflag, int vflag)
|
|||||||
if (rsq >= radsum * radsum) {
|
if (rsq >= radsum * radsum) {
|
||||||
|
|
||||||
data = &alldata[size_history * jj];
|
data = &alldata[size_history * jj];
|
||||||
if (touch[jj] == 1) {
|
if (touch[jj] == 1) process_data(i, j, data);
|
||||||
fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]);
|
|
||||||
}
|
|
||||||
touch[jj] = 0;
|
touch[jj] = 0;
|
||||||
data[0] = 0.0; // initial time
|
data[0] = 0.0; // initial timestep
|
||||||
data[1] = 0.0; // initial timestep
|
data[1] = 0.0; // sum of r, may be inaccurate over long times
|
||||||
data[2] = 0.0; // sum of r, may overflow
|
data[2] = 0.0; // min of r
|
||||||
data[3] = 0.0; // min of r
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
data = &alldata[size_history * jj];
|
data = &alldata[size_history * jj];
|
||||||
if (touch[jj] == 0) {
|
if (touch[jj] == 0) {
|
||||||
time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
|
data[0] = (double) update->ntimestep;
|
||||||
data[0] = time;
|
data[1] = r;
|
||||||
data[1] = (double) update->ntimestep;
|
|
||||||
data[2] = r;
|
data[2] = r;
|
||||||
data[3] = r;
|
|
||||||
} else if (updateflag) {
|
} else if (updateflag) {
|
||||||
data[2] += r;
|
data[1] += r;
|
||||||
if (data[3] > r) data[3] = r;
|
if (data[2] > r) data[2] = r;
|
||||||
}
|
}
|
||||||
touch[jj] = 1;
|
touch[jj] = 1;
|
||||||
}
|
}
|
||||||
@ -160,28 +165,23 @@ void PairTracker::compute(int eflag, int vflag)
|
|||||||
if (rsq >= cutsq[itype][jtype]) {
|
if (rsq >= cutsq[itype][jtype]) {
|
||||||
|
|
||||||
data = &alldata[size_history * jj];
|
data = &alldata[size_history * jj];
|
||||||
if (touch[jj] == 1) {
|
if (touch[jj] == 1) process_data(i, j, data);
|
||||||
fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
touch[jj] = 0;
|
touch[jj] = 0;
|
||||||
data[0] = 0.0; // initial time
|
data[0] = 0.0; // initial timestep
|
||||||
data[1] = 0.0; // initial timestep
|
data[1] = 0.0; // sum of r, may be inaccurate over long times
|
||||||
data[2] = 0.0; // sum of r, may overflow
|
data[2] = 0.0; // min of r
|
||||||
data[3] = 0.0; // min of r
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
data = &alldata[size_history * jj];
|
data = &alldata[size_history * jj];
|
||||||
if (touch[jj] == 0) {
|
if (touch[jj] == 0) {
|
||||||
time = update->atime + (update->ntimestep - update->atimestep) * update->dt;
|
data[0] = (double) update->ntimestep;
|
||||||
data[0] = time;
|
data[1] = r;
|
||||||
data[1] = (double) update->ntimestep;
|
|
||||||
data[2] = r;
|
data[2] = r;
|
||||||
data[3] = r;
|
|
||||||
} else if (updateflag) {
|
} else if (updateflag) {
|
||||||
data[2] += r;
|
data[1] += r;
|
||||||
if (data[3] > r) data[3] = r;
|
if (data[2] > r) data[2] = r;
|
||||||
}
|
}
|
||||||
touch[jj] = 1;
|
touch[jj] = 1;
|
||||||
}
|
}
|
||||||
@ -218,14 +218,89 @@ void PairTracker::allocate()
|
|||||||
|
|
||||||
void PairTracker::settings(int narg, char **arg)
|
void PairTracker::settings(int narg, char **arg)
|
||||||
{
|
{
|
||||||
if (narg != 0 && narg != 1) error->all(FLERR, "Illegal pair_style command");
|
if (narg < 2) error->all(FLERR, "Illegal pair_style command");
|
||||||
|
|
||||||
if (narg == 1) {
|
id_fix_store_local = utils::strdup(arg[0]);
|
||||||
if (strcmp(arg[0], "finite") == 0)
|
store_local_freq = utils::inumeric(FLERR, arg[1], false, lmp);
|
||||||
|
|
||||||
|
// If optional arguments included, this will be oversized
|
||||||
|
pack_choice = new FnPtrPack[narg - 1];
|
||||||
|
|
||||||
|
nvalues = 0;
|
||||||
|
int iarg = 2;
|
||||||
|
while (iarg < narg) {
|
||||||
|
if (strcmp(arg[iarg], "finite") == 0) {
|
||||||
finitecutflag = 1;
|
finitecutflag = 1;
|
||||||
else
|
} else if (strcmp(arg[iarg], "id1") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_id1;
|
||||||
|
} else if (strcmp(arg[iarg], "id2") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_id2;
|
||||||
|
} else if (strcmp(arg[iarg], "time/created") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_time_created;
|
||||||
|
} else if (strcmp(arg[iarg], "time/broken") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_time_broken;
|
||||||
|
} else if (strcmp(arg[iarg], "time/total") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_time_total;
|
||||||
|
} else if (strcmp(arg[iarg], "x") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_x;
|
||||||
|
} else if (strcmp(arg[iarg], "y") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_y;
|
||||||
|
} else if (strcmp(arg[iarg], "z") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_z;
|
||||||
|
} else if (strcmp(arg[iarg], "r/min") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_rmin;
|
||||||
|
} else if (strcmp(arg[iarg], "r/ave") == 0) {
|
||||||
|
pack_choice[nvalues++] = &PairTracker::pack_rave;
|
||||||
|
} else if (strcmp(arg[iarg], "time/min") == 0) {
|
||||||
|
if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in pair tracker command");
|
||||||
|
tmin = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
|
||||||
|
iarg++;
|
||||||
|
|
||||||
|
} else if (strcmp(arg[iarg], "type/include") == 0) {
|
||||||
|
if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in pair tracker command");
|
||||||
|
int ntypes = atom->ntypes;
|
||||||
|
int i, j, itype, jtype;
|
||||||
|
int inlo, inhi, jnlo, jnhi;
|
||||||
|
|
||||||
|
if (!type_filter) {
|
||||||
|
memory->create(type_filter, ntypes + 1, ntypes + 1, "pair/tracker:type_filter");
|
||||||
|
|
||||||
|
for (i = 0; i <= ntypes; i++) {
|
||||||
|
for (j = 0; j <= ntypes; j++) type_filter[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iwords = Tokenizer(arg[iarg + 1], ",").as_vector();
|
||||||
|
auto jwords = Tokenizer(arg[iarg + 2], ",").as_vector();
|
||||||
|
|
||||||
|
for (const auto &ifield : iwords) {
|
||||||
|
utils::bounds(FLERR, ifield, 1, ntypes, inlo, inhi, error);
|
||||||
|
for (const auto &jfield : jwords) {
|
||||||
|
utils::bounds(FLERR, jfield, 1, ntypes, jnlo, jnhi, error);
|
||||||
|
|
||||||
|
for (itype = inlo; itype <= inhi; itype++) {
|
||||||
|
for (jtype = jnlo; jtype <= jnhi; jtype++) {
|
||||||
|
type_filter[itype][jtype] = 1;
|
||||||
|
type_filter[jtype][itype] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iarg += 2;
|
||||||
|
|
||||||
|
} else {
|
||||||
error->all(FLERR, "Illegal pair_style command");
|
error->all(FLERR, "Illegal pair_style command");
|
||||||
}
|
}
|
||||||
|
iarg++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvalues == 0) error->all(FLERR, "Must request at least one value to output");
|
||||||
|
memory->create(output_data, nvalues, "pair/tracker:output_data");
|
||||||
|
|
||||||
|
fix_store_local = dynamic_cast<FixStoreLocal *>(modify->get_fix_by_id(id_fix_store_local));
|
||||||
|
if (!fix_store_local)
|
||||||
|
fix_store_local = dynamic_cast<FixStoreLocal *>(modify->add_fix(
|
||||||
|
fmt::format("{} all STORE_LOCAL {} {}", id_fix_store_local, store_local_freq, nvalues)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -263,8 +338,6 @@ void PairTracker::coeff(int narg, char **arg)
|
|||||||
|
|
||||||
void PairTracker::init_style()
|
void PairTracker::init_style()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
// error and warning checks
|
// error and warning checks
|
||||||
|
|
||||||
if (!atom->radius_flag && finitecutflag)
|
if (!atom->radius_flag && finitecutflag)
|
||||||
@ -292,35 +365,40 @@ void PairTracker::init_style()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (finitecutflag) {
|
if (finitecutflag) {
|
||||||
|
|
||||||
if (force->pair->beyond_contact)
|
if (force->pair->beyond_contact)
|
||||||
error->all(FLERR,
|
error->all(FLERR,
|
||||||
"Pair tracker incompatible with granular pairstyles that extend beyond contact");
|
"Pair tracker incompatible with granular pairstyles that extend beyond contact");
|
||||||
|
|
||||||
|
// check for FixFreeze and set freeze_group_bit
|
||||||
|
|
||||||
|
auto fixlist = modify->get_fix_by_style("^freeze");
|
||||||
|
if (fixlist.size() == 0)
|
||||||
|
freeze_group_bit = 0;
|
||||||
|
else if (fixlist.size() > 1)
|
||||||
|
error->all(FLERR, "Only one fix freeze command at a time allowed");
|
||||||
|
else
|
||||||
|
freeze_group_bit = fixlist.front()->groupbit;
|
||||||
|
|
||||||
// check for FixPour and FixDeposit so can extract particle radii
|
// check for FixPour and FixDeposit so can extract particle radii
|
||||||
|
|
||||||
int ipour;
|
auto pours = modify->get_fix_by_style("^pour");
|
||||||
for (ipour = 0; ipour < modify->nfix; ipour++)
|
auto deps = modify->get_fix_by_style("^deposit");
|
||||||
if (strcmp(modify->fix[ipour]->style, "pour") == 0) break;
|
|
||||||
if (ipour == modify->nfix) ipour = -1;
|
|
||||||
|
|
||||||
int idep;
|
|
||||||
for (idep = 0; idep < modify->nfix; idep++)
|
|
||||||
if (strcmp(modify->fix[idep]->style, "deposit") == 0) break;
|
|
||||||
if (idep == modify->nfix) idep = -1;
|
|
||||||
|
|
||||||
// set maxrad_dynamic and maxrad_frozen for each type
|
// set maxrad_dynamic and maxrad_frozen for each type
|
||||||
// include future FixPour and FixDeposit particles as dynamic
|
// include future FixPour and FixDeposit particles as dynamic
|
||||||
|
|
||||||
int itype;
|
int itype = 0;
|
||||||
for (i = 1; i <= atom->ntypes; i++) {
|
for (int i = 1; i <= atom->ntypes; i++) {
|
||||||
onerad_dynamic[i] = onerad_frozen[i] = 0.0;
|
onerad_dynamic[i] = onerad_frozen[i] = 0.0;
|
||||||
if (ipour >= 0) {
|
for (auto &ipour : pours) {
|
||||||
itype = i;
|
itype = i;
|
||||||
onerad_dynamic[i] = *((double *) modify->fix[ipour]->extract("radius", itype));
|
double maxrad = *((double *) ipour->extract("radius", itype));
|
||||||
|
if (maxrad > 0.0) onerad_dynamic[i] = maxrad;
|
||||||
}
|
}
|
||||||
if (idep >= 0) {
|
for (auto &idep : deps) {
|
||||||
itype = i;
|
itype = i;
|
||||||
onerad_dynamic[i] = *((double *) modify->fix[idep]->extract("radius", itype));
|
double maxrad = *((double *) idep->extract("radius", itype));
|
||||||
|
if (maxrad > 0.0) onerad_dynamic[i] = maxrad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +407,7 @@ void PairTracker::init_style()
|
|||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
for (i = 0; i < nlocal; i++)
|
for (int i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & freeze_group_bit)
|
if (mask[i] & freeze_group_bit)
|
||||||
onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]], radius[i]);
|
onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]], radius[i]);
|
||||||
else
|
else
|
||||||
@ -338,11 +416,6 @@ void PairTracker::init_style()
|
|||||||
MPI_Allreduce(&onerad_dynamic[1], &maxrad_dynamic[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world);
|
MPI_Allreduce(&onerad_dynamic[1], &maxrad_dynamic[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world);
|
||||||
MPI_Allreduce(&onerad_frozen[1], &maxrad_frozen[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world);
|
MPI_Allreduce(&onerad_frozen[1], &maxrad_frozen[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto trackfixes = modify->get_fix_by_style("pair/tracker");
|
|
||||||
if (trackfixes.size() != 1)
|
|
||||||
error->all(FLERR, "Must use exactly one fix pair/tracker command with pair style tracker");
|
|
||||||
fix_pair_tracker = dynamic_cast<FixPairTracker *>( trackfixes.front());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -354,8 +427,7 @@ double PairTracker::init_one(int i, int j)
|
|||||||
if (!allocated) allocate();
|
if (!allocated) allocate();
|
||||||
|
|
||||||
// always mix prefactors geometrically
|
// always mix prefactors geometrically
|
||||||
|
if (setflag[i][j] == 0) cut[i][j] = mix_distance(cut[i][i], cut[j][j]);
|
||||||
if (setflag[i][j] == 0) { cut[i][j] = mix_distance(cut[i][i], cut[j][j]); }
|
|
||||||
|
|
||||||
cut[j][i] = cut[i][j];
|
cut[j][i] = cut[i][j];
|
||||||
|
|
||||||
@ -384,7 +456,7 @@ void PairTracker::write_restart(FILE *fp)
|
|||||||
for (i = 1; i <= atom->ntypes; i++)
|
for (i = 1; i <= atom->ntypes; i++)
|
||||||
for (j = i; j <= atom->ntypes; j++) {
|
for (j = i; j <= atom->ntypes; j++) {
|
||||||
fwrite(&setflag[i][j], sizeof(int), 1, fp);
|
fwrite(&setflag[i][j], sizeof(int), 1, fp);
|
||||||
if (setflag[i][j]) { fwrite(&cut[i][j], sizeof(double), 1, fp); }
|
if (setflag[i][j]) fwrite(&cut[i][j], sizeof(double), 1, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +476,7 @@ void PairTracker::read_restart(FILE *fp)
|
|||||||
if (me == 0) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error);
|
if (me == 0) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error);
|
||||||
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
|
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
|
||||||
if (setflag[i][j]) {
|
if (setflag[i][j]) {
|
||||||
if (me == 0) { utils::sfread(FLERR, &cut[i][j], sizeof(double), 1, fp, nullptr, error); }
|
if (me == 0) utils::sfread(FLERR, &cut[i][j], sizeof(double), 1, fp, nullptr, error);
|
||||||
MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world);
|
MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,3 +538,91 @@ double PairTracker::radii2cut(double r1, double r2)
|
|||||||
double cut = r1 + r2;
|
double cut = r1 + r2;
|
||||||
return cut;
|
return cut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::process_data(int i, int j, double *input_data)
|
||||||
|
{
|
||||||
|
if ((update->ntimestep - input_data[0]) < tmin) return;
|
||||||
|
|
||||||
|
if (type_filter) {
|
||||||
|
int *type = atom->type;
|
||||||
|
if (type_filter[type[i]][type[j]] == 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < nvalues; k++) (this->*pack_choice[k])(k, i, j, input_data);
|
||||||
|
fix_store_local->add_data(output_data, i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
one method for every keyword fix pair/tracker can output
|
||||||
|
the atom property is packed into a local vector or array
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_time_created(int n, int /*i*/, int /*j*/, double *data)
|
||||||
|
{
|
||||||
|
output_data[n] = data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_time_broken(int n, int /*i*/, int /*j*/, double * /*data*/)
|
||||||
|
{
|
||||||
|
output_data[n] = update->ntimestep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_time_total(int n, int /*i*/, int /*j*/, double *data)
|
||||||
|
{
|
||||||
|
output_data[n] = update->ntimestep - data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_id1(int n, int i, int /*j*/, double * /*data*/)
|
||||||
|
{
|
||||||
|
output_data[n] = atom->tag[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_id2(int n, int /*i*/, int j, double * /*data*/)
|
||||||
|
{
|
||||||
|
output_data[n] = atom->tag[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_x(int n, int i, int j, double * /*data*/)
|
||||||
|
{
|
||||||
|
output_data[n] = (atom->x[i][0] + atom->x[j][0]) * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_y(int n, int i, int j, double * /*data*/)
|
||||||
|
{
|
||||||
|
output_data[n] = (atom->x[i][1] + atom->x[j][1]) * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_z(int n, int i, int j, double * /*data*/)
|
||||||
|
{
|
||||||
|
output_data[n] = (atom->x[i][2] + atom->x[j][2]) * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_rmin(int n, int /*i*/, int /*j*/, double *data)
|
||||||
|
{
|
||||||
|
output_data[n] = data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void PairTracker::pack_rave(int n, int /*i*/, int /*j*/, double *data)
|
||||||
|
{
|
||||||
|
output_data[n] = data[1] / (update->ntimestep - data[0]);
|
||||||
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ class PairTracker : public Pair {
|
|||||||
double single(int, int, int, int, double, double, double, double &) override;
|
double single(int, int, int, int, double, double, double, double &) override;
|
||||||
double atom2cut(int) override;
|
double atom2cut(int) override;
|
||||||
double radii2cut(double, double) override;
|
double radii2cut(double, double) override;
|
||||||
|
void transfer_history(double *, double *) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int sizeflag;
|
int sizeflag;
|
||||||
@ -50,12 +51,33 @@ class PairTracker : public Pair {
|
|||||||
double *onerad_dynamic, *onerad_frozen;
|
double *onerad_dynamic, *onerad_frozen;
|
||||||
double *maxrad_dynamic, *maxrad_frozen;
|
double *maxrad_dynamic, *maxrad_frozen;
|
||||||
int freeze_group_bit;
|
int freeze_group_bit;
|
||||||
|
int store_local_freq;
|
||||||
|
|
||||||
|
char *id_fix_store_local;
|
||||||
class FixDummy *fix_dummy;
|
class FixDummy *fix_dummy;
|
||||||
class FixNeighHistory *fix_history;
|
class FixNeighHistory *fix_history;
|
||||||
class FixPairTracker *fix_pair_tracker;
|
class FixStoreLocal *fix_store_local;
|
||||||
|
|
||||||
void transfer_history(double *, double *) override;
|
int **type_filter;
|
||||||
|
double tmin;
|
||||||
|
|
||||||
|
int nvalues, ncount;
|
||||||
|
double *output_data;
|
||||||
|
typedef void (PairTracker::*FnPtrPack)(int, int, int, double *);
|
||||||
|
FnPtrPack *pack_choice; // ptrs to pack functions
|
||||||
|
|
||||||
|
void pack_id1(int, int, int, double *);
|
||||||
|
void pack_id2(int, int, int, double *);
|
||||||
|
void pack_time_created(int, int, int, double *);
|
||||||
|
void pack_time_broken(int, int, int, double *);
|
||||||
|
void pack_time_total(int, int, int, double *);
|
||||||
|
void pack_x(int, int, int, double *);
|
||||||
|
void pack_y(int, int, int, double *);
|
||||||
|
void pack_z(int, int, int, double *);
|
||||||
|
void pack_rmin(int, int, int, double *);
|
||||||
|
void pack_rave(int, int, int, double *);
|
||||||
|
|
||||||
|
void process_data(int, int, double *);
|
||||||
void allocate();
|
void allocate();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,20 +94,37 @@ Self-explanatory. Check the input script syntax and compare to the
|
|||||||
documentation for the command. You can use -echo screen as a
|
documentation for the command. You can use -echo screen as a
|
||||||
command-line option when running LAMMPS to see the offending line.
|
command-line option when running LAMMPS to see the offending line.
|
||||||
|
|
||||||
|
E: Invalid keyword in pair tracker command
|
||||||
|
|
||||||
|
Self-explanatory.
|
||||||
|
|
||||||
E: Incorrect args for pair coefficients
|
E: Incorrect args for pair coefficients
|
||||||
|
|
||||||
Self-explanatory. Check the input script or data file.
|
Self-explanatory. Check the input script or data file.
|
||||||
|
|
||||||
|
E: Must request at least one value to output
|
||||||
|
|
||||||
|
Must include at least one bond property to store in fix store/local
|
||||||
|
|
||||||
E: Pair tracker requires atom attribute radius for finite cutoffs
|
E: Pair tracker requires atom attribute radius for finite cutoffs
|
||||||
|
|
||||||
The atom style defined does not have these attributes.
|
The atom style defined does not have these attributes.
|
||||||
|
|
||||||
|
E: Pair tracker incompatible with granular pairstyles that extend beyond contact
|
||||||
|
|
||||||
|
Self-explanatory.
|
||||||
|
|
||||||
E: Could not find pair fix neigh history ID
|
E: Could not find pair fix neigh history ID
|
||||||
|
|
||||||
The associated fix neigh/history is missing
|
The associated fix neigh/history is missing
|
||||||
|
|
||||||
E: Cannot use pair tracker without fix pair/tracker
|
E: Cannot use pair tracker without fix store/local
|
||||||
|
|
||||||
This pairstyle requires one to define a pair/tracker fix
|
The associated fix store/local does not exist
|
||||||
|
|
||||||
|
E: Inconsistent number of output variables in fix store/local
|
||||||
|
|
||||||
|
The number of values specified in fix store/local disagrees with
|
||||||
|
the number of values requested in pair tracker
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -36,6 +36,7 @@ using MathConst::MY_CUBEROOT2;
|
|||||||
BondQuartic::BondQuartic(LAMMPS *_lmp) :
|
BondQuartic::BondQuartic(LAMMPS *_lmp) :
|
||||||
Bond(_lmp), k(nullptr), b1(nullptr), b2(nullptr), rc(nullptr), u0(nullptr)
|
Bond(_lmp), k(nullptr), b1(nullptr), b2(nullptr), rc(nullptr), u0(nullptr)
|
||||||
{
|
{
|
||||||
|
partial_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -54,6 +54,7 @@ PACKAGE = \
|
|||||||
awpmd \
|
awpmd \
|
||||||
bocs \
|
bocs \
|
||||||
body \
|
body \
|
||||||
|
bpm \
|
||||||
brownian \
|
brownian \
|
||||||
cg-dna \
|
cg-dna \
|
||||||
cg-sdk \
|
cg-sdk \
|
||||||
@ -147,6 +148,7 @@ PACKMOST = \
|
|||||||
asphere \
|
asphere \
|
||||||
bocs \
|
bocs \
|
||||||
body \
|
body \
|
||||||
|
bpm \
|
||||||
brownian \
|
brownian \
|
||||||
cg-dna \
|
cg-dna \
|
||||||
cg-sdk \
|
cg-sdk \
|
||||||
|
|||||||
@ -578,7 +578,7 @@ void FixNeighHistoryOMP::post_neighbor()
|
|||||||
|
|
||||||
for (jj = 0; jj < jnum; jj++) {
|
for (jj = 0; jj < jnum; jj++) {
|
||||||
j = jlist[jj];
|
j = jlist[jj];
|
||||||
rflag = sbmask(j);
|
rflag = histmask(j);
|
||||||
j &= NEIGHMASK;
|
j &= NEIGHMASK;
|
||||||
jlist[jj] = j;
|
jlist[jj] = j;
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,10 @@
|
|||||||
#include "npair_half_size_bin_newtoff_omp.h"
|
#include "npair_half_size_bin_newtoff_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "npair_omp.h"
|
#include "npair_omp.h"
|
||||||
@ -40,8 +43,10 @@ NPairHalfSizeBinNewtoffOmp::NPairHalfSizeBinNewtoffOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
|
|
||||||
@ -50,7 +55,8 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutsq;
|
double radi,radsum,cutsq;
|
||||||
int *neighptr;
|
int *neighptr;
|
||||||
@ -61,7 +67,14 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -81,6 +94,11 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
|||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
ibin = atom2bin[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
|
// loop over all atoms in surrounding bins in stencil including self
|
||||||
// only store pair if i < j
|
// only store pair if i < j
|
||||||
@ -100,10 +118,23 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list)
|
|||||||
cutsq = (radsum+skin) * (radsum+skin);
|
cutsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutsq) {
|
if (rsq <= cutsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_bin_newton_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "npair_omp.h"
|
#include "npair_omp.h"
|
||||||
@ -39,8 +42,10 @@ NPairHalfSizeBinNewtonOmp::NPairHalfSizeBinNewtonOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
|
|
||||||
@ -49,7 +54,8 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutsq;
|
double radi,radsum,cutsq;
|
||||||
int *neighptr;
|
int *neighptr;
|
||||||
@ -58,7 +64,14 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -77,6 +90,11 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
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
|
// loop over rest of atoms in i's bin, ghosts are at end of linked list
|
||||||
// if j is owned atom, store it, since j is beyond i in linked list
|
// if j is 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);
|
cutsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutsq) {
|
if (rsq <= cutsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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);
|
cutsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutsq) {
|
if (rsq <= cutsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_bin_newton_tri_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "npair_omp.h"
|
#include "npair_omp.h"
|
||||||
@ -39,8 +42,10 @@ NPairHalfSizeBinNewtonTriOmp::NPairHalfSizeBinNewtonTriOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -48,7 +53,8 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutsq;
|
double radi,radsum,cutsq;
|
||||||
int *neighptr;
|
int *neighptr;
|
||||||
@ -59,7 +65,14 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -78,6 +91,11 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
|
if (moltemplate) {
|
||||||
|
imol = molindex[i];
|
||||||
|
iatom = molatom[i];
|
||||||
|
tagprev = tag[i] - iatom - 1;
|
||||||
|
}
|
||||||
|
|
||||||
// loop over all atoms in bins in stencil
|
// loop over all atoms in bins in stencil
|
||||||
// pairs for atoms j "below" i are excluded
|
// pairs for atoms j "below" i are excluded
|
||||||
@ -107,10 +125,23 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list)
|
|||||||
cutsq = (radsum+skin) * (radsum+skin);
|
cutsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutsq) {
|
if (rsq <= cutsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_multi_newtoff_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neighbor.h"
|
#include "neighbor.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
@ -41,8 +44,10 @@ NPairHalfSizeMultiNewtoffOmp::NPairHalfSizeMultiNewtoffOmp(LAMMPS *lmp) : NPair(
|
|||||||
void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -50,7 +55,9 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutdistsq;
|
double radi,radsum,cutdistsq;
|
||||||
int *neighptr,*s;
|
int *neighptr,*s;
|
||||||
@ -63,7 +70,14 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -84,6 +98,11 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
|
if (moltemplate) {
|
||||||
|
imol = molindex[i];
|
||||||
|
iatom = molatom[i];
|
||||||
|
tagprev = tag[i] - iatom - 1;
|
||||||
|
}
|
||||||
|
|
||||||
ibin = atom2bin[i];
|
ibin = atom2bin[i];
|
||||||
|
|
||||||
@ -119,10 +138,23 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list)
|
|||||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_multi_newton_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neighbor.h"
|
#include "neighbor.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
@ -40,8 +43,10 @@ NPairHalfSizeMultiNewtonOmp::NPairHalfSizeMultiNewtonOmp(LAMMPS *lmp) : NPair(lm
|
|||||||
void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -49,7 +54,9 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutdistsq;
|
double radi,radsum,cutdistsq;
|
||||||
int *neighptr,*s;
|
int *neighptr,*s;
|
||||||
@ -62,7 +69,14 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -83,6 +97,11 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
|
if (moltemplate) {
|
||||||
|
imol = molindex[i];
|
||||||
|
iatom = molatom[i];
|
||||||
|
tagprev = tag[i] - iatom - 1;
|
||||||
|
}
|
||||||
|
|
||||||
ibin = atom2bin[i];
|
ibin = atom2bin[i];
|
||||||
|
|
||||||
@ -129,10 +148,23 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list)
|
|||||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 (rsq <= cutdistsq) {
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
j = j ^ mask_history;
|
||||||
else
|
|
||||||
|
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;
|
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 "npair_half_size_multi_newton_tri_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neighbor.h"
|
#include "neighbor.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
@ -41,8 +44,10 @@ NPairHalfSizeMultiNewtonTriOmp::NPairHalfSizeMultiNewtonTriOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -50,7 +55,9 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutdistsq;
|
double radi,radsum,cutdistsq;
|
||||||
int *neighptr,*s;
|
int *neighptr,*s;
|
||||||
@ -63,7 +70,14 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -84,6 +98,11 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
|
if (moltemplate) {
|
||||||
|
imol = molindex[i];
|
||||||
|
iatom = molatom[i];
|
||||||
|
tagprev = tag[i] - iatom - 1;
|
||||||
|
}
|
||||||
|
|
||||||
ibin = atom2bin[i];
|
ibin = atom2bin[i];
|
||||||
|
|
||||||
@ -134,10 +153,23 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list)
|
|||||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_multi_old_newtoff_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "npair_omp.h"
|
#include "npair_omp.h"
|
||||||
@ -39,8 +43,10 @@ NPairHalfSizeMultiOldNewtoffOmp::NPairHalfSizeMultiOldNewtoffOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -48,7 +54,8 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutdistsq;
|
double radi,radsum,cutdistsq;
|
||||||
int *neighptr,*s;
|
int *neighptr,*s;
|
||||||
@ -58,7 +65,14 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -78,6 +92,11 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
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
|
// loop over all atoms in other bins in stencil including self
|
||||||
// only store pair if i < j
|
// only store pair if i < j
|
||||||
@ -106,10 +125,23 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list)
|
|||||||
cutdistsq = (radsum+skin) * (radsum+skin);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_multi_old_newton_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "npair_omp.h"
|
#include "npair_omp.h"
|
||||||
@ -39,8 +42,10 @@ NPairHalfSizeMultiOldNewtonOmp::NPairHalfSizeMultiOldNewtonOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -48,7 +53,8 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutdistsq;
|
double radi,radsum,cutdistsq;
|
||||||
int *neighptr,*s;
|
int *neighptr,*s;
|
||||||
@ -58,7 +64,14 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -78,6 +91,11 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
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
|
// loop over rest of atoms in i's bin, ghosts are at end of linked list
|
||||||
// if j is owned atom, store it, since j is beyond i in linked list
|
// if j is 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);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_multi_old_newton_tri_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
#include "npair_omp.h"
|
#include "npair_omp.h"
|
||||||
@ -39,8 +42,10 @@ NPairHalfSizeMultiOldNewtonTriOmp::NPairHalfSizeMultiOldNewtonTriOmp(LAMMPS *lmp
|
|||||||
void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
@ -48,7 +53,8 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutdistsq;
|
double radi,radsum,cutdistsq;
|
||||||
int *neighptr,*s;
|
int *neighptr,*s;
|
||||||
@ -58,7 +64,14 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
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 *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
@ -78,6 +91,11 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
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
|
// loop over all atoms in bins, including self, in stencil
|
||||||
// skip if i,j neighbor cutoff is less than bin distance
|
// 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);
|
cutdistsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutdistsq) {
|
if (rsq <= cutdistsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_nsq_newtoff_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
@ -42,8 +45,10 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
|||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
|
|
||||||
@ -52,7 +57,8 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutsq;
|
double radi,radsum,cutsq;
|
||||||
int *neighptr;
|
int *neighptr;
|
||||||
@ -61,9 +67,17 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
|||||||
double *radius = atom->radius;
|
double *radius = atom->radius;
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
tagint *molecule = atom->molecule;
|
tagint *molecule = atom->molecule;
|
||||||
|
tagint **special = atom->special;
|
||||||
|
int **nspecial = atom->nspecial;
|
||||||
|
|
||||||
int nall = atom->nlocal + atom->nghost;
|
int nall = atom->nlocal + atom->nghost;
|
||||||
|
|
||||||
|
int *molindex = atom->molindex;
|
||||||
|
int *molatom = atom->molatom;
|
||||||
|
Molecule **onemols = atom->avec->onemols;
|
||||||
|
|
||||||
int *ilist = list->ilist;
|
int *ilist = list->ilist;
|
||||||
int *numneigh = list->numneigh;
|
int *numneigh = list->numneigh;
|
||||||
int **firstneigh = list->firstneigh;
|
int **firstneigh = list->firstneigh;
|
||||||
@ -81,6 +95,11 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
|
if (moltemplate) {
|
||||||
|
imol = molindex[i];
|
||||||
|
iatom = molatom[i];
|
||||||
|
tagprev = tag[i] - iatom - 1;
|
||||||
|
}
|
||||||
|
|
||||||
// loop over remaining atoms, owned and ghost
|
// loop over remaining atoms, owned and ghost
|
||||||
|
|
||||||
@ -96,10 +115,23 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list)
|
|||||||
cutsq = (radsum+skin) * (radsum+skin);
|
cutsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutsq) {
|
if (rsq <= cutsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "npair_half_size_nsq_newton_omp.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "atom_vec.h"
|
||||||
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "molecule.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "my_page.h"
|
#include "my_page.h"
|
||||||
#include "neigh_list.h"
|
#include "neigh_list.h"
|
||||||
@ -42,9 +45,11 @@ NPairHalfSizeNsqNewtonOmp::NPairHalfSizeNsqNewtonOmp(LAMMPS *lmp) :
|
|||||||
void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
||||||
{
|
{
|
||||||
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
|
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 history = list->history;
|
||||||
const int mask_history = 3 << SBBITS;
|
const int mask_history = 1 << HISTBITS;
|
||||||
|
|
||||||
NPAIR_OMP_INIT;
|
NPAIR_OMP_INIT;
|
||||||
|
|
||||||
@ -53,7 +58,8 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
|||||||
#endif
|
#endif
|
||||||
NPAIR_OMP_SETUP(nlocal);
|
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 xtmp,ytmp,ztmp,delx,dely,delz,rsq;
|
||||||
double radi,radsum,cutsq;
|
double radi,radsum,cutsq;
|
||||||
int *neighptr;
|
int *neighptr;
|
||||||
@ -64,6 +70,13 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
|||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
tagint *molecule = atom->molecule;
|
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 nall = atom->nlocal + atom->nghost;
|
||||||
|
|
||||||
int *ilist = list->ilist;
|
int *ilist = list->ilist;
|
||||||
@ -84,6 +97,11 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
|||||||
ytmp = x[i][1];
|
ytmp = x[i][1];
|
||||||
ztmp = x[i][2];
|
ztmp = x[i][2];
|
||||||
radi = radius[i];
|
radi = radius[i];
|
||||||
|
if (moltemplate) {
|
||||||
|
imol = molindex[i];
|
||||||
|
iatom = molatom[i];
|
||||||
|
tagprev = tag[i] - iatom - 1;
|
||||||
|
}
|
||||||
|
|
||||||
// loop over remaining atoms, owned and ghost
|
// loop over remaining atoms, owned and ghost
|
||||||
|
|
||||||
@ -115,10 +133,23 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list)
|
|||||||
cutsq = (radsum+skin) * (radsum+skin);
|
cutsq = (radsum+skin) * (radsum+skin);
|
||||||
|
|
||||||
if (rsq <= cutsq) {
|
if (rsq <= cutsq) {
|
||||||
|
jh = j;
|
||||||
if (history && rsq < radsum*radsum)
|
if (history && rsq < radsum*radsum)
|
||||||
neighptr[n++] = j ^ mask_history;
|
jh = jh ^ mask_history;
|
||||||
else
|
|
||||||
neighptr[n++] = j;
|
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 "comm.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "fix_bond_history.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
@ -3093,6 +3094,10 @@ void FixBondReact::update_everything()
|
|||||||
// next let's update bond info
|
// next let's update bond info
|
||||||
// cool thing is, newton_bond issues are already taken care of in templates
|
// 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
|
// 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++) {
|
for (int i = 0; i < update_num_mega; i++) {
|
||||||
rxnID = update_mega_glove[0][i];
|
rxnID = update_mega_glove[0][i];
|
||||||
twomol = atom->molecules[reacted_mol[rxnID]];
|
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 (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
|
||||||
if (landlocked_atoms[j][rxnID] == 1) {
|
if (landlocked_atoms[j][rxnID] == 1) {
|
||||||
delta_bonds -= num_bond[atom->map(update_mega_glove[jj+1][i])];
|
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;
|
num_bond[atom->map(update_mega_glove[jj+1][i])] = 0;
|
||||||
}
|
}
|
||||||
if (landlocked_atoms[j][rxnID] == 0) {
|
if (landlocked_atoms[j][rxnID] == 0) {
|
||||||
@ -3109,10 +3122,21 @@ void FixBondReact::update_everything()
|
|||||||
for (int n = 0; n < twomol->natoms; n++) {
|
for (int n = 0; n < twomol->natoms; n++) {
|
||||||
int nn = equivalences[n][1][rxnID]-1;
|
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) {
|
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++) {
|
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_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];
|
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])]--;
|
num_bond[atom->map(update_mega_glove[jj+1][i])]--;
|
||||||
delta_bonds--;
|
delta_bonds--;
|
||||||
}
|
}
|
||||||
@ -3131,6 +3155,10 @@ void FixBondReact::update_everything()
|
|||||||
for (int p = 0; p < twomol->num_bond[j]; p++) {
|
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_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];
|
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) {
|
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])];
|
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_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];
|
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])]++;
|
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)
|
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");
|
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:
|
// Angles! First let's delete all angle info:
|
||||||
if (force->angle && twomol->angleflag) {
|
if (force->angle && twomol->angleflag) {
|
||||||
int *num_angle = atom->num_angle;
|
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;
|
omega = angmom = torque = nullptr;
|
||||||
radius = rmass = nullptr;
|
radius = rmass = nullptr;
|
||||||
ellipsoid = line = tri = body = nullptr;
|
ellipsoid = line = tri = body = nullptr;
|
||||||
|
quat = nullptr;
|
||||||
|
|
||||||
// molecular systems
|
// molecular systems
|
||||||
|
|
||||||
@ -426,6 +427,10 @@ void Atom::peratom_create()
|
|||||||
add_peratom("tri",&tri,INT,0);
|
add_peratom("tri",&tri,INT,0);
|
||||||
add_peratom("body",&body,INT,0);
|
add_peratom("body",&body,INT,0);
|
||||||
|
|
||||||
|
// BPM package
|
||||||
|
|
||||||
|
add_peratom("quat",&quat,DOUBLE,4);
|
||||||
|
|
||||||
// MOLECULE package
|
// MOLECULE package
|
||||||
|
|
||||||
add_peratom("molecule",&molecule,tagintsize,0);
|
add_peratom("molecule",&molecule,tagintsize,0);
|
||||||
@ -646,6 +651,7 @@ void Atom::set_atomflag_defaults()
|
|||||||
// identical list as 2nd customization in atom.h
|
// identical list as 2nd customization in atom.h
|
||||||
|
|
||||||
sphere_flag = ellipsoid_flag = line_flag = tri_flag = body_flag = 0;
|
sphere_flag = ellipsoid_flag = line_flag = tri_flag = body_flag = 0;
|
||||||
|
quat_flag = 0;
|
||||||
peri_flag = electron_flag = 0;
|
peri_flag = electron_flag = 0;
|
||||||
wavepacket_flag = sph_flag = 0;
|
wavepacket_flag = sph_flag = 0;
|
||||||
molecule_flag = molindex_flag = molatom_flag = 0;
|
molecule_flag = molindex_flag = molatom_flag = 0;
|
||||||
@ -1889,8 +1895,7 @@ void Atom::add_molecule(int narg, char **arg)
|
|||||||
int index = 1;
|
int index = 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
molecules = (Molecule **)
|
molecules = (Molecule **)
|
||||||
memory->srealloc(molecules,(nmolecule+1)*sizeof(Molecule *),
|
memory->srealloc(molecules,(nmolecule+1)*sizeof(Molecule *), "atom::molecules");
|
||||||
"atom::molecules");
|
|
||||||
molecules[nmolecule] = new Molecule(lmp,narg,arg,index);
|
molecules[nmolecule] = new Molecule(lmp,narg,arg,index);
|
||||||
molecules[nmolecule]->nset = 0;
|
molecules[nmolecule]->nset = 0;
|
||||||
molecules[nmolecule-ifile+1]->nset++;
|
molecules[nmolecule-ifile+1]->nset++;
|
||||||
@ -1920,8 +1925,7 @@ int Atom::find_molecule(char *id)
|
|||||||
called by fixes and commands that add molecules
|
called by fixes and commands that add molecules
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Atom::add_molecule_atom(Molecule *onemol, int iatom,
|
void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint offset)
|
||||||
int ilocal, tagint offset)
|
|
||||||
{
|
{
|
||||||
if (onemol->qflag && q_flag) q[ilocal] = onemol->q[iatom];
|
if (onemol->qflag && q_flag) q[ilocal] = onemol->q[iatom];
|
||||||
if (onemol->radiusflag && radius_flag) radius[ilocal] = onemol->radius[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);
|
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;
|
if (molecular != Atom::MOLECULAR) return;
|
||||||
|
|
||||||
// add bond topology info
|
// add bond topology info
|
||||||
@ -2614,6 +2631,10 @@ length of the data area, and a short description.
|
|||||||
- int
|
- int
|
||||||
- 1
|
- 1
|
||||||
- 1 if the particle is a body particle, 0 if not
|
- 1 if the particle is a body particle, 0 if not
|
||||||
|
* - quat
|
||||||
|
- double
|
||||||
|
- 4
|
||||||
|
- four quaternion components of the particles
|
||||||
* - i_name
|
* - i_name
|
||||||
- int
|
- int
|
||||||
- 1
|
- 1
|
||||||
@ -2669,6 +2690,7 @@ void *Atom::extract(const char *name)
|
|||||||
if (strcmp(name,"line") == 0) return (void *) line;
|
if (strcmp(name,"line") == 0) return (void *) line;
|
||||||
if (strcmp(name,"tri") == 0) return (void *) tri;
|
if (strcmp(name,"tri") == 0) return (void *) tri;
|
||||||
if (strcmp(name,"body") == 0) return (void *) body;
|
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,"vfrac") == 0) return (void *) vfrac;
|
||||||
if (strcmp(name,"s0") == 0) return (void *) s0;
|
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,"line") == 0) return LAMMPS_INT;
|
||||||
if (strcmp(name,"tri") == 0) return LAMMPS_INT;
|
if (strcmp(name,"tri") == 0) return LAMMPS_INT;
|
||||||
if (strcmp(name,"body") == 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,"vfrac") == 0) return LAMMPS_DOUBLE;
|
||||||
if (strcmp(name,"s0") == 0) return LAMMPS_DOUBLE;
|
if (strcmp(name,"s0") == 0) return LAMMPS_DOUBLE;
|
||||||
|
|||||||
@ -79,6 +79,7 @@ class Atom : protected Pointers {
|
|||||||
double *radius;
|
double *radius;
|
||||||
double **omega, **angmom, **torque;
|
double **omega, **angmom, **torque;
|
||||||
int *ellipsoid, *line, *tri, *body;
|
int *ellipsoid, *line, *tri, *body;
|
||||||
|
double **quat;
|
||||||
|
|
||||||
// molecular systems
|
// molecular systems
|
||||||
|
|
||||||
@ -180,7 +181,7 @@ class Atom : protected Pointers {
|
|||||||
|
|
||||||
int molecule_flag, molindex_flag, molatom_flag;
|
int molecule_flag, molindex_flag, molatom_flag;
|
||||||
int q_flag, mu_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 vfrac_flag, spin_flag, eradius_flag, ervel_flag, erforce_flag;
|
||||||
int cs_flag, csforce_flag, vforce_flag, ervelforce_flag, etag_flag;
|
int cs_flag, csforce_flag, vforce_flag, ervelforce_flag, etag_flag;
|
||||||
int rho_flag, esph_flag, cv_flag, vest_flag;
|
int rho_flag, esph_flag, cv_flag, vest_flag;
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
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.
|
the GNU General Public License.
|
||||||
|
|
||||||
See the README file in the top-level LAMMPS directory.
|
See the README file in the top-level LAMMPS directory.
|
||||||
|
|||||||
@ -27,6 +27,10 @@ using namespace LAMMPS_NS;
|
|||||||
|
|
||||||
enum { NONE, LINEAR, SPLINE };
|
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
|
set bond contribution to Vdwl energy to 0.0
|
||||||
a particular bond style can override this
|
a particular bond style can override this
|
||||||
@ -34,12 +38,17 @@ enum { NONE, LINEAR, SPLINE };
|
|||||||
|
|
||||||
Bond::Bond(LAMMPS *_lmp) : Pointers(_lmp)
|
Bond::Bond(LAMMPS *_lmp) : Pointers(_lmp)
|
||||||
{
|
{
|
||||||
|
instance_me = instance_total++;
|
||||||
|
|
||||||
energy = 0.0;
|
energy = 0.0;
|
||||||
virial[0] = virial[1] = virial[2] = virial[3] = virial[4] = virial[5] = 0.0;
|
virial[0] = virial[1] = virial[2] = virial[3] = virial[4] = virial[5] = 0.0;
|
||||||
writedata = 1;
|
writedata = 1;
|
||||||
|
|
||||||
|
comm_forward = comm_reverse = comm_reverse_off = 0;
|
||||||
|
|
||||||
allocated = 0;
|
allocated = 0;
|
||||||
suffix_flag = Suffix::NONE;
|
suffix_flag = Suffix::NONE;
|
||||||
|
partial_flag = 0;
|
||||||
|
|
||||||
maxeatom = maxvatom = 0;
|
maxeatom = maxvatom = 0;
|
||||||
eatom = nullptr;
|
eatom = nullptr;
|
||||||
|
|||||||
12
src/bond.h
12
src/bond.h
@ -23,13 +23,20 @@ class Bond : protected Pointers {
|
|||||||
friend class FixOMP;
|
friend class FixOMP;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static int instance_total; // # of Bond classes ever instantiated
|
||||||
|
|
||||||
int allocated;
|
int allocated;
|
||||||
int *setflag;
|
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
|
int writedata; // 1 if writes coeffs to data file
|
||||||
double energy; // accumulated energies
|
double energy; // accumulated energies
|
||||||
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
||||||
double *eatom, **vatom; // accumulated per-atom energy/virial
|
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
|
int reinitflag; // 1 if compatible with fix adapt and alike
|
||||||
|
|
||||||
// KOKKOS host/device flag and data masks
|
// KOKKOS host/device flag and data masks
|
||||||
@ -55,10 +62,15 @@ class Bond : protected Pointers {
|
|||||||
virtual double memory_usage();
|
virtual double memory_usage();
|
||||||
virtual void *extract(const char *, int &) { return nullptr; }
|
virtual void *extract(const char *, int &) { return nullptr; }
|
||||||
virtual void reinit();
|
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 **);
|
void write_file(int, char **);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
int instance_me; // which Bond class instantiation I am
|
||||||
int suffix_flag; // suffix compatibility flag
|
int suffix_flag; // suffix compatibility flag
|
||||||
|
|
||||||
int evflag;
|
int evflag;
|
||||||
|
|||||||
@ -218,6 +218,9 @@ void Comm::init()
|
|||||||
if (force->pair) maxforward = MAX(maxforward,force->pair->comm_forward);
|
if (force->pair) maxforward = MAX(maxforward,force->pair->comm_forward);
|
||||||
if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse);
|
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) {
|
for (const auto &fix : fix_list) {
|
||||||
maxforward = MAX(maxforward,fix->comm_forward);
|
maxforward = MAX(maxforward,fix->comm_forward);
|
||||||
maxreverse = MAX(maxreverse,fix->comm_reverse);
|
maxreverse = MAX(maxreverse,fix->comm_reverse);
|
||||||
@ -235,6 +238,7 @@ void Comm::init()
|
|||||||
|
|
||||||
if (force->newton == 0) maxreverse = 0;
|
if (force->newton == 0) maxreverse = 0;
|
||||||
if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse_off);
|
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
|
// maxexchange_atom = size of an exchanged atom, set by AtomVec
|
||||||
// only needs to be set if size > BUFEXTRA
|
// 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 exchange() = 0; // move atoms to new procs
|
||||||
virtual void borders() = 0; // setup list of atoms to comm
|
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 forward_comm(class Pair *) = 0;
|
||||||
virtual void reverse_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 forward_comm(class Fix *, int size = 0) = 0;
|
||||||
virtual void reverse_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;
|
virtual void reverse_comm_variable(class Fix *) = 0;
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
#include "atom_vec.h"
|
#include "atom_vec.h"
|
||||||
|
#include "bond.h"
|
||||||
#include "compute.h"
|
#include "compute.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "dump.h"
|
#include "dump.h"
|
||||||
@ -490,8 +491,7 @@ void CommBrick::setup()
|
|||||||
return how many procs away are needed to encompass cutghost away from loc
|
return how many procs away are needed to encompass cutghost away from loc
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int CommBrick::updown(int dim, int dir, int loc,
|
int CommBrick::updown(int dim, int dir, int loc, double prd, int periodicity, double *split)
|
||||||
double prd, int periodicity, double *split)
|
|
||||||
{
|
{
|
||||||
int index,count;
|
int index,count;
|
||||||
double frac,delta;
|
double frac,delta;
|
||||||
@ -552,19 +552,15 @@ void CommBrick::forward_comm(int /*dummy*/)
|
|||||||
if (comm_x_only) {
|
if (comm_x_only) {
|
||||||
if (size_forward_recv[iswap]) {
|
if (size_forward_recv[iswap]) {
|
||||||
buf = x[firstrecv[iswap]];
|
buf = x[firstrecv[iswap]];
|
||||||
MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE,
|
MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
recvproc[iswap],0,world,&request);
|
|
||||||
}
|
}
|
||||||
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
|
||||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
} else if (ghost_velocity) {
|
} else if (ghost_velocity) {
|
||||||
if (size_forward_recv[iswap])
|
if (size_forward_recv[iswap])
|
||||||
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
|
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
recvproc[iswap],0,world,&request);
|
n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
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 (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_recv);
|
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])
|
if (size_forward_recv[iswap])
|
||||||
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
|
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
|
||||||
recvproc[iswap],0,world,&request);
|
recvproc[iswap],0,world,&request);
|
||||||
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
|
||||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_recv);
|
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],
|
avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
||||||
x[firstrecv[iswap]],pbc_flag[iswap],pbc[iswap]);
|
x[firstrecv[iswap]],pbc_flag[iswap],pbc[iswap]);
|
||||||
} else if (ghost_velocity) {
|
} else if (ghost_velocity) {
|
||||||
avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],
|
avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
|
||||||
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_send);
|
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||||
} else {
|
} else {
|
||||||
avec->pack_comm(sendnum[iswap],sendlist[iswap],
|
avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
|
||||||
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_send);
|
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,18 +611,15 @@ void CommBrick::reverse_comm()
|
|||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (comm_f_only) {
|
if (comm_f_only) {
|
||||||
if (size_reverse_recv[iswap])
|
if (size_reverse_recv[iswap])
|
||||||
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,
|
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
sendproc[iswap],0,world,&request);
|
|
||||||
if (size_reverse_send[iswap]) {
|
if (size_reverse_send[iswap]) {
|
||||||
buf = f[firstrecv[iswap]];
|
buf = f[firstrecv[iswap]];
|
||||||
MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE,
|
MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE,recvproc[iswap],0,world);
|
||||||
recvproc[iswap],0,world);
|
|
||||||
}
|
}
|
||||||
if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
} else {
|
} else {
|
||||||
if (size_reverse_recv[iswap])
|
if (size_reverse_recv[iswap])
|
||||||
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,
|
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
sendproc[iswap],0,world,&request);
|
|
||||||
n = avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
|
n = avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||||
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
if (n) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||||
if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
@ -639,8 +629,7 @@ void CommBrick::reverse_comm()
|
|||||||
} else {
|
} else {
|
||||||
if (comm_f_only) {
|
if (comm_f_only) {
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],
|
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],f[firstrecv[iswap]]);
|
||||||
f[firstrecv[iswap]]);
|
|
||||||
} else {
|
} else {
|
||||||
avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
|
avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
|
||||||
avec->unpack_reverse(sendnum[iswap],sendlist[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;
|
if (procgrid[dim] == 1) nrecv = 0;
|
||||||
else {
|
else {
|
||||||
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0,
|
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0,
|
||||||
&nrecv1,1,MPI_INT,procneigh[dim][1],0,world,
|
&nrecv1,1,MPI_INT,procneigh[dim][1],0,world,MPI_STATUS_IGNORE);
|
||||||
MPI_STATUS_IGNORE);
|
|
||||||
nrecv = nrecv1;
|
nrecv = nrecv1;
|
||||||
if (procgrid[dim] > 2) {
|
if (procgrid[dim] > 2) {
|
||||||
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
|
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
|
||||||
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,
|
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE);
|
||||||
MPI_STATUS_IGNORE);
|
|
||||||
nrecv += nrecv2;
|
nrecv += nrecv2;
|
||||||
}
|
}
|
||||||
if (nrecv > maxrecv) grow_recv(nrecv);
|
if (nrecv > maxrecv) grow_recv(nrecv);
|
||||||
|
|
||||||
MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,
|
MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request);
|
||||||
world,&request);
|
|
||||||
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
|
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
|
||||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
|
|
||||||
if (procgrid[dim] > 2) {
|
if (procgrid[dim] > 2) {
|
||||||
MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,
|
MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request);
|
||||||
world,&request);
|
|
||||||
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
|
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
|
||||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
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 (nsend*size_border > maxsend) grow_send(nsend*size_border,0);
|
||||||
if (ghost_velocity)
|
if (ghost_velocity)
|
||||||
n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send,
|
n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
pbc_flag[iswap],pbc[iswap]);
|
|
||||||
else
|
else
|
||||||
n = avec->pack_border(nsend,sendlist[iswap],buf_send,
|
n = avec->pack_border(nsend,sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
pbc_flag[iswap],pbc[iswap]);
|
|
||||||
|
|
||||||
// swap atoms with other proc
|
// swap atoms with other proc
|
||||||
// no MPI calls except SendRecv if nsend/nrecv = 0
|
// no MPI calls except SendRecv if nsend/nrecv = 0
|
||||||
@ -938,8 +921,7 @@ void CommBrick::borders()
|
|||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
MPI_Sendrecv(&nsend,1,MPI_INT,sendproc[iswap],0,
|
MPI_Sendrecv(&nsend,1,MPI_INT,sendproc[iswap],0,
|
||||||
&nrecv,1,MPI_INT,recvproc[iswap],0,world,
|
&nrecv,1,MPI_INT,recvproc[iswap],0,world,MPI_STATUS_IGNORE);
|
||||||
MPI_STATUS_IGNORE);
|
|
||||||
if (nrecv*size_border > maxrecv) grow_recv(nrecv*size_border);
|
if (nrecv*size_border > maxrecv) grow_recv(nrecv*size_border);
|
||||||
if (nrecv) MPI_Irecv(buf_recv,nrecv*size_border,MPI_DOUBLE,
|
if (nrecv) MPI_Irecv(buf_recv,nrecv*size_border,MPI_DOUBLE,
|
||||||
recvproc[iswap],0,world,&request);
|
recvproc[iswap],0,world,&request);
|
||||||
@ -1013,16 +995,14 @@ void CommBrick::forward_comm(Pair *pair)
|
|||||||
|
|
||||||
// pack buffer
|
// pack buffer
|
||||||
|
|
||||||
n = pair->pack_forward_comm(sendnum[iswap],sendlist[iswap],
|
n = pair->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
|
||||||
|
|
||||||
// exchange with another proc
|
// exchange with another proc
|
||||||
// if self, set recv buffer to send buffer
|
// if self, set recv buffer to send buffer
|
||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,
|
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
recvproc[iswap],0,world,&request);
|
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
@ -1059,8 +1039,7 @@ void CommBrick::reverse_comm(Pair *pair)
|
|||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
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
|
forward communication invoked by a Fix
|
||||||
size/nsize used only to set recv buffer limit
|
size/nsize used only to set recv buffer limit
|
||||||
@ -1095,16 +1148,14 @@ void CommBrick::forward_comm(Fix *fix, int size)
|
|||||||
|
|
||||||
// pack buffer
|
// pack buffer
|
||||||
|
|
||||||
n = fix->pack_forward_comm(sendnum[iswap],sendlist[iswap],
|
n = fix->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]);
|
||||||
buf_send,pbc_flag[iswap],pbc[iswap]);
|
|
||||||
|
|
||||||
// exchange with another proc
|
// exchange with another proc
|
||||||
// if self, set recv buffer to send buffer
|
// if self, set recv buffer to send buffer
|
||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
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 (sendproc[iswap] != me) {
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
@ -1185,13 +1235,11 @@ void CommBrick::reverse_comm_variable(Fix *fix)
|
|||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
MPI_Sendrecv(&nsend,1,MPI_INT,recvproc[iswap],0,
|
MPI_Sendrecv(&nsend,1,MPI_INT,recvproc[iswap],0,
|
||||||
&nrecv,1,MPI_INT,sendproc[iswap],0,world,
|
&nrecv,1,MPI_INT,sendproc[iswap],0,world,MPI_STATUS_IGNORE);
|
||||||
MPI_STATUS_IGNORE);
|
|
||||||
|
|
||||||
if (sendnum[iswap]) {
|
if (sendnum[iswap]) {
|
||||||
if (nrecv > maxrecv) grow_recv(nrecv);
|
if (nrecv > maxrecv) grow_recv(nrecv);
|
||||||
MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0,
|
MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
}
|
}
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world);
|
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 (sendproc[iswap] != me) {
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
@ -1268,8 +1315,7 @@ void CommBrick::reverse_comm(Compute *compute)
|
|||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
@ -1307,8 +1353,7 @@ void CommBrick::forward_comm(Dump *dump)
|
|||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
@ -1345,8 +1390,7 @@ void CommBrick::reverse_comm(Dump *dump)
|
|||||||
|
|
||||||
if (sendproc[iswap] != me) {
|
if (sendproc[iswap] != me) {
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
|
||||||
if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
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 (sendproc[iswap] != me) {
|
||||||
if (recvnum[iswap])
|
if (recvnum[iswap])
|
||||||
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
|
MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request);
|
||||||
world,&request);
|
|
||||||
if (sendnum[iswap])
|
if (sendnum[iswap])
|
||||||
MPI_Send(buf_send,nsize*sendnum[iswap],MPI_DOUBLE,
|
MPI_Send(buf_send,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world);
|
||||||
sendproc[iswap],0,world);
|
|
||||||
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
buf = buf_recv;
|
buf = buf_recv;
|
||||||
} else buf = buf_send;
|
} else buf = buf_send;
|
||||||
@ -1444,21 +1486,18 @@ int CommBrick::exchange_variable(int n, double *inbuf, double *&outbuf)
|
|||||||
nrecv += nrecv1;
|
nrecv += nrecv1;
|
||||||
if (procgrid[dim] > 2) {
|
if (procgrid[dim] > 2) {
|
||||||
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
|
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
|
||||||
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,
|
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE);
|
||||||
MPI_STATUS_IGNORE);
|
|
||||||
nrecv += nrecv2;
|
nrecv += nrecv2;
|
||||||
} else nrecv2 = 0;
|
} else nrecv2 = 0;
|
||||||
|
|
||||||
if (nrecv > maxrecv) grow_recv(nrecv);
|
if (nrecv > maxrecv) grow_recv(nrecv);
|
||||||
|
|
||||||
MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0,
|
MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request);
|
||||||
world,&request);
|
|
||||||
MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
|
MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
|
||||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
|
|
||||||
if (procgrid[dim] > 2) {
|
if (procgrid[dim] > 2) {
|
||||||
MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,
|
MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request);
|
||||||
world,&request);
|
|
||||||
MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
|
MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
|
||||||
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ class CommBrick : public Comm {
|
|||||||
public:
|
public:
|
||||||
CommBrick(class LAMMPS *);
|
CommBrick(class LAMMPS *);
|
||||||
CommBrick(class LAMMPS *, class Comm *);
|
CommBrick(class LAMMPS *, class Comm *);
|
||||||
|
|
||||||
~CommBrick() override;
|
~CommBrick() override;
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
@ -33,6 +34,8 @@ class CommBrick : public Comm {
|
|||||||
|
|
||||||
void forward_comm(class Pair *) override; // forward comm from a Pair
|
void forward_comm(class Pair *) override; // forward comm from a Pair
|
||||||
void reverse_comm(class Pair *) override; // reverse 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 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(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
|
void reverse_comm_variable(class Fix *) override; // variable size reverse comm from a Fix
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
#include "atom_vec.h"
|
#include "atom_vec.h"
|
||||||
|
#include "bond.h"
|
||||||
#include "compute.h"
|
#include "compute.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "dump.h"
|
#include "dump.h"
|
||||||
@ -512,16 +513,14 @@ void CommTiled::setup()
|
|||||||
MIN(sbox_multi[3+idim]+cutghostmulti[icollection][idim],subhi[idim]);
|
MIN(sbox_multi[3+idim]+cutghostmulti[icollection][idim],subhi[idim]);
|
||||||
else
|
else
|
||||||
sbox_multi[3+idim] =
|
sbox_multi[3+idim] =
|
||||||
MIN(sbox_multi[3+idim]-prd[idim]+cutghostmulti[icollection][idim],
|
MIN(sbox_multi[3+idim]-prd[idim]+cutghostmulti[icollection][idim],subhi[idim]);
|
||||||
subhi[idim]);
|
|
||||||
} else {
|
} else {
|
||||||
if (i < noverlap1)
|
if (i < noverlap1)
|
||||||
sbox_multi[idim] =
|
sbox_multi[idim] =
|
||||||
MAX(sbox_multi[idim]-cutghostmulti[icollection][idim],sublo[idim]);
|
MAX(sbox_multi[idim]-cutghostmulti[icollection][idim],sublo[idim]);
|
||||||
else
|
else
|
||||||
sbox_multi[idim] =
|
sbox_multi[idim] =
|
||||||
MAX(sbox_multi[idim]+prd[idim]-cutghostmulti[icollection][idim],
|
MAX(sbox_multi[idim]+prd[idim]-cutghostmulti[icollection][idim],sublo[idim]);
|
||||||
sublo[idim]);
|
|
||||||
sbox_multi[3+idim] = subhi[idim];
|
sbox_multi[3+idim] = subhi[idim];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,16 +587,14 @@ void CommTiled::setup()
|
|||||||
MIN(sbox_multiold[3+idim]+cutghostmultiold[itype][idim],subhi[idim]);
|
MIN(sbox_multiold[3+idim]+cutghostmultiold[itype][idim],subhi[idim]);
|
||||||
else
|
else
|
||||||
sbox_multiold[3+idim] =
|
sbox_multiold[3+idim] =
|
||||||
MIN(sbox_multiold[3+idim]-prd[idim]+cutghostmultiold[itype][idim],
|
MIN(sbox_multiold[3+idim]-prd[idim]+cutghostmultiold[itype][idim],subhi[idim]);
|
||||||
subhi[idim]);
|
|
||||||
} else {
|
} else {
|
||||||
if (i < noverlap1)
|
if (i < noverlap1)
|
||||||
sbox_multiold[idim] =
|
sbox_multiold[idim] =
|
||||||
MAX(sbox_multiold[idim]-cutghostmultiold[itype][idim],sublo[idim]);
|
MAX(sbox_multiold[idim]-cutghostmultiold[itype][idim],sublo[idim]);
|
||||||
else
|
else
|
||||||
sbox_multiold[idim] =
|
sbox_multiold[idim] =
|
||||||
MAX(sbox_multiold[idim]+prd[idim]-cutghostmultiold[itype][idim],
|
MAX(sbox_multiold[idim]+prd[idim]-cutghostmultiold[itype][idim],sublo[idim]);
|
||||||
sublo[idim]);
|
|
||||||
sbox_multiold[3+idim] = subhi[idim];
|
sbox_multiold[3+idim] = subhi[idim];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,8 +744,7 @@ void CommTiled::forward_comm(int /*dummy*/)
|
|||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
x[firstrecv[iswap][nrecv]],pbc_flag[iswap][nsend],
|
x[firstrecv[iswap][nrecv]],pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
pbc[iswap][nsend]);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) MPI_Waitall(nrecv,requests,MPI_STATUS_IGNORE);
|
if (recvother[iswap]) MPI_Waitall(nrecv,requests,MPI_STATUS_IGNORE);
|
||||||
|
|
||||||
@ -756,8 +752,7 @@ void CommTiled::forward_comm(int /*dummy*/)
|
|||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]],
|
||||||
size_forward_recv[iswap][i],
|
size_forward_recv[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
@ -769,15 +764,13 @@ void CommTiled::forward_comm(int /*dummy*/)
|
|||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
avec->pack_comm_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
avec->pack_comm_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
avec->unpack_comm_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
avec->unpack_comm_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_comm_vel(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
avec->unpack_comm_vel(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||||
&buf_recv[size_forward*
|
&buf_recv[size_forward*forward_recv_offset[iswap][irecv]]);
|
||||||
forward_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,8 +778,7 @@ void CommTiled::forward_comm(int /*dummy*/)
|
|||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]],
|
||||||
size_forward_recv[iswap][i],
|
size_forward_recv[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
@ -798,15 +790,13 @@ void CommTiled::forward_comm(int /*dummy*/)
|
|||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
avec->pack_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]);
|
||||||
avec->unpack_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
avec->unpack_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
avec->unpack_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||||
&buf_recv[size_forward*
|
&buf_recv[size_forward*forward_recv_offset[iswap][irecv]]);
|
||||||
forward_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -839,8 +829,7 @@ void CommTiled::reverse_comm()
|
|||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]],
|
||||||
size_reverse_recv[iswap][i],MPI_DOUBLE,
|
size_reverse_recv[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||||
sendproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
@ -856,8 +845,7 @@ void CommTiled::reverse_comm()
|
|||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||||
&buf_recv[size_reverse*
|
&buf_recv[size_reverse*reverse_recv_offset[iswap][irecv]]);
|
||||||
reverse_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,28 +853,23 @@ void CommTiled::reverse_comm()
|
|||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++)
|
for (i = 0; i < nsend; i++)
|
||||||
MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]],
|
||||||
size_reverse_recv[iswap][i],MPI_DOUBLE,
|
size_reverse_recv[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||||
sendproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
n = avec->pack_reverse(recvnum[iswap][i],firstrecv[iswap][i],
|
n = avec->pack_reverse(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||||
buf_send);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
avec->pack_reverse(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
avec->pack_reverse(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
avec->unpack_reverse(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||||
avec->unpack_reverse(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||||
&buf_recv[size_reverse*
|
&buf_recv[size_reverse*reverse_recv_offset[iswap][irecv]]);
|
||||||
reverse_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -989,8 +972,7 @@ void CommTiled::exchange()
|
|||||||
if (!nexch) continue;
|
if (!nexch) continue;
|
||||||
|
|
||||||
for (m = 0; m < nexch; m++)
|
for (m = 0; m < nexch; m++)
|
||||||
MPI_Irecv(&exchnum[dim][m],1,MPI_INT,
|
MPI_Irecv(&exchnum[dim][m],1,MPI_INT,exchproc[dim][m],0,world,&requests[m]);
|
||||||
exchproc[dim][m],0,world,&requests[m]);
|
|
||||||
for (m = 0; m < nexch; m++)
|
for (m = 0; m < nexch; m++)
|
||||||
MPI_Send(&nsend,1,MPI_INT,exchproc[dim][m],0,world);
|
MPI_Send(&nsend,1,MPI_INT,exchproc[dim][m],0,world);
|
||||||
MPI_Waitall(nexch,requests,MPI_STATUS_IGNORE);
|
MPI_Waitall(nexch,requests,MPI_STATUS_IGNORE);
|
||||||
@ -1001,8 +983,7 @@ void CommTiled::exchange()
|
|||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for (m = 0; m < nexch; m++) {
|
for (m = 0; m < nexch; m++) {
|
||||||
MPI_Irecv(&buf_recv[offset],exchnum[dim][m],
|
MPI_Irecv(&buf_recv[offset],exchnum[dim][m],MPI_DOUBLE,exchproc[dim][m],0,world,&requests[m]);
|
||||||
MPI_DOUBLE,exchproc[dim][m],0,world,&requests[m]);
|
|
||||||
offset += exchnum[dim][m];
|
offset += exchnum[dim][m];
|
||||||
}
|
}
|
||||||
for (m = 0; m < nexch; m++)
|
for (m = 0; m < nexch; m++)
|
||||||
@ -1233,8 +1214,7 @@ void CommTiled::borders()
|
|||||||
|
|
||||||
if (recvother[iswap])
|
if (recvother[iswap])
|
||||||
for (m = 0; m < nrecv; m++)
|
for (m = 0; m < nrecv; m++)
|
||||||
MPI_Irecv(&recvnum[iswap][m],1,MPI_INT,
|
MPI_Irecv(&recvnum[iswap][m],1,MPI_INT,recvproc[iswap][m],0,world,&requests[m]);
|
||||||
recvproc[iswap][m],0,world,&requests[m]);
|
|
||||||
if (sendother[iswap])
|
if (sendother[iswap])
|
||||||
for (m = 0; m < nsend; m++)
|
for (m = 0; m < nsend; m++)
|
||||||
MPI_Send(&sendnum[iswap][m],1,MPI_INT,sendproc[iswap][m],0,world);
|
MPI_Send(&sendnum[iswap][m],1,MPI_INT,sendproc[iswap][m],0,world);
|
||||||
@ -1294,17 +1274,14 @@ void CommTiled::borders()
|
|||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
avec->pack_border_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
avec->pack_border_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
pbc[iswap][nsend]);
|
avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_border_vel(recvnum[iswap][m],firstrecv[iswap][m],
|
avec->unpack_border_vel(recvnum[iswap][m],firstrecv[iswap][m],
|
||||||
&buf_recv[size_border*
|
&buf_recv[size_border*forward_recv_offset[iswap][m]]);
|
||||||
forward_recv_offset[iswap][m]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1325,15 +1302,13 @@ void CommTiled::borders()
|
|||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
avec->pack_border(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
avec->pack_border(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
||||||
avec->unpack_border(recvnum[iswap][m],firstrecv[iswap][m],
|
avec->unpack_border(recvnum[iswap][m],firstrecv[iswap][m],
|
||||||
&buf_recv[size_border*
|
&buf_recv[size_border*forward_recv_offset[iswap][m]]);
|
||||||
forward_recv_offset[iswap][m]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1351,10 +1326,8 @@ void CommTiled::borders()
|
|||||||
// For molecular systems we lose some bits for local atom indices due
|
// For molecular systems we lose some bits for local atom indices due
|
||||||
// to encoding of special pairs in neighbor lists. Check for overflows.
|
// to encoding of special pairs in neighbor lists. Check for overflows.
|
||||||
|
|
||||||
if ((atom->molecular != Atom::ATOMIC)
|
if ((atom->molecular != Atom::ATOMIC) && ((atom->nlocal + atom->nghost) > NEIGHMASK))
|
||||||
&& ((atom->nlocal + atom->nghost) > NEIGHMASK))
|
error->one(FLERR,"Per-processor number of atoms is too large for molecular neighbor lists");
|
||||||
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
|
// insure send/recv buffers are long enough for all forward & reverse comm
|
||||||
// send buf is for one forward or reverse sends to one proc
|
// 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]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||||
nsize*recvnum[iswap][i],
|
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
@ -1402,17 +1374,14 @@ void CommTiled::forward_comm(Pair *pair)
|
|||||||
|
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
pair->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
pair->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
pbc[iswap][nsend]);
|
pair->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
pair->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
pair->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
pair->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||||
forward_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1436,28 +1405,107 @@ void CommTiled::reverse_comm(Pair *pair)
|
|||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++)
|
for (i = 0; i < nsend; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||||
sendproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
n = pair->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
n = pair->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||||
buf_send);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
pair->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
pair->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
pair->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||||
pair->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
pair->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
pair->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||||
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]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||||
nsize*recvnum[iswap][i],
|
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
@ -1498,17 +1545,14 @@ void CommTiled::forward_comm(Fix *fix, int size)
|
|||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
fix->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
fix->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
pbc[iswap][nsend]);
|
fix->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
fix->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
fix->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
fix->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||||
forward_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1537,28 +1581,23 @@ void CommTiled::reverse_comm(Fix *fix, int size)
|
|||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++)
|
for (i = 0; i < nsend; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||||
sendproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
n = fix->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
n = fix->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||||
buf_send);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
fix->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
fix->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
fix->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||||
fix->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
fix->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
fix->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||||
reverse_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1594,31 +1633,26 @@ void CommTiled::forward_comm(Compute *compute)
|
|||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||||
nsize*recvnum[iswap][i],
|
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
n = compute->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
n = compute->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
||||||
buf_send,pbc_flag[iswap][i],
|
buf_send,pbc_flag[iswap][i],pbc[iswap][i]);
|
||||||
pbc[iswap][i]);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
compute->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
compute->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
pbc[iswap][nsend]);
|
compute->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
compute->unpack_forward_comm(recvnum[iswap][nrecv],
|
|
||||||
firstrecv[iswap][nrecv],buf_send);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
compute->
|
compute->
|
||||||
unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||||
forward_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1642,29 +1676,24 @@ void CommTiled::reverse_comm(Compute *compute)
|
|||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++)
|
for (i = 0; i < nsend; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||||
sendproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
n = compute->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
n = compute->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||||
buf_send);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
compute->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
compute->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
compute->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||||
compute->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
compute->
|
compute->
|
||||||
unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||||
reverse_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1688,21 +1717,18 @@ void CommTiled::forward_comm(Dump *dump)
|
|||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||||
nsize*recvnum[iswap][i],
|
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
n = dump->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
n = dump->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i],
|
||||||
buf_send,pbc_flag[iswap][i],
|
buf_send,pbc_flag[iswap][i],pbc[iswap][i]);
|
||||||
pbc[iswap][i]);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
dump->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
dump->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
||||||
buf_send,pbc_flag[iswap][nsend],
|
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
|
||||||
pbc[iswap][nsend]);
|
|
||||||
dump->unpack_forward_comm(recvnum[iswap][nrecv],
|
dump->unpack_forward_comm(recvnum[iswap][nrecv],
|
||||||
firstrecv[iswap][nrecv],buf_send);
|
firstrecv[iswap][nrecv],buf_send);
|
||||||
}
|
}
|
||||||
@ -1710,8 +1736,7 @@ void CommTiled::forward_comm(Dump *dump)
|
|||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
dump->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
dump->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*forward_recv_offset[iswap][irecv]]);
|
||||||
forward_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1735,28 +1760,23 @@ void CommTiled::reverse_comm(Dump *dump)
|
|||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++)
|
for (i = 0; i < nsend; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]],
|
||||||
nsize*sendnum[iswap][i],MPI_DOUBLE,
|
nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]);
|
||||||
sendproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++) {
|
for (i = 0; i < nrecv; i++) {
|
||||||
n = dump->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],
|
n = dump->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send);
|
||||||
buf_send);
|
|
||||||
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
if (sendself[iswap]) {
|
||||||
dump->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
|
dump->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send);
|
||||||
buf_send);
|
dump->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send);
|
||||||
dump->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],
|
|
||||||
buf_send);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
for (i = 0; i < nsend; i++) {
|
||||||
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE);
|
||||||
dump->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
dump->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv],
|
||||||
&buf_recv[nsize*
|
&buf_recv[nsize*reverse_recv_offset[iswap][irecv]]);
|
||||||
reverse_recv_offset[iswap][irecv]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1788,8 +1808,7 @@ void CommTiled::forward_comm_array(int nsize, double **array)
|
|||||||
if (recvother[iswap]) {
|
if (recvother[iswap]) {
|
||||||
for (i = 0; i < nrecv; i++)
|
for (i = 0; i < nrecv; i++)
|
||||||
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]],
|
||||||
nsize*recvnum[iswap][i],
|
nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
||||||
MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]);
|
|
||||||
}
|
}
|
||||||
if (sendother[iswap]) {
|
if (sendother[iswap]) {
|
||||||
for (i = 0; i < nsend; i++) {
|
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++)
|
for (k = 0; k < nsize; k++)
|
||||||
buf_send[m++] = array[j][k];
|
buf_send[m++] = array[j][k];
|
||||||
}
|
}
|
||||||
MPI_Send(buf_send,nsize*sendnum[iswap][i],
|
MPI_Send(buf_send,nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world);
|
||||||
MPI_DOUBLE,sendproc[iswap][i],0,world);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendself[iswap]) {
|
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);
|
box_drop_tiled_recurse(lo,hi,0,nprocs-1,indexme);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommTiled::box_drop_tiled_recurse(double *lo, double *hi,
|
void CommTiled::box_drop_tiled_recurse(double *lo, double *hi, int proclower, int procupper,
|
||||||
int proclower, int procupper,
|
|
||||||
int &indexme)
|
int &indexme)
|
||||||
{
|
{
|
||||||
// end recursion when partition is a single proc
|
// 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
|
return other box owned by proc as lo/hi corner pts
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void CommTiled::box_other_brick(int idim, int idir,
|
void CommTiled::box_other_brick(int idim, int idir, int proc, double *lo, double *hi)
|
||||||
int proc, double *lo, double *hi)
|
|
||||||
{
|
{
|
||||||
lo[0] = sublo[0]; lo[1] = sublo[1]; lo[2] = sublo[2];
|
lo[0] = sublo[0]; lo[1] = sublo[1]; lo[2] = sublo[2];
|
||||||
hi[0] = subhi[0]; hi[1] = subhi[1]; hi[2] = subhi[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
|
return other box owned by proc as lo/hi corner pts
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void CommTiled::box_other_tiled(int /*idim*/, int /*idir*/,
|
void CommTiled::box_other_tiled(int /*idim*/, int /*idir*/, int proc, double *lo, double *hi)
|
||||||
int proc, double *lo, double *hi)
|
|
||||||
{
|
{
|
||||||
double (*split)[2] = rcbinfo[proc].mysplit;
|
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
|
recursive point drop thru RCB tree
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int CommTiled::point_drop_tiled_recurse(double *x,
|
int CommTiled::point_drop_tiled_recurse(double *x, int proclower, int procupper)
|
||||||
int proclower, int procupper)
|
|
||||||
{
|
{
|
||||||
// end recursion when partition is a single proc
|
// end recursion when partition is a single proc
|
||||||
// return proc
|
// return proc
|
||||||
@ -2195,8 +2209,7 @@ void CommTiled::coord2proc_setup()
|
|||||||
memcpy(&rcbone.mysplit[0][0],&mysplit[0][0],6*sizeof(double));
|
memcpy(&rcbone.mysplit[0][0],&mysplit[0][0],6*sizeof(double));
|
||||||
rcbone.cutfrac = rcbcutfrac;
|
rcbone.cutfrac = rcbcutfrac;
|
||||||
rcbone.dim = rcbcutdim;
|
rcbone.dim = rcbcutdim;
|
||||||
MPI_Allgather(&rcbone,sizeof(RCBinfo),MPI_CHAR,
|
MPI_Allgather(&rcbone,sizeof(RCBinfo),MPI_CHAR,rcbinfo,sizeof(RCBinfo),MPI_CHAR,world);
|
||||||
rcbinfo,sizeof(RCBinfo),MPI_CHAR,world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
|
|||||||
@ -22,6 +22,7 @@ class CommTiled : public Comm {
|
|||||||
public:
|
public:
|
||||||
CommTiled(class LAMMPS *);
|
CommTiled(class LAMMPS *);
|
||||||
CommTiled(class LAMMPS *, class Comm *);
|
CommTiled(class LAMMPS *, class Comm *);
|
||||||
|
|
||||||
~CommTiled() override;
|
~CommTiled() override;
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
@ -33,6 +34,8 @@ class CommTiled : public Comm {
|
|||||||
|
|
||||||
void forward_comm(class Pair *) override; // forward comm from a Pair
|
void forward_comm(class Pair *) override; // forward comm from a Pair
|
||||||
void reverse_comm(class Pair *) override; // reverse 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 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(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
|
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) {
|
} else if (strcmp(arg[iarg],"quatw") == 0) {
|
||||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
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");
|
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||||
pack_choice[i] = &ComputePropertyAtom::pack_quatw;
|
pack_choice[i] = &ComputePropertyAtom::pack_quatw;
|
||||||
} else if (strcmp(arg[iarg],"quati") == 0) {
|
} else if (strcmp(arg[iarg],"quati") == 0) {
|
||||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
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");
|
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||||
pack_choice[i] = &ComputePropertyAtom::pack_quati;
|
pack_choice[i] = &ComputePropertyAtom::pack_quati;
|
||||||
} else if (strcmp(arg[iarg],"quatj") == 0) {
|
} else if (strcmp(arg[iarg],"quatj") == 0) {
|
||||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
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");
|
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||||
pack_choice[i] = &ComputePropertyAtom::pack_quatj;
|
pack_choice[i] = &ComputePropertyAtom::pack_quatj;
|
||||||
} else if (strcmp(arg[iarg],"quatk") == 0) {
|
} else if (strcmp(arg[iarg],"quatk") == 0) {
|
||||||
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
avec_ellipsoid = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
||||||
avec_body = dynamic_cast<AtomVecBody *>( atom->style_match("body"));
|
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");
|
error->all(FLERR,"Compute property/atom for atom property that isn't allocated");
|
||||||
pack_choice[i] = &ComputePropertyAtom::pack_quatk;
|
pack_choice[i] = &ComputePropertyAtom::pack_quatk;
|
||||||
|
|
||||||
@ -1334,7 +1334,7 @@ void ComputePropertyAtom::pack_quatw(int n)
|
|||||||
n += nvalues;
|
n += nvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (avec_body) {
|
||||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||||
int *body = atom->body;
|
int *body = atom->body;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
@ -1346,6 +1346,17 @@ void ComputePropertyAtom::pack_quatw(int n)
|
|||||||
else buf[n] = 0.0;
|
else buf[n] = 0.0;
|
||||||
n += nvalues;
|
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;
|
n += nvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (avec_body) {
|
||||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||||
int *body = atom->body;
|
int *body = atom->body;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
@ -1378,6 +1389,17 @@ void ComputePropertyAtom::pack_quati(int n)
|
|||||||
else buf[n] = 0.0;
|
else buf[n] = 0.0;
|
||||||
n += nvalues;
|
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;
|
n += nvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (avec_body) {
|
||||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||||
int *body = atom->body;
|
int *body = atom->body;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
@ -1410,6 +1432,17 @@ void ComputePropertyAtom::pack_quatj(int n)
|
|||||||
else buf[n] = 0.0;
|
else buf[n] = 0.0;
|
||||||
n += nvalues;
|
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;
|
n += nvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (avec_body) {
|
||||||
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
AtomVecBody::Bonus *bonus = avec_body->bonus;
|
||||||
int *body = atom->body;
|
int *body = atom->body;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
@ -1442,6 +1475,17 @@ void ComputePropertyAtom::pack_quatk(int n)
|
|||||||
else buf[n] = 0.0;
|
else buf[n] = 0.0;
|
||||||
n += nvalues;
|
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 "comm.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "fix_bond_history.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
|
#include "modify.h"
|
||||||
#include "special.h"
|
#include "special.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -116,6 +118,10 @@ void DeleteBonds::command(int narg, char **arg)
|
|||||||
iarg++;
|
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
|
// border swap to insure type and mask is current for off-proc atoms
|
||||||
// enforce PBC before in case atoms are outside box
|
// 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];
|
n = atom->num_bond[i];
|
||||||
atom->bond_type[i][m] = atom->bond_type[i][n-1];
|
atom->bond_type[i][m] = atom->bond_type[i][n-1];
|
||||||
atom->bond_atom[i][m] = atom->bond_atom[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]--;
|
atom->num_bond[i]--;
|
||||||
} else m++;
|
} else m++;
|
||||||
} else m++;
|
} else m++;
|
||||||
@ -431,32 +442,28 @@ void DeleteBonds::command(int narg, char **arg)
|
|||||||
if (atom->avec->bonds_allow) {
|
if (atom->avec->bonds_allow) {
|
||||||
bigint nbonds = 0;
|
bigint nbonds = 0;
|
||||||
for (i = 0; i < nlocal; i++) nbonds += atom->num_bond[i];
|
for (i = 0; i < nlocal; i++) nbonds += atom->num_bond[i];
|
||||||
MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT,
|
MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||||
MPI_SUM,world);
|
|
||||||
if (force->newton_bond == 0) atom->nbonds /= 2;
|
if (force->newton_bond == 0) atom->nbonds /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atom->avec->angles_allow) {
|
if (atom->avec->angles_allow) {
|
||||||
bigint nangles = 0;
|
bigint nangles = 0;
|
||||||
for (i = 0; i < nlocal; i++) nangles += atom->num_angle[i];
|
for (i = 0; i < nlocal; i++) nangles += atom->num_angle[i];
|
||||||
MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT,
|
MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||||
MPI_SUM,world);
|
|
||||||
if (force->newton_bond == 0) atom->nangles /= 3;
|
if (force->newton_bond == 0) atom->nangles /= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atom->avec->dihedrals_allow) {
|
if (atom->avec->dihedrals_allow) {
|
||||||
bigint ndihedrals = 0;
|
bigint ndihedrals = 0;
|
||||||
for (i = 0; i < nlocal; i++) ndihedrals += atom->num_dihedral[i];
|
for (i = 0; i < nlocal; i++) ndihedrals += atom->num_dihedral[i];
|
||||||
MPI_Allreduce(&ndihedrals,&atom->ndihedrals,
|
MPI_Allreduce(&ndihedrals,&atom->ndihedrals,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||||
1,MPI_LMP_BIGINT,MPI_SUM,world);
|
|
||||||
if (force->newton_bond == 0) atom->ndihedrals /= 4;
|
if (force->newton_bond == 0) atom->ndihedrals /= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atom->avec->impropers_allow) {
|
if (atom->avec->impropers_allow) {
|
||||||
bigint nimpropers = 0;
|
bigint nimpropers = 0;
|
||||||
for (i = 0; i < nlocal; i++) nimpropers += atom->num_improper[i];
|
for (i = 0; i < nlocal; i++) nimpropers += atom->num_improper[i];
|
||||||
MPI_Allreduce(&nimpropers,&atom->nimpropers,
|
MPI_Allreduce(&nimpropers,&atom->nimpropers,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||||
1,MPI_LMP_BIGINT,MPI_SUM,world);
|
|
||||||
if (force->newton_bond == 0) atom->nimpropers /= 4;
|
if (force->newton_bond == 0) atom->nimpropers /= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,21 +542,18 @@ void DeleteBonds::command(int narg, char **arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (comm->me == 0) {
|
if (comm->me == 0) {
|
||||||
|
constexpr auto fmtstr = " {} total {}, {} turned on, {} turned off\n";
|
||||||
if (atom->avec->bonds_allow)
|
if (atom->avec->bonds_allow)
|
||||||
utils::logmesg(lmp," {} total bonds, {} turned on, {} turned off\n",
|
utils::logmesg(lmp,fmtstr,atom->nbonds,"bonds",bond_on,bond_off);
|
||||||
atom->nbonds,bond_on,bond_off);
|
|
||||||
|
|
||||||
if (atom->avec->angles_allow)
|
if (atom->avec->angles_allow)
|
||||||
utils::logmesg(lmp," {} total angles, {} turned on, {} turned off\n",
|
utils::logmesg(lmp,fmtstr,atom->nangles,"angles",angle_on,angle_off);
|
||||||
atom->nangles,angle_on,angle_off);
|
|
||||||
|
|
||||||
if (atom->avec->dihedrals_allow)
|
if (atom->avec->dihedrals_allow)
|
||||||
utils::logmesg(lmp," {} total dihedrals, {} turned on, {} turned off\n",
|
utils::logmesg(lmp,fmtstr,atom->ndihedrals,"dihedrals",dihedral_on,dihedral_off);
|
||||||
atom->ndihedrals,dihedral_on,dihedral_off);
|
|
||||||
|
|
||||||
if (atom->avec->impropers_allow)
|
if (atom->avec->impropers_allow)
|
||||||
utils::logmesg(lmp," {} total impropers, {} turned on, {} turned off\n",
|
utils::logmesg(lmp,fmtstr,atom->nimpropers,"impropers",improper_on,improper_off);
|
||||||
atom->nimpropers,improper_on,improper_off);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-compute special list if requested
|
// 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) {
|
} else if (strcmp(arg[iarg],"header") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
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;
|
iarg += 2;
|
||||||
|
|
||||||
} else if (strcmp(arg[iarg],"maxfiles") == 0) {
|
} else if (strcmp(arg[iarg],"maxfiles") == 0) {
|
||||||
|
|||||||
@ -66,7 +66,6 @@ class Dump : protected Pointers {
|
|||||||
char *multiname; // filename with % converted to cluster ID
|
char *multiname; // filename with % converted to cluster ID
|
||||||
MPI_Comm clustercomm; // MPI communicator within my cluster of procs
|
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 flush_flag; // 0 if no flush, 1 if flush every dump
|
||||||
int sort_flag; // 1 if sorted output
|
int sort_flag; // 1 if sorted output
|
||||||
int balance_flag; // 1 if load balanced 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