Merge remote-tracking branch 'github/develop' into collected-small-fixes

This commit is contained in:
Axel Kohlmeyer
2024-07-18 18:40:22 -04:00
104 changed files with 15212 additions and 109 deletions

View File

@ -322,6 +322,7 @@ set(STANDARD_PACKAGES
REACTION
REAXFF
REPLICA
RHEO
RIGID
SCAFACOS
SHOCK
@ -426,6 +427,7 @@ pkg_depends(CG-DNA ASPHERE)
pkg_depends(ELECTRODE KSPACE)
pkg_depends(EXTRA-MOLECULE MOLECULE)
pkg_depends(MESONT MOLECULE)
pkg_depends(RHEO BPM)
# detect if we may enable OpenMP support by default
set(BUILD_OMP_DEFAULT OFF)
@ -566,7 +568,7 @@ else()
endif()
foreach(PKG_WITH_INCL KSPACE PYTHON ML-IAP VORONOI COLVARS ML-HDNNP MDI MOLFILE NETCDF
PLUMED QMMM ML-QUIP SCAFACOS MACHDYN VTK KIM COMPRESS ML-PACE LEPTON)
PLUMED QMMM ML-QUIP SCAFACOS MACHDYN VTK KIM COMPRESS ML-PACE LEPTON RHEO)
if(PKG_${PKG_WITH_INCL})
include(Packages/${PKG_WITH_INCL})
endif()

View File

@ -0,0 +1,2 @@
find_package(GSL 2.7 REQUIRED)
target_link_libraries(lammps PRIVATE GSL::gsl)

View File

@ -82,6 +82,7 @@ set(ALL_PACKAGES
REACTION
REAXFF
REPLICA
RHEO
RIGID
SCAFACOS
SHOCK

View File

@ -84,6 +84,7 @@ set(ALL_PACKAGES
REACTION
REAXFF
REPLICA
RHEO
RIGID
SCAFACOS
SHOCK

View File

@ -59,6 +59,7 @@ This is the list of packages that may require additional steps.
* :ref:`POEMS <poems>`
* :ref:`PYTHON <python>`
* :ref:`QMMM <qmmm>`
* :ref:`RHEO <rheo>`
* :ref:`SCAFACOS <scafacos>`
* :ref:`VORONOI <voronoi>`
* :ref:`VTK <vtk>`
@ -1566,10 +1567,11 @@ LAMMPS build.
.. tab:: CMake build
When the ``-D PKG_PLUMED=yes`` flag is included in the cmake
command you must ensure that GSL is installed in locations that
are specified in your environment. There are then two additional
variables that control the manner in which PLUMED is obtained and
linked into LAMMPS.
command you must ensure that `the GNU Scientific Library (GSL)
<https://www.gnu.org/software/gsl/>` is installed in locations
that are accessible in your environment. There are then two
additional variables that control the manner in which PLUMED is
obtained and linked into LAMMPS.
.. code-block:: bash
@ -2040,6 +2042,36 @@ verified to work in February 2020 with Quantum Espresso versions 6.3 to
----------
.. _rheo:
RHEO package
------------
To build with this package you must have the `GNU Scientific Library
(GSL) <https://www.gnu.org/software/gsl/>` installed in locations that
are accessible in your environment. The GSL library should be at least
version 2.7.
.. tabs::
.. tab:: CMake build
If CMake cannot find the GSL library or include files, you can set:
.. code-block:: bash
-D GSL_ROOT_DIR=path # path to root of GSL installation
.. tab:: Traditional make
LAMMPS will try to auto-detect the GSL compiler and linker flags
from the corresponding ``pkg-config`` file (``gsl.pc``), otherwise
you can edit the file ``lib/rheo/Makefile.lammps``
to specify the paths and library names where indicated by comments.
This must be done **before** the package is installed.
----------
.. _scafacos:
SCAFACOS package

View File

@ -62,6 +62,7 @@ packages:
* :ref:`POEMS <poems>`
* :ref:`PYTHON <python>`
* :ref:`QMMM <qmmm>`
* :ref:`RHEO <rheo>`
* :ref:`SCAFACOS <scafacos>`
* :ref:`VORONOI <voronoi>`
* :ref:`VTK <vtk>`

View File

@ -54,6 +54,7 @@ OPT.
* :doc:`oxdna2/fene <bond_oxdna>`
* :doc:`oxrna2/fene <bond_oxdna>`
* :doc:`quartic (o) <bond_quartic>`
* :doc:`rheo/shell <bond_rheo_shell>`
* :doc:`special <bond_special>`
* :doc:`table (o) <bond_table>`

View File

@ -126,6 +126,7 @@ KOKKOS, o = OPENMP, t = OPT.
* :doc:`reduce <compute_reduce>`
* :doc:`reduce/chunk <compute_reduce_chunk>`
* :doc:`reduce/region <compute_reduce>`
* :doc:`rheo/property/atom <compute_rheo_property_atom>`
* :doc:`rigid/local <compute_rigid_local>`
* :doc:`saed <compute_saed>`
* :doc:`slcsa/atom <compute_slcsa_atom>`

View File

@ -28,6 +28,7 @@ OPT.
* :doc:`adapt <fix_adapt>`
* :doc:`adapt/fep <fix_adapt_fep>`
* :doc:`addforce <fix_addforce>`
* :doc:`add/heat <fix_add_heat>`
* :doc:`addtorque <fix_addtorque>`
* :doc:`alchemy <fix_alchemy>`
* :doc:`amoeba/bitorsion <fix_amoeba_bitorsion>`
@ -204,6 +205,11 @@ OPT.
* :doc:`reaxff/species (k) <fix_reaxff_species>`
* :doc:`recenter <fix_recenter>`
* :doc:`restrain <fix_restrain>`
* :doc:`rheo <fix_rheo>`
* :doc:`rheo/oxidation <fix_rheo_oxidation>`
* :doc:`rheo/pressure <fix_rheo_pressure>`
* :doc:`rheo/thermal <fix_rheo_thermal>`
* :doc:`rheo/viscosity <fix_rheo_viscosity>`
* :doc:`rhok <fix_rhok>`
* :doc:`rigid (o) <fix_rigid>`
* :doc:`rigid/meso <fix_rigid_meso>`

View File

@ -264,6 +264,8 @@ OPT.
* :doc:`rebo (io) <pair_airebo>`
* :doc:`rebomos (o) <pair_rebomos>`
* :doc:`resquared (go) <pair_resquared>`
* :doc:`rheo <pair_rheo>`
* :doc:`rheo/solid <pair_rheo_solid>`
* :doc:`saip/metal (t) <pair_saip_metal>`
* :doc:`sdpd/taitwater/isothermal <pair_sdpd_taitwater_isothermal>`
* :doc:`smatb <pair_smatb>`

View File

@ -134,6 +134,8 @@ Lowercase directories
+-------------+------------------------------------------------------------------+
| rerun | use of rerun and read_dump commands |
+-------------+------------------------------------------------------------------+
| rheo | RHEO simulations of fluid flows and phase transitions |
+-------------+------------------------------------------------------------------+
| rigid | rigid bodies modeled as independent or coupled |
+-------------+------------------------------------------------------------------+
| shear | sideways shear applied to 2d solid, with and without a void |

View File

@ -89,6 +89,7 @@ Packages howto
Howto_drude2
Howto_peri
Howto_manifold
Howto_rheo
Howto_spins
Tutorials howto

116
doc/src/Howto_rheo.rst Normal file
View File

@ -0,0 +1,116 @@
Reproducing hydrodynamics and elastic objects (RHEO)
====================================================
The RHEO package is a hybrid implementation of smoothed particle
hydrodynamics (SPH) for fluid flow, which can couple to the :doc:`BPM package
<Howto_bpm>` to model solid elements. RHEO combines these methods to enable
mesh-free modeling of multi-phase material systems. Its SPH solver supports
many advanced options including reproducing kernels, particle shifting, free
surface identification, and solid surface reconstruction. To model fluid-solid
systems, the status of particles can dynamically change between a fluid and
solid state, e.g. during melting/solidification, which determines how they
interact and their physical behavior. The package is designed with modularity
in mind, so one can easily turn various features on/off, adjust physical
details of the system, or develop new capabilities. For instance, the numerics
associated with calculating gradients, reproducing kernels, etc. are separated
into distinctclasses to simplify the development of new integration schemes
which can call these calculations. Additional numerical details can be found in
:ref:`(Palermo) <howto_rheo_palermo>` and
:ref:`(Clemmer) <howto_rheo_clemmer>`.
Note, if you simply want to run a traditional SPH simulation, the :ref:`SPH package
<PKG-SPH>` package is likely better suited for your application. It has fewer advanced
features and therefore benefits from improved performance. The :ref:`MACHDYN
<PKG-MACHDYN>` package for solids may also be relevant for fluid-solid problems.
----------
At the core of the package is :doc:`fix rheo <fix_rheo>` which integrates
particle trajectories and controls many optional features (e.g. the use
of reproducing kernels). In conjunction to fix rheo, one must specify an
instance of :doc:`fix rheo/pressure <fix_rheo_pressure>` and
:doc:`fix rheo/viscosity <fix_rheo_viscosity>` to define a pressure equation
of state and viscosity model, respectively. Optionally, one can model
a heat equation with :doc:`fix rheo/thermal <fix_rheo_thermal>`, which also
allows the user to specify equations for a particle's thermal conductivity,
specific heat, latent heat, and melting temperature. The ordering of these
fixes in an an input script matters. Fix rheo must be defined prior to all
other RHEO fixes.
Typically, RHEO requires atom style rheo. In addition to typical atom
properties like positions and forces, particles store a local density,
viscosity, pressure, and status. If thermal evolution is modeled, one must
use atom style rheo/thermal which also includes a local energy, temperature, and
conductivity. Note that the temperature is always derived from the energy.
This implies the *temperature* attribute of :doc:`the set command <set>` does not
affect particles. Instead, one should use the *sph/e* attribute.
The status variable uses bit-masking to track various properties of a particle
such as its current state of matter (fluid or solid) and its location relative
to a surface. Some of these properties (and others) can be accessed using
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`. The *status*
attribute in :doc:`the set command <set>` only allows control over the first bit
which sets the state of matter, 0 is fluid and 1 is solid.
Fluid interactions, including pressure forces, viscous forces, and heat exchange,
are calculated using :doc:`pair rheo <pair_rheo>`. Unlike typical pair styles,
pair rheo ignores the :doc:`special bond <special_bonds>` settings. Instead,
it determines whether to calculate forces based on the status of particles: e.g.,
hydrodynamic forces are only calculated if a fluid particle is involved.
----------
To model elastic objects, there are currently two mechanisms in RHEO, one designed
for bulk solid bodies and the other for thin shells. Both mechanisms rely on
introducing bonded forces between particles and therefore require a hybrid of atom
style bond and rheo (or rheo/thermal).
To create an elastic solid body, one has to (a) change the status of constituent
particles to solid (e.g. with the :doc:`set <set>` command), (b) create bpm
bonds between the particles (see the :doc:`bpm howto <Howto_bpm>` page for
more details), and (c) use :doc:`pair rheo/solid <pair_rheo_solid>` to
apply repulsive contact forces between distinct solid bodies. Akin to pair rheo,
pair rheo/solid considers a particles fluid/solid phase to determine whether to
apply forces. However, unlike pair rheo, pair rheo/solid does obey special bond
settings such that contact forces do not have to be calculated between two bonded
solid particles in the same elastic body.
In systems with thermal evolution, fix rheo/thermal can optionally set a
melting/solidification temperature allowing particles to dynamically swap their
state between fluid and solid when the temperature exceeds or drops below the
critical temperature, respectively. Using the *react* option, one can specify a maximum
bond length and a bond type. Then, when solidifying, particles will search their
local neighbors and automatically create bonds with any neighboring solid particles
in range. For BPM bond styles, bonds will then use the immediate position of the two
particles to calculate a reference state. When melting, particles will delete any
bonds of the specified type when reverting to a fluid state. Special bonds are updated
as bonds are created/broken.
The other option for elastic objects is an elastic shell that is nominally much
thinner than a particle diameter, e.g. a oxide skin which gradually forms over time
on the surface of a fluid. Currently, this is implemented using
:doc:`fix rheo/oxidation <fix_rheo_oxidation>` and bond style
:doc:`rheo/shell <bond_rheo_shell>`. Essentially, fix rheo/oxidation creates candidate
bonds of a specified type between surface fluid particles within a specified distance.
a newly created rheo/shell bond will then start a timer. While the timer is counting
down, the bond will delete itself if particles move too far apart or move away from the
surface. However, if the timer reaches a user-defined threshold, then the bond will
activate and apply additional forces to the fluid particles. Bond style rheo/shell
then operates very similarly to a BPM bond style, storing a reference length and
breaking if stretched too far. Unlike the above method, this option does not remove
the underlying fluid interactions (although particle shifting is turned off) and does
not modify special bond settings of particles.
While these two options are not expected to be appropriate for every system,
either framework can be modified to create more suitable models (e.g. by changing the
criteria for creating/deleting a bond or altering force calculations).
----------
.. _howto_rheo_palermo:
**(Palermo)** Palermo, Wolf, Clemmer, O'Connor, in preparation.
.. _howto_rheo_clemmer:
**(Clemmer)** Clemmer, Pierce, O'Connor, Nevins, Jones, Lechman, Tencer, Appl. Math. Model., 130, 310-326 (2024).

View File

@ -8,12 +8,12 @@ info on how to download or build any extra library it requires. It also
gives links to documentation, example scripts, and pictures/movies (if
available) that illustrate use of the package.
The majority of packages can be included in a LAMMPS build with a
single setting (``-D PKG_<NAME>=on`` for CMake) or command
(``make yes-<name>`` for make). See the :doc:`Build package <Build_package>`
page for more info. A few packages may require additional steps;
this is indicated in the descriptions below. The :doc:`Build extras <Build_extras>`
page gives those details.
The majority of packages can be included in a LAMMPS build with a single
setting (``-D PKG_<NAME>=on`` for CMake) or command (``make yes-<name>``
for make). See the :doc:`Build package <Build_package>` page for more
info. A few packages may require additional steps; this is indicated in
the descriptions below. The :doc:`Build extras <Build_extras>` page
gives those details.
.. note::
@ -103,6 +103,7 @@ page gives those details.
* :ref:`QEQ <PKG-QEQ>`
* :ref:`QMMM <PKG-QMMM>`
* :ref:`QTB <PKG-QTB>`
* :ref:`RHEO <PKG-RHEO>`
* :ref:`REACTION <PKG-REACTION>`
* :ref:`REAXFF <PKG-REAXFF>`
* :ref:`REPLICA <PKG-REPLICA>`
@ -2622,6 +2623,45 @@ another set.
----------
.. _PKG-RHEO:
RHEO package
------------
**Contents:**
Pair styles, bond styles, fixes, and computes for reproducing
hydrodynamics and elastic objects. See the :doc:`Howto rheo
<Howto_rheo>` page for an overview.
**Install:**
This package has :ref:`specific installation instructions <rheo>` on the :doc:`Build extras <Build_extras>` page.
**Authors:** Joel T. Clemmer (Sandia National Labs),
Thomas C. O'Connor (Carnegie Mellon University)
.. versionadded:: TBD
**Supporting info:**
* src/RHEO filenames -> commands
* :doc:`Howto_rheo <Howto_rheo>`
* :doc:`atom_style rheo <atom_style>`
* :doc:`atom_style rheo/thermal <atom_style>`
* :doc:`bond_style rheo/shell <bond_rheo_shell>`
* :doc:`compute rheo/property/atom <compute_rheo_property_atom>`
* :doc:`fix rheo <fix_rheo>`
* :doc:`fix rheo/oxidation <fix_rheo_oxidation>`
* :doc:`fix rheo/pressure <fix_rheo_pressure>`
* :doc:`fix rheo/thermal <fix_rheo_thermal>`
* :doc:`fix rheo/viscosity <fix_rheo_viscosity>`
* :doc:`pair_style rheo <pair_rheo>`
* :doc:`pair_style rheo/solid <pair_rheo_solid>`
* examples/rheo
----------
.. _PKG-RIGID:
RIGID package

View File

@ -413,6 +413,11 @@ whether an extra library is needed to build and use the package:
- :doc:`fix qtb <fix_qtb>` :doc:`fix qbmsst <fix_qbmsst>`
- qtb
- no
* - :ref:`RHEO <PKG-RHEO>`
- reproducing hydrodynamics and elastic objects
- :doc:`Howto rheo <Howto_rheo>`
- rheo
- no
* - :ref:`REACTION <PKG-REACTION>`
- chemical reactions in classical MD
- :doc:`fix bond/react <fix_bond_react>`

View File

@ -189,6 +189,14 @@ the Additional Information section below.
- *atomic* + molecule, radius, rmass + "smd data"
- :ref:`MACHDYN <PKG-MACHDYN>`
- Smooth Mach Dynamics models
* - *rheo*
- *atomic* + rho, status
- :ref:`RHEO <PKG-RHEO>`
- solid and fluid RHEO particles
* - *rheo/thermal*
- *atomic* + rho, status, energy, temperature
- :ref:`RHEO <PKG-RHEO>`
- RHEO particles with temperature
* - *sph*
- *atomic* + "sph data"
- :ref:`SPH <PKG-SPH>`

188
doc/src/bond_rheo_shell.rst Normal file
View File

@ -0,0 +1,188 @@
.. index:: bond_style rheo/shell
bond_style rheo/shell command
=============================
Syntax
""""""
.. code-block:: LAMMPS
bond_style rheo/shell keyword value attribute1 attribute2 ...
* required keyword = *t/form*
* optional keyword = *store/local*
.. parsed-literal::
*t/form* value = formation time for a bond (time units)
*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)
Examples
""""""""
.. code-block:: LAMMPS
bond_style rheo/shell t/form 10.0
bond_coeff 1 1.0 0.05 0.1
Description
"""""""""""
.. versionadded:: TBD
The *rheo/shell* bond style is designed to work with
:doc:`fix rheo/oxidation <fix_rheo_oxidation>` which creates candidate
bonds between eligible surface or near-surface particles. When a bond
is first created, it computes no forces and starts a timer. Forces are
not computed until the timer reaches the specified bond formation time,
*t/form*, and the bond is enabled and applies forces. If the two particles
move outside of the maximum bond distance or move into the bulk before
the timer reaches *t/form*, the bond automatically deletes itself. This
deletion is not recorded as a broken bond in the optional *store/local* fix.
Before bonds are enabled, they are still treated as regular bonds by
all other parts of LAMMPS. This means they are written to data files
and counted in computes such as :doc:`nbond/atom <compute_nbond_atom>`.
To only count enabled bonds, use the *nbond/shell* attribute in
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`.
When enabled, the bond then computes forces based on deviations from
the initial reference state of the two atoms much like a BPM style
bond (as further discussed in the :doc:`BPM howto page <Howto_bpm>`).
The reference state is stored by each bond when it is first enabled.
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 or the timer.
This bond style is based on a model described in
:ref:`(Clemmer) <rheo_clemmer>`. The force has a magnitude of
.. math::
F = 2 k (r - r_0) + \frac{2 k}{r_0^2 \epsilon_c^2} (r - r_0)^3
where :math:`k` is a stiffness, :math:`r` is the current distance
and :math:`r_0` is the initial distance between the two particles, and
:math:`\epsilon_c` is maximum strain beyond which a bond breaks. This
is done by setting the bond type to 0 such that forces are no longer
computed.
A damping force proportional to the difference in the normal velocity
of particles is also applied to bonded particles:
.. math::
F_D = - \gamma w (\hat{r} \bullet \vec{v})
where :math:`\gamma` is the damping strength, :math:`\hat{r}` is the
displacement normal vector, and :math:`\vec{v}` is the velocity difference
between the two particles.
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)
Unlike other BPM-style bonds, this bond style does not update special
bond settings when bonds are created or deleted. This bond style also
does not enforce specific :doc:`special_bonds <special_bonds>` settings.
This behavior is purposeful such :doc:`RHEO pair <pair_rheo>` forces
and heat flows are still calculated.
If the *store/local* keyword is used, an internal 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 this optional
keyword, 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 restore bonds. However, the reference state is NOT
written to data files. Therefore reading a data file will not
restore bonds and will cause their reference states to be redefined.
If the *store/local* option is used, an internal fix will calculate
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, broken bonds. 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.
The single() function of this bond style returns 0.0 for the energy
of a bonded interaction, since energy is not conserved in these
dissipative potentials. The single() function also calculates two
extra bond quantities, the initial distance :math:`r_0` and a time.
These extra quantities can be accessed by the
:doc:`compute bond/local <compute_bond_local>` command as *b1* and *b2*\ .
Restrictions
""""""""""""
This bond style is part of the RHEO 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:`bond_coeff <bond_coeff>`, :doc:`fix rheo/oxidation <fix_rheo_oxidation>`
Default
"""""""
NA
----------
.. _rheo_clemmer:
**(Clemmer)** Clemmer, Pierce, O'Connor, Nevins, Jones, Lechman, Tencer, Appl. Math. Model., 130, 310-326 (2024).

View File

@ -105,6 +105,7 @@ accelerated styles exist.
* :doc:`oxdna2/fene <bond_oxdna>` - same as oxdna but used with different pair styles
* :doc:`oxrna2/fene <bond_oxdna>` - modified FENE bond suitable for RNA modeling
* :doc:`quartic <bond_quartic>` - breakable quartic bond
* :doc:`rheo/shell <bond_rheo_shell>` - shell bond for oxidation modeling in RHEO
* :doc:`special <bond_special>` - enable special bond exclusions for 1-5 pairs and beyond
* :doc:`table <bond_table>` - tabulated by bond length

View File

@ -290,6 +290,7 @@ The individual style names on the :doc:`Commands compute <Commands_compute>` pag
* :doc:`reduce <compute_reduce>` - combine per-atom quantities into a single global value
* :doc:`reduce/chunk <compute_reduce_chunk>` - reduce per-atom quantities within each chunk
* :doc:`reduce/region <compute_reduce>` - same as compute reduce, within a region
* :doc:`rheo/property/atom <compute_rheo_property_atom>` - convert atom attributes in RHEO package to per-atom vectors/arrays
* :doc:`rigid/local <compute_rigid_local>` - extract rigid body attributes
* :doc:`saed <compute_saed>` - electron diffraction intensity on a mesh of reciprocal lattice nodes
* :doc:`slcsa/atom <compute_slcsa_atom>` - perform Supervised Learning Crystal Structure Analysis (SL-CSA)

View File

@ -8,10 +8,17 @@ Syntax
.. code-block:: LAMMPS
compute ID group-ID nbond/atom
compute ID group-ID nbond/atom keyword value
* ID, group-ID are documented in :doc:`compute <compute>` command
* nbond/atom = style name of this compute command
* zero or more keyword/value pairs may be appended
* keyword = *bond/type*
.. parsed-literal::
*bond/type* value = *btype*
*btype* = bond type included in count
Examples
""""""""
@ -19,6 +26,7 @@ Examples
.. code-block:: LAMMPS
compute 1 all nbond/atom
compute 1 all nbond/atom bond/type 2
Description
"""""""""""
@ -31,6 +39,9 @@ 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.
If the keyword *bond/type* is specified, only bonds of *btype* are
counted.
Output info
"""""""""""

View File

@ -0,0 +1,143 @@
.. index:: compute rheo/property/atom
compute rheo/property/atom command
==================================
Syntax
""""""
.. code-block:: LAMMPS
compute ID group-ID rheo/property/atom input1 input2 ...
* ID, group-ID are documented in :doc:`compute <compute>` command
* rheo/property/atom = style name of this compute command
* input = one or more atom attributes
.. parsed-literal::
possible attributes = phase, surface, surface/r,
surface/divr, surface/n/a, coordination,
shift/v/a, energy, temperature, heatflow,
conductivity, cv, viscosity, pressure, rho,
grad/v/ab, stress/v/ab, stress/t/ab, nbond/shell
.. parsed-literal::
*phase* = atom phase state
*surface* = atom surface status
*surface/r* = atom distance from the surface
*surface/divr* = divergence of position at atom position
*surface/n/a* = a-component of surface normal vector
*coordination* = coordination number
*shift/v/a* = a-component of atom shifting velocity
*energy* = atom energy
*temperature* = atom temperature
*heatflow* = atom heat flow
*conductivity* = atom conductivity
*cv* = atom specific heat
*viscosity* = atom viscosity
*pressure* = atom pressure
*rho* = atom density
*grad/v/ab* = ab-component of atom velocity gradient tensor
*stress/v/ab* = ab-component of atom viscous stress tensor
*stress/t/ab* = ab-component of atom total stress tensor (pressure and viscous)
*nbond/shell* = number of oxide bonds
Examples
""""""""
.. code-block:: LAMMPS
compute 1 all rheo/property/atom phase surface/r surface/n/* pressure
compute 2 all rheo/property/atom shift/v/x grad/v/xx stress/v/*
Description
"""""""""""
.. versionadded:: TBD
Define a computation that stores atom attributes specific to the RHEO
package for each atom in the group. This is useful so that the values
can be used by other :doc:`output commands <Howto_output>` that take
computes as inputs. See for example, the
:doc:`compute reduce <compute_reduce>`,
:doc:`fix ave/atom <fix_ave_atom>`,
:doc:`fix ave/histo <fix_ave_histo>`,
:doc:`fix ave/chunk <fix_ave_chunk>`, and
:doc:`atom-style variable <variable>` commands.
For vector attributes, e.g. *shift/v/*:math:`\alpha`, one must specify
:math:`\alpha` as the *x*, *y*, or *z* component, e.g. *shift/v/x*.
Alternatively, a wild card \* will include all components, *x* and *y* in
2D or *x*, *y*, and *z* in 3D.
For tensor attributes, e.g. *grad/v/*:math:`\alpha \beta`, one must specify
both :math:`\alpha` and :math:`\beta` as *x*, *y*, or *z*, e.g. *grad/v/xy*.
Alternatively, a wild card \* will include all components. In 2D, this
includes *xx*, *xy*, *yx*, and *yy*. In 3D, this includes *xx*, *xy*, *xz*,
*yx*, *yy*, *yz*, *zx*, *zy*, and *zz*.
Many properties require their respective fixes, listed below in related
commands, be defined. For instance, the *viscosity* attribute is the
viscosity of a particle calculated by
:doc:`fix rheo/viscous <fix_rheo_viscosity>`. The meaning of less obvious
properties is described below.
The *phase* property indicates whether the particle is in a fluid state,
a value of 0, or a solid state, a value of 1.
The *surface* property indicates the surface designation produced by
the *interface/reconstruct* option of :doc:`fix rheo <fix_rheo>`. Bulk
particles have a value of 0, surface particles have a value of 1, and
splash particles have a value of 2. The *surface/r* property is the
distance from the surface, up to the kernel cutoff length. Surface particles
have a value of 0. The *surface/n/*:math:`\alpha` properties are the
components of the surface normal vector.
The *shift/v/*:math:`\alpha` properties are the components of the shifting
velocity produced by the *shift* option of :doc:`fix rheo <fix_rheo>`.
The *nbond/shell* property is the number of shell bonds that have been
activated from :doc:`bond style rheo/shell <bond_rheo_shell>`.
The values are stored in a per-atom vector or array as discussed
below. Zeroes are stored for atoms not in the specified group or for
quantities that are not defined for a particular particle in the group
Output info
"""""""""""
This compute calculates a per-atom vector or per-atom array depending
on the number of input values. Generally, if a single input is specified,
a per-atom vector is produced. If two or more inputs are specified, a
per-atom array is produced where the number of columns = the number of
inputs. However, if a wild card \* is used for a vector or tensor, then
the number of inputs is considered to be incremented by the dimension or
the dimension squared, respectively. The vector or array can be accessed
by any command that uses per-atom 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 in whatever :doc:`units <units>` the
corresponding attribute is in (e.g., density units for *rho*).
Restrictions
""""""""""""
none
Related commands
""""""""""""""""
:doc:`dump custom <dump>`, :doc:`compute reduce <compute_reduce>`,
:doc:`fix ave/atom <fix_ave_atom>`, :doc:`fix ave/chunk <fix_ave_chunk>`,
:doc:`fix rheo/viscosity <fix_rheo_viscosity>`,
:doc:`fix rheo/pressure <fix_rheo_pressure>`,
:doc:`fix rheo/thermal <fix_rheo_thermal>`,
:doc:`fix rheo/oxdiation <fix_rheo_oxidation>`,
:doc:`fix rheo <fix_rheo>`
Default
"""""""
none

View File

@ -193,6 +193,7 @@ accelerated styles exist.
* :doc:`adapt <fix_adapt>` - change a simulation parameter over time
* :doc:`adapt/fep <fix_adapt_fep>` - enhanced version of fix adapt
* :doc:`addforce <fix_addforce>` - add a force to each atom
* :doc:`add/heat <fix_add_heat>` - add a heat flux to each atom
* :doc:`addtorque <fix_addtorque>` - add a torque to a group of atoms
* :doc:`alchemy <fix_alchemy>` - perform an "alchemical transformation" between two partitions
* :doc:`amoeba/bitorsion <fix_amoeba_bitorsion>` - torsion/torsion terms in AMOEBA force field
@ -369,6 +370,11 @@ accelerated styles exist.
* :doc:`reaxff/species <fix_reaxff_species>` - write out ReaxFF molecule information
* :doc:`recenter <fix_recenter>` - constrain the center-of-mass position of a group of atoms
* :doc:`restrain <fix_restrain>` - constrain a bond, angle, dihedral
* :doc:`rheo <fix_rheo>` - integrator for the RHEO package
* :doc:`rheo/thermal <fix_rheo_thermal>` - thermal integrator for the RHEO package
* :doc:`rheo/oxidation <fix_rheo_oxidation>` - create oxidation bonds for the RHEO package
* :doc:`rheo/pressure <fix_rheo_pressure>` - pressure calculation for the RHEO package
* :doc:`rheo/viscosity <fix_rheo_pressure>` - viscosity calculation for the RHEO package
* :doc:`rhok <fix_rhok>` - add bias potential for long-range ordered systems
* :doc:`rigid <fix_rigid>` - constrain one or more clusters of atoms to move as a rigid body with NVE integration
* :doc:`rigid/meso <fix_rigid_meso>` - constrain clusters of mesoscopic SPH/SDPD particles to move as a rigid body

111
doc/src/fix_add_heat.rst Normal file
View File

@ -0,0 +1,111 @@
.. index:: fix add/heat
fix add/heat command
====================
Syntax
""""""
.. code-block:: LAMMPS
fix ID group-ID add/heat style args keyword values ...
* ID, group-ID are documented in :doc:`fix <fix>` command
* add/heat = style name of this fix command
* style = *constant* or *linear* or *quartic*
.. parsed-literal::
*constant* args = *rate*
*rate* = rate of heat flow (energy/time units)
*linear* args = :math:`T_{target}` *k*
:math:`T_{target}` = target temperature (temperature units)
*k* = prefactor (energy/(time*temperature) units)
*quartic* args = :math:`T_{target}` *k*
:math:`T_{target}` = target temperature (temperature units)
*k* = prefactor (energy/(time*temperature^4) units)
* zero or more keyword/value pairs may be appended to args
* keyword = *overwrite*
.. parsed-literal::
*overwrite* value = *yes* or *no*
*yes* = sets current heat flow of particle
*no* = adds to current heat flow of particle
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all add/heat constant v_heat
fix 1 all add/heat linear 10.0 1.0 overwrite yes
Description
"""""""""""
This fix adds heat to particles with the temperature attribute every timestep.
Note that this is an internal temperature of a particle intended for use with
non-atomistic models like the discrete element method.
For the *constant* style, heat is added at the specified rate. For the *linear* style,
heat is added at a rate of :math:`k (T_{target} - T)` where :math:`k` is the
specified prefactor, :math:`T_{target}` is the specified target temperature, and
:math:`T` is the temperature of the atom. This may be more representative of a
conductive process. For the *quartic* style, heat is added at a rate of
:math:`k (T_{target}^4 - T^4)`, akin to radiative heat transfer.
The rate or temperature can be can be specified as an equal-style or atom-style
:doc:`variable <variable>`. If the value is a variable, it should be
specified as v_name, where name is the variable name. In this case, the
variable will be evaluated each time step, and its value will be used to
determine the rate of heat added.
Equal-style variables can specify formulas with various mathematical
functions and include :doc:`thermo_style <thermo_style>` command
keywords for the simulation box parameters, time step, and elapsed time
to specify time-dependent heating.
Atom-style variables can specify the same formulas as equal-style
variables but can also include per-atom values, such as atom
coordinates to specify spatially-dependent heating.
If the *overwrite* keyword is set to *yes*, this fix will set the total
heat flow on a particle every timestep, overwriting contributions from pair
styles or other fixes. If *overwrite* is *no*, this fix will add heat on
top of other contributions.
----------
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 pair style is part of the GRANULAR package. It is
only enabled if LAMMPS was built with that package.
See the :doc:`Build package <Build_package>` page for more info.
This fix requires that atoms store temperature and heat flow
as defined by the :doc:`fix property/atom <fix_property_atom>` command.
Related commands
""""""""""""""""
:doc:`fix heat/flow <fix_heat_flow>`,
:doc:`fix property/atom <fix_property_atom>`,
:doc:`fix rheo/thermal <fix_rheo_thermal>`
Default
"""""""
The default for the *overwrite* keyword is *no*

View File

@ -1,7 +1,7 @@
.. index:: fix heat/flow
fix heat/flow command
==========================
=====================
Syntax
""""""
@ -56,13 +56,19 @@ not invoked during :doc:`energy minimization <minimize>`.
Restrictions
""""""""""""
This pair style is part of the GRANULAR package. It is
only enabled if LAMMPS was built with that package.
See the :doc:`Build package <Build_package>` page for more info.
This fix requires that atoms store temperature and heat flow
as defined by the :doc:`fix property/atom <fix_property_atom>` command.
Related commands
""""""""""""""""
:doc:`pair granular <pair_granular>`, :doc:`fix property/atom <fix_property_atom>`
:doc:`pair granular <pair_granular>`,
:doc:`fix add/heat <fix_add_heat>`,
:doc:`fix property/atom <fix_property_atom>`
Default
"""""""

180
doc/src/fix_rheo.rst Normal file
View File

@ -0,0 +1,180 @@
.. index:: fix rheo
fix rheo command
================
Syntax
""""""
.. parsed-literal::
fix ID group-ID rheo cut kstyle zmin keyword values...
* ID, group-ID are documented in :doc:`fix <fix>` command
* rheo = style name of this fix command
* cut = cutoff for the kernel (distance)
* kstyle = *quintic* or *RK0* or *RK1* or *RK2*
* zmin = minimal number of neighbors for reproducing kernels
* zero or more keyword/value pairs may be appended to args
* keyword = *thermal* or *interface/reconstruct* or *surface/detection* or
*shift* or *rho/sum* or *density* or *self/mass* or *speed/sound*
.. parsed-literal::
*thermal* values = none, turns on thermal evolution
*interface/reconstruct* values = none, reconstructs interfaces with solid particles
*surface/detection* values = *sdstyle* *limit* *limit/splash*
*sdstyle* = *coordination* or *divergence*
*limit* = threshold for surface particles
*limit/splash* = threshold for splash particles
*shift* values = none, turns on velocity shifting
*rho/sum* values = none, uses the kernel to compute the density of particles
*self/mass* values = none, a particle uses its own mass in a rho summation
*density* values = *rho01*, ... *rho0N* (density)
*speed/sound* values = *cs0*, ... *csN* (velocity)
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all rheo 3.0 quintic 0 thermal density 0.1 0.1 speed/sound 10.0 1.0
fix 1 all rheo 3.0 RK1 10 shift surface/detection coordination 40
Description
"""""""""""
.. versionadded:: TBD
Perform time integration for RHEO particles, updating positions, velocities,
and densities. For a detailed breakdown of the integration timestep and
numerical details, see :ref:`(Palermo) <rheo_palermo>`. For an
overview of other features available in the RHEO package, see
:doc:`the RHEO howto <Howto_rheo>`.
The type of kernel is specified using *kstyle* and the cutoff is *cut*. Four
kernels are currently available. The *quintic* kernel is a standard quintic
spline function commonly used in SPH. The other options, *RK0*, *RK1*, and
*RK2*, are zeroth, first, and second order reproducing. To generate a
reproducing kernel, a particle must have sufficient neighbors inside the
kernel cutoff distance (a coordination number) to accurately calculate
moments. This threshold is set by *zmin*. If reproducing kernels are
requested but a particle has fewer neighbors, then it will revert to a
non-reproducing quintic kernel until it gains more neighbors.
To model temperature evolution, one must specify the *thermal* keyword,
define a separate instance of :doc:`fix rheo/thermal <fix_rheo_thermal>`,
and use atom style rheo/thermal.
By default, the density of solid RHEO particles does not evolve and forces
with fluid particles are calculated using the current velocity of the solid
particle. If the *interface/reconstruct* keyword is used, then the density
and velocity of solid particles are alternatively reconstructed for every
fluid-solid interaction to ensure no-slip and pressure-balanced boundaries.
This is done by estimating the location of the fluid-solid interface and
extrapolating fluid particle properties across the interface to calculate a
temporary apparent density and velocity for a solid particle. The numerical
details are the same as those described in
:ref:`(Palermo) <howto_rheo_palermo>` except there is an additional
restriction that the reconstructed solid density cannot be less than the
equilibrium density. This prevents fluid particles from sticking to solid
surfaces.
A modified form of Fickian particle shifting can be enabled with the
*shift* keyword. This effectively shifts particle positions to generate a
more uniform spatial distribution. Shifting currently does not consider the
type of a particle and therefore may be inappropriate in systems consisting
of multiple fluid phases.
In systems with free surfaces, the *surface/detection* keyword can be used
to classify the location of particles as being within the bulk fluid, on a
free surface, or isolated from other particles in a splash or droplet.
Shifting is then disabled in the normal direction away from the free surface
to prevent particles from diffusing away. Surface detection can also be used
to control surface-nucleated effects like oxidation when used in combination
with :doc:`fix rheo/oxidation <fix_rheo_oxidation>`. Surface detection is not
performed on solid bodies.
The *surface/detection* keyword takes three arguments: *sdstyle*, *limit*,
and *limit/splash*. The first, *sdstyle*, specifies whether surface particles
are identified using a coordination number (*coordination*) or the divergence
of the local particle positions (*divergence*). The threshold value for a
surface particle for either of these criteria is set by the numerical value
of *limit*. Additionally, if a particle's coordination number is too low,
i.e. if it has separated off from the bulk in a droplet, it is not possible
to define surfaces and the particle is classified as a splash. The coordination
threshold for this classification is set by the numerical value of
*limit/splash*.
By default, RHEO integrates particles' densities using a mass diffusion
equation. Alternatively, one can update densities every timestep by performing
a kernel summation of the masses of neighboring particles by specifying the *rho/sum*
keyword.
The *self/mass* keyword modifies the behavior of the density summation in *rho/sum*.
Typically, the density :math:`\rho` of a particle is calculated as the sum over neighbors
.. math::
\rho_i = \sum_{j} W_{ij} M_j
where :math:`W_{ij}` is the kernel, and :math:`M_j` is the mass of particle :math:`j`.
The *self/mass* keyword augments this expression by replacing :math:`M_j` with
:math:`M_i`. This may be useful in simulations of multiple fluid phases with large
differences in density, :ref:`(Hu) <fix_rheo_hu>`.
The *density* keyword is used to specify the equilibrium density of each of the N
particle types. It must be followed by N numerical values specifying each type's
equilibrium density *rho0*.
The *speed/sound* keyword is used to specify the speed of sound of each of the
N particle types. It must be followed by N numerical values specifying each type's
speed of sound *cs*.
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 must be used with atom style rheo or rheo/thermal. This fix must
be used in conjunction with :doc:`fix rheo/pressure <fix_rheo_pressure>`.
and :doc:`fix rheo/viscosity <fix_rheo_viscosity>`. If the *thermal* setting
is used, there must also be an instance of
:doc:`fix rheo/thermal <fix_rheo_thermal>`. The fix group must be set to all.
Only one instance of fix rheo may be defined and it must be defined prior
to all other RHEO fixes in the input script.
This fix is part of the RHEO 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:`fix rheo/viscosity <fix_rheo_viscosity>`,
:doc:`fix rheo/pressure <fix_rheo_pressure>`,
:doc:`fix rheo/thermal <fix_rheo_thermal>`,
:doc:`pair rheo <pair_rheo>`,
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`
Default
"""""""
*rho0* and *cs* are set to 1.0 for all atom types.
----------
.. _rheo_palermo:
**(Palermo)** Palermo, Wolf, Clemmer, O'Connor, in preparation.
.. _fix_rheo_hu:
**(Hu)** Hu, and Adams J. Comp. Physics, 213, 844-861 (2006).

View File

@ -0,0 +1,85 @@
.. index:: fix rheo/oxidation
fix rheo/oxidation command
==========================
Syntax
""""""
.. parsed-literal::
fix ID group-ID rheo/oxidation cut btype rsurf
* ID, group-ID are documented in :doc:`fix <fix>` command
* rheo/oxidation = style name of this fix command
* cut = maximum bond length (distance units)
* btype = type of bonds created
* rsurf = distance from surface to create bonds (distance units)
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all rheo/oxidation 1.5 2 0.0
fix 1 all rheo/oxidation 1.0 1 2.0
Description
"""""""""""
.. versionadded:: TBD
This fix dynamically creates bonds on the surface of fluids to
represent physical processes such as oxidation. It is intended
for use with bond style :doc:`bond rheo/shell <bond_rheo_shell>`.
Every timestep, particles check neighbors within a distance of *cut*.
This distance must be smaller than the kernel length defined in
:doc:`fix rheo <fix_rheo>`. Bonds of type *btype* are created between
a fluid particle and either a fluid or solid neighbor. The fluid particles
must also be on the fluid surface, or within a distance of *rsurf* from
the surface. This process is further described in
:ref:`(Clemmer) <howto_rheo_clemmer2>`.
If used in conjunction with solid bodies, such as those generated
by the *react* option of :doc:`fix rheo/thermal <fix_rheo_thermal>`,
it is recommended to use a :doc:`hybrid bond style <bond_hybrid>`
with different bond types for solid and oxide bonds.
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 must be used with the bond style :doc:`rheo/shell <bond_rheo_shell>`
and :doc:`fix rheo <fix_rheo>` with surface detection enabled.
This fix is part of the RHEO 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:`fix rheo <fix_rheo>`,
:doc:`bond rheo/shell <bond_rheo_shell>`,
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`
Default
"""""""
none
----------
.. _howto_rheo_clemmer2:
**(Clemmer)** Clemmer, Pierce, O'Connor, Nevins, Jones, Lechman, Tencer, Appl. Math. Model., 130, 310-326 (2024).

View File

@ -0,0 +1,106 @@
.. index:: fix rheo/pressure
fix rheo/pressure command
=========================
Syntax
""""""
.. parsed-literal::
fix ID group-ID rheo/pressure type1 pstyle1 args1 ... typeN pstyleN argsN
* ID, group-ID are documented in :doc:`fix <fix>` command
* rheo/pressure = style name of this fix command
* one or more types and pressure styles must be appended
* types = lists of types (see below)
* pstyle = *linear* or *taitwater* or *cubic*
.. parsed-literal::
*linear* args = none
*taitwater* args = none
*cubic* args = cubic prefactor :math:`A_3` (pressure/density\^2)
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all rheo/pressure * linear
fix 1 all rheo/pressure 1 linear 2 cubic 10.0
Description
"""""""""""
.. versionadded:: TBD
This fix defines a pressure equation of state for RHEO particles. One can
define different equations of state for different atom types. An equation
must be specified for every atom type.
One first defines the atom *types*. A wild-card asterisk can be used in place
of or in conjunction with the *types* argument to set the coefficients for
multiple pairs of atom types. This takes the form "\*" or "\*n" or "m\*"
or "m\*n". If :math:`N` is the number of atom types, then an asterisk with
no numeric values means all types from 1 to :math:`N`. A leading asterisk
means all types from 1 to n (inclusive). A trailing asterisk means all types
from m to :math:`N` (inclusive). A middle asterisk means all types from m to n
(inclusive).
The *types* definition is followed by the pressure style, *pstyle*. Current
options *linear*, *taitwater*, and *cubic*. Style *linear* is a linear
equation of state with a particle pressure :math:`P` calculated as
.. math::
P = c (\rho - \rho_0)
where :math:`c` is the speed of sound, :math:`\rho_0` is the equilibrium density,
and :math:`\rho` is the current density of a particle. The numerical values of
:math:`c` and :math:`\rho_0` are set in :doc:`fix rheo <fix_rheo>`. Style *cubic*
is a cubic equation of state which has an extra argument :math:`A_3`,
.. math::
P = c ((\rho - \rho_0) + A_3 (\rho - \rho_0)^3) .
Style *taitwater* is Tait's equation of state:
.. math::
P = \frac{c^2 \rho_0}{7} \biggl[\left(\frac{\rho}{\rho_0}\right)^{7} - 1\biggr].
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 must be used with an atom style that includes density
such as atom_style rheo or rheo/thermal. This fix must be used in
conjunction with :doc:`fix rheo <fix_rheo>`. The fix group must be
set to all. Only one instance of fix rheo/pressure can be defined.
This fix is part of the RHEO 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:`fix rheo <fix_rheo>`,
:doc:`pair rheo <pair_rheo>`,
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`
Default
"""""""
none

View File

@ -0,0 +1,128 @@
.. index:: fix rheo/thermal
fix rheo/thermal command
========================
Syntax
""""""
.. parsed-literal::
fix ID group-ID rheo/thermal attribute values ...
* ID, group-ID are documented in :doc:`fix <fix>` command
* rheo/thermal = style name of this fix command
* one or more attributes may be appended
* attribute = *conductivity* or *specific/heat* or *latent/heat* or *Tfreeze* or *react*
.. parsed-literal::
*conductivity* args = types style args
types = lists of types (see below)
style = *constant*
*constant* arg = conductivity (power/temperature)
*specific/heat* args = types style args
types = lists of types (see below)
style = *constant*
*constant* arg = specific heat (energy/(mass*temperature))
*latent/heat* args = types style args
types = lists of types (see below)
style = *constant*
*constant* arg = latent heat (energy/mass)
*Tfreeze* args = types style args
types = lists of types (see below)
style = *constant*
*constant* arg = freezing temperature (temperature)
*react* args = cut type
cut = maximum bond distance
type = bond type
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all rheo/thermal conductivity * constant 1.0 specific/heat * constant 1.0 Tfreeze * constant 1.0
fix 1 all rheo/pressure conductivity 1*2 constant 1.0 conductivity 3*4 constant 2.0 specific/heat * constant 1.0
Description
"""""""""""
.. versionadded:: TBD
This fix performs time integration of temperature for atom style rheo/thermal.
In addition, it defines multiple thermal properties of particles and handles
melting/solidification, if applicable. For more details on phase transitions
in RHEO, see :doc:`the RHEO howto <Howto_rheo>`.
Note that the temperature of a particle is always derived from the energy.
This implies the *temperature* attribute of :doc:`the set command <set>` does
not affect particles. Instead, one should use the *sph/e* attribute.
For each atom type, one can define expressions for the *conductivity*,
*specific/heat*, *latent/heat*, and critical temperature (*Tfreeze*).
The conductivity and specific heat must be defined for all atom types.
The latent heat and critical temperature are optional. However, a
critical temperature must be defined to specify a latent heat.
Note, if shifting is turned on in :doc:`fix rheo <fix_rheo>`, the gradient
of the energy is used to shift energies. This may be inappropriate in systems
with multiple atom types with different specific heats.
For each property, one must first define a list of atom types. A wild-card
asterisk can be used in place of or in conjunction with the *types* argument
to set the coefficients for multiple pairs of atom types. This takes the
form "\*" or "\*n" or "m\*" or "m\*n". If :math:`N` is the number of atom
types, then an asterisk with no numeric values means all types from 1 to
:math:`N`. A leading asterisk means all types from 1 to n (inclusive).
A trailing asterisk means all types from m to :math:`N` (inclusive). A
middle asterisk means all types from m to n (inclusive).
The *types* definition for each property is followed by the style. Currently,
the only option is *constant*. Style *constant* simply applies a constant value
of respective property to each particle of the assigned type.
The *react* keyword controls whether bonds are created/deleted when particles
transition between a fluid and solid state. This option only applies to atom
types that have a defined value of *Tfreeze*. When a fluid particle's
temperature drops below *Tfreeze*, bonds of type *btype* are created between
nearby solid particles within a distance of *cut*. The particle's status also
swaps to a solid state. When a solid particle's temperature rises above
*Tfreeze*, all bonds of type *btype* are broken and the particle's status swaps
to a fluid state.
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 must be used with an atom style that includes temperature,
heatflow, and conductivity such as atom_style rheo/thermal This fix
must be used in conjunction with :doc:`fix rheo <fix_rheo>` with the
*thermal* setting. The fix group must be set to all. Only one
instance of fix rheo/pressure can be defined.
This fix is part of the RHEO 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:`fix rheo <fix_rheo>`,
:doc:`pair rheo <pair_rheo>`,
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`,
:doc:`fix add/heat <fix_add_heat>`
Default
"""""""
none

View File

@ -0,0 +1,117 @@
.. index:: fix rheo/viscosity
fix rheo/viscosity command
==========================
Syntax
""""""
.. parsed-literal::
fix ID group-ID rheo/viscosity type1 pstyle1 args1 ... typeN pstyleN argsN
* ID, group-ID are documented in :doc:`fix <fix>` command
* rheo/viscosity = style name of this fix command
* one or more types and viscosity styles must be appended
* types = lists of types (see below)
* vstyle = *constant* or *power*
.. parsed-literal::
*constant* args = *eta*
*eta* = viscosity
*power* args = *eta*, *gd0*, *K*, *n*
*eta* = viscosity
*gd0* = critical strain rate
*K* = consistency index
*n* = power-law exponent
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all rheo/viscosity * constant 1.0
fix 1 all rheo/viscosity 1 constant 1.0 2 power 0.1 5e-4 0.001 0.5
Description
"""""""""""
.. versionadded:: TBD
This fix defines a viscosity for RHEO particles. One can define different
viscosities for different atom types, but a viscosity must be specified for
every atom type.
One first defines the atom *types*. A wild-card asterisk can be used in place
of or in conjunction with the *types* argument to set the coefficients for
multiple pairs of atom types. This takes the form "\*" or "\*n" or "m\*"
or "m\*n". If :math:`N` is the number of atom types, then an asterisk with
no numeric values means all types from 1 to :math:`N`. A leading asterisk
means all types from 1 to n (inclusive). A trailing asterisk means all types
from m to :math:`N` (inclusive). A middle asterisk means all types from m to n
(inclusive).
The *types* definition is followed by the viscosity style, *vstyle*. Two
options are available, *constant* and *power*. Style *constant* simply
applies a constant value of the viscosity *eta* to each particle of the
assigned type. Style *power* is a Hershchel-Bulkley constitutive equation
for the stress :math:`\tau`
.. math::
\tau = \left(\frac{\tau_0}{\dot{\gamma}} + K \dot{\gamma}^{n - 1}\right) \dot{\gamma}, \tau \ge \tau_0
where :math:`\dot{\gamma}` is the strain rate and :math:`\tau_0` is the critical
yield stress, below which :math:`\dot{\gamma} = 0.0`. To avoid divergences, this
expression is regularized by defining a critical strain rate *gd0*. If the local
strain rate on a particle falls below this limit, a constant viscosity of *eta*
is assigned. This implies a value of
.. math::
\tau_0 = \eta \dot{\gamma}_0 - K \dot{\gamma}_0^N
as further discussed in :ref:`(Palermo) <rheo_palermo2>`.
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 must be used with an atom style that includes viscosity
such as atom_style rheo or rheo/thermal. This fix must be used in
conjunction with :doc:`fix rheo <fix_rheo>`. The fix group must be
set to all. Only one instance of fix rheo/viscosity can be defined.
This fix is part of the RHEO 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:`fix rheo <fix_rheo>`,
:doc:`pair rheo <pair_rheo>`,
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`
Default
"""""""
none
----------
.. _rheo_palermo2:
**(Palermo)** Palermo, Wolf, Clemmer, O'Connor, in preparation.

102
doc/src/pair_rheo.rst Normal file
View File

@ -0,0 +1,102 @@
.. index:: pair_style rheo
pair_style rheo command
=======================
Syntax
""""""
.. code-block:: LAMMPS
pair_style rheo cutoff keyword values
* cutoff = global cutoff for kernel (distance units)
* zero or more keyword/value pairs may be appended to args
* keyword = *rho/damp* or *artificial/visc* or *harmonic/means*
.. parsed-literal::
*rho/damp* args = density damping prefactor :math:`\xi`
*artificial/visc* args = artificial viscosity prefactor :math:`\zeta`
*harmonic/means* args = none
Examples
""""""""
.. code-block:: LAMMPS
pair_style rheo 3.0 rho/damp 1.0 artificial/visc 2.0
pair_coeff * *
Description
"""""""""""
.. versionadded:: TBD
Pair style *rheo* computes pressure and viscous forces between particles
in the :doc:`rheo package <Howto_rheo>`. If thermal evolution is turned
on in :doc:`fix rheo <fix_rheo>`, then the pair style also calculates
heat exchanged between particles.
The *artificial/viscosity* keyword is used to specify the magnitude
:math:`\zeta` of an optional artificial viscosity contribution to forces.
This factor can help stabilize simulations by smoothing out small length
scale variations in velocity fields. Artificial viscous forces typically
are only exchanged by fluid particles. However, if interfaces are not
reconstructed in fix rheo, fluid particles will also exchange artificial
viscous forces with solid particles to improve stability.
The *rho/damp* keyword is used to specify the magnitude :math:`\xi` of
an optional pairwise damping term between the density of particles. This
factor can help stabilize simulations by smoothing out small length
scale variations in density fields. However, in systems that develop
a density gradient in equilibrium (e.g. in a hydrostatic column underlying
gravity), this option may be inappropriate.
If particles have different viscosities or conductivities, the
*harmonic/means* keyword changes how they are averaged before calculating
pairwise forces or heat exchanges. By default, an arithmetic averaged is
used, however, a harmonic mean may improve stability in systems with multiple
fluid phases with large disparities in viscosities.
No coefficients are defined for each pair of atoms types via the
:doc:`pair_coeff <pair_coeff>` command as in the examples
above.
----------
Mixing, shift, table, tail correction, restart, rRESPA info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
This style does not support the :doc:`pair_modify <pair_modify>`
shift, table, and tail options.
This style does not write information to :doc:`binary restart files <restart>`.
Thus, you need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
This 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
""""""""""""
This fix is part of the RHEO 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:`fix rheo <fix_rheo>`,
:doc:`fix rheo/pressure <fix_rheo_pressure>`,
:doc:`fix rheo/thermal <fix_rheo_thermal>`,
:doc:`fix rheo/viscosity <fix_rheo_viscosity>`,
:doc:`compute rheo/property/atom <compute_rheo_property_atom>`
Default
"""""""
Density damping and artificial viscous forces are not calculated.
Arithmetic means are used for mixing particle properties.

112
doc/src/pair_rheo_solid.rst Normal file
View File

@ -0,0 +1,112 @@
.. index:: pair_style rheo/solid
pair_style rheo/solid command
=============================
Syntax
""""""
.. code-block:: LAMMPS
pair_style rheo/solid
Examples
""""""""
.. code-block:: LAMMPS
pair_style rheo/solid
pair_coeff * * 1.0 1.5 1.0
Description
"""""""""""
.. versionadded:: TBD
Style *rheo/solid* is effectively a copy of pair style
:doc:`bpm/spring <pair_bpm_spring>` except it only applies forces
between solid RHEO particles, determined by checking the status of
each pair of neighboring particles before calculating forces.
The style 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
displacement 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 .
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
""""""""""""
This pair style is part of the RHEO 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:`fix rheo <fix_rheo>`,
:doc:`fix rheo/thermal <fix_rheo_thermal>`,
:doc:`pair bpm/spring <pair_bpm_spring>`
Default
"""""""
none

View File

@ -337,6 +337,8 @@ accelerated styles exist.
* :doc:`reaxff <pair_reaxff>` - ReaxFF potential
* :doc:`rebo <pair_airebo>` - Second generation REBO potential of Brenner
* :doc:`rebomos <pair_rebomos>` - REBOMoS potential for MoS2
* :doc:`rheo <pair_rheo>` - fluid interactions in RHEO package
* :doc:`rheo/solid <pair_rheo_solid>` - solid interactions in RHEO package
* :doc:`resquared <pair_resquared>` - Everaers RE-Squared ellipsoidal potential
* :doc:`saip/metal <pair_saip_metal>` - Interlayer potential for hetero-junctions formed with hexagonal 2D materials and metal surfaces
* :doc:`sdpd/taitwater/isothermal <pair_sdpd_taitwater_isothermal>` - Smoothed dissipative particle dynamics for water at isothermal conditions

View File

@ -859,6 +859,10 @@ of analysis.
- atom-ID molecule-ID atom-type x y z
* - peri
- atom-ID atom-type volume density x y z
* - rheo
- atom-ID atom-type status rho x y z
* - rheo/thermal
- atom-ID atom-type status rho energy x y z
* - smd
- atom-ID atom-type molecule volume mass kradius cradius x0 y0 z0 x y z
* - sph

View File

@ -120,6 +120,8 @@ Syntax
*angle* value = numeric angle type or angle type label, for all angles between selected atoms
*dihedral* value = numeric dihedral type or dihedral type label, for all dihedrals between selected atoms
*improper* value = numeric improper type or improper type label, for all impropers between selected atoms
*rheo/rho* value = density of RHEO particles (mass/distance\^3)
*rheo/status* value = status or phase of RHEO particles (unitless)
*sph/e* value = energy of SPH particles (need units)
value can be an atom-style variable (see below)
*sph/cv* value = heat capacity of SPH particles (need units)
@ -506,6 +508,10 @@ by the *bond types* (\ *angle types*, etc) field in the header of the
data file read by the :doc:`read_data <read_data>` command. These
keywords do not allow use of an atom-style variable.
Keywords *rheo/rho* and *rheo/status* set the density and the status of
rheo particles. In particular, one can only set the phase in the status
as described by the :doc:`RHEO howto page <Howto_rheo>`.
Keywords *sph/e*, *sph/cv*, and *sph/rho* set the energy, heat capacity,
and density of smoothed particle hydrodynamics (SPH) particles. See
`this PDF guide <PDF/SPH_LAMMPS_userguide.pdf>`_ to using SPH in LAMMPS.

View File

@ -393,6 +393,7 @@ buf
builtin
Bulacu
Bulatov
Bulkley
Bureekaew
burlywood
Bussi
@ -564,6 +565,7 @@ cond
conda
Conda
Condens
conductivities
conf
config
configfile
@ -1441,6 +1443,7 @@ henrich
Henrich
Hermitian
Herrmann
Hershchel
Hertizian
hertzian
Hertzsch
@ -1832,6 +1835,7 @@ Kspace
KSpace
KSpaceStyle
Kspring
kstyle
kT
kTequil
kth
@ -2272,6 +2276,7 @@ modelled
modelling
Modelling
Modine
modularity
moduli
mofff
MOFFF
@ -2489,6 +2494,7 @@ Neumann
Nevent
nevery
Nevery
Nevins
newfile
Newns
newtype
@ -3068,6 +3074,7 @@ quatw
queryargs
Queteschiner
quickmin
quintic
qw
qx
qy
@ -3079,6 +3086,7 @@ radialscreenedspin
radialspin
radian
radians
radiative
radj
Rafferty
rahman
@ -3182,6 +3190,7 @@ rg
Rg
Rhaphson
Rhe
rheo
rheological
rheology
rhodo
@ -3269,6 +3278,7 @@ rsort
rsq
rst
rstyle
rsurf
Rubensson
Rubia
Rud
@ -3652,6 +3662,7 @@ Telsa
tempCorrCoeff
templated
Templeton
Tencer
Tequil
ters
tersoff
@ -3998,6 +4009,7 @@ Vries
Vsevolod
Vsmall
Vstream
vstyle
vtarget
vtk
VTK

View File

@ -0,0 +1,75 @@
# ------ 2D water balloon ------ #
dimension 2
units lj
atom_style hybrid rheo bond
boundary m m p
comm_modify vel yes
newton off
region box block -40 40 0 80 -0.01 0.01 units box
create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50
region fluid sphere -10 40 0 30 units box side in
lattice hex 1.0
create_atoms 1 region fluid
region shell sphere -10 40 0 27 units box side out
group shell region shell
set group shell rheo/status 1
set group all vx 0.005 vy -0.04
# ------ Model parameters ------#
variable cut equal 3.0
variable n equal 1.0
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable zeta equal 0.05
variable kappa equal 0.01*${rho0}/${mp}
variable dt_max equal 0.1*${cut}/${cs}/3
variable eta equal 0.05
variable Cv equal 1.0
variable L equal 1.0
variable Tf equal 1.0
mass * ${mp}
timestep 0.1
pair_style hybrid/overlay rheo ${cut} artificial/visc ${zeta} rheo/solid
pair_coeff * * rheo
pair_coeff * * rheo/solid 1.0 1.0 1.0
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
create_bonds many shell shell 1 0 1.5
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style bpm/spring
bond_coeff 1 1.0 1.0 1.0
# A lower critical strain allows the balloon to pop
#bond_coeff 1 1.0 0.05 1.0
# ------ Drop balloon ------#
fix 1 all rheo ${cut} quintic 0 &
shift &
surface/detection coordination 22 8
fix 2 all rheo/viscosity * constant ${eta}
fix 3 all rheo/pressure * linear
fix 4 all wall/harmonic ylo EDGE 2.0 1.0 1.0
fix 5 all enforce2d
compute rho all rheo/property/atom rho
compute phase all rheo/property/atom phase
compute nbond all nbond/atom
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press atoms
#dump 1 all custom 200 atomDump id type x y vx vy fx fy c_phase c_nbond c_rho
run 30000

View File

@ -0,0 +1,382 @@
LAMMPS (17 Apr 2024 - Development - patch_5May2020-18508-g3c0eaf6870-modified)
# ------ 2D water balloon ------ #
dimension 2
units lj
atom_style hybrid rheo bond
boundary m m p
comm_modify vel yes
newton off
region box block -40 40 0 80 -0.01 0.01 units box
create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50
Created orthogonal box = (-40 0 -0.01) to (40 80 0.01)
2 by 2 by 1 MPI processor grid
region fluid sphere -10 40 0 30 units box side in
lattice hex 1.0
Lattice spacing in x,y,z = 1.0745699 1.8612097 1.0745699
create_atoms 1 region fluid
Created 2830 atoms
using lattice units in orthogonal box = (-40 0 -0.01) to (40 80 0.01)
create_atoms CPU = 0.001 seconds
region shell sphere -10 40 0 27 units box side out
group shell region shell
544 atoms in group shell
set group shell rheo/status 1
Setting atom values ...
544 settings made for rheo/status
set group all vx 0.005 vy -0.04
Setting atom values ...
2830 settings made for vx
2830 settings made for vy
# ------ Model parameters ------#
variable cut equal 3.0
variable n equal 1.0
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable mp equal 1/${n}
variable mp equal 1/1
variable zeta equal 0.05
variable kappa equal 0.01*${rho0}/${mp}
variable kappa equal 0.01*1/${mp}
variable kappa equal 0.01*1/1
variable dt_max equal 0.1*${cut}/${cs}/3
variable dt_max equal 0.1*3/${cs}/3
variable dt_max equal 0.1*3/1/3
variable eta equal 0.05
variable Cv equal 1.0
variable L equal 1.0
variable Tf equal 1.0
mass * ${mp}
mass * 1
timestep 0.1
pair_style hybrid/overlay rheo ${cut} artificial/visc ${zeta} rheo/solid
pair_style hybrid/overlay rheo 3 artificial/visc ${zeta} rheo/solid
pair_style hybrid/overlay rheo 3 artificial/visc 0.05 rheo/solid
pair_coeff * * rheo
pair_coeff * * rheo/solid 1.0 1.0 1.0
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
0 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.000 seconds
create_bonds many shell shell 1 0 1.5
Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 49 49 1
3 neighbor lists, perpetual/occasional/extra = 2 1 0
(1) command create_bonds, occasional
attributes: full, newton off
pair build: full/bin
stencil: full/bin/2d
bin: standard
(2) pair rheo, perpetual
attributes: half, newton off
pair build: half/bin/newtoff
stencil: full/bin/2d
bin: standard
(3) pair rheo/solid, perpetual, trim from (2)
attributes: half, newton off, cut 1.3
pair build: trim
stencil: none
bin: none
Added 1263 bonds, new total = 1263
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
6 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.000 seconds
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style bpm/spring
bond_coeff 1 1.0 1.0 1.0
# A lower critical strain allows the balloon to pop
#bond_coeff 1 1.0 0.05 1.0
# ------ Drop balloon ------#
fix 1 all rheo ${cut} quintic 0 shift surface/detection coordination 22 8
fix 1 all rheo 3 quintic 0 shift surface/detection coordination 22 8
fix 2 all rheo/viscosity * constant ${eta}
fix 2 all rheo/viscosity * constant 0.05
fix 3 all rheo/pressure * linear
fix 4 all wall/harmonic ylo EDGE 2.0 1.0 1.0
fix 5 all enforce2d
compute rho all rheo/property/atom rho
compute phase all rheo/property/atom phase
compute nbond all nbond/atom
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press atoms
dump 1 all custom 200 atomDump id type x y vx vy fx fy c_phase c_nbond c_rho
run 30000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- BPM bond style: doi:10.1039/D3SM01373A
@Article{Clemmer2024,
author = {Clemmer, Joel T. and Monti, Joseph M. and Lechman, Jeremy B.},
title = {A soft departure from jamming: the compaction of deformable
granular matter under high pressures},
journal = {Soft Matter},
year = 2024,
volume = 20,
number = 8,
pages = {1702--1718}
}
- @article{PalermoInPrep,
journal = {in prep},
title = {RHEO: A Hybrid Mesh-Free Model Framework for Dynamic Multi-Phase Flows},
year = {2024},
author = {Eric T. Palermo and Ki T. Wolf and Joel T. Clemmer and Thomas C. O'Connor},
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 49 49 1
6 neighbor lists, perpetual/occasional/extra = 6 0 0
(1) pair rheo, perpetual, half/full from (3)
attributes: half, newton off
pair build: halffull/newtoff
stencil: none
bin: none
(2) pair rheo/solid, perpetual, trim from (1)
attributes: half, newton off, cut 1.3
pair build: trim
stencil: none
bin: none
(3) compute RHEO/KERNEL, perpetual
attributes: full, newton off
pair build: full/bin
stencil: full/bin/2d
bin: standard
(4) compute RHEO/GRAD, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(5) compute RHEO/VSHIFT, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(6) compute RHEO/SURFACE, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
Per MPI rank memory allocation (min/avg/max) = 17.63 | 17.64 | 17.65 Mbytes
Step Time KinEng Press Atoms
0 0 0.0008125 0.00035927734 2830
200 20 0.0008125 0.00035927734 2830
400 40 0.0008125 0.00035927734 2830
600 60 0.0008125 0.00035927734 2830
800 80 0.0008125 0.00035927734 2830
1000 100 0.0008125 0.00035927734 2830
1200 120 0.0008125 0.00035927734 2830
1400 140 0.0008125 0.00035927734 2830
1600 160 0.0008125 0.00035927734 2830
1800 180 0.0008125 0.00035927734 2830
2000 200 0.0008125 0.00035927734 2830
2200 220 0.0008125 0.00035927734 2830
2400 240 0.00079033569 0.00043037861 2830
2600 260 0.0007549229 0.00045188383 2830
2800 280 0.00072808836 0.00031695003 2830
3000 300 0.0007017958 1.6121754e-05 2830
3200 320 0.00067479047 -0.00015725514 2830
3400 340 0.00064762254 -0.00023361314 2830
3600 360 0.00061960255 -0.00033837679 2830
3800 380 0.0005857206 -0.00051770716 2830
4000 400 0.00055061733 -0.00070309251 2830
4200 420 0.00051884719 -0.0008247795 2830
4400 440 0.00049022236 -0.00099918413 2830
4600 460 0.00046060011 -0.0010923159 2830
4800 480 0.00042900173 -0.0011524571 2830
5000 500 0.00039751503 -0.0012586358 2830
5200 520 0.00036620054 -0.0013973543 2830
5400 540 0.00033130023 -0.0015185231 2830
5600 560 0.00030565892 -0.0016159836 2830
5800 580 0.00028209836 -0.0016925198 2830
6000 600 0.00024695044 -0.0017796892 2830
6200 620 0.00021190635 -0.0018706272 2830
6400 640 0.0001947093 -0.0019146643 2830
6600 660 0.00018903936 -0.0019146199 2830
6800 680 0.00017753371 -0.0019390155 2830
7000 700 0.00015170593 -0.0020247472 2830
7200 720 0.00011509692 -0.0021222209 2830
7400 740 7.9861785e-05 -0.0022033181 2830
7600 760 6.1350463e-05 -0.0022511971 2830
7800 780 6.5269523e-05 -0.0022222806 2830
8000 800 8.5709569e-05 -0.0021089664 2830
8200 820 0.00011746348 -0.0019351493 2830
8400 840 0.00015698134 -0.0017079928 2830
8600 860 0.00019758065 -0.0014618965 2830
8800 880 0.00023338199 -0.0012365832 2830
9000 900 0.00026282353 -0.0010348527 2830
9200 920 0.00028604776 -0.00085287884 2830
9400 940 0.00030388767 -0.000681122 2830
9600 960 0.000317589 -0.00052203521 2830
9800 980 0.00032716728 -0.00037501187 2830
10000 1000 0.00033270692 -0.00025576132 2830
10200 1020 0.00033485986 -0.00016554207 2830
10400 1040 0.00033476763 -9.8525417e-05 2830
10600 1060 0.00033351922 -5.1166347e-05 2830
10800 1080 0.00033161645 -2.0773965e-05 2830
11000 1100 0.00032913022 2.2384421e-07 2830
11200 1120 0.00032618376 1.2304773e-05 2830
11400 1140 0.00032310409 1.3725982e-05 2830
11600 1160 0.0003202128 9.0431945e-06 2830
11800 1180 0.00031760386 -5.3537879e-07 2830
12000 1200 0.00031518884 -1.331708e-05 2830
12200 1220 0.00031283958 -3.0838612e-05 2830
12400 1240 0.0003104901 -5.0038548e-05 2830
12600 1260 0.00030811597 -6.9699925e-05 2830
12800 1280 0.00030555782 -8.9972287e-05 2830
13000 1300 0.00030256671 -0.00011712941 2830
13200 1320 0.00029907961 -0.00015495826 2830
13400 1340 0.00029504656 -0.00020292633 2830
13600 1360 0.0002905184 -0.00024892421 2830
13800 1380 0.00028564542 -0.000295085 2830
14000 1400 0.00028073246 -0.00034571956 2830
14200 1420 0.00027611457 -0.00039341977 2830
14400 1440 0.00027217382 -0.0004281012 2830
14600 1460 0.00026919129 -0.00045342545 2830
14800 1480 0.00026727674 -0.00047323419 2830
15000 1500 0.0002663482 -0.00048423944 2830
15200 1520 0.00026616663 -0.0004816085 2830
15400 1540 0.00026634862 -0.00047573486 2830
15600 1560 0.0002664314 -0.00046803192 2830
15800 1580 0.00026603348 -0.00045753668 2830
16000 1600 0.00026511015 -0.00044676105 2830
16200 1620 0.00026373403 -0.00044075794 2830
16400 1640 0.00026217342 -0.00043684036 2830
16600 1660 0.0002607038 -0.00042774771 2830
16800 1680 0.00025951097 -0.00041603026 2830
17000 1700 0.00025869088 -0.00040302996 2830
17200 1720 0.00025825588 -0.00038415247 2830
17400 1740 0.00025818373 -0.00035742127 2830
17600 1760 0.00025843381 -0.00032854722 2830
17800 1780 0.00025897836 -0.00029821183 2830
18000 1800 0.00025981472 -0.00026108907 2830
18200 1820 0.00026095775 -0.00021731058 2830
18400 1840 0.00026239688 -0.00017030825 2830
18600 1860 0.00026404432 -0.00011868778 2830
18800 1880 0.00026574247 -5.9556286e-05 2830
19000 1900 0.00026729563 2.3014881e-06 2830
19200 1920 0.00026852418 6.2100169e-05 2830
19400 1940 0.00026929086 0.00012090325 2830
19600 1960 0.0002695407 0.00017904223 2830
19800 1980 0.00026929677 0.00023112254 2830
20000 2000 0.00026863577 0.0002756697 2830
20200 2020 0.00026765699 0.0003158399 2830
20400 2040 0.00026646841 0.00035200747 2830
20600 2060 0.00026516938 0.00038018442 2830
20800 2080 0.00026383495 0.00040179111 2830
21000 2100 0.00026252489 0.00042030921 2830
21200 2120 0.00026128616 0.00043466976 2830
21400 2140 0.00026014896 0.00044221445 2830
21600 2160 0.00025912325 0.00044531883 2830
21800 2180 0.00025821515 0.00044661709 2830
22000 2200 0.00025742576 0.00044409089 2830
22200 2220 0.00025674938 0.00043634999 2830
22400 2240 0.00025617111 0.00042630344 2830
22600 2260 0.0002556791 0.00041561603 2830
22800 2280 0.00025525963 0.00040166735 2830
23000 2300 0.00025489538 0.00038430419 2830
23200 2320 0.00025456861 0.0003669402 2830
23400 2340 0.00025426747 0.00034972373 2830
23600 2360 0.00025398353 0.0003302242 2830
23800 2380 0.00025370842 0.00030993088 2830
24000 2400 0.00025344084 0.00029143258 2830
24200 2420 0.00025318683 0.00027421708 2830
24400 2440 0.0002529591 0.00025603123 2830
24600 2460 0.0002527713 0.00023950245 2830
24800 2480 0.00025264228 0.00022644812 2830
25000 2500 0.00025259021 0.00021540748 2830
25200 2520 0.00025262892 0.00020544201 2830
25400 2540 0.00025276229 0.00019845807 2830
25600 2560 0.0002529876 0.00019449958 2830
25800 2580 0.00025329374 0.00019082606 2830
26000 2600 0.00025366066 0.00018700064 2830
26200 2620 0.00025406164 0.00018426061 2830
26400 2640 0.00025446737 0.00018098339 2830
26600 2660 0.00025484714 0.00017471869 2830
26800 2680 0.00025516604 0.00016565557 2830
27000 2700 0.00025538911 0.00015493626 2830
27200 2720 0.00025548177 0.00014075592 2830
27400 2740 0.00025541168 0.00012205573 2830
27600 2760 0.00025514889 0.00010039772 2830
27800 2780 0.00025467547 7.7069215e-05 2830
28000 2800 0.0002539915 5.1158042e-05 2830
28200 2820 0.00025312083 2.3468384e-05 2830
28400 2840 0.00025211323 -3.2184465e-06 2830
28600 2860 0.00025104366 -2.7726301e-05 2830
28800 2880 0.00025000263 -5.0202987e-05 2830
29000 2900 0.00024907814 -6.9244776e-05 2830
29200 2920 0.00024833815 -8.2874516e-05 2830
29400 2940 0.0002478155 -9.1854992e-05 2830
29600 2960 0.00024750313 -9.766055e-05 2830
29800 2980 0.00024735538 -9.9681291e-05 2830
30000 3000 0.00024730191 -9.818759e-05 2830
Loop time of 177.982 on 4 procs for 30000 steps with 2830 atoms
Performance: 1456330.235 tau/day, 168.557 timesteps/s, 477.016 katom-step/s
99.7% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 22.913 | 27.061 | 34.594 | 87.2 | 15.20
Bond | 0.22386 | 0.26159 | 0.30792 | 6.0 | 0.15
Neigh | 0.84412 | 0.84509 | 0.8462 | 0.1 | 0.47
Comm | 0.50015 | 0.55579 | 0.60346 | 5.2 | 0.31
Output | 0.65854 | 0.69412 | 0.72473 | 2.8 | 0.39
Modify | 133.13 | 136 | 137.38 | 14.5 | 76.41
Other | | 12.57 | | | 7.06
Nlocal: 707.5 ave 1576 max 53 min
Histogram: 2 0 0 0 0 0 1 0 0 1
Nghost: 164.75 ave 239 max 94 min
Histogram: 1 0 1 0 0 0 0 1 0 1
Neighs: 12307.8 ave 27380 max 983 min
Histogram: 2 0 0 0 0 0 1 0 0 1
FullNghs: 23517 ave 53040 max 1502 min
Histogram: 2 0 0 0 0 0 1 0 0 1
Total # of neighbors = 94068
Ave neighs/atom = 33.239576
Ave special neighs/atom = 0.89257951
Neighbor list builds = 783
Dangerous builds = 0
Total wall time: 0:02:58

View File

@ -0,0 +1,76 @@
# ------ 2D dam break ------ #
dimension 2
units lj
atom_style rheo
boundary f s p
comm_modify vel yes
newton off
# ------ Create simulation box ------ #
variable n equal 1.0
variable cut equal 2.2
variable dx equal 3.0
region box block -1 150 -1 80 -0.1 0.1 units box
create_box 2 box
lattice hex ${n}
region fluid block $(xlo+v_dx+1.0) $(xlo+40.0) $(ylo+v_dx+1.0) $(yhi-20.0) EDGE EDGE units box
region walls1 block $(xlo+v_dx) $(xhi-v_dx) $(ylo+v_dx) $(yhi-v_dx) EDGE EDGE side out units box
region walls2 block EDGE EDGE EDGE $(yhi-v_dx) EDGE EDGE side in units box
region walls intersect 2 walls1 walls2
create_atoms 1 region fluid
create_atoms 2 region walls
group fluid type 1
group rig type 2
# ------ Model parameters ------ #
variable rho0 equal 1.0
variable mp equal ${rho0}/${n}
variable cs equal 1.0
variable zeta equal 0.1
variable dt_max equal 0.1*${cut}/${cs}/3
variable eta equal 0.1
variable Dr equal 0.1
mass 1 ${mp}
mass 2 $(2*v_mp)
set group all rheo/rho ${rho0}
set group all rheo/status 0
set group rig rheo/status 1
timestep ${dt_max}
pair_style rheo ${cut} artificial/visc ${zeta} #rho/damp ${Dr}
pair_coeff * *
# ------ Fixes & computes ------ #
fix 1 all rheo ${cut} quintic 10 &
surface/detection coordination 22 8 &
rho/sum
fix 2 all rheo/viscosity * constant ${eta}
fix 3 all rheo/pressure * linear
fix 4 all gravity 1e-3 vector 0 -1 0
fix 5 rig setforce 0.0 0.0 0.0
fix 6 all enforce2d
compute rho all rheo/property/atom rho
compute p all rheo/property/atom pressure
compute surf all rheo/property/atom surface
compute sn all rheo/property/atom surface/n/x surface/n/y
# ------ Output & Run ------ #
thermo 20
thermo_style custom step time ke press
#dump 1 all custom 200 atomDump id type x y vx vy fx fy c_rho c_surf c_p c_sn[*]
run 30000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
# ------ 2D Ice Cube Pour ------ #
dimension 2
units lj
atom_style hybrid rheo/thermal bond
boundary m m p
comm_modify vel yes
newton off
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
region box block -25 25 0 100 -0.01 0.01 units box
create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50
region fluid block $(xlo+1) $(xhi-1) $(ylo+1) $(ylo+30) EDGE EDGE units box
lattice sq 1.0
create_atoms 1 region fluid
set group all sph/e 8.0
# ------ Model parameters ------#
variable cut equal 3.0
variable n equal 1.0
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable zeta equal 0.05
variable kappa equal 0.01*${rho0}/${mp}
variable dt_max equal 0.1*${cut}/${cs}/3
variable eta equal 0.05
variable Cv equal 1.0
variable L equal 1.0
variable Tf equal 1.0
mass * ${mp}
timestep 0.1
pair_style hybrid/overlay rheo ${cut} artificial/visc ${zeta} rheo/solid
pair_coeff * * rheo
pair_coeff * * rheo/solid 1.0 1.0 1.0
bond_style bpm/spring
bond_coeff 1 1.0 1.0 1.0
# ------ Pour particles ------#
molecule my_mol "square.mol"
# Wall region extends far enough in z to avoid contact
region wall block EDGE EDGE EDGE EDGE -5 5 side in open 4 units box
region drop block -16 16 70 90 EDGE EDGE side in units box
fix 1 all rheo ${cut} quintic 0 &
thermal &
shift &
surface/detection coordination 22 8
fix 2 all rheo/viscosity * constant ${eta}
fix 3 all rheo/pressure * linear
fix 4 all rheo/thermal conductivity * constant ${kappa} &
specific/heat * constant ${Cv} &
Tfreeze * constant ${Tf} &
latent/heat * constant ${L} &
react 1.5 1
fix 5 all wall/region wall harmonic 1.0 1.0 1.0
fix 6 all gravity 5e-4 vector 0 -1 0
fix 7 all deposit 8 0 1000 37241459 mol my_mol region drop near 2.0 vy -0.02 -0.02
fix 8 all enforce2d
compute rho all rheo/property/atom rho
compute phase all rheo/property/atom phase
compute temp all rheo/property/atom temperature
compute eng all rheo/property/atom energy
compute nbond all nbond/atom
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press atoms
#dump 1 all custom 200 atomDump id type x y vx vy fx fy c_phase c_temp c_eng c_nbond c_rho
run 30000

View File

@ -0,0 +1,379 @@
LAMMPS (17 Apr 2024 - Development - patch_5May2020-18508-g3c0eaf6870-modified)
# ------ 2D Ice Cube Pour ------ #
dimension 2
units lj
atom_style hybrid rheo/thermal bond
boundary m m p
comm_modify vel yes
newton off
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
region box block -25 25 0 100 -0.01 0.01 units box
create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50
Created orthogonal box = (-25 0 -0.01) to (25 100 0.01)
2 by 2 by 1 MPI processor grid
region fluid block $(xlo+1) $(xhi-1) $(ylo+1) $(ylo+30) EDGE EDGE units box
region fluid block -24 $(xhi-1) $(ylo+1) $(ylo+30) EDGE EDGE units box
region fluid block -24 24 $(ylo+1) $(ylo+30) EDGE EDGE units box
region fluid block -24 24 1 $(ylo+30) EDGE EDGE units box
region fluid block -24 24 1 30 EDGE EDGE units box
lattice sq 1.0
Lattice spacing in x,y,z = 1 1 1
create_atoms 1 region fluid
Created 1470 atoms
using lattice units in orthogonal box = (-25 0 -0.01) to (25 100 0.01)
create_atoms CPU = 0.001 seconds
set group all sph/e 8.0
Setting atom values ...
1470 settings made for sph/e
# ------ Model parameters ------#
variable cut equal 3.0
variable n equal 1.0
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable mp equal 1/${n}
variable mp equal 1/1
variable zeta equal 0.05
variable kappa equal 0.01*${rho0}/${mp}
variable kappa equal 0.01*1/${mp}
variable kappa equal 0.01*1/1
variable dt_max equal 0.1*${cut}/${cs}/3
variable dt_max equal 0.1*3/${cs}/3
variable dt_max equal 0.1*3/1/3
variable eta equal 0.05
variable Cv equal 1.0
variable L equal 1.0
variable Tf equal 1.0
mass * ${mp}
mass * 1
timestep 0.1
pair_style hybrid/overlay rheo ${cut} artificial/visc ${zeta} rheo/solid
pair_style hybrid/overlay rheo 3 artificial/visc ${zeta} rheo/solid
pair_style hybrid/overlay rheo 3 artificial/visc 0.05 rheo/solid
pair_coeff * * rheo
pair_coeff * * rheo/solid 1.0 1.0 1.0
bond_style bpm/spring
bond_coeff 1 1.0 1.0 1.0
# ------ Pour particles ------#
molecule my_mol "square.mol"
Read molecule template my_mol:
#Made with create_mol.py
1 molecules
0 fragments
100 atoms with max type 1
342 bonds with max type 1
0 angles with max type 0
0 dihedrals with max type 0
0 impropers with max type 0
# Wall region extends far enough in z to avoid contact
region wall block EDGE EDGE EDGE EDGE -5 5 side in open 4 units box
region drop block -16 16 70 90 EDGE EDGE side in units box
fix 1 all rheo ${cut} quintic 0 thermal shift surface/detection coordination 22 8
fix 1 all rheo 3 quintic 0 thermal shift surface/detection coordination 22 8
fix 2 all rheo/viscosity * constant ${eta}
fix 2 all rheo/viscosity * constant 0.05
fix 3 all rheo/pressure * linear
fix 4 all rheo/thermal conductivity * constant ${kappa} specific/heat * constant ${Cv} Tfreeze * constant ${Tf} latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.01 specific/heat * constant ${Cv} Tfreeze * constant ${Tf} latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.01 specific/heat * constant 1 Tfreeze * constant ${Tf} latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.01 specific/heat * constant 1 Tfreeze * constant 1 latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.01 specific/heat * constant 1 Tfreeze * constant 1 latent/heat * constant 1 react 1.5 1
fix 5 all wall/region wall harmonic 1.0 1.0 1.0
fix 6 all gravity 5e-4 vector 0 -1 0
fix 7 all deposit 8 0 1000 37241459 mol my_mol region drop near 2.0 vy -0.02 -0.02
WARNING: Molecule attributes do not match system attributes (../molecule.cpp:1881)
fix 8 all enforce2d
compute rho all rheo/property/atom rho
compute phase all rheo/property/atom phase
compute temp all rheo/property/atom temperature
compute eng all rheo/property/atom energy
compute nbond all nbond/atom
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press atoms
dump 1 all custom 200 atomDump id type x y vx vy fx fy c_phase c_temp c_eng c_nbond c_rho
run 30000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- BPM bond style: doi:10.1039/D3SM01373A
@Article{Clemmer2024,
author = {Clemmer, Joel T. and Monti, Joseph M. and Lechman, Jeremy B.},
title = {A soft departure from jamming: the compaction of deformable
granular matter under high pressures},
journal = {Soft Matter},
year = 2024,
volume = 20,
number = 8,
pages = {1702--1718}
}
- @article{PalermoInPrep,
journal = {in prep},
title = {RHEO: A Hybrid Mesh-Free Model Framework for Dynamic Multi-Phase Flows},
year = {2024},
author = {Eric T. Palermo and Ki T. Wolf and Joel T. Clemmer and Thomas C. O'Connor},
}
- @article{ApplMathModel.130.310,
title = {A hybrid smoothed-particle hydrodynamics model of oxide skins on molten aluminum},
journal = {Applied Mathematical Modelling},
volume = {130},
pages = {310-326},
year = {2024},
issn = {0307-904X},
doi = {https://doi.org/10.1016/j.apm.2024.02.027},
author = {Joel T. Clemmer and Flint Pierce and Thomas C. O'Connor and Thomas D. Nevins and Elizabeth M.C. Jones and Jeremy B. Lechman and John Tencer},
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 31 61 1
7 neighbor lists, perpetual/occasional/extra = 6 1 0
(1) pair rheo, perpetual, half/full from (3)
attributes: half, newton off
pair build: halffull/newtoff
stencil: none
bin: none
(2) pair rheo/solid, perpetual, trim from (4)
attributes: half, newton off, cut 1.3
pair build: trim
stencil: none
bin: none
(3) compute RHEO/KERNEL, perpetual
attributes: full, newton off
pair build: full/bin
stencil: full/bin/2d
bin: standard
(4) compute RHEO/GRAD, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(5) compute RHEO/VSHIFT, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(6) compute RHEO/SURFACE, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(7) fix rheo/thermal, occasional, trim from (4)
attributes: half, newton off, cut 3
pair build: trim
stencil: none
bin: none
Per MPI rank memory allocation (min/avg/max) = 15.53 | 15.61 | 15.69 Mbytes
Step Time KinEng Press Atoms
0 0 0 0 1470
200 20 5.6002982e-05 3.4434234e-05 1570
400 40 8.2173099e-05 8.6171768e-05 1570
600 60 8.019018e-05 0.00010750355 1570
800 80 0.00013866953 0.00010265608 1570
1000 100 0.00018965028 8.1985605e-05 1570
1200 120 0.00022033242 7.4736443e-05 1670
1400 140 0.00030767062 0.00011264333 1670
1600 160 0.00040770127 0.00018779992 1670
1800 180 0.00047476332 0.00023153009 1670
2000 200 0.00059116774 0.00027200445 1670
2200 220 0.0007151733 0.0002919963 1770
2400 240 0.00083392135 0.00029757889 1770
2600 260 0.00099653466 0.00036547269 1770
2800 280 0.0011964069 0.00045983458 1770
3000 300 0.0013716953 0.00055013647 1770
3200 320 0.0015174096 0.00064203572 1870
3400 340 0.0016539743 0.00086671622 1870
3600 360 0.0015887858 0.00066353749 1870
3800 380 0.0016451684 0.00070551483 1870
4000 400 0.0017330971 0.00080722283 1870
4200 420 0.001812193 0.00073573903 1970
4400 440 0.001755871 0.0010621909 1970
4600 460 0.0016190772 0.00072913706 1970
4800 480 0.0015741931 0.00073524088 1970
5000 500 0.0016488815 0.00088684275 1970
5200 520 0.0017213288 0.00077042378 2070
5400 540 0.0018509598 0.0010219434 2070
5600 560 0.0020251064 0.00083182483 2070
5800 580 0.0022473255 0.00095076144 2070
6000 600 0.0024843519 0.0011247014 2070
6200 620 0.0022282321 0.0018105932 2170
6400 640 0.0020289063 0.0014158497 2170
6600 660 0.002145241 0.0011359383 2170
6800 680 0.0024313937 0.0016475504 2170
7000 700 0.0021000599 0.0020983745 2170
7200 720 0.0019137235 0.0010439152 2270
7400 740 0.0018801367 0.00095436448 2270
7600 760 0.0017979449 0.0011184039 2270
7800 780 0.0018005205 0.0009243205 2270
8000 800 0.0017827073 0.0013671228 2270
8200 820 0.0018387108 0.0015426012 2270
8400 840 0.0016000788 0.0016751514 2270
8600 860 0.0013954964 0.0016884335 2270
8800 880 0.0013283728 0.0012399398 2270
9000 900 0.001389385 0.0012968496 2270
9200 920 0.0012295438 0.0012995821 2270
9400 940 0.0010522655 0.00082245528 2270
9600 960 0.00097085496 0.00053833131 2270
9800 980 0.0009398987 0.00063467387 2270
10000 1000 0.00092710392 0.00059494446 2270
10200 1020 0.00095545471 0.00074560644 2270
10400 1040 0.0009645841 0.00085429807 2270
10600 1060 0.00064037148 0.0017222246 2270
10800 1080 0.00046790978 0.00088204234 2270
11000 1100 0.00030106229 0.00074950209 2270
11200 1120 0.00027746016 0.00052831745 2270
11400 1140 0.0002533348 0.0006272715 2270
11600 1160 0.00021825085 0.00029691552 2270
11800 1180 0.0001451308 0.00015037478 2270
12000 1200 0.0001314823 0.00017227174 2270
12200 1220 0.00013693632 0.00017791384 2270
12400 1240 0.00014987347 0.0002286677 2270
12600 1260 0.00015092598 0.0003698436 2270
12800 1280 0.0001291653 0.00047229532 2270
13000 1300 0.00011949988 0.00049560375 2270
13200 1320 0.00011694665 0.00057542084 2270
13400 1340 9.6164519e-05 0.00062714755 2270
13600 1360 8.4517591e-05 0.00044156913 2270
13800 1380 0.00019140516 0.0003264745 2270
14000 1400 0.00013868599 0.00037753497 2270
14200 1420 9.3701636e-05 0.00031517848 2270
14400 1440 6.7389077e-05 0.0002946861 2270
14600 1460 5.3640086e-05 0.00026650711 2270
14800 1480 4.2699992e-05 0.00023789279 2270
15000 1500 5.3012016e-05 0.00019933234 2270
15200 1520 5.8834197e-05 0.00022407007 2270
15400 1540 5.0899982e-05 0.00029695531 2270
15600 1560 3.0476742e-05 0.00039119066 2270
15800 1580 1.6633264e-05 0.00033770401 2270
16000 1600 1.098906e-05 0.00036684894 2270
16200 1620 1.464848e-05 0.00036449759 2270
16400 1640 1.9598429e-05 0.00021056689 2270
16600 1660 1.2644955e-05 0.00020781781 2270
16800 1680 8.8428553e-06 0.000165 2270
17000 1700 8.8971439e-06 0.00012266475 2270
17200 1720 1.7032781e-05 0.00019873443 2270
17400 1740 1.9448563e-05 0.00025661663 2270
17600 1760 1.3714713e-05 0.000324022 2270
17800 1780 9.1326468e-06 0.00031392513 2270
18000 1800 9.2464802e-06 0.00029729527 2270
18200 1820 1.5553042e-05 0.00027488475 2270
18400 1840 1.4132933e-05 0.00019565459 2270
18600 1860 9.4734832e-06 0.00016716988 2270
18800 1880 5.5115145e-06 0.00013728033 2270
19000 1900 8.268812e-06 0.00015119605 2270
19200 1920 1.2470136e-05 0.00020222131 2270
19400 1940 9.9387775e-06 0.00024503373 2270
19600 1960 5.4241999e-06 0.00026921858 2270
19800 1980 2.7987348e-06 0.00026201267 2270
20000 2000 6.272538e-06 0.00025626323 2270
20200 2020 8.0157781e-06 0.000220139 2270
20400 2040 6.1652093e-06 0.00017089058 2270
20600 2060 2.9967592e-06 0.00014582864 2270
20800 2080 3.016678e-06 0.000148629 2270
21000 2100 7.287645e-06 0.00016486102 2270
21200 2120 8.6905277e-06 0.00020276916 2270
21400 2140 6.8453018e-06 0.00023156153 2270
21600 2160 3.3853799e-06 0.0002432462 2270
21800 2180 4.1241209e-06 0.00022829024 2270
22000 2200 7.0802396e-06 0.00020784823 2270
22200 2220 7.3361691e-06 0.00018114134 2270
22400 2240 5.0764593e-06 0.00014351106 2270
22600 2260 2.7487537e-06 0.00012919872 2270
22800 2280 4.620167e-06 0.00013746218 2270
23000 2300 6.9819357e-06 0.00015985102 2270
23200 2320 6.8923916e-06 0.00018713045 2270
23400 2340 4.1795088e-06 0.00019846682 2270
23600 2360 2.2871028e-06 0.00021068421 2270
23800 2380 3.862046e-06 0.00019553306 2270
24000 2400 5.2448555e-06 0.00017398041 2270
24200 2420 4.7565441e-06 0.00015008142 2270
24400 2440 2.2952135e-06 0.00012747106 2270
24600 2460 2.1575617e-06 0.00012516996 2270
24800 2480 4.1777868e-06 0.0001331902 2270
25000 2500 5.5679133e-06 0.00015504562 2270
25200 2520 4.5758741e-06 0.00017146032 2270
25400 2540 2.3403277e-06 0.00017611666 2270
25600 2560 2.7029302e-06 0.00016850788 2270
25800 2580 4.3601102e-06 0.00015884642 2270
26000 2600 5.2244249e-06 0.00013793898 2270
26200 2620 3.4577672e-06 0.00012395875 2270
26400 2640 2.361577e-06 0.00011600057 2270
26600 2660 2.8515644e-06 0.00011277063 2270
26800 2680 4.0851213e-06 0.0001290832 2270
27000 2700 4.2579644e-06 0.0001476495 2270
27200 2720 2.6593858e-06 0.00015977745 2270
27400 2740 1.990115e-06 0.00015612787 2270
27600 2760 2.6756835e-06 0.00014913772 2270
27800 2780 3.9032806e-06 0.00014014763 2270
28000 2800 3.2729446e-06 0.00012216846 2270
28200 2820 1.9357278e-06 0.00011078621 2270
28400 2840 1.7094832e-06 0.00010910509 2270
28600 2860 2.8731406e-06 0.00011179644 2270
28800 2880 3.7062354e-06 0.00012254091 2270
29000 2900 2.7844262e-06 0.00013060331 2270
29200 2920 1.7680655e-06 0.00013797514 2270
29400 2940 1.706873e-06 0.0001350685 2270
29600 2960 2.8764562e-06 0.00012428508 2270
29800 2980 3.1502029e-06 0.00011456718 2270
30000 3000 2.1833409e-06 0.00010317469 2270
Loop time of 165.611 on 4 procs for 30000 steps with 2270 atoms
Performance: 1565111.240 tau/day, 181.147 timesteps/s, 411.204 katom-step/s
99.7% 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.63183 | 21.226 | 42.266 | 444.6 | 12.82
Bond | 0.095073 | 0.17799 | 0.27877 | 17.0 | 0.11
Neigh | 2.0745 | 2.0781 | 2.0822 | 0.2 | 1.25
Comm | 0.32024 | 0.38703 | 0.45564 | 8.1 | 0.23
Output | 0.60459 | 0.76798 | 0.93724 | 18.6 | 0.46
Modify | 119.85 | 140.76 | 161.36 | 172.2 | 85.00
Other | | 0.2124 | | | 0.13
Nlocal: 567.5 ave 1139 max 0 min
Histogram: 2 0 0 0 0 0 0 0 0 2
Nghost: 75.5 ave 152 max 0 min
Histogram: 2 0 0 0 0 0 0 0 0 2
Neighs: 9238.25 ave 18490 max 0 min
Histogram: 2 0 0 0 0 0 0 0 0 2
FullNghs: 17945 ave 35917 max 0 min
Histogram: 2 0 0 0 0 0 0 0 0 2
Total # of neighbors = 71780
Ave neighs/atom = 31.621145
Ave special neighs/atom = 0.22026432
Neighbor list builds = 2071
Dangerous builds = 0
Total wall time: 0:02:45

View File

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

View File

@ -0,0 +1,102 @@
# ------ 2D oxidizing bar ------ #
dimension 2
units lj
atom_style hybrid rheo/thermal bond
boundary m m p
comm_modify vel yes
newton off
region box block -60 60 0 80 -0.01 0.01 units box
create_box 3 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50
region lbar block -15 0 3 80 EDGE EDGE units box
region rbar block 0 15 3 80 EDGE EDGE units box
region bar union 2 lbar rbar
region floor block EDGE EDGE EDGE 3.0 EDGE EDGE units box
lattice hex 1.0
create_atoms 1 region bar
create_atoms 3 region floor
set region rbar type 2
group bar type 1 2
group rbar type 2
group floor type 3
set group all sph/e 0.0
set group all rheo/status 1
# ------ Model parameters ------#
variable cut equal 3.0
variable n equal 1.0
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable zeta equal 0.05
variable kappa equal 0.1*${rho0}/${mp}
variable dt_max equal 0.1*${cut}/${cs}/3
variable eta equal 0.05
variable Cv equal 1.0
variable L equal 0.1
variable Tf equal 1.0
mass * ${mp}
timestep 0.1
pair_style hybrid/overlay rheo ${cut} artificial/visc ${zeta} rheo/solid
pair_coeff * * rheo
pair_coeff * * rheo/solid 1.0 1.0 1.0
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
create_bonds many bar bar 1 0 1.5
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style hybrid bpm/spring rheo/shell t/form 100
bond_coeff 1 bpm/spring 1.0 1.0 1.0
bond_coeff 2 rheo/shell 0.2 0.2 0.1
# ------ Apply dynamics ------#
# Note: surface detection is not performed on solid bodies, so cannot use surface property
compute coord all rheo/property/atom coordination
variable surf atom c_coord<22
group surf dynamic all var surf every 10
fix 1 all rheo ${cut} quintic 0 &
thermal &
shift &
surface/detection coordination 22 8
fix 2 all rheo/viscosity * constant ${eta}
fix 3 all rheo/pressure * linear
fix 4 all rheo/thermal conductivity * constant ${kappa} &
specific/heat * constant ${Cv} &
Tfreeze * constant ${Tf} &
latent/heat * constant ${L} &
react 1.5 1
fix 5 rbar rheo/oxidation 1.5 2 1.0
fix 6 all wall/harmonic ylo EDGE 2.0 1.0 1.0
fix 7 all gravity 5e-5 vector 0 -1 0
fix 8 floor setforce 0.0 0.0 0.0
fix 9 surf add/heat linear 1.1 0.05
fix 10 floor add/heat constant 0 overwrite yes # fix the temperature of the floor
fix 11 all enforce2d
compute surf all rheo/property/atom surface
compute rho all rheo/property/atom rho
compute phase all rheo/property/atom phase
compute temp all rheo/property/atom temperature
compute eng all rheo/property/atom energy
compute nbond_shell all rheo/property/atom nbond/shell
compute nbond_solid all nbond/atom bond/type 1
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press atoms
#dump 1 all custom 200 atomDump id type x y vx vy fx fy c_phase c_temp c_eng c_nbond_solid c_nbond_shell c_rho c_surf
run 40000

View File

@ -0,0 +1,488 @@
LAMMPS (17 Apr 2024 - Development - patch_5May2020-18508-g3c0eaf6870-modified)
# ------ 2D oxidizing bar ------ #
dimension 2
units lj
atom_style hybrid rheo/thermal bond
boundary m m p
comm_modify vel yes
newton off
region box block -60 60 0 80 -0.01 0.01 units box
create_box 3 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50
Created orthogonal box = (-60 0 -0.01) to (60 80 0.01)
2 by 2 by 1 MPI processor grid
region lbar block -15 0 3 80 EDGE EDGE units box
region rbar block 0 15 3 80 EDGE EDGE units box
region bar union 2 lbar rbar
region floor block EDGE EDGE EDGE 3.0 EDGE EDGE units box
lattice hex 1.0
Lattice spacing in x,y,z = 1.0745699 1.8612097 1.0745699
create_atoms 1 region bar
Created 2255 atoms
using lattice units in orthogonal box = (-60 0 -0.01) to (60 80 0.01)
create_atoms CPU = 0.001 seconds
create_atoms 3 region floor
Created 446 atoms
using lattice units in orthogonal box = (-60 0 -0.01) to (60 80 0.01)
create_atoms CPU = 0.000 seconds
set region rbar type 2
Setting atom values ...
1148 settings made for type
group bar type 1 2
2255 atoms in group bar
group rbar type 2
1148 atoms in group rbar
group floor type 3
446 atoms in group floor
set group all sph/e 0.0
Setting atom values ...
2701 settings made for sph/e
set group all rheo/status 1
Setting atom values ...
2701 settings made for rheo/status
# ------ Model parameters ------#
variable cut equal 3.0
variable n equal 1.0
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable mp equal 1/${n}
variable mp equal 1/1
variable zeta equal 0.05
variable kappa equal 0.1*${rho0}/${mp}
variable kappa equal 0.1*1/${mp}
variable kappa equal 0.1*1/1
variable dt_max equal 0.1*${cut}/${cs}/3
variable dt_max equal 0.1*3/${cs}/3
variable dt_max equal 0.1*3/1/3
variable eta equal 0.05
variable Cv equal 1.0
variable L equal 0.1
variable Tf equal 1.0
mass * ${mp}
mass * 1
timestep 0.1
pair_style hybrid/overlay rheo ${cut} artificial/visc ${zeta} rheo/solid
pair_style hybrid/overlay rheo 3 artificial/visc ${zeta} rheo/solid
pair_style hybrid/overlay rheo 3 artificial/visc 0.05 rheo/solid
pair_coeff * * rheo
pair_coeff * * rheo/solid 1.0 1.0 1.0
special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
0 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.000 seconds
create_bonds many bar bar 1 0 1.5
Generated 0 of 3 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 73 49 1
3 neighbor lists, perpetual/occasional/extra = 2 1 0
(1) command create_bonds, occasional
attributes: full, newton off
pair build: full/bin
stencil: full/bin/2d
bin: standard
(2) pair rheo, perpetual
attributes: half, newton off
pair build: half/bin/newtoff
stencil: full/bin/2d
bin: standard
(3) pair rheo/solid, perpetual, trim from (2)
attributes: half, newton off, cut 1.3
pair build: trim
stencil: none
bin: none
Added 6547 bonds, new total = 6547
Finding 1-2 1-3 1-4 neighbors ...
special bond factors lj: 0 1 1
special bond factors coul: 0 1 1
6 = max # of 1-2 neighbors
101 = max # of special neighbors
special bonds CPU = 0.000 seconds
special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0
bond_style hybrid bpm/spring rheo/shell t/form 100
bond_coeff 1 bpm/spring 1.0 1.0 1.0
bond_coeff 2 rheo/shell 0.2 0.2 0.1
# ------ Apply dynamics ------#
# Note: surface detection is not performed on solid bodies, so cannot use surface property
compute coord all rheo/property/atom coordination
variable surf atom c_coord<22
group surf dynamic all var surf every 10
dynamic group surf defined
fix 1 all rheo ${cut} quintic 0 thermal shift surface/detection coordination 22 8
fix 1 all rheo 3 quintic 0 thermal shift surface/detection coordination 22 8
fix 2 all rheo/viscosity * constant ${eta}
fix 2 all rheo/viscosity * constant 0.05
fix 3 all rheo/pressure * linear
fix 4 all rheo/thermal conductivity * constant ${kappa} specific/heat * constant ${Cv} Tfreeze * constant ${Tf} latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.1 specific/heat * constant ${Cv} Tfreeze * constant ${Tf} latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.1 specific/heat * constant 1 Tfreeze * constant ${Tf} latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.1 specific/heat * constant 1 Tfreeze * constant 1 latent/heat * constant ${L} react 1.5 1
fix 4 all rheo/thermal conductivity * constant 0.1 specific/heat * constant 1 Tfreeze * constant 1 latent/heat * constant 0.1 react 1.5 1
fix 5 rbar rheo/oxidation 1.5 2 1.0
fix 6 all wall/harmonic ylo EDGE 2.0 1.0 1.0
fix 7 all gravity 5e-5 vector 0 -1 0
fix 8 floor setforce 0.0 0.0 0.0
fix 9 surf add/heat linear 1.1 0.05
fix 10 floor add/heat constant 0 overwrite yes # fix the temperature of the floor
fix 11 all enforce2d
compute surf all rheo/property/atom surface
compute rho all rheo/property/atom rho
compute phase all rheo/property/atom phase
compute status all rheo/property/atom status
compute temp all rheo/property/atom temperature
compute eng all rheo/property/atom energy
compute nbond_shell all rheo/property/atom nbond/shell
compute nbond_solid all nbond/atom bond/type 1
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press atoms
dump 1 all custom 200 atomDump id type x y vx vy fx fy c_phase c_temp c_eng c_nbond_solid c_nbond_shell c_rho c_surf c_status
run 40000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- BPM bond style: doi:10.1039/D3SM01373A
@Article{Clemmer2024,
author = {Clemmer, Joel T. and Monti, Joseph M. and Lechman, Jeremy B.},
title = {A soft departure from jamming: the compaction of deformable
granular matter under high pressures},
journal = {Soft Matter},
year = 2024,
volume = 20,
number = 8,
pages = {1702--1718}
}
- @article{PalermoInPrep,
journal = {in prep},
title = {RHEO: A Hybrid Mesh-Free Model Framework for Dynamic Multi-Phase Flows},
year = {2024},
author = {Eric T. Palermo and Ki T. Wolf and Joel T. Clemmer and Thomas C. O'Connor},
}
- @article{ApplMathModel.130.310,
title = {A hybrid smoothed-particle hydrodynamics model of oxide skins on molten aluminum},
journal = {Applied Mathematical Modelling},
volume = {130},
pages = {310-326},
year = {2024},
issn = {0307-904X},
doi = {https://doi.org/10.1016/j.apm.2024.02.027},
author = {Joel T. Clemmer and Flint Pierce and Thomas C. O'Connor and Thomas D. Nevins and Elizabeth M.C. Jones and Jeremy B. Lechman and John Tencer},
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Generated 0 of 3 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 73 49 1
8 neighbor lists, perpetual/occasional/extra = 7 1 0
(1) pair rheo, perpetual, half/full from (3)
attributes: half, newton off
pair build: halffull/newtoff
stencil: none
bin: none
(2) pair rheo/solid, perpetual, trim from (4)
attributes: half, newton off, cut 1.3
pair build: trim
stencil: none
bin: none
(3) compute RHEO/KERNEL, perpetual
attributes: full, newton off
pair build: full/bin
stencil: full/bin/2d
bin: standard
(4) compute RHEO/GRAD, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(5) compute RHEO/VSHIFT, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(6) compute RHEO/SURFACE, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(7) fix rheo/thermal, occasional, trim from (4)
attributes: half, newton off, cut 3
pair build: trim
stencil: none
bin: none
(8) fix rheo/oxidation, perpetual, trim from (3)
attributes: full, newton off, cut 1.8
pair build: trim
stencil: none
bin: none
Per MPI rank memory allocation (min/avg/max) = 25.96 | 25.96 | 25.96 Mbytes
Step Time KinEng Press Atoms
0 0 0 0 2701
200 20 4.1743799e-07 1.1743617e-07 2701
400 40 1.6697519e-06 4.6974469e-07 2701
600 60 3.7127333e-06 1.0646825e-05 2701
800 80 4.6683656e-06 0.00015182605 2701
1000 100 4.7368707e-06 0.00028128761 2701
1200 120 3.4384322e-06 0.00045913378 2701
1400 140 1.4119866e-06 0.00055627091 2701
1600 160 4.4114517e-07 0.00058247308 2701
1800 180 4.8289229e-07 0.0005510948 2701
2000 200 1.8494183e-06 0.00048386222 2701
2200 220 3.3319816e-06 0.00037903264 2701
2400 240 3.8128922e-06 0.00024115906 2701
2600 260 3.1943401e-06 9.727407e-05 2701
2800 280 1.6172816e-06 -2.632162e-05 2701
3000 300 3.6100709e-07 -8.5761867e-05 2701
3200 320 1.4745502e-07 -5.9204127e-05 2701
3400 340 8.3369782e-07 8.8312464e-07 2701
3600 360 2.0484052e-06 5.8521477e-05 2701
3800 380 3.1639387e-06 0.0001685663 2701
4000 400 3.1692907e-06 0.00026875988 2701
4200 420 2.391933e-06 0.00038621787 2701
4400 440 1.1964404e-06 0.00048901286 2701
4600 460 4.0508824e-07 0.00051863639 2701
4800 480 5.4908507e-07 0.00049263754 2701
5000 500 1.3139665e-06 0.00041984264 2701
5200 520 2.1939161e-06 0.00033095351 2701
5400 540 2.3687031e-06 0.00022422981 2701
5600 560 1.8280882e-06 0.00011544328 2701
5800 580 8.8610517e-07 2.9307791e-05 2701
6000 600 2.0989359e-07 -1.7340941e-05 2701
6200 620 2.8658301e-07 -8.1237835e-06 2701
6400 640 9.7636239e-07 4.3755922e-05 2701
6600 660 1.891303e-06 0.0001185719 2701
6800 680 2.4149904e-06 0.00020830273 2701
7000 700 2.3174953e-06 0.00030114767 2701
7200 720 1.7918612e-06 0.00037821537 2701
7400 740 1.2114987e-06 0.0004233475 2701
7600 760 9.9661553e-07 0.00042958263 2701
7800 780 1.1552559e-06 0.00039944618 2701
8000 800 1.5249138e-06 0.00034034478 2701
8200 820 1.7453861e-06 0.00026826463 2701
8400 840 1.6259021e-06 0.00019131768 2701
8600 860 1.2612805e-06 0.0001162957 2701
8800 880 8.6964518e-07 7.1771506e-05 2701
9000 900 7.6892472e-07 5.6170687e-05 2701
9200 920 1.0780045e-06 7.1925995e-05 2701
9400 940 1.6514902e-06 0.00011635293 2701
9600 960 2.1891377e-06 0.00017599885 2701
9800 980 2.4551701e-06 0.00024127934 2701
10000 1000 2.4277051e-06 0.00029918622 2701
10200 1020 2.2655987e-06 0.00034067996 2701
10400 1040 2.1767207e-06 0.00035598133 2701
10600 1060 2.2796719e-06 0.00034359076 2701
10800 1080 2.4884225e-06 0.00030749714 2701
11000 1100 2.6387215e-06 0.00025725198 2701
11200 1120 2.5968908e-06 0.00020170699 2701
11400 1140 2.4108931e-06 0.00015185858 2701
11600 1160 2.2375166e-06 0.00011800349 2701
11800 1180 2.2407196e-06 0.00010646971 2701
12000 1200 2.4845263e-06 0.00011817498 2701
12200 1220 2.8733204e-06 0.00015013186 2701
12400 1240 3.2437087e-06 0.00019211975 2701
12600 1260 3.4732728e-06 0.00023620276 2701
12800 1280 3.5836611e-06 0.00027352269 2701
13000 1300 3.6592211e-06 0.00029533734 2701
13200 1320 3.782506e-06 0.00030032559 2701
13400 1340 3.9807086e-06 0.00028395722 2701
13600 1360 4.2023176e-06 0.00025390325 2701
13800 1380 4.3559781e-06 0.00021794236 2701
14000 1400 4.4273371e-06 0.00018026034 2701
14200 1420 4.49867e-06 0.0001526569 2701
14400 1440 4.6591574e-06 0.00013707051 2701
14600 1460 4.9589583e-06 0.00013803875 2701
14800 1480 5.3859375e-06 0.00015455425 2701
15000 1500 5.8639557e-06 0.00017954785 2701
15200 1520 6.3075561e-06 0.0002084257 2701
15400 1540 6.7022179e-06 0.0002347669 2701
15600 1560 7.0789688e-06 0.00025020766 2701
15800 1580 7.4734777e-06 0.00025394845 2701
16000 1600 7.8884743e-06 0.00024571725 2701
16200 1620 8.3224059e-06 0.00022706648 2701
16400 1640 8.7337783e-06 0.00020320706 2701
16600 1660 9.1454649e-06 0.00017824346 2701
16800 1680 9.5948793e-06 0.00015961835 2701
17000 1700 1.0106407e-05 0.00015135471 2701
17200 1720 1.0707273e-05 0.00015166884 2701
17400 1740 1.1392597e-05 0.0001645916 2701
17600 1760 1.2118829e-05 0.00018119729 2701
17800 1780 1.2846056e-05 0.0002003616 2701
18000 1800 1.3555288e-05 0.00021585952 2701
18200 1820 1.4301024e-05 0.00022290158 2701
18400 1840 1.5089217e-05 0.00021970192 2701
18600 1860 1.5902351e-05 0.00020911128 2701
18800 1880 1.6753175e-05 0.00019278718 2701
19000 1900 1.7602996e-05 0.00017584076 2701
19200 1920 1.8479378e-05 0.00016206226 2701
19400 1940 1.9421603e-05 0.00015575677 2701
19600 1960 2.0477421e-05 0.00015687558 2701
19800 1980 2.1617288e-05 0.00016424998 2701
20000 2000 2.2814347e-05 0.00017466664 2701
20200 2020 2.4029097e-05 0.00018647149 2701
20400 2040 2.5255953e-05 0.00019516077 2701
20600 2060 2.649418e-05 0.00019906384 2701
20800 2080 2.7755897e-05 0.00019630586 2701
21000 2100 2.9067854e-05 0.00018674721 2701
21200 2120 3.0396477e-05 0.0001758048 2701
21400 2140 3.1759719e-05 0.00016782801 2701
21600 2160 3.3193597e-05 0.00016324138 2701
21800 2180 3.4729384e-05 0.00016124274 2701
22000 2200 3.6367594e-05 0.00016437457 2701
22200 2220 3.8095131e-05 0.00017015573 2701
22400 2240 3.9867003e-05 0.00017649465 2701
22600 2260 4.169511e-05 0.00018111374 2701
22800 2280 4.3566134e-05 0.00018104136 2701
23000 2300 4.5461538e-05 0.00017822707 2701
23200 2320 4.7377333e-05 0.00017285066 2701
23400 2340 4.9354403e-05 0.00016826524 2701
23600 2360 5.1399791e-05 0.00016517913 2701
23800 2380 5.3510931e-05 0.00016299649 2701
24000 2400 5.5681048e-05 0.00016256674 2701
24200 2420 5.7902429e-05 0.00016513449 2701
24400 2440 6.0216049e-05 0.00016895109 2701
24600 2460 6.270982e-05 0.00016946227 2701
24800 2480 6.5390117e-05 0.00016589426 2701
25000 2500 6.8121899e-05 0.00016241676 2701
25200 2520 7.0947331e-05 0.00015624292 2701
25400 2540 7.4304148e-05 0.0001449537 2701
25600 2560 7.7745077e-05 0.00013179658 2701
25800 2580 8.0739829e-05 0.00013098838 2701
26000 2600 8.3827874e-05 0.00014278841 2701
26200 2620 8.7060677e-05 0.00015381649 2701
26400 2640 9.0266508e-05 0.00016130999 2701
26600 2660 9.3339049e-05 0.00016908268 2701
26800 2680 9.6347013e-05 0.00016771087 2701
27000 2700 9.9294711e-05 0.00016577315 2701
27200 2720 0.00010230007 0.0001670893 2701
27400 2740 0.00010547172 0.00016569077 2701
27600 2760 0.00010872426 0.00016506303 2701
27800 2780 0.00011201844 0.00016482702 2701
28000 2800 0.00011532129 0.00016694886 2701
28200 2820 0.00011869854 0.00016163005 2701
28400 2840 0.00012209747 0.00015339281 2701
28600 2860 0.00012549322 0.00014765883 2701
28800 2880 0.00012898685 0.00014241765 2701
29000 2900 0.00013259039 0.00014215724 2701
29200 2920 0.00013628209 0.00014881155 2701
29400 2940 0.00014001213 0.00015671333 2701
29600 2960 0.00014379216 0.00016446215 2701
29800 2980 0.00014764687 0.0001639602 2701
30000 3000 0.00015142301 0.00015664816 2701
30200 3020 0.00015496407 0.00015545099 2701
30400 3040 0.00015797338 0.00015368625 2701
30600 3060 0.00016042141 0.00015679918 2701
30800 3080 0.00016244716 0.00016093678 2701
31000 3100 0.00016202247 0.00016066954 2701
31200 3120 0.0001613312 0.00015932059 2701
31400 3140 0.00016274961 0.00015988567 2701
31600 3160 0.00016541518 0.00015724809 2701
31800 3180 0.00016809362 0.00015498827 2701
32000 3200 0.00017067801 0.00014830489 2701
32200 3220 0.00017333906 0.00014371345 2701
32400 3240 0.0001759011 0.00014421259 2701
32600 3260 0.00017849952 0.00014228443 2701
32800 3280 0.00017801812 0.00014117391 2701
33000 3300 0.00017718857 0.00014644675 2701
33200 3320 0.00017833666 0.0001291286 2701
33400 3340 0.000178576 0.00014878558 2701
33600 3360 0.00017846711 0.00013905481 2701
33800 3380 0.00017822937 0.00015535996 2701
34000 3400 0.00017899663 0.00016094303 2701
34200 3420 0.00017924661 0.00015017553 2701
34400 3440 0.00018024855 0.00014723549 2701
34600 3460 0.00018143865 0.00013903131 2701
34800 3480 0.00018258173 0.00013722112 2701
35000 3500 0.00018404873 0.00014675949 2701
35200 3520 0.00018538521 0.00015108242 2701
35400 3540 0.00018669649 0.00014564852 2701
35600 3560 0.00018814608 0.00013762161 2701
35800 3580 0.00018967415 0.00014602307 2701
36000 3600 0.00019146735 0.000126909 2701
36200 3620 0.00019414036 0.00012384379 2701
36400 3640 0.00019613057 0.00011059573 2701
36600 3660 0.00019897104 0.00013621801 2701
36800 3680 0.00020169688 0.00013665462 2701
37000 3700 0.00020447655 0.00013929258 2701
37200 3720 0.00020711105 0.0001363895 2701
37400 3740 0.00021077854 0.00013610672 2701
37600 3760 0.00021303084 0.00015051235 2701
37800 3780 0.00021619561 0.00012664801 2701
38000 3800 0.0002194018 0.00012808247 2701
38200 3820 0.00022242646 0.0001360174 2701
38400 3840 0.00022531568 0.00013311221 2701
38600 3860 0.00022821731 0.00013523939 2701
38800 3880 0.000231228 0.00014090695 2701
39000 3900 0.00023404038 0.00013661835 2701
39200 3920 0.00023755044 0.00013659469 2701
39400 3940 0.00024009059 0.00012097907 2701
39600 3960 0.0002432098 9.7877876e-05 2701
39800 3980 0.00024475294 0.0001164688 2701
40000 4000 0.00024171274 0.00012432219 2701
Loop time of 192.659 on 4 procs for 40000 steps with 2701 atoms
Performance: 1793840.118 tau/day, 207.620 timesteps/s, 560.783 katom-step/s
99.6% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 16.881 | 24.402 | 30.74 | 114.6 | 12.67
Bond | 1.1126 | 1.8917 | 2.6935 | 43.3 | 0.98
Neigh | 35.387 | 35.508 | 35.625 | 1.5 | 18.43
Comm | 1.5499 | 1.6694 | 1.8006 | 7.4 | 0.87
Output | 0.99755 | 1.0072 | 1.0165 | 0.8 | 0.52
Modify | 120.6 | 127.43 | 135.54 | 54.8 | 66.14
Other | | 0.7553 | | | 0.39
Nlocal: 675.25 ave 1373 max 7 min
Histogram: 2 0 0 0 0 0 0 0 0 2
Nghost: 103 ave 163 max 50 min
Histogram: 2 0 0 0 0 0 0 0 1 1
Neighs: 10509 ave 21592 max 126 min
Histogram: 2 0 0 0 0 0 0 0 0 2
FullNghs: 20367 ave 41981 max 141 min
Histogram: 2 0 0 0 0 0 0 0 0 2
Total # of neighbors = 81468
Ave neighs/atom = 30.162162
Ave special neighs/atom = 1.6593854
Neighbor list builds = 39932
Dangerous builds = 0
Total wall time: 0:03:12

View File

@ -0,0 +1,75 @@
# ------ 2D Poiseuille flow ------ #
dimension 2
units lj
atom_style rheo
boundary p p p
comm_modify vel yes
# ------ Create simulation box ------ #
variable n equal 1.0
variable cut equal 3.0
region box block 0 20 -10 10 -0.01 0.01
create_box 2 box
lattice sq ${n}
region inner block INF INF -7.5 7.5 INF INF units box
region walls block INF INF -7.5 7.5 INF INF units box side out
create_atoms 2 region walls
create_atoms 1 region inner
group fluid type 1
group rig type 2
displace_atoms fluid random 0.1 0.1 0 135414 units box
# ------ Model parameters ------ #
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable zeta equal 1.0
variable kappa equal 1.0*${rho0}/${mp}
variable fext equal 1e-4/${n}
variable dt_max equal 0.1*${cut}/${cs}/3
variable Dr equal 0.05*${cut}*${cs}
variable eta equal 0.1
variable gd0 equal 5e-4
variable npow equal 0.5
variable K equal 0.001
mass * ${mp}
set group all rheo/rho ${rho0}
set group all rheo/status 0
set group rig rheo/status 1
timestep ${dt_max}
pair_style rheo ${cut} artificial/visc ${zeta} rho/damp ${Dr}
pair_coeff * *
# ------ Fixes & computes ------ #
fix 1 all rheo ${cut} quintic 0 shift
fix 2 all rheo/viscosity * constant ${eta}
#fix 2 all rheo/viscosity * power ${eta} ${gd0} ${K} ${npow}
fix 3 all rheo/pressure * linear
fix 4 rig setforce 0.0 0.0 0.0
fix 5 fluid addforce ${fext} 0.0 0.0
fix 6 all enforce2d
compute rho all rheo/property/atom rho
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press
#dump 1 all custom 200 atomDump id type x y vx vy fx fy c_rho
run 20000

View File

@ -0,0 +1,288 @@
LAMMPS (17 Apr 2024 - Development - patch_5May2020-18508-g3c0eaf6870-modified)
# ------ 2D Poiseuille flow ------ #
dimension 2
units lj
atom_style rheo
boundary p p p
comm_modify vel yes
# ------ Create simulation box ------ #
variable n equal 1.0
variable cut equal 3.0
region box block 0 20 -10 10 -0.01 0.01
create_box 2 box
Created orthogonal box = (0 -10 -0.01) to (20 10 0.01)
2 by 2 by 1 MPI processor grid
lattice sq ${n}
lattice sq 1
Lattice spacing in x,y,z = 1 1 1
region inner block INF INF -7.5 7.5 INF INF units box
region walls block INF INF -7.5 7.5 INF INF units box side out
create_atoms 2 region walls
Created 100 atoms
using lattice units in orthogonal box = (0 -10 -0.01) to (20 10 0.01)
create_atoms CPU = 0.000 seconds
create_atoms 1 region inner
Created 300 atoms
using lattice units in orthogonal box = (0 -10 -0.01) to (20 10 0.01)
create_atoms CPU = 0.000 seconds
group fluid type 1
300 atoms in group fluid
group rig type 2
100 atoms in group rig
displace_atoms fluid random 0.1 0.1 0 135414 units box
Displacing atoms ...
# ------ Model parameters ------ #
variable rho0 equal 1.0
variable cs equal 1.0
variable mp equal ${rho0}/${n}
variable mp equal 1/${n}
variable mp equal 1/1
variable zeta equal 1.0
variable kappa equal 1.0*${rho0}/${mp}
variable kappa equal 1.0*1/${mp}
variable kappa equal 1.0*1/1
variable fext equal 1e-4/${n}
variable fext equal 1e-4/1
variable dt_max equal 0.1*${cut}/${cs}/3
variable dt_max equal 0.1*3/${cs}/3
variable dt_max equal 0.1*3/1/3
variable Dr equal 0.05*${cut}*${cs}
variable Dr equal 0.05*3*${cs}
variable Dr equal 0.05*3*1
variable eta equal 0.1
variable gd0 equal 5e-4
variable npow equal 0.5
variable K equal 0.001
mass * ${mp}
mass * 1
set group all rheo/rho ${rho0}
set group all rheo/rho 1
Setting atom values ...
400 settings made for rheo/rho
set group all rheo/status 0
Setting atom values ...
400 settings made for rheo/status
set group rig rheo/status 1
Setting atom values ...
100 settings made for rheo/status
timestep ${dt_max}
timestep 0.1
pair_style rheo ${cut} artificial/visc ${zeta} rho/damp ${Dr}
pair_style rheo 3 artificial/visc ${zeta} rho/damp ${Dr}
pair_style rheo 3 artificial/visc 1 rho/damp ${Dr}
pair_style rheo 3 artificial/visc 1 rho/damp 0.15
pair_coeff * *
# ------ Fixes & computes ------ #
fix 1 all rheo ${cut} quintic 0 shift
fix 1 all rheo 3 quintic 0 shift
fix 2 all rheo/viscosity * constant ${eta}
fix 2 all rheo/viscosity * constant 0.1
#fix 2 all rheo/viscosity * power ${eta} ${gd0} ${K} ${npow}
fix 3 all rheo/pressure * linear
fix 4 rig setforce 0.0 0.0 0.0
fix 5 fluid addforce ${fext} 0.0 0.0
fix 5 fluid addforce 0.0001 0.0 0.0
fix 6 all enforce2d
compute rho all rheo/property/atom rho
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press
dump 1 all custom 200 atomDump id type x y vx vy fx fy c_rho
run 20000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- @article{PalermoInPrep,
journal = {in prep},
title = {RHEO: A Hybrid Mesh-Free Model Framework for Dynamic Multi-Phase Flows},
year = {2024},
author = {Eric T. Palermo and Ki T. Wolf and Joel T. Clemmer and Thomas C. O'Connor},
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Generated 0 of 1 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 13 13 1
4 neighbor lists, perpetual/occasional/extra = 4 0 0
(1) pair rheo, perpetual, half/full from (2)
attributes: half, newton on
pair build: halffull/newton
stencil: none
bin: none
(2) compute RHEO/KERNEL, perpetual
attributes: full, newton on
pair build: full/bin/atomonly
stencil: full/bin/2d
bin: standard
(3) compute RHEO/GRAD, perpetual, copy from (1)
attributes: half, newton on
pair build: copy
stencil: none
bin: none
(4) compute RHEO/VSHIFT, perpetual, copy from (1)
attributes: half, newton on
pair build: copy
stencil: none
bin: none
Per MPI rank memory allocation (min/avg/max) = 5.693 | 5.693 | 5.693 Mbytes
Step Time KinEng Press
0 0 0 0
200 20 1.2220462e-06 3.7383146e-05
400 40 4.345762e-06 7.5866885e-05
600 60 8.8559433e-06 0.00011353743
800 80 1.4370506e-05 0.00015135634
1000 100 2.0576198e-05 0.00018903722
1200 120 2.721926e-05 0.00022533997
1400 140 3.4099653e-05 0.00026016069
1600 160 4.1064175e-05 0.00029445207
1800 180 4.8001225e-05 0.00032893763
2000 200 5.4832849e-05 0.00036402396
2200 220 6.1508431e-05 0.00039945249
2400 240 6.8000141e-05 0.00043534411
2600 260 7.430136e-05 0.00046943441
2800 280 8.0415328e-05 0.00049807225
3000 300 8.6335032e-05 0.00051815375
3200 320 9.2021626e-05 0.00052618224
3400 340 9.7387936e-05 0.00051877918
3600 360 0.00010231526 0.00048650828
3800 380 0.00010676617 0.00044578079
4000 400 0.00011080098 0.00044777126
4200 420 0.00011448127 0.00047047629
4400 440 0.00011787852 0.00050280249
4600 460 0.00012106805 0.0005397213
4800 480 0.00012412056 0.00057885539
5000 500 0.0001271078 0.00061396896
5200 520 0.00013006637 0.00063981812
5400 540 0.00013295039 0.00065094073
5600 560 0.00013561487 0.00063918847
5800 580 0.00013791796 0.00059087656
6000 600 0.00013983422 0.00052171998
6200 620 0.00014144833 0.00050658002
6400 640 0.00014286538 0.0005248626
6600 660 0.00014417734 0.00055826606
6800 680 0.00014546931 0.00060063748
7000 700 0.00014682553 0.00064421411
7200 720 0.0001482833 0.00068252242
7400 740 0.00014977996 0.00070671308
7600 760 0.00015114829 0.00069774026
7800 780 0.0001522719 0.00064408311
8000 800 0.00015312897 0.00055977044
8200 820 0.00015375669 0.0005225573
8400 840 0.00015425683 0.00053833691
8600 860 0.00015471278 0.00057447427
8800 880 0.0001552059 0.00061980921
9000 900 0.00015581593 0.0006659836
9200 920 0.0001565564 0.00070813532
9400 940 0.00015733573 0.00073378551
9600 960 0.00015802107 0.00071560835
9800 980 0.00015855339 0.00065636189
10000 1000 0.00015890743 0.0005699855
10200 1020 0.00015908095 0.00053138971
10400 1040 0.00015915523 0.00054790708
10600 1060 0.00015921254 0.00058899454
10800 1080 0.00015934193 0.00063964906
11000 1100 0.00015959891 0.00069241358
11200 1120 0.0001599636 0.00073734651
11400 1140 0.00016036526 0.00074477329
11600 1160 0.00016075471 0.00071047555
11800 1180 0.00016109516 0.00064173183
12000 1200 0.00016131524 0.00055500553
12200 1220 0.00016136366 0.0005290215
12400 1240 0.0001613025 0.00055124296
12600 1260 0.00016123023 0.00059758627
12800 1280 0.00016123043 0.00065488735
13000 1300 0.00016132935 0.0007140876
13200 1320 0.00016152165 0.00074795629
13400 1340 0.00016180372 0.00074730778
13600 1360 0.00016216585 0.00071370995
13800 1380 0.0001625339 0.00065176323
14000 1400 0.00016274999 0.00057515371
14200 1420 0.00016271295 0.00055878258
14400 1440 0.00016249768 0.00058448193
14600 1460 0.00016223675 0.00063096229
14800 1480 0.00016201846 0.00068639548
15000 1500 0.00016190593 0.00072444357
15200 1520 0.00016194466 0.00073830636
15400 1540 0.00016216164 0.00072773256
15600 1560 0.00016253174 0.00069215481
15800 1580 0.00016290895 0.00063239408
16000 1600 0.00016306463 0.00057466273
16200 1620 0.00016292218 0.00057951567
16400 1640 0.00016261117 0.00061504156
16600 1660 0.00016225906 0.00066066637
16800 1680 0.00016197993 0.00069751908
17000 1700 0.0001618568 0.00072202303
17200 1720 0.00016194264 0.00073255034
17400 1740 0.00016225911 0.0007231031
17600 1760 0.00016270465 0.00068931224
17800 1780 0.00016304053 0.00062934836
18000 1800 0.00016302624 0.00058060272
18200 1820 0.00016274847 0.00058859513
18400 1840 0.00016236893 0.00061804803
18600 1860 0.00016202777 0.00065393237
18800 1880 0.0001618184 0.00068747094
19000 1900 0.0001618044 0.00071352541
19200 1920 0.00016204402 0.00072351769
19400 1940 0.00016249999 0.00071330322
19600 1960 0.00016297924 0.00067984167
19800 1980 0.00016317435 0.00061634142
20000 2000 0.00016301186 0.00057234115
Loop time of 15.6198 on 4 procs for 20000 steps with 400 atoms
Performance: 11062881.511 tau/day, 1280.426 timesteps/s, 512.170 katom-step/s
99.7% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 2.1979 | 2.4473 | 2.6992 | 15.7 | 15.67
Neigh | 0.024709 | 0.027006 | 0.029223 | 1.3 | 0.17
Comm | 0.4657 | 0.71686 | 0.9662 | 29.0 | 4.59
Output | 0.033698 | 0.036781 | 0.039359 | 1.1 | 0.24
Modify | 12.306 | 12.313 | 12.319 | 0.2 | 78.83
Other | | 0.07916 | | | 0.51
Nlocal: 100 ave 107 max 93 min
Histogram: 1 0 0 1 0 0 1 0 0 1
Nghost: 185.5 ave 192 max 179 min
Histogram: 1 0 0 1 0 0 1 0 0 1
Neighs: 1712 ave 1848 max 1598 min
Histogram: 1 0 1 0 0 1 0 0 0 1
FullNghs: 3424 ave 3682 max 3174 min
Histogram: 1 0 1 0 0 0 1 0 0 1
Total # of neighbors = 13696
Ave neighs/atom = 34.24
Neighbor list builds = 331
Dangerous builds = 0
Total wall time: 0:00:15

View File

@ -0,0 +1,65 @@
# ------ 2D Taylor Green vortex ------ #
dimension 2
units lj
atom_style rheo
boundary p p p
comm_modify vel yes
newton off
# ------ Create simulation box ------ #
variable n equal 1.0
variable cut equal 3.0
region box block 0 40 0 40 -0.01 0.01
create_box 1 box
lattice sq ${n}
create_atoms 1 region box
displace_atoms all random 0.1 0.1 0 135414 units box
# ------ Model parameters ------ #
variable rho0 equal 1.0
variable mp equal ${rho0}/${n}
variable cs equal 1.0
variable eta equal 0.05
variable zeta equal 1
variable dt_max equal 0.1*${cut}/${cs}/3
variable Dr equal 0.1*${cut}*${cs}
mass * ${mp}
set group all rheo/rho ${rho0}
set group all rheo/status 0
variable u0 equal 0.05
variable uy atom ${u0}*sin(2*PI*x/lx)*cos(2*PI*y/ly)
variable ux atom -${u0}*sin(2*PI*y/ly)*cos(2*PI*x/ly)
variable d0 atom ${rho0}-${u0}*${u0}*${rho0}*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/${cs}/${cs}
velocity all set v_ux v_uy 0.0 units box
timestep ${dt_max}
pair_style rheo ${cut} artificial/visc ${zeta} rho/damp ${Dr}
pair_coeff * *
# ------ Fixes & computes ------ #
fix 1 all rheo ${cut} RK1 8 shift
fix 2 all rheo/viscosity * constant ${eta}
fix 3 all rheo/pressure * linear
fix 4 all enforce2d
compute rho all rheo/property/atom rho
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press
#dump 1 all custom 200 atomDump id type x y vx vy fx fy c_rho
run 10000

View File

@ -0,0 +1,224 @@
LAMMPS (17 Apr 2024 - Development - patch_5May2020-18508-g3c0eaf6870-modified)
# ------ 2D Taylor Green vortex ------ #
dimension 2
units lj
atom_style rheo
boundary p p p
comm_modify vel yes
newton off
# ------ Create simulation box ------ #
variable n equal 1.0
variable cut equal 3.0
region box block 0 40 0 40 -0.01 0.01
create_box 1 box
Created orthogonal box = (0 0 -0.01) to (40 40 0.01)
2 by 2 by 1 MPI processor grid
lattice sq ${n}
lattice sq 1
Lattice spacing in x,y,z = 1 1 1
create_atoms 1 region box
Created 1600 atoms
using lattice units in orthogonal box = (0 0 -0.01) to (40 40 0.01)
create_atoms CPU = 0.001 seconds
displace_atoms all random 0.1 0.1 0 135414 units box
Displacing atoms ...
# ------ Model parameters ------ #
variable rho0 equal 1.0
variable mp equal ${rho0}/${n}
variable mp equal 1/${n}
variable mp equal 1/1
variable cs equal 1.0
variable eta equal 0.05
variable zeta equal 1
variable dt_max equal 0.1*${cut}/${cs}/3
variable dt_max equal 0.1*3/${cs}/3
variable dt_max equal 0.1*3/1/3
variable Dr equal 0.1*${cut}*${cs}
variable Dr equal 0.1*3*${cs}
variable Dr equal 0.1*3*1
mass * ${mp}
mass * 1
set group all rheo/rho ${rho0}
set group all rheo/rho 1
Setting atom values ...
1600 settings made for rheo/rho
set group all rheo/status 0
Setting atom values ...
1600 settings made for rheo/status
variable u0 equal 0.05
variable uy atom ${u0}*sin(2*PI*x/lx)*cos(2*PI*y/ly)
variable uy atom 0.05*sin(2*PI*x/lx)*cos(2*PI*y/ly)
variable ux atom -${u0}*sin(2*PI*y/ly)*cos(2*PI*x/ly)
variable ux atom -0.05*sin(2*PI*y/ly)*cos(2*PI*x/ly)
variable d0 atom ${rho0}-${u0}*${u0}*${rho0}*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/${cs}/${cs}
variable d0 atom 1-${u0}*${u0}*${rho0}*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/${cs}/${cs}
variable d0 atom 1-0.05*${u0}*${rho0}*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/${cs}/${cs}
variable d0 atom 1-0.05*0.05*${rho0}*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/${cs}/${cs}
variable d0 atom 1-0.05*0.05*1*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/${cs}/${cs}
variable d0 atom 1-0.05*0.05*1*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/1/${cs}
variable d0 atom 1-0.05*0.05*1*0.25*(cos(4*PI*x/lx)+cos(4*PI*y/ly))/1/1
velocity all set v_ux v_uy 0.0 units box
timestep ${dt_max}
timestep 0.1
pair_style rheo ${cut} artificial/visc ${zeta} rho/damp ${Dr}
pair_style rheo 3 artificial/visc ${zeta} rho/damp ${Dr}
pair_style rheo 3 artificial/visc 1 rho/damp ${Dr}
pair_style rheo 3 artificial/visc 1 rho/damp 0.3
pair_coeff * *
# ------ Fixes & computes ------ #
fix 1 all rheo ${cut} RK1 8 shift
fix 1 all rheo 3 RK1 8 shift
fix 2 all rheo/viscosity * constant ${eta}
fix 2 all rheo/viscosity * constant 0.05
fix 3 all rheo/pressure * linear
fix 4 all enforce2d
compute rho all rheo/property/atom rho
# ------ Output & Run ------ #
thermo 200
thermo_style custom step time ke press
dump 1 all custom 200 atomDump id type x y vx vy fx fy c_rho
run 10000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- @article{PalermoInPrep,
journal = {in prep},
title = {RHEO: A Hybrid Mesh-Free Model Framework for Dynamic Multi-Phase Flows},
year = {2024},
author = {Eric T. Palermo and Ki T. Wolf and Joel T. Clemmer and Thomas C. O'Connor},
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 3.3
ghost atom cutoff = 3.3
binsize = 1.65, bins = 25 25 1
4 neighbor lists, perpetual/occasional/extra = 4 0 0
(1) pair rheo, perpetual, half/full from (2)
attributes: half, newton off
pair build: halffull/newtoff
stencil: none
bin: none
(2) compute RHEO/KERNEL, perpetual
attributes: full, newton off
pair build: full/bin/atomonly
stencil: full/bin/2d
bin: standard
(3) compute RHEO/GRAD, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
(4) compute RHEO/VSHIFT, perpetual, copy from (1)
attributes: half, newton off
pair build: copy
stencil: none
bin: none
Per MPI rank memory allocation (min/avg/max) = 6.835 | 6.835 | 6.835 Mbytes
Step Time KinEng Press
0 0 0.00062497276 0.00062607301
200 20 0.00056200647 0.00056633785
400 40 0.00050570968 0.00051098771
600 60 0.00045586684 0.00046081672
800 80 0.00041124523 0.00041549607
1000 100 0.00037065341 0.00037412741
1200 120 0.00033391585 0.00033580899
1400 140 0.00030078316 0.00030057307
1600 160 0.00027093231 0.00026842603
1800 180 0.00024403239 0.00023839026
2000 200 0.0002197865 0.00021148941
2200 220 0.0001979269 0.00018659386
2400 240 0.00017822267 0.00016430442
2600 260 0.00016047141 0.00014408514
2800 280 0.00014448504 0.00012574125
3000 300 0.00013009159 0.00010869938
3200 320 0.00011713578 9.414951e-05
3400 340 0.00010547564 8.1900579e-05
3600 360 9.4982139e-05 7.1285649e-05
3800 380 8.5538983e-05 6.1571123e-05
4000 400 7.7040171e-05 5.3462572e-05
4200 420 6.9390317e-05 4.6338308e-05
4400 440 6.2503763e-05 3.9697323e-05
4600 460 5.6303766e-05 3.4234465e-05
4800 480 5.0721595e-05 3.0841338e-05
5000 500 4.5695301e-05 2.7788566e-05
5200 520 4.1169161e-05 2.5744409e-05
5400 540 3.7093059e-05 2.3912739e-05
5600 560 3.3421819e-05 2.2494185e-05
5800 580 3.0114735e-05 2.1594384e-05
6000 600 2.7135224e-05 2.1164421e-05
6200 620 2.4450446e-05 2.0979349e-05
6400 640 2.2030925e-05 2.0858567e-05
6600 660 1.9850196e-05 2.098115e-05
6800 680 1.7884553e-05 2.1134827e-05
7000 700 1.6112763e-05 2.1242242e-05
7200 720 1.4515783e-05 2.1312763e-05
7400 740 1.3076456e-05 2.1370947e-05
7600 760 1.1779327e-05 2.1332126e-05
7800 780 1.0610469e-05 2.1156562e-05
8000 800 9.5573298e-06 2.0898126e-05
8200 820 8.6085799e-06 2.0517958e-05
8400 840 7.7539888e-06 1.9841551e-05
8600 860 6.9843033e-06 1.9114769e-05
8800 880 6.2911575e-06 1.8362959e-05
9000 900 5.6669785e-06 1.7473404e-05
9200 920 5.1049208e-06 1.6452745e-05
9400 940 4.5987908e-06 1.5578629e-05
9600 960 4.1429972e-06 1.4427274e-05
9800 980 3.7324962e-06 1.3169649e-05
10000 1000 3.3627455e-06 1.1938723e-05
Loop time of 38.2006 on 4 procs for 10000 steps with 1600 atoms
Performance: 2261743.875 tau/day, 261.776 timesteps/s, 418.841 katom-step/s
99.7% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 8.2958 | 8.7273 | 9.3582 | 15.2 | 22.85
Neigh | 0.034282 | 0.035689 | 0.037115 | 0.7 | 0.09
Comm | 0.16788 | 0.17018 | 0.17278 | 0.4 | 0.45
Output | 0.066977 | 0.06882 | 0.071704 | 0.7 | 0.18
Modify | 28.483 | 28.793 | 28.962 | 3.6 | 75.37
Other | | 0.4053 | | | 1.06
Nlocal: 400 ave 402 max 399 min
Histogram: 2 0 0 1 0 0 0 0 0 1
Nghost: 307.25 ave 308 max 305 min
Histogram: 1 0 0 0 0 0 0 0 0 3
Neighs: 7618.25 ave 7697 max 7564 min
Histogram: 1 0 1 1 0 0 0 0 0 1
FullNghs: 13343 ave 13497 max 13258 min
Histogram: 1 1 1 0 0 0 0 0 0 1
Total # of neighbors = 53372
Ave neighs/atom = 33.3575
Neighbor list builds = 123
Dangerous builds = 0
Total wall time: 0:00:38

14
lib/rheo/Makefile.lammps Normal file
View File

@ -0,0 +1,14 @@
# Settings that the LAMMPS build will import when this package is installed
ifeq ($(strip $(shell pkg-config --version)),)
# manual configuration w/o pkg-config/pkgconf
# change this to -I/path/to/your/lib/gsl/include/
rheo_SYSINC = -I../../lib/rheo/gsl/include/
# change this to -L/path/to/your/lib/gsl/lib/
rheo_SYSLIB = -L../../lib/rheo/gsl/lib/ -lgsl -lgslcblas
else
# autodetect GSL settings from pkg-config/pkgconf
rheo_SYSINC = $(shell pkg-config --cflags gsl)
rheo_SYSLIB = $(shell pkg-config --libs gsl)
endif

7
lib/rheo/README Normal file
View File

@ -0,0 +1,7 @@
This directory has a Makefile.lammps file with settings that allows LAMMPS to
dynamically link to the GSL library. This is required to use the RHEO package
in a LAMMPS input script. If you have the pkg-config command available, it
will automatically import the GSL settings. Otherwise they will have to be
added manually.
See the header of Makefile.lammps for more info.

5
src/.gitignore vendored
View File

@ -245,6 +245,9 @@
/pair_tdpd.cpp
/pair_tdpd.h
/*rheo*.cpp
/*rheo*.h
/compute_grid.cpp
/compute_grid.h
/compute_grid_local.cpp
@ -790,6 +793,8 @@
/fix_acks2_reaxff.h
/fix_adapt_fep.cpp
/fix_adapt_fep.h
/fix_add_heat.cpp
/fix_add_heat.h
/fix_addtorque.cpp
/fix_addtorque.h
/fix_append_atoms.cpp

View File

@ -18,6 +18,7 @@
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "fix.h"
#include "fix_bond_history.h"
#include "fix_store_local.h"
#include "fix_update_special_bonds.h"
@ -53,10 +54,14 @@ BondBPM::BondBPM(LAMMPS *_lmp) :
pack_choice(nullptr), output_data(nullptr)
{
overlay_flag = 0;
ignore_special_flag = 0;
prop_atom_flag = 0;
break_flag = 1;
nvalues = 0;
nhistory = 0;
update_flag = 0;
r0_max_estimate = 0.0;
max_stretch = 1.0;
@ -64,10 +69,10 @@ BondBPM::BondBPM(LAMMPS *_lmp) :
// 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");
id_fix_dummy = utils::strdup(fmt::format("BPM_DUMMY_{}", instance_total));
modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy));
id_fix_dummy2 = utils::strdup("BPM_DUMMY2");
id_fix_dummy2 = utils::strdup(fmt::format("BPM_DUMMY2_{}", instance_total));
modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy2));
if (lmp->citeme) lmp->citeme->add(cite_bpm);
@ -82,7 +87,7 @@ BondBPM::~BondBPM()
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 (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);
@ -109,39 +114,46 @@ void BondBPM::init_style()
fix_store_local->nvalues = nvalues;
}
if (overlay_flag) {
if (force->special_lj[1] != 1.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0 ||
force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 || force->special_coul[3] != 1.0)
error->all(FLERR,
"With overlay/pair yes, BPM bond styles require a value of 1.0 for all special_bonds weights");
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 && break_flag)
error->all(FLERR, "With overlay/pair no, or break yes, BPM bond styles require Newton bond off");
if (!ignore_special_flag) {
if (overlay_flag) {
if (force->special_lj[1] != 1.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0 ||
force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 || force->special_coul[3] != 1.0)
error->all(FLERR,
"With overlay/pair yes, BPM bond styles require a value of 1.0 for all special_bonds weights");
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 && break_flag)
error->all(FLERR, "With overlay/pair no, or break yes, BPM bond styles require Newton bond off");
// special lj must be 0 1 1 to censor pair forces between bonded particles
if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0)
error->all(FLERR,
"With overlay/pair no, BPM bond styles require special LJ weights = 0,1,1");
// if bonds can break, 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 (break_flag && (force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 ||
force->special_coul[3] != 1.0))
error->all(FLERR,
"With overlay/pair no, and break yes, BPM bond styles requires special Coulomb weights = 1,1,1");
// special lj must be 0 1 1 to censor pair forces between bonded particles
if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0)
error->all(FLERR,
"With overlay/pair no, BPM bond styles require special LJ weights = 0,1,1");
// if bonds can break, 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 (break_flag && (force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 ||
force->special_coul[3] != 1.0))
error->all(FLERR,
"With overlay/pair no, and break yes, BPM bond styles requires special Coulomb weights = 1,1,1");
if (id_fix_dummy && break_flag) {
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 (id_fix_dummy && break_flag) {
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;
}
}
// 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");
}
if (force->angle || force->dihedral || force->improper)
@ -149,10 +161,16 @@ void BondBPM::init_style()
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");
// find all instances of bond history to delete/shift data
// (bond hybrid may create multiple)
histories = modify->get_fix_by_style("BOND_HISTORY");
n_histories = histories.size();
// If a bond type isn't set, must be using bond style hybrid
hybrid_flag = 0;
for (int i = 1; i <= atom->nbondtypes; i++)
if (!setflag[i]) hybrid_flag = 1;
fix_bond_history->setflag = setflag;
}
/* ----------------------------------------------------------------------
@ -269,6 +287,14 @@ void BondBPM::settings(int narg, char **arg)
}
}
}
// Set up necessary history fix
if (!fix_bond_history) {
fix_bond_history = dynamic_cast<FixBondHistory *>(modify->replace_fix(
id_fix_dummy2, fmt::format("{} all BOND_HISTORY {} {}", id_fix_bond_history, update_flag, nhistory), 1));
delete[] id_fix_dummy2;
id_fix_dummy2 = nullptr;
}
}
/* ----------------------------------------------------------------------
@ -385,12 +411,15 @@ void BondBPM::process_broken(int i, int j)
if (i < nlocal) {
for (m = 0; m < num_bond[i]; m++) {
if (bond_atom[i][m] == tag[j]) {
if (bond_atom[i][m] == tag[j] && setflag[bond_type[i][m]]) {
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);
for (auto &ihistory: histories) {
auto fix_bond_history2 = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history2->shift_history(i, m, n - 1);
fix_bond_history2->delete_history(i, n - 1);
}
num_bond[i]--;
break;
}
@ -399,12 +428,15 @@ void BondBPM::process_broken(int i, int j)
if (j < nlocal) {
for (m = 0; m < num_bond[j]; m++) {
if (bond_atom[j][m] == tag[i]) {
if (bond_atom[j][m] == tag[i] && setflag[bond_type[j][m]]) {
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);
for (auto &ihistory: histories) {
auto fix_bond_history2 = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history2->shift_history(j, m, n - 1);
fix_bond_history2->delete_history(j, n - 1);
}
num_bond[j]--;
break;
}

View File

@ -16,8 +16,12 @@
#include "bond.h"
#include <vector>
namespace LAMMPS_NS {
class Fix;
class BondBPM : public Bond {
public:
BondBPM(class LAMMPS *);
@ -34,7 +38,7 @@ class BondBPM : public Bond {
protected:
double r0_max_estimate;
double max_stretch;
int store_local_freq;
int store_local_freq, nhistory, update_flag, hybrid_flag;
std::vector<int> leftover_iarg;
@ -50,9 +54,12 @@ class BondBPM : public Bond {
FnPtrPack *pack_choice; // ptrs to pack functions
double *output_data;
int prop_atom_flag, nvalues, overlay_flag, break_flag;
int prop_atom_flag, nvalues, overlay_flag, break_flag, ignore_special_flag;
int index_x_ref, index_y_ref, index_z_ref;
int n_histories;
std::vector<Fix *> histories;
void pack_id1(int, int, int);
void pack_id2(int, int, int);
void pack_time(int, int, int);

View File

@ -52,6 +52,9 @@ BondBPMRotational::BondBPMRotational(LAMMPS *_lmp) :
smooth_flag = 1;
normalize_flag = 0;
nhistory = 4;
id_fix_bond_history = utils::strdup("HISTORY_BPM_ROTATIONAL");
single_extra = 7;
svector = new double[7];
}
@ -458,6 +461,9 @@ void BondBPMRotational::compute(int eflag, int vflag)
store_data();
}
if (hybrid_flag)
fix_bond_history->compress_history();
int i1, i2, itmp, n, type;
double r[3], r0[3], rhat[3];
double rsq, r0_mag, r_mag, r_mag_inv;
@ -563,6 +569,9 @@ void BondBPMRotational::compute(int eflag, int vflag)
ev_tally_xyz(i1, i2, nlocal, newton_bond, 0.0, -force1on2[0] * smooth, -force1on2[1] * smooth,
-force1on2[2] * smooth, r[0], r[1], r[2]);
}
if (hybrid_flag)
fix_bond_history->uncompress_history();
}
/* ---------------------------------------------------------------------- */
@ -652,14 +661,6 @@ void BondBPMRotational::init_style()
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;
}
}
/* ---------------------------------------------------------------------- */

View File

@ -39,6 +39,9 @@ BondBPMSpring::BondBPMSpring(LAMMPS *_lmp) :
smooth_flag = 1;
normalize_flag = 0;
nhistory = 1;
id_fix_bond_history = utils::strdup("HISTORY_BPM_SPRING");
single_extra = 1;
svector = new double[1];
}
@ -137,6 +140,9 @@ void BondBPMSpring::compute(int eflag, int vflag)
store_data();
}
if (hybrid_flag)
fix_bond_history->compress_history();
int i1, i2, itmp, n, type;
double delx, dely, delz, delvx, delvy, delvz;
double e, rsq, r, r0, rinv, smooth, fbond, dot;
@ -226,6 +232,9 @@ void BondBPMSpring::compute(int eflag, int vflag)
if (evflag) ev_tally(i1, i2, nlocal, newton_bond, 0.0, fbond, delx, dely, delz);
}
if (hybrid_flag)
fix_bond_history->uncompress_history();
}
/* ---------------------------------------------------------------------- */
@ -283,14 +292,6 @@ void BondBPMSpring::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;
}
}
/* ---------------------------------------------------------------------- */

View File

@ -14,7 +14,9 @@
#include "compute_nbond_atom.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "memory.h"
@ -27,6 +29,21 @@ ComputeNBondAtom::ComputeNBondAtom(LAMMPS *_lmp, int narg, char **arg) :
{
if (narg < 3) utils::missing_cmd_args(FLERR, "compute nbond/atom", error);
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Compute nbond/atom used in system without bonds");
btype = -1;
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg], "bond/type") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "compute nbond/atom bond/type", error);
btype = utils::inumeric(FLERR, arg[iarg + 1], false, lmp);
iarg += 2;
} else {
error->all(FLERR, "Unknown compute nbond/atom command {}", arg[iarg]);
}
}
peratom_flag = 1;
size_peratom_cols = 0;
comm_reverse = 1;
@ -77,6 +94,7 @@ void ComputeNBondAtom::compute_peratom()
for (i = 0; i < nlocal; i++) {
for (j = 0; j < num_bond[i]; j++) {
if (bond_type[i][j] <= 0) continue;
if (btype != -1 && bond_type[i][j] != btype) continue;
k = atom->map(bond_atom[i][j]);
if (k < 0) continue;

View File

@ -35,7 +35,7 @@ class ComputeNBondAtom : public Compute {
double memory_usage() override;
private:
int nmax;
int nmax, btype;
double *nbond;
};

View File

@ -90,11 +90,13 @@ void FixUpdateSpecialBonds::pre_exchange()
for (auto const &it : broken_pairs) {
tagi = it.first;
tagj = it.second;
i = atom->map(tagi);
j = atom->map(tagj);
// remove i from special bond list for atom j and vice versa
// ignore n2, n3 since 1-3, 1-4 special factors required to be 1.0
// assume ghosts don't need special information
if (i < nlocal) {
slist = special[i];
n1 = nspecial[i][0];
@ -126,19 +128,24 @@ void FixUpdateSpecialBonds::pre_exchange()
// add i to special bond list for atom j and vice versa
// ignore n2, n3 since 1-3, 1-4 special factors required to be 1.0
n1 = nspecial[i][0];
if (n1 >= atom->maxspecial)
error->one(FLERR, "Special list size exceeded in fix update/special/bond");
special[i][n1] = tagj;
nspecial[i][0] += 1;
nspecial[i][1] = nspecial[i][2] = nspecial[i][0];
// assume ghosts don't need special information
if (i < nlocal) {
n1 = nspecial[i][0];
if (n1 >= atom->maxspecial)
error->one(FLERR, "Special list size exceeded for atom {}", tagi);
special[i][n1] = tagj;
nspecial[i][0] += 1;
nspecial[i][1] = nspecial[i][2] = nspecial[i][0];
}
n1 = nspecial[j][0];
if (n1 >= atom->maxspecial)
error->one(FLERR, "Special list size exceeded in fix update/special/bond");
special[j][n1] = tagi;
nspecial[j][0] += 1;
nspecial[j][1] = nspecial[j][2] = nspecial[j][0];
if (j < nlocal) {
n1 = nspecial[j][0];
if (n1 >= atom->maxspecial)
error->one(FLERR, "Special list size exceeded for atom {}", tagj);
special[j][n1] = tagi;
nspecial[j][0] += 1;
nspecial[j][1] = nspecial[j][2] = nspecial[j][0];
}
}
broken_pairs.clear();
@ -162,7 +169,7 @@ void FixUpdateSpecialBonds::pre_force(int /*vflag*/)
tagint *tag = atom->tag;
// In theory could communicate a list of broken bonds to neighboring processors here
// to remove restriction that users use Newton bond off
// to remove restriction on Newton bond off
for (int ilist = 0; ilist < neighbor->nlist; ilist++) {
list = neighbor->lists[ilist];

View File

@ -0,0 +1,161 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Joel Clemmer (SNL)
------------------------------------------------------------------------- */
#include "fix_add_heat.h"
#include "atom.h"
#include "error.h"
#include "input.h"
#include "memory.h"
#include "update.h"
#include "variable.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum { CONSTANT, EQUAL, ATOM };
enum { ADD, LINEAR, QUARTIC };
/* ---------------------------------------------------------------------- */
FixAddHeat::FixAddHeat(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), varstr(nullptr), vatom(nullptr)
{
if (narg < 5) utils::missing_cmd_args(FLERR, "fix add/heat", error);
dynamic_group_allow = 1;
overwrite_flag = 0;
if (strcmp(arg[3], "constant") == 0) {
style = ADD;
} else if (strcmp(arg[3], "linear") == 0) {
style = LINEAR;
} else if (strcmp(arg[3], "quartic") == 0) {
style = QUARTIC;
} else {
error->all(FLERR, "Invalid option {}", arg[3]);
}
if (utils::strmatch(arg[4], "^v_")) {
varstr = utils::strdup(arg[4] + 2);
} else {
value = utils::numeric(FLERR, arg[4], false, lmp);
vstyle = CONSTANT;
}
int iarg = 5;
if (style != ADD) {
if (narg != 6) utils::missing_cmd_args(FLERR, "fix add/heat", error);
prefactor = utils::numeric(FLERR, arg[5], false, lmp);
iarg = 6;
}
// optional args
while (iarg < narg) {
if (strcmp(arg[iarg], "overwrite") == 0) {
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix add/heat", error);
overwrite_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
iarg += 2;
} else {
error->all(FLERR, "Illegal fix add/heat command, invalid argument {}", arg[iarg]);
}
}
maxatom = -1;
}
/* ---------------------------------------------------------------------- */
FixAddHeat::~FixAddHeat()
{
delete[] varstr;
memory->destroy(vatom);
}
/* ---------------------------------------------------------------------- */
int FixAddHeat::setmask()
{
int mask = 0;
mask |= POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixAddHeat::init()
{
if (!atom->temperature_flag)
error->all(FLERR, "Fix add/heat requires atom style with temperature property");
if (!atom->heatflow_flag)
error->all(FLERR, "Fix add/heat requires atom style with heatflow property");
// check variable
if (varstr) {
var = input->variable->find(varstr);
if (var < 0) error->all(FLERR, "Variable {} for fix addforce does not exist", varstr);
if (input->variable->equalstyle(var))
vstyle = EQUAL;
else if (input->variable->atomstyle(var))
vstyle = ATOM;
else
error->all(FLERR, "Variable {} for fix addforce is invalid style", varstr);
}
}
/* ---------------------------------------------------------------------- */
void FixAddHeat::post_force(int /*vflag*/)
{
int *mask = atom->mask;
double *heatflow = atom->heatflow;
double *temperature = atom->temperature;
double dtinv = 1.0 / update->dt;
if (vstyle == ATOM) {
if (atom->nmax > maxatom) {
maxatom = atom->nmax;
memory->destroy(vatom);
memory->create(vatom, maxatom, "addheat:vatom");
}
input->variable->compute_atom(var, igroup, &vatom[0], 1, 0);
}
if (overwrite_flag)
for (int i = 0; i < atom->nlocal; i++)
if (mask[i] & groupbit)
heatflow[i] = 0.0;
double vtmp, dt;
if (vstyle == CONSTANT) vtmp = value;
if (vstyle == EQUAL) vtmp = input->variable->compute_equal(var);
for (int i = 0; i < atom->nlocal; i++) {
if (mask[i] & groupbit) {
if (vstyle == ATOM) vtmp = vatom[i];
if (style == ADD) {
heatflow[i] += dtinv * vtmp;
} else if (style == LINEAR) {
heatflow[i] += dtinv * prefactor * (vtmp - temperature[i]);
} else if (style == QUARTIC) {
heatflow[i] += dtinv * prefactor * (pow(vtmp, 4.0) - pow(temperature[i], 4.0));
}
}
}
}

View File

@ -0,0 +1,45 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(add/heat,FixAddHeat);
// clang-format on
#else
#ifndef LMP_FIX_ADD_HEAT_H
#define LMP_FIX_ADD_HEAT_H
#include "fix.h"
namespace LAMMPS_NS {
class FixAddHeat : public Fix {
public:
FixAddHeat(class LAMMPS *, int, char **);
~FixAddHeat() override;
int setmask() override;
void init() override;
void post_force(int) override;
protected:
double value, prefactor;
int var, vstyle, maxatom, style, overwrite_flag;
char *varstr;
double *vatom;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -124,6 +124,7 @@ PACKAGE = \
reaction \
reaxff \
replica \
rheo \
rigid \
scafacos \
shock \
@ -233,6 +234,7 @@ PACKLIB = \
plumed \
qmmm \
ml-quip \
rheo \
scafacos \
machdyn \
vtk \
@ -254,6 +256,7 @@ PACKEXT = \
netcdf \
plumed \
qmmm \
rheo \
scafacos \
voronoi \
vtk \

70
src/RHEO/Install.sh Normal file
View File

@ -0,0 +1,70 @@
# Install/unInstall package files in LAMMPS
# mode = 0/1/2 for uninstall/install/update
mode=$1
# enforce using portable C locale
LC_ALL=C
export LC_ALL
# arg1 = file, arg2 = file it depends on
action () {
if (test $mode = 0) then
rm -f ../$1
elif (! cmp -s $1 ../$1) then
if (test -z "$2" || test -e ../$2) then
cp $1 ..
if (test $mode = 2) then
echo " updating src/$1"
fi
fi
elif (test -n "$2") then
if (test ! -e ../$2) then
rm -f ../$1
fi
fi
}
# some styles in RHEO have base classes in BPM
if (test $1 = 1) then
if (test ! -e ../bond_bpm.cpp) then
echo "Must install BPM package with RHEO"
exit 1
fi
fi
for file in *.cpp *.h; do
action ${file}
done
# edit 2 Makefile.package files to include/exclude package info
if (test $1 = 1) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*rheo[^ \t]* //' ../Makefile.package
sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(rheo_SYSINC) |' ../Makefile.package
sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(rheo_SYSLIB) |' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^[ \t]*include.*rheo.*$/d' ../Makefile.package.settings
# multiline form needed for BSD sed on Macs
sed -i -e '4 i \
include ..\/..\/lib\/rheo\/Makefile.lammps
' ../Makefile.package.settings
fi
elif (test $1 = 0) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*rheo[^ \t]* //' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^[ \t]*include.*rheo.*$/d' ../Makefile.package.settings
fi
fi

10
src/RHEO/README Normal file
View File

@ -0,0 +1,10 @@
RHEO or Reproducing Hydrodynamics and Elastic Objects is a package to model
multiphase fluid systems. The authors include Joel Clemmer (Sandia), Thomas
O'Connor (Carnegie Mellon), and Eric Palermo (Carnegie Mellon).
Bond style rheo/shell, compute style rheo/property/atom, and fix style
rheo/temperature all depend on the BPM package.
This package requires the GNU scientific library (GSL). We recommend version
2.7 or later. To build this package, one must first separately install GSL in
a location that can be found by your environment.

174
src/RHEO/atom_vec_rheo.cpp Normal file
View File

@ -0,0 +1,174 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "atom_vec_rheo.h"
#include "atom.h"
#include <cstring>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
AtomVecRHEO::AtomVecRHEO(LAMMPS *lmp) : AtomVec(lmp)
{
molecular = Atom::ATOMIC;
mass_type = PER_TYPE;
forceclearflag = 1;
atom->rheo_status_flag = 1;
atom->pressure_flag = 1;
atom->rho_flag = 1;
atom->viscosity_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
fields_grow = {"rheo_status", "rho", "drho", "pressure", "viscosity"};
fields_copy = {"rheo_status", "rho", "drho", "pressure", "viscosity"};
fields_comm = {"rheo_status", "rho"};
fields_comm_vel = {"rheo_status", "rho"};
fields_reverse = {"drho"};
fields_border = {"rheo_status", "rho"};
fields_border_vel = {"rheo_status", "rho"};
fields_exchange = {"rheo_status", "rho"};
fields_restart = {"rheo_status", "rho"};
fields_create = {"rheo_status", "rho", "drho", "pressure", "viscosity"};
fields_data_atom = {"id", "type", "rheo_status", "rho", "x"};
fields_data_vel = {"id", "v"};
setup_fields();
}
/* ----------------------------------------------------------------------
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 AtomVecRHEO::grow_pointers()
{
rheo_status = atom->rheo_status;
pressure = atom->pressure;
rho = atom->rho;
drho = atom->drho;
viscosity = atom->viscosity;
}
/* ----------------------------------------------------------------------
clear extra forces starting at atom N
nbytes = # of bytes to clear for a per-atom vector
------------------------------------------------------------------------- */
void AtomVecRHEO::force_clear(int n, size_t nbytes)
{
memset(&drho[n], 0, nbytes);
}
/* ----------------------------------------------------------------------
initialize non-zero atom quantities
------------------------------------------------------------------------- */
void AtomVecRHEO::create_atom_post(int ilocal)
{
rho[ilocal] = 1.0;
}
/* ----------------------------------------------------------------------
modify what AtomVec::data_atom() just unpacked
or initialize other atom quantities
------------------------------------------------------------------------- */
void AtomVecRHEO::data_atom_post(int ilocal)
{
drho[ilocal] = 0.0;
pressure[ilocal] = 0.0;
viscosity[ilocal] = 0.0;
}
/* ----------------------------------------------------------------------
assign an index to named atom property and return index
return -1 if name is unknown to this atom style
------------------------------------------------------------------------- */
int AtomVecRHEO::property_atom(const std::string &name)
{
if (name == "rheo_status") return 0;
if (name == "pressure") return 1;
if (name == "rho") return 2;
if (name == "drho") return 3;
if (name == "viscosity") return 4;
return -1;
}
/* ----------------------------------------------------------------------
pack per-atom data into buf for ComputePropertyAtom
index maps to data specific to this atom style
------------------------------------------------------------------------- */
void AtomVecRHEO::pack_property_atom(int index, double *buf, int nvalues, int groupbit)
{
int *mask = atom->mask;
int nlocal = atom->nlocal;
int n = 0;
if (index == 0) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = rheo_status[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 1) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = pressure[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 2) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = rho[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 3) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = drho[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 4) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = viscosity[i];
else
buf[n] = 0.0;
n += nvalues;
}
}
}

46
src/RHEO/atom_vec_rheo.h Normal file
View File

@ -0,0 +1,46 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef ATOM_CLASS
// clang-format off
AtomStyle(rheo,AtomVecRHEO);
// clang-format on
#else
#ifndef LMP_ATOM_VEC_RHEO_H
#define LMP_ATOM_VEC_RHEO_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecRHEO : virtual public AtomVec {
public:
AtomVecRHEO(class LAMMPS *);
void grow_pointers() override;
void force_clear(int, size_t) override;
void create_atom_post(int) override;
void data_atom_post(int) override;
int property_atom(const std::string &) override;
void pack_property_atom(int, double *, int, int) override;
private:
int *rheo_status;
double *pressure, *rho, *drho, *viscosity;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,222 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "atom_vec_rheo_thermal.h"
#include "atom.h"
#include <cstring>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
AtomVecRHEOThermal::AtomVecRHEOThermal(LAMMPS *lmp) : AtomVec(lmp)
{
molecular = Atom::ATOMIC;
mass_type = PER_TYPE;
forceclearflag = 1;
atom->rheo_status_flag = 1;
atom->conductivity_flag = 1;
atom->temperature_flag = 1;
atom->esph_flag = 1;
atom->heatflow_flag = 1;
atom->pressure_flag = 1;
atom->rho_flag = 1;
atom->viscosity_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
fields_grow = {"rheo_status", "rho", "drho", "temperature", "esph", "heatflow", "conductivity", "pressure", "viscosity"};
fields_copy = {"rheo_status", "rho", "drho", "temperature", "esph", "heatflow", "conductivity", "pressure", "viscosity"};
fields_comm = {"rheo_status", "rho", "esph"};
fields_comm_vel = {"rheo_status", "rho", "esph"};
fields_reverse = {"drho", "heatflow"};
fields_border = {"rheo_status", "rho", "esph"};
fields_border_vel = {"rheo_status", "rho", "esph"};
fields_exchange = {"rheo_status", "rho", "esph"};
fields_restart = {"rheo_status", "rho", "esph"};
fields_create = {"rheo_status", "rho", "drho", "temperature", "esph", "heatflow", "conductivity", "pressure", "viscosity"};
fields_data_atom = {"id", "type", "rheo_status", "rho", "esph", "x"};
fields_data_vel = {"id", "v"};
setup_fields();
}
/* ----------------------------------------------------------------------
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 AtomVecRHEOThermal::grow_pointers()
{
rheo_status = atom->rheo_status;
conductivity = atom->conductivity;
temperature = atom->temperature;
esph = atom->esph;
heatflow = atom->heatflow;
pressure = atom->pressure;
rho = atom->rho;
drho = atom->drho;
viscosity = atom->viscosity;
}
/* ----------------------------------------------------------------------
clear extra forces starting at atom N
nbytes = # of bytes to clear for a per-atom vector
------------------------------------------------------------------------- */
void AtomVecRHEOThermal::force_clear(int n, size_t nbytes)
{
memset(&drho[n], 0, nbytes);
memset(&heatflow[n], 0, nbytes);
}
/* ----------------------------------------------------------------------
initialize non-zero atom quantities
------------------------------------------------------------------------- */
void AtomVecRHEOThermal::create_atom_post(int ilocal)
{
rho[ilocal] = 1.0;
}
/* ----------------------------------------------------------------------
modify what AtomVec::data_atom() just unpacked
or initialize other atom quantities
------------------------------------------------------------------------- */
void AtomVecRHEOThermal::data_atom_post(int ilocal)
{
drho[ilocal] = 0.0;
heatflow[ilocal] = 0.0;
temperature[ilocal] = 0.0;
pressure[ilocal] = 0.0;
viscosity[ilocal] = 0.0;
conductivity[ilocal] = 0.0;
}
/* ----------------------------------------------------------------------
assign an index to named atom property and return index
return -1 if name is unknown to this atom style
------------------------------------------------------------------------- */
int AtomVecRHEOThermal::property_atom(const std::string &name)
{
if (name == "rheo_status") return 0;
if (name == "rho") return 1;
if (name == "drho") return 2;
if (name == "temperature") return 3;
if (name == "esph") return 4;
if (name == "heatflow") return 5;
if (name == "conductivity") return 6;
if (name == "pressure") return 7;
if (name == "viscosity") return 8;
return -1;
}
/* ----------------------------------------------------------------------
pack per-atom data into buf for ComputePropertyAtom
index maps to data specific to this atom style
------------------------------------------------------------------------- */
void AtomVecRHEOThermal::pack_property_atom(int index, double *buf, int nvalues, int groupbit)
{
int *mask = atom->mask;
int nlocal = atom->nlocal;
int n = 0;
if (index == 0) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = rheo_status[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 1) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = rho[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 2) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = drho[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 3) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = temperature[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 4) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = esph[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 5) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = heatflow[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 6) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = conductivity[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 7) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = pressure[i];
else
buf[n] = 0.0;
n += nvalues;
}
} else if (index == 8) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = viscosity[i];
else
buf[n] = 0.0;
n += nvalues;
}
}
}

View File

@ -0,0 +1,47 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef ATOM_CLASS
// clang-format off
AtomStyle(rheo/thermal,AtomVecRHEOThermal);
// clang-format on
#else
#ifndef LMP_ATOM_VEC_RHEO_THERMAL_H
#define LMP_ATOM_VEC_RHEO_THERMAL_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecRHEOThermal : virtual public AtomVec {
public:
AtomVecRHEOThermal(class LAMMPS *);
void grow_pointers() override;
void force_clear(int, size_t) override;
void create_atom_post(int) override;
void data_atom_post(int) override;
int property_atom(const std::string &) override;
void pack_property_atom(int, double *, int, int) override;
private:
int *rheo_status;
double *conductivity, *temperature, *heatflow, *esph;
double *pressure, *rho, *drho, *viscosity;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,591 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "bond_rheo_shell.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_surface.h"
#include "domain.h"
#include "error.h"
#include "fix_bond_history.h"
#include "fix_rheo.h"
#include "fix_rheo_oxidation.h"
#include "fix_store_local.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include "update.h"
#include <cmath>
#include <cstring>
#define EPSILON 1e-10
using namespace LAMMPS_NS;
using namespace RHEO_NS;
/* ---------------------------------------------------------------------- */
BondRHEOShell::BondRHEOShell(LAMMPS *_lmp) :
BondBPM(_lmp), compute_surface(nullptr), k(nullptr), ecrit(nullptr), gamma(nullptr)
{
partial_flag = 1;
comm_reverse = 1;
nhistory = 2;
update_flag = 1;
id_fix_bond_history = utils::strdup("HISTORY_RHEO_SHELL");
ignore_special_flag = 1;
tform = -1;
single_extra = 1;
svector = new double[1];
// For nbond, create an instance of fix property atom
// Need restarts + exchanging with neighbors since it needs to persist
// between timesteps (fix property atom will handle callbacks)
int tmp1, tmp2;
index_nb = atom->find_custom("shell_nbond", tmp1, tmp2);
if (index_nb == -1) {
id_fix = utils::strdup("bond_rheo_shell_fix_property_atom");
modify->add_fix(fmt::format("{} all property/atom i_shell_nbond", id_fix));
index_nb = atom->find_custom("shell_nbond", tmp1, tmp2);
}
nbond = atom->ivector[index_nb];
//Store non-persistent per atom quantities, intermediate
nmax_store = atom->nmax;
memory->create(dbond, nmax_store, "rheo/react:dbond");
}
/* ---------------------------------------------------------------------- */
BondRHEOShell::~BondRHEOShell()
{
if (modify->nfix) modify->delete_fix(id_fix);
delete[] id_fix;
delete[] svector;
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(ecrit);
memory->destroy(gamma);
}
memory->destroy(dbond);
}
/* ----------------------------------------------------------------------
Store data for a single bond - if bond added after LAMMPS init (e.g. pour)
------------------------------------------------------------------------- */
double BondRHEOShell::store_bond(int n, int i, int j)
{
double **bondstore = fix_bond_history->bondstore;
tagint *tag = atom->tag;
bondstore[n][0] = 0.0;
bondstore[n][1] = 0.0;
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, 0.0);
fix_bond_history->update_atom_value(i, m, 1, 0.0);
}
}
}
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, 0.0);
fix_bond_history->update_atom_value(j, m, 1, 0.0);
}
}
}
return 0.0;
}
/* ----------------------------------------------------------------------
Store data for all bonds called once
------------------------------------------------------------------------- */
void BondRHEOShell::store_data()
{
int i, j, m, type;
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");
fix_bond_history->update_atom_value(i, m, 0, 0.0);
fix_bond_history->update_atom_value(i, m, 1, 0.0);
}
}
fix_bond_history->post_neighbor();
}
/* ---------------------------------------------------------------------- */
void BondRHEOShell::compute(int eflag, int vflag)
{
if (!fix_bond_history->stored_flag) {
fix_bond_history->stored_flag = true;
store_data();
}
if (hybrid_flag)
fix_bond_history->compress_history();
int i1, i2, itmp, n, type;
double delx, dely, delz, delvx, delvy, delvz;
double e, rsq, r, r0, rinv, dr, fbond, dot, t;
double dt = update->dt;
ev_init(eflag, vflag);
double *rsurface = compute_surface->rsurface;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
tagint *tag = atom->tag;
int *status = atom->rheo_status;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
double **bondstore = fix_bond_history->bondstore;
if (atom->nmax > nmax_store){
nmax_store = atom->nmax;
memory->destroy(dbond);
memory->create(dbond, nmax_store, "rheo/shell:dbond");
}
size_t nbytes = nmax_store * sizeof(int);
memset(&dbond[0], 0, nbytes);
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];
t = bondstore[n][1];
// 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;
}
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);
// If bond hasn't been set - zero data
if (t < EPSILON || std::isnan(t))
t = 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);
// Bond has not yet formed, check if in range + update timer
if (t < tform) {
// Check if eligible
if (r > rmax || rsurface[i1] > rsurf || rsurface[i2] > rsurf) {
bondlist[n][2] = 0;
process_ineligibility(i1, i2);
continue;
}
// Check ellapsed time
t += dt;
bondstore[n][1] = t;
if (t >= tform) {
bondstore[n][0] = r;
r0 = r;
if (newton_bond || i1 < nlocal) dbond[i1]++;
if (newton_bond || i2 < nlocal) dbond[i2]++;
} else {
continue;
}
}
e = (r - r0) / r0;
if (fabs(e) > ecrit[type]) {
bondlist[n][2] = 0;
process_broken(i1, i2);
if (newton_bond || i1 < nlocal) dbond[i1]--;
if (newton_bond || i2 < nlocal) dbond[i2]--;
continue;
}
rinv = 1.0 / r;
dr = r - r0;
fbond = 2 * k[type] * (-dr + dr * dr * dr / (r0 * r0 * ecrit[type] * ecrit[type]));
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 (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);
}
// Communicate changes in nbond
if (newton_bond) comm->reverse_comm(this);
for(int i = 0; i < nlocal; i++) {
nbond[i] += dbond[i];
// If it has bonds, no shifting
if (nbond[i] != 0) status[i] |= STATUS_NO_SHIFT;
}
if (hybrid_flag)
fix_bond_history->uncompress_history();
}
/* ---------------------------------------------------------------------- */
void BondRHEOShell::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 BondRHEOShell::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 BondRHEOShell::init_style()
{
BondBPM::init_style();
if (comm->ghost_velocity == 0)
error->all(FLERR, "Bond rheo/shell requires ghost atoms store velocity");
auto fixes = modify->get_fix_by_style("^rheo$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use bond rheo/shell");
class FixRHEO *fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
if (!fix_rheo->surface_flag) error->all(FLERR,
"Bond rheo/shell requires surface calculation in fix rheo");
compute_surface = fix_rheo->compute_surface;
fixes = modify->get_fix_by_style("^rheo/oxidation$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo/oxidation to use bond rheo/shell");
class FixRHEOOxidation *fix_rheo_oxidation = dynamic_cast<FixRHEOOxidation *>(fixes[0]);
rsurf = fix_rheo_oxidation->rsurf;
rmax = fix_rheo_oxidation->cut;
}
/* ---------------------------------------------------------------------- */
void BondRHEOShell::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], "t/form") == 0) {
if (iarg + 1 > narg) utils::missing_cmd_args(FLERR, "bond rheo/shell t/form", error);
tform = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
i += 1;
} else {
error->all(FLERR, "Illegal bond rheo/shell command, invalid argument {}", arg[iarg]);
}
}
if (tform < 0.0)
error->all(FLERR, "Illegal bond rheo/shell command, must specify positive formation time");
}
/* ----------------------------------------------------------------------
used to check bond communiction cutoff - not perfect, estimates based on local-local only
------------------------------------------------------------------------- */
double BondRHEOShell::equilibrium_distance(int /*i*/)
{
// Divide out heuristic prefactor added in comm class
return max_stretch * rmax / 1.5;
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondRHEOShell::write_restart(FILE *fp)
{
BondBPM::write_restart(fp);
write_restart_settings(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 BondRHEOShell::read_restart(FILE *fp)
{
BondBPM::read_restart(fp);
read_restart_settings(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 restart file
------------------------------------------------------------------------- */
void BondRHEOShell::write_restart_settings(FILE *fp)
{
fwrite(&tform, sizeof(double), 1, fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void BondRHEOShell::read_restart_settings(FILE *fp)
{
if (comm->me == 0) {
utils::sfread(FLERR, &tform, sizeof(double), 1, fp, nullptr, error);
}
MPI_Bcast(&tform, 1, MPI_DOUBLE, 0, world);
}
/* ---------------------------------------------------------------------- */
int BondRHEOShell::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++] = dbond[i];
}
return m;
}
/* ---------------------------------------------------------------------- */
void BondRHEOShell::unpack_reverse_comm(int n, int *list, double *buf)
{
int i, j, m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
dbond[j] += buf[m++];
}
}
/* ---------------------------------------------------------------------- */
double BondRHEOShell::single(int type, double rsq, int i, int j, double &fforce)
{
if (type <= 0) return 0.0;
double r0, t;
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);
t = fix_bond_history->get_atom_value(i, n, 1);
}
}
svector[1] = t;
if (t < tform) return 0.0;
double r = sqrt(rsq);
double rinv = 1.0 / r;
double dr = r0 - r;
fforce = 2 * k[type] * (dr + dr * dr * dr / (r0 * r0 * ecrit[type] * ecrit[type]));
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;
// set single_extra quantities
svector[0] = r0;
return 0.0;
}
/* ----------------------------------------------------------------------
Similar to BondBPM->process_broken(), but don't send to FixStoreLocal
------------------------------------------------------------------------- */
void BondRHEOShell::process_ineligibility(int i, int j)
{
// Manually search and remove from atom arrays
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] && setflag[bond_type[i][m]]) {
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];
for (auto &ihistory: histories) {
auto fix_bond_history2 = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history2->shift_history(i, m, n - 1);
fix_bond_history2->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] && setflag[bond_type[j][m]]) {
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];
for (auto &ihistory: histories) {
auto fix_bond_history2 = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history2->shift_history(j, m, n - 1);
fix_bond_history2->delete_history(j, n - 1);
}
num_bond[j]--;
break;
}
}
}
}

View File

@ -0,0 +1,63 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef BOND_CLASS
// clang-format off
BondStyle(rheo/shell,BondRHEOShell);
// clang-format on
#else
#ifndef LMP_BOND_RHEO_SHELL_H
#define LMP_BOND_RHEO_SHELL_H
#include "bond_bpm.h"
namespace LAMMPS_NS {
class BondRHEOShell : public BondBPM {
public:
BondRHEOShell(class LAMMPS *);
~BondRHEOShell() override;
void compute(int, int) override;
void coeff(int, char **) override;
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_restart_settings(FILE *) override;
void read_restart_settings(FILE *) override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
double single(int, double, int, int, double &) override;
protected:
double *k, *ecrit, *gamma;
double tform, rmax, rsurf;
int *dbond, *nbond;
int index_nb, nmax_store;
char *id_fix;
class ComputeRHEOSurface *compute_surface;
void process_ineligibility(int, int);
void allocate();
void store_data();
double store_bond(int, int, int);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,506 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU)
----------------------------------------------------------------------- */
#include "compute_rheo_grad.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_kernel.h"
#include "compute_rheo_interface.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "update.h"
#include <cmath>
using namespace LAMMPS_NS;
using namespace RHEO_NS;
enum{COMMGRAD, COMMFIELD};
/* ---------------------------------------------------------------------- */
ComputeRHEOGrad::ComputeRHEOGrad(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), rho0(nullptr), compute_interface(nullptr), compute_kernel(nullptr),
gradv(nullptr), gradr(nullptr), grade(nullptr), gradn(nullptr)
{
if (narg < 4) error->all(FLERR,"Illegal compute rheo/grad command");
velocity_flag = energy_flag = rho_flag = eta_flag = 0;
for (int iarg = 3; iarg < narg; iarg++) {
if (strcmp(arg[iarg], "velocity") == 0) velocity_flag = 1;
else if (strcmp(arg[iarg], "rho") == 0) rho_flag = 1;
else if (strcmp(arg[iarg], "energy") == 0) energy_flag = 1;
else if (strcmp(arg[iarg], "viscosity") == 0) eta_flag = 1;
else error->all(FLERR, "Illegal compute rheo/grad command, {}", arg[iarg]);
}
ncomm_grad = 0;
ncomm_field = 0;
comm_reverse = 0;
int dim = domain->dimension;
if (velocity_flag) {
ncomm_grad += dim * dim;
ncomm_field += dim;
comm_reverse += dim * dim;
}
if (rho_flag) {
ncomm_grad += dim;
ncomm_field += 1;
comm_reverse += dim;
}
if (energy_flag) {
ncomm_grad += dim;
ncomm_field += 1;
comm_reverse += dim;
}
if (eta_flag) {
ncomm_grad += dim;
comm_reverse += dim;
}
comm_forward = ncomm_grad;
nmax_store = 0;
grow_arrays(atom->nmax);
}
/* ---------------------------------------------------------------------- */
ComputeRHEOGrad::~ComputeRHEOGrad()
{
memory->destroy(gradv);
memory->destroy(gradr);
memory->destroy(grade);
memory->destroy(gradn);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::init()
{
cut = fix_rheo->cut;
cutsq = cut * cut;
rho0 = fix_rheo->rho0;
interface_flag = fix_rheo->interface_flag;
compute_kernel = fix_rheo->compute_kernel;
compute_interface = fix_rheo->compute_interface;
remap_v_flag = domain->deform_vremap;
neighbor->add_request(this, NeighConst::REQ_DEFAULT);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::compute_peratom()
{
int i, j, k, ii, jj, jnum, itype, jtype, a, b, fluidi, fluidj;
double xtmp, ytmp, ztmp, delx, dely, delz;
double rsq, imass, jmass;
double rhoi, rhoj, Voli, Volj, drho, de, deta;
double vi[3], vj[3], vij[3];
double wp, *dWij, *dWji;
int inum, *ilist, *numneigh, **firstneigh;
int *jlist;
int nlocal = atom->nlocal;
double **x = atom->x;
double **v = atom->v;
double *rho = atom->rho;
double *energy = atom->esph;
double *viscosity = atom->viscosity;
int *status = atom->rheo_status;
int *type = atom->type;
double *mass = atom->mass;
int newton = force->newton;
int dim = domain->dimension;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// initialize arrays
if (atom->nmax > nmax_store) grow_arrays(atom->nmax);
for (i = 0; i < nmax_store; i++) {
if (velocity_flag) {
for (k = 0; k < dim * dim; k++)
gradv[i][k] = 0.0;
}
if (rho_flag) {
for (k = 0; k < dim; k++)
gradr[i][k] = 0.0;
}
if (energy_flag) {
for (k = 0; k < dim; k++)
grade[i][k] = 0.0;
}
if (eta_flag) {
for (k = 0; k < dim; k++)
gradn[i][k] = 0.0;
}
}
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
fluidi = !(status[i] & PHASECHECK);
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = type[j];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx * delx + dely * dely + delz * delz;
if (rsq < cutsq) {
fluidj = !(status[j] & PHASECHECK);
rhoi = rho[i];
rhoj = rho[j];
vi[0] = v[i][0];
vi[1] = v[i][1];
vi[2] = v[i][2];
vj[0] = v[j][0];
vj[1] = v[j][1];
vj[2] = v[j][2];
// Add corrections for walls
if (interface_flag) {
if (fluidi && (!fluidj)) {
compute_interface->correct_v(vj, vi, j, i);
rhoj = compute_interface->correct_rho(j, i);
} else if ((!fluidi) && fluidj) {
compute_interface->correct_v(vi, vj, i, j);
rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) {
rhoi = rho0[itype];
rhoj = rho0[jtype];
}
}
Voli = mass[itype] / rhoi;
Volj = mass[jtype] / rhoj;
vij[0] = vi[0] - vj[0];
vij[1] = vi[1] - vj[1];
vij[2] = vi[2] - vj[2];
if (rho_flag) drho = rhoi - rhoj;
if (energy_flag) de = energy[i] - energy[j];
if (eta_flag) deta = viscosity[i] - viscosity[j];
wp = compute_kernel->calc_dw(i, j, delx, dely, delz, sqrt(rsq));
dWij = compute_kernel->dWij;
dWji = compute_kernel->dWji;
for (a = 0; a < dim; a++) {
for (b = 0; b < dim; b++) {
if (velocity_flag) // uxx uxy uxz uyx uyy uyz uzx uzy uzz
gradv[i][a * dim + b] -= vij[a] * Volj * dWij[b];
}
if (rho_flag) // P,x P,y P,z
gradr[i][a] -= drho * Volj * dWij[a];
if (energy_flag) // e,x e,y e,z
grade[i][a] -= de * Volj * dWij[a];
if (eta_flag) // n,x n,y n,z
gradn[i][a] -= deta * Volj * dWij[a];
}
if (newton || j < nlocal) {
for (a = 0; a < dim; a++) {
for (b = 0; b < dim; b++) {
if (velocity_flag) // uxx uxy uxz uyx uyy uyz uzx uzy uzz
gradv[j][a * dim + b] += vij[a] * Voli * dWji[b];
}
if (rho_flag) // P,x P,y P,z
gradr[j][a] += drho * Voli * dWji[a];
if (energy_flag) // e,x e,y e,z
grade[j][a] += de * Voli * dWji[a];
if (eta_flag) // n,x n,y n,z
gradn[j][a] += deta * Voli * dWji[a];
}
}
}
}
}
if (newton) comm->reverse_comm(this);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::forward_gradients()
{
comm_stage = COMMGRAD;
comm_forward = ncomm_grad;
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::forward_fields()
{
comm_stage = COMMFIELD;
comm_forward = ncomm_field;
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOGrad::pack_forward_comm(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,k,m;
int *mask = atom->mask;
double *rho = atom->rho;
double *energy = atom->esph;
double **v = atom->v;
int dim = domain->dimension;
double *h_rate = domain->h_rate;
int deform_groupbit = domain->deform_groupbit;
double dv[3];
if (remap_v_flag) {
dv[0] = pbc[0] * h_rate[0] + pbc[5] * h_rate[5] + pbc[4] * h_rate[4];
dv[1] = pbc[1] * h_rate[1] + pbc[3] * h_rate[3];
dv[2] = pbc[2] * h_rate[2];
}
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (comm_stage == COMMGRAD) {
if (velocity_flag)
for (k = 0; k < dim * dim; k++)
buf[m++] = gradv[j][k];
if (rho_flag)
for (k = 0; k < dim; k++)
buf[m++] = gradr[j][k];
if (energy_flag)
for (k = 0; k < dim; k++)
buf[m++] = grade[j][k];
if (eta_flag)
for (k = 0; k < dim; k++)
buf[m++] = gradn[j][k];
} else if (comm_stage == COMMFIELD) {
if (velocity_flag) {
if (remap_v_flag && pbc_flag && (mask[j] & deform_groupbit)) {
for (k = 0; k < dim; k++)
buf[m++] = v[j][k] + dv[k];
} else {
for (k = 0; k < dim; k++)
buf[m++] = v[j][k];
}
}
if (rho_flag)
buf[m++] = rho[j];
if (energy_flag)
buf[m++] = energy[j];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *rho = atom->rho;
double *energy = atom->esph; double **v = atom->v;
int dim = domain->dimension;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (comm_stage == COMMGRAD) {
if (velocity_flag)
for (k = 0; k < dim * dim; k++)
gradv[i][k] = buf[m++];
if (rho_flag)
for (k = 0; k < dim; k++)
gradr[i][k] = buf[m++];
if (energy_flag)
for (k = 0; k < dim; k++)
grade[i][k] = buf[m++];
if (eta_flag)
for (k = 0; k < dim; k++)
gradn[i][k] = buf[m++];
} else if (comm_stage == COMMFIELD) {
if (velocity_flag)
for (k = 0; k < dim; k++)
v[i][k] = buf[m++];
if (rho_flag)
rho[i] = buf[m++];
if (energy_flag)
energy[i] = buf[m++];
}
}
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOGrad::pack_reverse_comm(int n, int first, double *buf)
{
int i,k,m,last;
int dim = domain->dimension;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (velocity_flag)
for (k = 0; k < dim * dim; k++)
buf[m++] = gradv[i][k];
if (rho_flag)
for (k = 0; k < dim; k++)
buf[m++] = gradr[i][k];
if (energy_flag)
for (k = 0; k < dim; k++)
buf[m++] = grade[i][k];
if (eta_flag)
for (k = 0; k < dim; k++)
buf[m++] = gradn[i][k];
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::unpack_reverse_comm(int n, int *list, double *buf)
{
int i,k,j,m;
int dim = domain->dimension;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (velocity_flag)
for (k = 0; k < dim * dim; k++)
gradv[j][k] += buf[m++];
if (rho_flag)
for (k = 0; k < dim; k++)
gradr[j][k] += buf[m++];
if (energy_flag)
for (k = 0; k < dim; k++)
grade[j][k] += buf[m++];
if (eta_flag)
for (k = 0; k < dim; k++)
gradn[j][k] += buf[m++];
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOGrad::grow_arrays(int nmax)
{
int dim = domain->dimension;
if (velocity_flag)
memory->grow(gradv, nmax, dim * dim, "rheo:grad_v");
if (rho_flag)
memory->grow(gradr, nmax, dim, "rheo:grad_rho");
if (energy_flag)
memory->grow(grade, nmax, dim, "rheo:grad_energy");
if (eta_flag)
memory->grow(gradn, nmax, dim, "rheo:grad_eta");
nmax_store = nmax;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOGrad::memory_usage()
{
double bytes = 0.0;
int dim = domain->dimension;
if (velocity_flag)
bytes = (size_t) nmax_store * dim * dim * sizeof(double);
if (rho_flag)
bytes = (size_t) nmax_store * dim * sizeof(double);
if (energy_flag)
bytes = (size_t) nmax_store * dim * sizeof(double);
if (eta_flag)
bytes = (size_t) nmax_store * dim * sizeof(double);
return bytes;
}

View File

@ -0,0 +1,64 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(RHEO/GRAD,ComputeRHEOGrad)
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_GRAD_H
#define LMP_COMPUTE_RHEO_GRAD_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeRHEOGrad : public Compute {
public:
ComputeRHEOGrad(class LAMMPS *, int, char **);
~ComputeRHEOGrad() override;
void init() override;
void init_list(int, class NeighList *) override;
void compute_peratom() override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
double memory_usage() override;
void forward_gradients();
void forward_fields();
double **gradv;
double **gradr;
double **grade;
double **gradn;
class FixRHEO *fix_rheo;
private:
int comm_stage, ncomm_grad, ncomm_field, nmax_store;
double cut, cutsq, *rho0;
int velocity_flag, energy_flag, rho_flag, eta_flag;
int interface_flag, remap_v_flag;
class ComputeRHEOKernel *compute_kernel;
class ComputeRHEOInterface *compute_interface;
class NeighList *list;
void grow_arrays(int);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,384 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU), Eric Palermo (CMU)
----------------------------------------------------------------------- */
#include "compute_rheo_interface.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "compute_rheo_kernel.h"
#include "error.h"
#include "force.h"
#include "fix_rheo.h"
#include "fix_rheo_pressure.h"
#include "math_extra.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include <cmath>
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace MathExtra;
static constexpr double EPSILON = 1e-1;
/* ---------------------------------------------------------------------- */
ComputeRHEOInterface::ComputeRHEOInterface(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), compute_kernel(nullptr), fp_store(nullptr),
rho0(nullptr), norm(nullptr), normwf(nullptr), chi(nullptr), id_fix_pa(nullptr)
{
if (narg != 3) error->all(FLERR,"Illegal compute rheo/interface command");
comm_forward = 3;
comm_reverse = 4;
nmax_store = atom->nmax;
memory->create(chi, nmax_store, "rheo:chi");
memory->create(norm, nmax_store, "rheo/interface:norm");
memory->create(normwf, nmax_store, "rheo/interface:normwf");
// For fp_store, create an instance of fix property atom
// Need restarts + exchanging with neighbors since it needs to persist
// between timesteps (fix property atom will handle callbacks)
int tmp1, tmp2;
int index = atom->find_custom("fp_store", tmp1, tmp2);
if (index == -1) {
id_fix_pa = utils::strdup(id + std::string("_fix_property_atom"));
modify->add_fix(fmt::format("{} all property/atom d2_fp_store 3", id_fix_pa));
index = atom->find_custom("fp_store", tmp1, tmp2);
}
fp_store = atom->darray[index];
}
/* ---------------------------------------------------------------------- */
ComputeRHEOInterface::~ComputeRHEOInterface()
{
if (id_fix_pa && modify->nfix) modify->delete_fix(id_fix_pa);
delete[] id_fix_pa;
memory->destroy(chi);
memory->destroy(norm);
memory->destroy(normwf);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::init()
{
compute_kernel = fix_rheo->compute_kernel;
rho0 = fix_rheo->rho0;
cut = fix_rheo->cut;
cutsq = cut * cut;
wall_max = sqrt(3.0) / 12.0 * cut;
auto fixes = modify->get_fix_by_style("rheo/pressure");
fix_pressure = dynamic_cast<FixRHEOPressure *>(fixes[0]);
neighbor->add_request(this, NeighConst::REQ_DEFAULT);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::compute_peratom()
{
int a, i, j, ii, jj, jnum, itype, jtype, fluidi, fluidj, status_match;
double xtmp, ytmp, ztmp, rsq, w, dot, dx[3];
int inum, *ilist, *jlist, *numneigh, **firstneigh;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
double **x = atom->x;
int *type = atom->type;
int newton = force->newton;
int *status = atom->rheo_status;
double *rho = atom->rho;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
if (atom->nmax > nmax_store) {
nmax_store = atom->nmax;
memory->grow(norm, nmax_store, "rheo/interface:norm");
memory->grow(normwf, nmax_store, "rheo/interface:normwf");
memory->grow(chi, nmax_store, "rheo:chi");
}
for (i = 0; i < nall; i++) {
if (status[i] & PHASECHECK) rho[i] = 0.0;
normwf[i] = 0.0;
norm[i] = 0.0;
chi[i] = 0.0;
}
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
fluidi = !(status[i] & PHASECHECK);
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
if (rsq < cutsq) {
jtype = type[j];
fluidj = !(status[j] & PHASECHECK);
w = compute_kernel->calc_w_quintic(i, j, dx[0], dx[1], dx[2], sqrt(rsq));
norm[i] += w;
status_match = 0;
if ((fluidi && fluidj) || ((!fluidi) && (!fluidj)))
status_match = 1;
if (status_match) {
chi[i] += w;
} else {
if (!fluidi) {
dot = 0;
for (a = 0; a < 3; a++)
dot += (-fp_store[j][a] + fp_store[i][a]) * dx[a];
rho[i] += w * (fix_pressure->calc_pressure(rho[j], jtype) - rho[j] * dot);
normwf[i] += w;
}
}
if (newton || j < nlocal) {
norm[j] += w;
if (status_match) {
chi[j] += w;
} else {
if (!fluidj) {
dot = 0;
for (a = 0; a < 3; a++)
dot += (-fp_store[i][a] + fp_store[j][a]) * dx[a];
rho[j] += w * (fix_pressure->calc_pressure(rho[i], itype) + rho[i] * dot);
normwf[j] += w;
}
}
}
}
}
}
if (newton) comm->reverse_comm(this);
for (i = 0; i < nlocal; i++) {
if (norm[i] != 0.0) chi[i] /= norm[i];
// Recalculate rho for non-fluid particles
if (status[i] & PHASECHECK) {
if (normwf[i] != 0.0) {
// Stores rho for solid particles 1+Pw in Adami Adams 2012
rho[i] = MAX(EPSILON, fix_pressure->calc_rho(rho[i] / normwf[i], type[i]));
} else {
rho[i] = rho0[itype];
}
}
}
comm_stage = 1;
comm_forward = 2;
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOInterface::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/)
{
int i, j, k, m;
m = 0;
double *rho = atom->rho;
for (i = 0; i < n; i++) {
j = list[i];
if (comm_stage == 0) {
buf[m++] = fp_store[j][0];
buf[m++] = fp_store[j][1];
buf[m++] = fp_store[j][2];
} else {
buf[m++] = chi[j];
buf[m++] = rho[j];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *rho = atom->rho;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (comm_stage == 0) {
fp_store[i][0] = buf[m++];
fp_store[i][1] = buf[m++];
fp_store[i][2] = buf[m++];
} else {
chi[i] = buf[m++];
rho[i] = buf[m++];
}
}
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOInterface::pack_reverse_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *rho = atom->rho;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = norm[i];
buf[m++] = chi[i];
buf[m++] = normwf[i];
buf[m++] = rho[i];
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::unpack_reverse_comm(int n, int *list, double *buf)
{
int i, k, j, m;
double *rho = atom->rho;
int *status = atom->rheo_status;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
norm[j] += buf[m++];
chi[j] += buf[m++];
if (status[j] & PHASECHECK){
normwf[j] += buf[m++];
rho[j] += buf[m++];
} else {
m++;
m++;
}
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::correct_v(double *v_solid, double *v_fluid, int i_solid, int i_fluid)
{
double wall_prefactor, wall_denom, wall_numer;
wall_numer = MAX(2.0 * cut * (chi[i_solid] - 0.5), 0.0);
wall_denom = MAX(2.0 * cut * (chi[i_fluid] - 0.5), wall_max);
wall_prefactor = wall_numer / wall_denom;
v_solid[0] = (v_solid[0] - v_fluid[0]) * wall_prefactor;
v_solid[1] = (v_solid[1] - v_fluid[1]) * wall_prefactor;
v_solid[2] = (v_solid[2] - v_fluid[2]) * wall_prefactor;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOInterface::correct_rho(int i_solid, int i_fluid)
{
int itype = atom->type[i_solid];
return MAX(rho0[itype], atom->rho[i_solid]);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOInterface::store_forces()
{
double minv;
int *type = atom->type;
int *mask = atom->mask;
double *mass = atom->mass;
double **f = atom->f;
// When this is called, fp_store stores the pressure force
// After this method, fp_store instead stores non-pressure forces
// and is also normalized by the particles mass
// If forces are overwritten by a fix, there are no pressure forces
// so just normalize
auto fixlist = modify->get_fix_by_style("setforce");
if (fixlist.size() != 0) {
for (const auto &fix : fixlist) {
for (int i = 0; i < atom->nlocal; i++) {
minv = 1.0 / mass[type[i]];
if (mask[i] & fix->groupbit)
for (int a = 0; a < 3; a++)
fp_store[i][a] = f[i][a] * minv;
else
for (int a = 0; a < 3; a++)
fp_store[i][a] = (f[i][a] - fp_store[i][a]) * minv;
}
}
} else {
for (int i = 0; i < atom->nlocal; i++) {
minv = 1.0 / mass[type[i]];
for (int a = 0; a < 3; a++)
fp_store[i][a] = (f[i][a] - fp_store[i][a]) * minv;
}
}
// Forward comm forces
comm_forward = 3;
comm_stage = 0;
comm->forward_comm(this);
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeRHEOInterface::memory_usage()
{
double bytes = 3 * nmax_store * sizeof(double);
return bytes;
}

View File

@ -0,0 +1,61 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain 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(RHEO/INTERFACE,ComputeRHEOInterface)
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_INTERFACE_H
#define LMP_COMPUTE_RHEO_INTERFACE_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeRHEOInterface : public Compute {
public:
ComputeRHEOInterface(class LAMMPS *, int, char **);
~ComputeRHEOInterface() override;
void init() override;
void init_list(int, class NeighList *) override;
void compute_peratom() override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
double memory_usage() override;
void correct_v(double *, double *, int, int);
double correct_rho(int, int);
void store_forces();
double *chi, **fp_store;
class FixRHEO *fix_rheo;
private:
int nmax_store, comm_stage;
double *rho0, cut, cutsq, wall_max;
double *norm, *normwf;
char *id_fix_pa;
class NeighList *list;
class ComputeRHEOKernel *compute_kernel;
class FixRHEOPressure *fix_pressure;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,913 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU)
----------------------------------------------------------------------- */
#include "compute_rheo_kernel.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_interface.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "math_const.h"
#include "math_extra.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "pair.h"
#include "update.h"
#include "utils.h"
#include <cmath>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_cblas.h>
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace MathConst;
using namespace MathExtra;
static constexpr int DELTA = 2000;
/* ---------------------------------------------------------------------- */
ComputeRHEOKernel::ComputeRHEOKernel(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg),
list(nullptr), C(nullptr), C0(nullptr), coordination(nullptr), compute_interface(nullptr)
{
if (narg != 4) error->all(FLERR,"Illegal compute rheo/kernel command");
kernel_style = utils::inumeric(FLERR, arg[3], false, lmp);
if (kernel_style == QUINTIC || kernel_style == WENDLANDC4) {
correction_order = -1;
} else if (kernel_style == RK0) {
correction_order = 0;
} else if (kernel_style == RK1) {
correction_order = 1;
} else if (kernel_style == RK2) {
correction_order = 2;
}
dim = domain->dimension;
comm_forward = 1;
ncor = 0;
Mdim = 0;
if (kernel_style == RK1) {
Mdim = 1 + dim;
ncor = 1 + dim;
comm_forward = ncor * Mdim;
} else if (kernel_style == RK2) {
//Polynomial basis size (up to quadratic order)
Mdim = 1 + dim + dim * (dim + 1) / 2;
//Number of sets of correction coefficients (1 x y xx yy) + z zz (3D)
ncor = 1 + 2 * dim;
comm_forward = ncor * Mdim;
}
comm_forward_save = comm_forward;
corrections_calculated = 0;
gsl_error_flag = 0;
}
/* ---------------------------------------------------------------------- */
ComputeRHEOKernel::~ComputeRHEOKernel()
{
memory->destroy(coordination);
memory->destroy(C);
memory->destroy(C0);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::init()
{
neighbor->add_request(this, NeighConst::REQ_FULL);
interface_flag = fix_rheo->interface_flag;
compute_interface = fix_rheo->compute_interface;
zmin = fix_rheo->zmin_kernel;
cut = fix_rheo->cut;
cutsq = cut * cut;
cutinv = 1.0 / cut;
cutsqinv = cutinv * cutinv;
if (kernel_style != WENDLANDC4) {
if (dim == 3) {
pre_w = 1.0 / (120.0 * MY_PI) * 27.0 * cutsqinv * cutinv;
pre_wp = pre_w * 3.0 * cutinv;
} else {
pre_w = 7.0 / (478.0 * MY_PI) * 9 * cutsqinv;
pre_wp = pre_w * 3.0 * cutinv;
}
} else {
if (dim == 3) {
pre_w = 495.0 / (32.0 * MY_PI * cutsq * cut);
pre_wp = pre_w * cutinv;
} else {
pre_w = 9.0 / (MY_PI * cutsq);
pre_wp = pre_w * cutinv;
}
}
nmax_store = atom->nmax;
memory->create(coordination, nmax_store, "rheo:coordination");
if (kernel_style == RK0) {
memory->create(C0, nmax_store, "rheo/kernel:C0");
} else if (kernel_style == RK1) {
memory->create(C, nmax_store, ncor, Mdim, "rheo/kernel:C");
} else if (kernel_style == RK2) {
memory->create(C, nmax_store, ncor, Mdim, "rheo/kernel:C");
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOKernel::check_corrections(int i)
{
// Skip if there were gsl errors for this atom
if (gsl_error_flag)
if (gsl_error_tags.find(atom->tag[i]) != gsl_error_tags.end())
return 0;
// Skip if undercoordinated
if (coordination[i] < zmin)
return 0;
// Skip if corrections not yet calculated
if (!corrections_calculated)
return 0;
return 1;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w_self(int i, int j)
{
double w;
if (kernel_style == WENDLANDC4)
w = calc_w_wendlandc4(i, j, 0.0, 0.0, 0.0, 0.0);
else
w = calc_w_quintic(i, j, 0.0, 0.0, 0.0, 0.0);
return w;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w(int i, int j, double delx, double dely, double delz, double r)
{
double w;
int corrections_i, corrections_j, corrections;
if (kernel_style == WENDLANDC4)
return calc_w_wendlandc4(i, j, delx, dely, delz, r);
if (kernel_style != QUINTIC) {
corrections_i = check_corrections(i);
corrections_j = check_corrections(j);
corrections = corrections_i & corrections_j;
} else {
corrections = 0;
}
if (!corrections) w = calc_w_quintic(i, j, delx, dely, delz, r);
else if (kernel_style == RK0) w = calc_w_rk0(i, j, delx, dely, delz, r);
else if (kernel_style == RK1) w = calc_w_rk1(i, j, delx, dely, delz, r);
else if (kernel_style == RK2) w = calc_w_rk2(i, j, delx, dely, delz, r);
return w;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_dw(int i, int j, double delx, double dely, double delz, double r)
{
double wp;
int corrections_i, corrections_j;
if (kernel_style == WENDLANDC4)
return calc_dw_wendlandc4(i, j, delx, dely, delz, r, dWij, dWji);
if (kernel_style != QUINTIC) {
corrections_i = check_corrections(i);
corrections_j = check_corrections(j);
}
// Calc wp and default dW's, a bit inefficient but can redo later
wp = calc_dw_quintic(i, j, delx, dely, delz, r, dWij, dWji);
// Overwrite if there are corrections
if (kernel_style == RK1) {
if (corrections_i) calc_dw_rk1(i, j, delx, dely, delz, r, dWij);
if (corrections_j) calc_dw_rk1(j, i, -delx, -dely, -delz, r, dWji);
} else if (kernel_style == RK2) {
if (corrections_i) calc_dw_rk2(i, j, delx, dely, delz, r, dWij);
if (corrections_j) calc_dw_rk2(j, i, -delx, -dely, -delz, r, dWji);
}
return wp;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w_quintic(int i, int j, double delx, double dely, double delz, double r)
{
double w, tmp1, tmp2, tmp3, tmp1sq, tmp2sq, tmp3sq, s;
s = r * 3.0 * cutinv;
if (s > 3.0) {
w = 0.0;
}
if (s <= 3.0) {
tmp3 = 3.0 - s;
tmp3sq = tmp3 * tmp3;
w = tmp3sq * tmp3sq * tmp3;
}
if (s <= 2.0) {
tmp2 = 2.0 - s;
tmp2sq = tmp2 * tmp2;
w -= 6.0 * tmp2sq * tmp2sq * tmp2;
}
if (s <= 1.0) {
tmp1 = 1.0 - s;
tmp1sq = tmp1 * tmp1;
w += 15.0 * tmp1sq * tmp1sq * tmp1;
}
w *= pre_w;
Wij = w;
Wji = w;
return w;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_dw_quintic(int i, int j, double delx, double dely, double delz, double r, double *dW1, double *dW2)
{
double wp, tmp1, tmp2, tmp3, tmp1sq, tmp2sq, tmp3sq, s, wprinv;
double *mass = atom->mass;
int *type = atom->type;
s = r * 3.0 * cutinv;
if (s > 3.0) {
wp = 0.0;
}
if (s <= 3.0) {
tmp3 = 3.0 - s;
tmp3sq = tmp3 * tmp3;
wp = -5.0 * tmp3sq * tmp3sq;
}
if (s <= 2.0) {
tmp2 = 2.0 - s;
tmp2sq = tmp2 * tmp2;
wp += 30.0 * tmp2sq * tmp2sq;
}
if (s <= 1.0) {
tmp1 = 1.0 - s;
tmp1sq = tmp1 * tmp1;
wp -= 75.0 * tmp1sq * tmp1sq;
}
wp *= pre_wp;
wprinv = wp / r;
dW1[0] = delx * wprinv;
dW1[1] = dely * wprinv;
dW1[2] = delz * wprinv;
dW2[0] = -delx * wprinv;
dW2[1] = -dely * wprinv;
dW2[2] = -delz * wprinv;
return wp;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w_wendlandc4(int i, int j, double delx, double dely, double delz, double r)
{
double w, tmp6, s;
s = r * cutinv;
if (s > 1.0) {
w = 0.0;
} else {
tmp6 = (1.0 - s) * (1.0 - s);
tmp6 *= tmp6 * tmp6;
w = tmp6 * (1.0 + 6.0 * s + 35.0 * THIRD * s * s);
}
w *= pre_w;
Wij = w;
Wji = w;
return w;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_dw_wendlandc4(int i, int j, double delx, double dely, double delz, double r, double *dW1, double *dW2)
{
double wp, tmp1, tmp5, tmp6, s, wprinv;
double *mass = atom->mass;
int *type = atom->type;
s = r * cutinv;
if (s > 1.0) {
wp = 0.0;
} else {
tmp1 = 1.0 - s;
tmp5 = tmp1 * tmp1;
tmp5 = tmp5 * tmp5 * tmp1;
tmp6 = tmp5 * tmp1;
wp = tmp6 * (6.0 + 70.0 * THIRD * s);
wp -= 6 * tmp5 * (1.0 + 6.0 * s + 35.0 * THIRD * s * s);
}
wp *= pre_wp;
wprinv = wp / r;
dW1[0] = delx * wprinv;
dW1[1] = dely * wprinv;
dW1[2] = delz * wprinv;
dW2[0] = -delx * wprinv;
dW2[1] = -dely * wprinv;
dW2[2] = -delz * wprinv;
return wp;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w_rk0(int i, int j, double delx, double dely, double delz, double r)
{
double w;
w = calc_w_quintic(i, j, delx, dely, delz, r);
Wij = C0[i] * w;
Wji = C0[j] * w;
return w;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w_rk1(int i, int j, double delx, double dely, double delz, double r)
{
int b;
double w, wR, dx[3], H[Mdim];
dx[0] = delx;
dx[1] = dely;
dx[2] = delz;
w = calc_w_quintic(i, j, delx, dely, delz, r);
if (dim == 2) {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
} else {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = dx[2] * cutinv;
}
Wij = 0;
for (b = 0; b < Mdim; b++) {
Wij += C[i][0][b] * H[b]; // C columns: 1 x y (z) xx yy (zz)
}
Wij *= w;
//Now compute Wji
H[1] *= -1;
H[2] *= -1;
if (dim == 3) H[3] *= -1;
Wji = 0;
for (b = 0; b < Mdim; b++) {
Wji += C[j][0][b] * H[b]; // C columns: 1 x y (z) xx yy (zz)
}
Wji *= w;
return w;
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::calc_w_rk2(int i, int j, double delx, double dely, double delz, double r)
{
int b;
double w, wR, dx[3], H[Mdim];
dx[0] = delx;
dx[1] = dely;
dx[2] = delz;
w = calc_w_quintic(i, j, delx, dely, delz, r);
if (dim == 2) {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = 0.5 * dx[0] * dx[0] * cutsqinv;
H[4] = 0.5 * dx[1] * dx[1] * cutsqinv;
H[5] = dx[0] * dx[1] * cutsqinv;
} else {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = dx[2] * cutinv;
H[4] = 0.5 * dx[0] * dx[0] * cutsqinv;
H[5] = 0.5 * dx[1] * dx[1] * cutsqinv;
H[6] = 0.5 * dx[2] * dx[2] * cutsqinv;
H[7] = dx[0] * dx[1] * cutsqinv;
H[8] = dx[0] * dx[2] * cutsqinv;
H[9] = dx[1] * dx[2] * cutsqinv;
}
Wij = 0;
for (b = 0; b < Mdim; b++) {
Wij += C[i][0][b] * H[b]; // C columns: 1 x y (z) xx yy (zz)
}
Wij *= w;
//Now compute Wji
H[1] *= -1;
H[2] *= -1;
if (dim == 3) H[3] *= -1;
Wji = 0;
for (b = 0; b < Mdim; b++) {
Wji += C[j][0][b] * H[b]; // C columns: 1 x y (z) xx yy (zz)
}
Wji *= w;
return w;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::calc_dw_rk1(int i, int j, double delx, double dely, double delz, double r, double *dW)
{
int a, b;
double w, dx[3], H[Mdim];
dx[0] = delx;
dx[1] = dely;
dx[2] = delz;
w = calc_w_quintic(i, j, delx, dely, delz, r);
//Populate correction basis
if (dim == 2) {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
} else {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = dx[2] * cutinv;
}
// dWij[] = dWx dWy (dWz)
//compute derivative operators
for (a = 0; a < dim; a++) {
dW[a] = 0.0;
for (b = 0; b < Mdim; b++) {
//First derivative kernels
dW[a] += C[i][1 + a][b] * H[b]; // C columns: 1 x y (z)
}
dW[a] *= w;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::calc_dw_rk2(int i, int j, double delx, double dely, double delz, double r, double *dW)
{
int a, b;
double w, dx[3], H[Mdim];
dx[0] = delx;
dx[1] = dely;
dx[2] = delz;
w = calc_w_quintic(i, j, delx, dely, delz, r);
//Populate correction basis
if (dim == 2) {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = 0.5 * dx[0] * dx[0] * cutsqinv;
H[4] = 0.5 * dx[1] * dx[1] * cutsqinv;
H[5] = dx[0] * dx[1] * cutsqinv;
} else {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = dx[2] * cutinv;
H[4] = 0.5 * dx[0] * dx[0] * cutsqinv;
H[5] = 0.5 * dx[1] * dx[1] * cutsqinv;
H[6] = 0.5 * dx[2] * dx[2] * cutsqinv;
H[7] = dx[0] * dx[1] * cutsqinv;
H[8] = dx[0] * dx[2] * cutsqinv;
H[9] = dx[1] * dx[2] * cutsqinv;
}
// dWij[] = dWx dWy (dWz)
//compute derivative operators
for (a = 0; a < dim; a++) {
dW[a] = 0.0;
for (b = 0; b < Mdim; b++) {
//First derivative kernels
dW[a] += C[i][1 + a][b] * H[b]; // C columns: 1 x y (z) xx yy (zz)
}
dW[a] *= w;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::compute_peratom()
{
gsl_error_flag = 0;
gsl_error_tags.clear();
if (kernel_style == QUINTIC) return;
corrections_calculated = 1;
int i, j, ii, jj, inum, jnum, itype, g, a, b, gsl_error;
double xtmp, ytmp, ztmp, r, rsq, w, vj, rhoj;
double dx[3];
gsl_matrix_view gM;
// Turn off GSL error handler, revert RK to Quintic when insufficient neighbors
gsl_set_error_handler_off();
double **x = atom->x;
int *type = atom->type;
double *mass = atom->mass;
double *rho = atom->rho;
int *status = atom->rheo_status;
tagint *tag = atom->tag;
int *ilist, *jlist, *numneigh, **firstneigh;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// Grow arrays if necessary
if (nmax_store < atom->nmax) grow_arrays(atom->nmax);
if (kernel_style == RK0) {
double M;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
//Initialize M to zero:
M = 0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
if (rsq < cutsq) {
r = sqrt(rsq);
w = calc_w_quintic(i, j, dx[0], dx[1], dx[2], r);
rhoj = rho[j];
if (interface_flag)
if (status[j] & PHASECHECK)
rhoj = compute_interface->correct_rho(j, i);
vj = mass[type[j]] / rhoj;
M += w * vj;
}
}
// Inverse of 1x1 matrix
if (coordination[i] >= zmin) C0[i] = 1.0 / M;
}
} else if (correction_order > 0) {
// Moment matrix M and polynomial basis vector cut (1d for gsl compatibility)
double H[Mdim], M[Mdim * Mdim];
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
itype = type[i];
// Zero upper-triangle M and cut (will be symmetric):
for (a = 0; a < Mdim; a++) {
for (b = a; b < Mdim; b++) {
M[a * Mdim + b] = 0;
}
}
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
if (rsq < cutsq) {
r = sqrt(rsq);
w = calc_w_quintic(i, j, dx[0], dx[1], dx[2], r);
rhoj = rho[j];
if (interface_flag)
if (status[j] & PHASECHECK)
rhoj = compute_interface->correct_rho(j, i);
vj = mass[type[j]] / rhoj;
//Populate the H-vector of polynomials (2D)
if (dim == 2) {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
if (kernel_style == RK2) {
H[3] = 0.5 * dx[0] * dx[0] * cutsqinv;
H[4] = 0.5 * dx[1] * dx[1] * cutsqinv;
H[5] = dx[0] * dx[1] * cutsqinv;
}
} else {
H[0] = 1.0;
H[1] = dx[0] * cutinv;
H[2] = dx[1] * cutinv;
H[3] = dx[2] * cutinv;
if (kernel_style == RK2) {
H[4] = 0.5 * dx[0] * dx[0] * cutsqinv;
H[5] = 0.5 * dx[1] * dx[1] * cutsqinv;
H[6] = 0.5 * dx[2] * dx[2] * cutsqinv;
H[7] = dx[0] * dx[1] * cutsqinv;
H[8] = dx[0] * dx[2] * cutsqinv;
H[9] = dx[1] * dx[2] * cutsqinv;
}
}
// Populate the upper triangle
for (a = 0; a < Mdim; a++) {
for (b = a; b < Mdim; b++) {
M[a * Mdim + b] += H[a] * H[b] * w * vj;
}
}
}
}
// Populate the lower triangle from the symmetric entries of M:
for (a = 0; a < Mdim; a++) {
for (b = a; b < Mdim; b++) {
M[b * Mdim + a] = M[a * Mdim + b];
}
}
// Skip if undercoordinated
if (coordination[i] < zmin) continue;
// Use gsl to get Minv, use Cholesky decomposition since the
// polynomials are independent, M is symmetrix & positive-definite
gM = gsl_matrix_view_array(M,Mdim,Mdim);
gsl_error = gsl_linalg_cholesky_decomp1(&gM.matrix);
if (gsl_error) {
//Revert to uncorrected SPH for this particle
gsl_error_flag = 1;
gsl_error_tags.insert(tag[i]);
//check if not positive-definite
if (gsl_error != GSL_EDOM)
error->warning(FLERR, "Failed decomposition in rheo/kernel, gsl_error = {}", gsl_error);
continue;
}
gsl_linalg_cholesky_invert(&gM.matrix); //M is now M^-1
// Correction coefficients are columns of M^-1 multiplied by an appropriate coefficient
// Solve the linear system several times to get coefficientns
// M: 1 x y (z) x^2 y^2 (z^2) xy (xz) (yz)
// ----------------------------------------------------------
// 0 1 2 3 4 5 || 2D indexing
// 0 1 2 3 4 5 6 7 8 9 || 3D indexing
// W 1 . . . . . . . . .
// dWx . -1 . . . . . . . .
// dWy . . -1 . . . . . . .
// dWz . . . (-1) . . . . . .
// d2Wx . . . . 2 . . . . .
// d2Wy . . . . . 2 . . . .
// d2Wz . . . . . . (2) . . .
//0 1 2 3 4
//0 1 2 3 4 5 6
// Pack coefficients into C
for (a = 0; a < Mdim; a++) {
C[i][0][a] = M[a * Mdim + 0]; // all rows of column 0
for (b = 0; b < dim; b++) {
//First derivatives
C[i][1 + b][a] = -M[a * Mdim + b + 1] * cutinv;
// columns 1-2 (2D) or 1-3 (3D)
//Second derivatives
if (kernel_style == RK2)
C[i][1 + dim + b][a] = M[a * Mdim + b + 1 + dim] * cutsqinv;
// columns 3-4 (2D) or 4-6 (3D)
}
}
}
}
// communicate calculated quantities
comm_stage = 1;
comm_forward = comm_forward_save;
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::compute_coordination()
{
int i, j, ii, jj, inum, jnum;
double xtmp, ytmp, ztmp, rsq;
double dx[3];
double **x = atom->x;
int *ilist, *jlist, *numneigh, **firstneigh;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// Grow arrays if necessary
if (nmax_store < atom->nmax) grow_arrays(atom->nmax);
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
coordination[i] = 0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
if (rsq < cutsq)
coordination[i] += 1;
}
}
// communicate calculated quantities
comm_stage = 0;
comm_forward = 1;
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::grow_arrays(int nmax)
{
memory->grow(coordination, nmax, "rheo:coordination");
if (kernel_style == RK0) {
memory->grow(C0, nmax, "rheo/kernel:C0");
} else if (correction_order > 0) {
memory->grow(C, nmax, ncor, Mdim, "rheo/kernel:C");
}
nmax_store = nmax;
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOKernel::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i,j,k,m,a,b;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (comm_stage == 0) {
buf[m++] = coordination[j];
} else {
if (kernel_style == RK0) {
buf[m++] = C0[j];
} else {
for (a = 0; a < ncor; a++)
for (b = 0; b < Mdim; b++)
buf[m++] = C[j][a][b];
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOKernel::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last,a,b;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (comm_stage == 0) {
coordination[i] = buf[m++];
} else {
if (kernel_style == RK0) {
C0[i] = buf[m++];
} else {
for (a = 0; a < ncor; a++)
for (b = 0; b < Mdim; b++)
C[i][a][b] = buf[m++];
}
}
}
}
/* ---------------------------------------------------------------------- */
double ComputeRHEOKernel::memory_usage()
{
double bytes = 0.0;
bytes = (size_t) nmax_store * sizeof(int);
if (kernel_style == RK0) {
bytes += (size_t) nmax_store * sizeof(double);
} else if (correction_order > 0) {
bytes += (size_t) nmax_store * ncor * Mdim * sizeof(double);
}
return bytes;
}

View File

@ -0,0 +1,81 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(RHEO/KERNEL,ComputeRHEOKernel)
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_KERNEL_H
#define LMP_COMPUTE_RHEO_KERNEL_H
#include "compute.h"
#include <unordered_set>
namespace LAMMPS_NS {
class ComputeRHEOKernel : public Compute {
public:
ComputeRHEOKernel(class LAMMPS *, int, char **);
~ComputeRHEOKernel() override;
void init() override;
void init_list(int, class NeighList *) override;
void compute_peratom() override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
double memory_usage() override;
void compute_coordination();
double calc_w_self(int,int);
double calc_w(int,int,double,double,double,double);
double calc_dw(int,int,double,double,double,double);
double calc_w_quintic(int,int,double,double,double,double);
double calc_dw_quintic(int,int,double,double,double,double,double *,double *);
double calc_w_wendlandc4(int,int,double,double,double,double);
double calc_dw_wendlandc4(int,int,double,double,double,double,double *,double *);
void grow_arrays(int);
double dWij[3], dWji[3], Wij, Wji;
int correction_order;
int *coordination;
class FixRHEO *fix_rheo;
private:
int comm_stage, comm_forward_save;
int interface_flag;
int gsl_error_flag;
std::unordered_set<tagint> gsl_error_tags;
int corrections_calculated;
int kernel_style, zmin, dim, Mdim, ncor;
int nmax_store;
double cut, cutsq, cutinv, cutsqinv, pre_w, pre_wp;
double ***C;
double *C0;
class NeighList *list;
class ComputeRHEOInterface *compute_interface;
int check_corrections(int);
double calc_w_rk0(int,int,double,double,double,double);
double calc_w_rk1(int,int,double,double,double,double);
double calc_w_rk2(int,int,double,double,double,double);
void calc_dw_rk1(int,int,double,double,double,double,double *);
void calc_dw_rk2(int,int,double,double,double,double,double *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,614 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "compute_rheo_property_atom.h"
#include "atom.h"
#include "atom_vec.h"
#include "compute_rheo_interface.h"
#include "compute_rheo_kernel.h"
#include "compute_rheo_surface.h"
#include "compute_rheo_vshift.h"
#include "compute_rheo_grad.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "fix_rheo_oxidation.h"
#include "fix_rheo_pressure.h"
#include "fix_rheo_thermal.h"
#include "memory.h"
#include "modify.h"
#include "update.h"
#include "utils.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace RHEO_NS;
/* ---------------------------------------------------------------------- */
ComputeRHEOPropertyAtom::ComputeRHEOPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), fix_pressure(nullptr), fix_thermal(nullptr), compute_interface(nullptr),
compute_kernel(nullptr), compute_surface(nullptr), compute_vshift(nullptr), compute_grad(nullptr),
avec_index(nullptr), pack_choice(nullptr), col_index(nullptr)
{
if (narg < 4) utils::missing_cmd_args(FLERR, "compute property/atom", error);
peratom_flag = 1;
int dim = domain->dimension;
// Determine number of values
nvalues = 0;
for (int iarg = 3; iarg < narg; iarg++) {
if (strcmp(arg[iarg], "surface/n/*") == 0) {
nvalues += dim;
} else if (strcmp(arg[iarg], "shift/v/*") == 0) {
nvalues += dim;
} else if (strcmp(arg[iarg], "grad/v/*") == 0) {
nvalues += dim * dim;
} else if (strcmp(arg[iarg], "stress/v/*") == 0) {
nvalues += dim * dim;
} else if (strcmp(arg[iarg], "stress/t/*") == 0) {
nvalues += dim * dim;
} else {
nvalues += 1;
}
}
if (nvalues == 1) size_peratom_cols = 0;
else size_peratom_cols = nvalues;
pressure_flag = thermal_flag = interface_flag = 0;
surface_flag = shift_flag = shell_flag = 0;
// parse input values
// customize a new keyword by adding to if statement
pack_choice = new FnPtrPack[nvalues];
avec_index = new int[nvalues];
col_index = new int[nvalues];
col_t_index = new int[nvalues];
int i = 0;
int index, a, b;
for (int iarg = 3; iarg < narg; iarg++) {
if (strcmp(arg[iarg], "phase") == 0) {
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_phase;
} else if (strcmp(arg[iarg], "status") == 0) {
// Short hand for "rheo_status"
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_status;
} else if (strcmp(arg[iarg], "chi") == 0) {
interface_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_chi;
} else if (strcmp(arg[iarg], "surface") == 0) {
surface_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_surface;
} else if (strcmp(arg[iarg], "surface/r") == 0) {
surface_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_surface_r;
} else if (strcmp(arg[iarg], "surface/divr") == 0) {
surface_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_surface_divr;
} else if (strcmp(arg[iarg], "coordination") == 0) {
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_coordination;
} else if (strcmp(arg[iarg], "pressure") == 0) {
pressure_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_pressure;
} else if (strcmp(arg[iarg], "cv") == 0) {
thermal_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_cv;
} else if (utils::strmatch(arg[iarg], "^surface/n/")) {
surface_flag = 1;
i += add_vector_component(arg[iarg], i, &ComputeRHEOPropertyAtom::pack_surface_n) - 1;
} else if (utils::strmatch(arg[iarg], "^shift/v/")) {
shift_flag = 1;
i += add_vector_component(arg[iarg], i, &ComputeRHEOPropertyAtom::pack_shift_v) - 1;
} else if (utils::strmatch(arg[iarg], "^grad/v/")) {
i += add_tensor_component(arg[iarg], i, &ComputeRHEOPropertyAtom::pack_gradv) - 1;
} else if (utils::strmatch(arg[iarg], "^stress/v/")) {
i += add_tensor_component(arg[iarg], i, &ComputeRHEOPropertyAtom::pack_viscous_stress) - 1;
} else if (utils::strmatch(arg[iarg], "^stress/t/")) {
i += add_tensor_component(arg[iarg], i, &ComputeRHEOPropertyAtom::pack_total_stress) - 1;
} else if (strcmp(arg[iarg], "energy") == 0) {
avec_index[i] = atom->avec->property_atom("esph");
if (avec_index[i] < 0)
error->all(FLERR,
"Invalid keyword {} for atom style {} in compute rheo/property/atom command ",
arg[iarg], atom->get_style());
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_atom_style;
thermal_flag = 1;
} else if (strcmp(arg[iarg], "nbond/shell") == 0) {
shell_flag = 1;
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_nbond_shell;
} else {
avec_index[i] = atom->avec->property_atom(arg[iarg]);
if (avec_index[i] < 0)
error->all(FLERR,
"Invalid keyword {} for atom style {} in compute rheo/property/atom command ",
arg[iarg], atom->get_style());
pack_choice[i] = &ComputeRHEOPropertyAtom::pack_atom_style;
if (strcmp(arg[iarg], "temperature") == 0) thermal_flag = 1;
if (strcmp(arg[iarg], "heatflow") == 0) thermal_flag = 1;
if (strcmp(arg[iarg], "conductivity") == 0) thermal_flag = 1;
}
i++;
}
nmax = 0;
}
/* ---------------------------------------------------------------------- */
ComputeRHEOPropertyAtom::~ComputeRHEOPropertyAtom()
{
delete[] pack_choice;
delete[] avec_index;
delete[] col_index;
delete[] col_t_index;
memory->destroy(vector_atom);
memory->destroy(array_atom);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::init()
{
auto fixes = modify->get_fix_by_style("^rheo$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use compute rheo/property/atom");
fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
if (interface_flag && !(fix_rheo->interface_flag))
error->all(FLERR, "Cannot request interfacial property without corresponding option in fix rheo");
if (surface_flag && !(fix_rheo->surface_flag))
error->all(FLERR, "Cannot request surface property without corresponding option in fix rheo");
if (shift_flag && !(fix_rheo->shift_flag))
error->all(FLERR, "Cannot request velocity shifting property without corresponding option in fix rheo");
if (thermal_flag && !(fix_rheo->thermal_flag))
error->all(FLERR, "Cannot request thermal property without fix rheo/thermal");
compute_interface = fix_rheo->compute_interface;
compute_kernel = fix_rheo->compute_kernel;
compute_surface = fix_rheo->compute_surface;
compute_vshift = fix_rheo->compute_vshift;
compute_grad = fix_rheo->compute_grad;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::setup()
{
if (thermal_flag) {
auto fixes = modify->get_fix_by_style("rheo/thermal");
fix_thermal = dynamic_cast<FixRHEOThermal *>(fixes[0]);
}
if (pressure_flag) {
auto fixes = modify->get_fix_by_style("rheo/pressure");
fix_pressure = dynamic_cast<FixRHEOPressure *>(fixes[0]);
}
if (shell_flag) {
auto fixes = modify->get_fix_by_style("rheo/oxidation");
fix_oxidation = dynamic_cast<FixRHEOOxidation *>(fixes[0]);
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::compute_peratom()
{
invoked_peratom = update->ntimestep;
// grow vector or array if necessary
if (atom->nmax > nmax) {
nmax = atom->nmax;
if (nvalues == 1) {
memory->destroy(vector_atom);
memory->create(vector_atom, nmax, "rheo/property/atom:vector");
} else {
memory->destroy(array_atom);
memory->create(array_atom, nmax, nvalues, "rheo/property/atom:array");
}
}
// fill vector or array with per-atom values
if (nvalues == 1) {
buf = vector_atom;
(this->*pack_choice[0])(0);
} else {
if (nmax) buf = &array_atom[0][0];
else buf = nullptr;
for (int n = 0; n < nvalues; n++)
(this->*pack_choice[n])(n);
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeRHEOPropertyAtom::memory_usage()
{
double bytes = (double)nmax * nvalues * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
one method for every keyword compute rheo/property/atom can output
the atom property is packed into buf starting at n with stride nvalues
customize a new keyword by adding a method
------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_phase(int n)
{
int *status = atom->rheo_status;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = (status[i] & PHASECHECK);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_status(int n)
{
int *status = atom->rheo_status;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = status[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_chi(int n)
{
double *chi = compute_interface->chi;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = chi[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_surface(int n)
{
int *status = atom->rheo_status;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double label;
for (int i = 0; i < nlocal; i++) {
label = 0;
if (mask[i] & groupbit) {
if (status[i] & STATUS_SURFACE) label = 1.0;
if (status[i] & STATUS_SPLASH) label = 2.0;
}
buf[n] = label;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_surface_r(int n)
{
double *rsurface = compute_surface->rsurface;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = rsurface[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_surface_divr(int n)
{
double *divr = compute_surface->divr;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = divr[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_surface_n(int n)
{
double **nsurface = compute_surface->nsurface;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int index = col_index[n];
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = nsurface[i][index];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_coordination(int n)
{
int *coordination = compute_kernel->coordination;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = coordination[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_cv(int n)
{
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = fix_thermal->calc_cv(i, type[i]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_pressure(int n)
{
int *type = atom->type;
int *mask = atom->mask;
double *rho = atom->rho;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = fix_pressure->calc_pressure(rho[i], type[i]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_viscous_stress(int n)
{
double **gradv = compute_grad->gradv;
double *viscosity = atom->viscosity;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int index = col_index[n];
int dim = domain->dimension;
int a = index / dim;
int b = index % dim;
int index_transpose = b * dim + a;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = viscosity[i] * (gradv[i][index] + gradv[i][index_transpose]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_total_stress(int n)
{
double **gradv = compute_grad->gradv;
double *viscosity = atom->viscosity;
double *rho = atom->rho;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int index = col_index[n];
int dim = domain->dimension;
int a = index / dim;
int b = index % dim;
int index_transpose = b * dim + a;
double p;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (index == index_transpose)
p = fix_pressure->calc_pressure(rho[i], type[i]);
else
p = 0.0;
buf[n] = viscosity[i] * (gradv[i][index] + gradv[i][index_transpose]) + p;
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_nbond_shell(int n)
{
int *nbond = fix_oxidation->nbond;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = nbond[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_shift_v(int n)
{
double **vshift = compute_vshift->vshift;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int index = col_index[n];
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = vshift[i][index];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_gradv(int n)
{
double **gradv = compute_grad->gradv;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int index = col_index[n];
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = gradv[i][index];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOPropertyAtom::pack_atom_style(int n)
{
atom->avec->pack_property_atom(avec_index[n], &buf[n], nvalues, groupbit);
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOPropertyAtom::add_tensor_component(char* option, int i, FnPtrPack pack_function)
{
int shift;
int dim = domain->dimension;
if (((std::string) option).back() == '*') {
for (int a = 0; a < dim; a++) {
for (int b = 0; b < dim; b++) {
pack_choice[i + a * dim + b] = pack_function;
col_index[i + a * dim + b] = a * dim + b;
}
}
shift = dim * dim;
} else {
int index;
int dim_error = 0;
if (utils::strmatch(option, "xx$")) {
index = 0;
} else if (utils::strmatch(option, "xy$")) {
index = 1;
} else if (utils::strmatch(option, "xz$")) {
index = 2;
if (dim == 2) dim_error = 1;
} else if (utils::strmatch(option, "yx$")) {
if (dim == 2) index = 2;
else index = 3;
} else if (utils::strmatch(option, "yy$")) {
if (dim == 2) index = 3;
else index = 4;
} else if (utils::strmatch(option, "yz$")) {
index = 5;
if (dim == 2) dim_error = 1;
} else if (utils::strmatch(option, "zx$")) {
index = 6;
if (dim == 2) dim_error = 1;
} else if (utils::strmatch(option, "zy$")) {
index = 7;
if (dim == 2) dim_error = 1;
} else if (utils::strmatch(option, "zz$")) {
index = 8;
if (dim == 2) dim_error = 1;
} else {
error->all(FLERR, "Invalid compute rheo/property/atom property {}", option);
}
if (dim_error)
error->all(FLERR, "Invalid compute rheo/property/atom property {} in 2D", option);
pack_choice[i] = pack_function;
col_index[i] = index;
shift = 1;
}
return shift;
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOPropertyAtom::add_vector_component(char* option, int i, FnPtrPack pack_function)
{
int shift;
int dim = domain->dimension;
if (((std::string) option).back() == '*') {
for (int a = 0; a < dim; a++) {
pack_choice[i + a] = pack_function;
col_index[i + a] = a;
}
shift = dim;
} else {
int index;
if (utils::strmatch(option, "x$")) {
index = 0;
} else if (utils::strmatch(option, "y$")) {
index = 1;
} else if (utils::strmatch(option, "z$")) {
if (dim == 2)
error->all(FLERR, "Invalid compute rheo/property/atom property {} in 2D", option);
index = 2;
} else {
error->all(FLERR, "Invalid compute rheo/property/atom property {}", option);
}
pack_choice[i] = pack_function;
col_index[i] = index;
shift = 1;
}
return shift;
}

View File

@ -0,0 +1,83 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(rheo/property/atom,ComputeRHEOPropertyAtom);
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_PROPERTY_ATOM_H
#define LMP_COMPUTE_RHEO_PROPERTY_ATOM_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeRHEOPropertyAtom : public Compute {
public:
ComputeRHEOPropertyAtom(class LAMMPS *, int, char **);
~ComputeRHEOPropertyAtom() override;
void init() override;
void setup() override;
void compute_peratom() override;
double memory_usage() override;
private:
int nvalues, nmax;
int pressure_flag, thermal_flag, interface_flag;
int surface_flag, shift_flag, shell_flag;
int *avec_index;
int *col_index, *col_t_index;
double *buf;
typedef void (ComputeRHEOPropertyAtom::*FnPtrPack)(int);
FnPtrPack *pack_choice; // ptrs to pack functions
void pack_phase(int);
void pack_status(int);
void pack_chi(int);
void pack_surface(int);
void pack_surface_r(int);
void pack_surface_divr(int);
void pack_surface_n(int);
void pack_coordination(int);
void pack_cv(int);
void pack_shift_v(int);
void pack_gradv(int);
void pack_pressure(int);
void pack_viscous_stress(int);
void pack_total_stress(int);
void pack_nbond_shell(int);
void pack_atom_style(int);
int add_vector_component(char*, int, FnPtrPack);
int add_tensor_component(char*, int, FnPtrPack);
class FixRHEO *fix_rheo;
class FixRHEOPressure *fix_pressure;
class FixRHEOThermal *fix_thermal;
class FixRHEOOxidation *fix_oxidation;
class ComputeRHEOInterface *compute_interface;
class ComputeRHEOKernel *compute_kernel;
class ComputeRHEOSurface *compute_surface;
class ComputeRHEOVShift *compute_vshift;
class ComputeRHEOGrad *compute_grad;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,197 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "compute_rheo_rho_sum.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_kernel.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeRHEORhoSum::ComputeRHEORhoSum(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), compute_kernel(nullptr)
{
if (narg != 4) error->all(FLERR,"Illegal compute RHEO/rho command");
self_mass_flag = utils::bnumeric(FLERR, arg[3], false, lmp);
comm_forward = 1;
comm_reverse = 1;
}
/* ---------------------------------------------------------------------- */
ComputeRHEORhoSum::~ComputeRHEORhoSum() {}
/* ---------------------------------------------------------------------- */
void ComputeRHEORhoSum::init()
{
compute_kernel = fix_rheo->compute_kernel;
cut = fix_rheo->cut;
cutsq = cut * cut;
// need an occasional half neighbor list
neighbor->add_request(this, NeighConst::REQ_DEFAULT);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEORhoSum::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEORhoSum::compute_peratom()
{
int i, j, ii, jj, inum, jnum, itype, jtype;
double xtmp, ytmp, ztmp, delx, dely, delz;
int *ilist, *jlist, *numneigh, **firstneigh;
double rsq, w;
int nlocal = atom->nlocal;
double **x = atom->x;
double *rho = atom->rho;
int *type = atom->type;
double *mass = atom->mass;
int newton = force->newton;
double jmass;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
int nall = nlocal + atom->nghost;
// initialize arrays, local with quintic self-contribution, ghosts are zeroed
for (i = 0; i < nlocal; i++) {
w = compute_kernel->calc_w_self(i, i);
rho[i] = w * mass[type[i]];
}
for (i = nlocal; i < nall; i++) rho[i] = 0.0;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx * delx + dely * dely + delz * delz;
if (rsq < cutsq) {
w = compute_kernel->calc_w(i, j, delx, dely, delz, sqrt(rsq));
if (self_mass_flag) {
rho[i] += w * mass[type[i]];
if (newton || j < nlocal)
rho[j] += w * mass[type[j]];
} else {
rho[i] += w * mass[type[j]];
if (newton || j < nlocal)
rho[j] += w * mass[type[i]];
}
}
}
}
if (newton) comm->reverse_comm(this);
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
int ComputeRHEORhoSum::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i, j, k, m;
double *rho = atom->rho;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = rho[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEORhoSum::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *rho = atom->rho;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
rho[i] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int ComputeRHEORhoSum::pack_reverse_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *rho = atom->rho;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = rho[i];
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEORhoSum::unpack_reverse_comm(int n, int *list, double *buf)
{
int i, k, j, m;
double *rho = atom->rho;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
rho[j] += buf[m++];
}
}

View File

@ -0,0 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(RHEO/RHO/SUM,ComputeRHEORhoSum)
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_RHO_SUM_H
#define LMP_COMPUTE_RHEO_RHO_SUM_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeRHEORhoSum : public Compute {
public:
ComputeRHEORhoSum(class LAMMPS *, int, char **);
~ComputeRHEORhoSum() override;
void init() override;
void init_list(int, class NeighList *) override;
void compute_peratom() override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
class FixRHEO *fix_rheo;
private:
int self_mass_flag;
double cut, cutsq;
class NeighList *list;
class ComputeRHEOKernel *compute_kernel;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,417 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU), Eric Palermo (CMU)
----------------------------------------------------------------------- */
#include "compute_rheo_surface.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_interface.h"
#include "compute_rheo_kernel.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "math_extra.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace FixConst;
using namespace MathExtra;
static constexpr double EPSILON = 1e-10;
/* ---------------------------------------------------------------------- */
ComputeRHEOSurface::ComputeRHEOSurface(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), rho0(nullptr), compute_kernel(nullptr), compute_interface(nullptr),
B(nullptr), gradC(nullptr), nsurface(nullptr), divr(nullptr), rsurface(nullptr)
{
if (narg != 3) error->all(FLERR,"Illegal compute RHEO/SURFACE command");
int dim = domain->dimension;
comm_forward = 2;
comm_reverse = dim * dim + 1;
nmax_store = 0;
grow_arrays(atom->nmax);
}
/* ---------------------------------------------------------------------- */
ComputeRHEOSurface::~ComputeRHEOSurface()
{
memory->destroy(divr);
memory->destroy(rsurface);
memory->destroy(nsurface);
memory->destroy(B);
memory->destroy(gradC);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOSurface::init()
{
compute_kernel = fix_rheo->compute_kernel;
compute_interface = fix_rheo->compute_interface;
cut = fix_rheo->cut;
rho0 = fix_rheo->rho0;
threshold_style = fix_rheo->surface_style;
threshold_divr = fix_rheo->divr_surface;
threshold_z = fix_rheo->zmin_surface;
threshold_splash = fix_rheo->zmin_splash;
interface_flag = fix_rheo->interface_flag;
cutsq = cut * cut;
// need an occasional half neighbor list
neighbor->add_request(this, NeighConst::REQ_DEFAULT);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOSurface::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOSurface::compute_peratom()
{
int i, j, ii, jj, inum, jnum, a, b, itype, jtype, fluidi, fluidj;
double xtmp, ytmp, ztmp, rsq, Voli, Volj, rhoi, rhoj, wp;
double dWij[3], dWji[3], dx[3];
int *ilist, *jlist, *numneigh, **firstneigh;
int nlocal = atom->nlocal;
double **x = atom->x;
int *status = atom->rheo_status;
int newton = force->newton;
int dim = domain->dimension;
int *mask = atom->mask;
int *type = atom->type;
double *mass = atom->mass;
double *rho = atom->rho;
int *coordination = compute_kernel->coordination;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// Grow and zero arrays
if (nmax_store < atom->nmax)
grow_arrays(atom->nmax);
size_t nbytes = nmax_store * sizeof(double);
memset(&divr[0], 0, nbytes);
memset(&rsurface[0], 0, nbytes);
memset(&nsurface[0][0], 0, dim * nbytes);
memset(&gradC[0][0], 0, dim * dim * nbytes);
memset(&B[0][0], 0, dim * dim * nbytes);
// loop over neighbors to calculate the average orientation of neighbors
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
itype = type[i];
fluidi = !(status[i] & PHASECHECK);
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
if (rsq < cutsq) {
jtype = type[j];
fluidj = !(status[j] & PHASECHECK);
rhoi = rho[i];
rhoj = rho[j];
// Add corrections for walls
if (interface_flag) {
if (fluidi && (!fluidj)) {
rhoj = compute_interface->correct_rho(j, i);
} else if ((!fluidi) && fluidj) {
rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) {
rhoi = rho0[itype];
rhoj = rho0[jtype];
}
}
Voli = mass[itype] / rhoi;
Volj = mass[jtype] / rhoj;
wp = compute_kernel->calc_dw_quintic(i, j, dx[0], dx[1], dx[2], sqrt(rsq), dWij, dWji);
for (a = 0; a < dim; a++) {
divr[i] -= dWij[a] * dx[a] * Volj;
gradC[i][a] += dWij[a] * Volj;
}
if ((j < nlocal) || newton) {
for (a = 0; a < dim; a++){
divr[j] += dWji[a] * dx[a] * Voli;
gradC[j][a] += dWji[a] * Voli;
}
}
}
}
}
// reverse gradC and divr, forward divr
comm_stage = 0;
comm_reverse = dim * dim + 1;
comm_forward = 1;
if (newton) comm->reverse_comm(this);
comm->forward_comm(this);
// calculate nsurface for local atoms
// Note, this isn't forwarded to ghosts
double maggC;
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
maggC = 0.0;
for (a = 0;a < dim; a++)
maggC += gradC[i][a] * gradC[i][a];
maggC = sqrt(maggC) + EPSILON;
maggC = 1.0 / maggC;
for (a = 0; a < dim; a++)
nsurface[i][a] = -gradC[i][a] * maggC;
}
}
// Remove surface settings and assign new values
int nall = nlocal + atom->nghost;
int test;
for (i = 0; i < nall; i++) {
status[i] &= SURFACEMASK;
if (mask[i] & groupbit) {
if (threshold_style == DIVR)
test = divr[i] < threshold_divr;
else
test = coordination[i] < threshold_z;
// Treat nonfluid particles as bulk
if (status[i] & PHASECHECK)
test = 0;
if (test) {
if (coordination[i] < threshold_splash)
status[i] |= STATUS_SPLASH;
else
status[i] |= STATUS_SURFACE;
rsurface[i] = 0.0;
} else {
status[i] |= STATUS_BULK;
rsurface[i] = cut;
}
}
}
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
fluidi = !(status[i] & PHASECHECK);
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
fluidj = !(status[j] & PHASECHECK);
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
if (rsq < cutsq) {
if (fluidi) {
if ((status[i] & STATUS_BULK) && (status[j] & STATUS_SURFACE)) {
status[i] &= SURFACEMASK;
status[i] |= STATUS_LAYER;
}
if (status[j] & STATUS_SURFACE)
rsurface[i] = MIN(rsurface[i], sqrt(rsq));
}
if (fluidj && (j < nlocal || newton)) {
if ((status[j] & STATUS_BULK) && (status[j] & PHASECHECK) && (status[i] & STATUS_SURFACE)) {
status[j] &= SURFACEMASK;
status[j] |= STATUS_LAYER;
}
if (status[i] & STATUS_SURFACE)
rsurface[j] = MIN(rsurface[j], sqrt(rsq));
}
}
}
}
// clear normal vectors for non-surface particles
for (i = 0; i < nall; i++) {
if (mask[i] & groupbit) {
if (!(status[i] & STATUS_SURFACE))
for (a = 0; a < dim; a++)
nsurface[i][a] = 0.0;
}
}
// forward/reverse status and rsurface
comm_stage = 1;
comm_reverse = 2;
comm_forward = 2;
if (newton) comm->reverse_comm(this);
comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOSurface::pack_reverse_comm(int n, int first, double *buf)
{
int i,a,b,k,m,last;
int dim = domain->dimension;
int *status = atom->rheo_status;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (comm_stage == 0) {
buf[m++] = divr[i];
for (a = 0; a < dim; a ++ )
for (b = 0; b < dim; b ++)
buf[m++] = gradC[i][a * dim + b];
} else if (comm_stage == 1) {
buf[m++] = (double) status[i];
buf[m++] = rsurface[i];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOSurface::unpack_reverse_comm(int n, int *list, double *buf)
{
int i,a,b,k,j,m;
int dim = domain->dimension;
int *status = atom->rheo_status;
int tmp1;
double tmp2;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (comm_stage == 0) {
divr[j] += buf[m++];
for (a = 0; a < dim; a ++ )
for (b = 0; b < dim; b ++)
gradC[j][a * dim + b] += buf[m++];
} else if (comm_stage == 1) {
tmp1 = (int) buf[m++];
if ((status[j] & STATUS_BULK) && (tmp1 & STATUS_LAYER)) {
status[j] &= SURFACEMASK;
status[j] |= STATUS_LAYER;
}
tmp2 = buf[m++];
rsurface[j] = MIN(rsurface[j], tmp2);
}
}
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOSurface::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i,j,a,b,k,m;
int *status = atom->rheo_status;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (comm_stage == 0) {
buf[m++] = divr[j];
} else if (comm_stage == 1) {
buf[m++] = (double) status[j];
buf[m++] = rsurface[j];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOSurface::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, a, b, m, last;
int *status = atom->rheo_status;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (comm_stage == 0) {
divr[i] = buf[m++];
} else if (comm_stage == 1) {
status[i] = (int) buf[m++];
rsurface[i] = buf[m++];
}
}
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOSurface::grow_arrays(int nmax)
{
int dim = domain->dimension;
memory->grow(divr, nmax, "rheo/surface:divr");
memory->grow(rsurface, nmax, "rheo/surface:rsurface");
memory->grow(nsurface, nmax, dim, "rheo/surface:nsurface");
memory->grow(B, nmax, dim * dim, "rheo/surface:B");
memory->grow(gradC, nmax, dim * dim, "rheo/surface:gradC");
nmax_store = nmax;
}

View File

@ -0,0 +1,59 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(RHEO/SURFACE,ComputeRHEOSurface)
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_SURFACE_H
#define LMP_COMPUTE_RHEO_SURFACE_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeRHEOSurface : public Compute {
public:
ComputeRHEOSurface(class LAMMPS *, int, char **);
~ComputeRHEOSurface() override;
void init() override;
void init_list(int, class NeighList *) override;
void compute_peratom() override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
double **nsurface, *rsurface, *divr;
class FixRHEO *fix_rheo;
private:
int surface_style, nmax_store, threshold_z, threshold_splash, interface_flag;
int threshold_style, comm_stage;
double cut, cutsq, *rho0, threshold_divr;
double **B, **gradC;
class NeighList *list;
class ComputeRHEOKernel *compute_kernel;
class ComputeRHEOInterface *compute_interface;
void grow_arrays(int);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,321 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU), Eric Palermo (CMU)
----------------------------------------------------------------------- */
#include "compute_rheo_vshift.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_interface.h"
#include "compute_rheo_kernel.h"
#include "compute_rheo_surface.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "update.h"
using namespace LAMMPS_NS;
using namespace RHEO_NS;
/* ---------------------------------------------------------------------- */
ComputeRHEOVShift::ComputeRHEOVShift(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), list(nullptr), vshift(nullptr), fix_rheo(nullptr),
compute_kernel(nullptr), compute_interface(nullptr), compute_surface(nullptr)
{
if (narg != 3) error->all(FLERR,"Illegal compute RHEO/VShift command");
comm_reverse = 3;
surface_flag = 0;
nmax_store = atom->nmax;
memory->create(vshift, nmax_store, 3, "rheo:vshift");
}
/* ---------------------------------------------------------------------- */
ComputeRHEOVShift::~ComputeRHEOVShift()
{
memory->destroy(vshift);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOVShift::init()
{
neighbor->add_request(this, NeighConst::REQ_DEFAULT);
surface_flag = fix_rheo->surface_flag;
interface_flag = fix_rheo->interface_flag;
compute_kernel = fix_rheo->compute_kernel;
compute_interface = fix_rheo->compute_interface;
compute_surface = fix_rheo->compute_surface;
rho0 = fix_rheo->rho0;
cut = fix_rheo->cut;
cutsq = cut * cut;
cutthird = cut / 3.0;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOVShift::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOVShift::compute_peratom()
{
int i, j, a, b, ii, jj, jnum, itype, jtype;
int fluidi, fluidj;
double xtmp, ytmp, ztmp, rsq, r, rinv;
double w, wp, dr, w0, w4, vmag, prefactor;
double imass, jmass, voli, volj, rhoi, rhoj;
double dx[3], vi[3], vj[3];
int dim = domain->dimension;
int *jlist;
int inum, *ilist, *numneigh, **firstneigh;
int *type = atom->type;
int *status = atom->rheo_status;
int *mask = atom->mask;
double **x = atom->x;
double **v = atom->v;
double *rho = atom->rho;
double *mass = atom->mass;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
int newton_pair = force->newton_pair;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
if (nmax_store < atom->nmax) {
memory->grow(vshift, atom->nmax, 3, "rheo:vshift");
nmax_store = atom->nmax;
}
for (i = 0; i < nall; i++)
for (a = 0; a < dim; a++)
vshift[i][a] = 0.0;
for (a = 0; a < 3; a++) {
vi[a] = 0.0;
vj[a] = 0.0;
}
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
imass = mass[itype];
fluidi = !(status[i] & PHASECHECK);
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
fluidj = !(status[j] & PHASECHECK);
if ((!fluidi) && (!fluidj)) continue;
// Will skip shifting in FixRHEO initial integrate, but also skip here to save time
if ((status[i] & STATUS_NO_SHIFT) && (status[j] & STATUS_NO_SHIFT)) continue;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2];
if (rsq < cutsq) {
jtype = type[j];
jmass = mass[jtype];
r = sqrt(rsq);
rinv = 1 / r;
for (a = 0; a < dim; a++) {
vi[a] = v[i][a];
vj[a] = v[j][a];
}
rhoi = rho[i];
rhoj = rho[j];
// Add corrections for walls
if (interface_flag) {
if (fluidi && (!fluidj)) {
compute_interface->correct_v(vj, vi, j, i);
rhoj = compute_interface->correct_rho(j, i);
} else if ((!fluidi) && fluidj) {
compute_interface->correct_v(vi, vj, i, j);
rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) {
rhoi = rho0[itype];
rhoj = rho0[jtype];
}
}
voli = imass / rhoi;
volj = jmass / rhoj;
wp = compute_kernel->calc_dw(i, j, dx[0], dx[1], dx[2], r);
w = compute_kernel->calc_w(i, j, dx[0], dx[1], dx[2], r);
w0 = compute_kernel->calc_w(i, j, 0, 0, 0, cutthird); // dx, dy, dz irrelevant
w4 = w * w * w * w / (w0 * w0 * w0 * w0);
dr = -2 * cutthird * (1 + 0.2 * w4) * wp * rinv;
if ((mask[i] & groupbit) && fluidi) {
vmag = sqrt(vi[0] * vi[0] + vi[1] * vi[1] + vi[2] * vi[2]);
prefactor = vmag * volj * dr;
vshift[i][0] += prefactor * dx[0];
vshift[i][1] += prefactor * dx[1];
vshift[i][2] += prefactor * dx[2];
}
if (newton_pair || j < nlocal) {
if ((mask[j] & groupbit) && fluidj) {
vmag = sqrt(vj[0] * vj[0] + vj[1] * vj[1] + vj[2] * vj[2]);
prefactor = vmag * voli * dr;
vshift[j][0] -= prefactor * dx[0];
vshift[j][1] -= prefactor * dx[1];
vshift[j][2] -= prefactor * dx[2];
}
}
}
}
}
if (newton_pair) comm->reverse_comm(this);
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOVShift::correct_surfaces()
{
if (!surface_flag) return;
int i, a, b;
int *status = atom->rheo_status;
int *mask = atom->mask;
double **nsurface = compute_surface->nsurface;
int nlocal = atom->nlocal;
int dim = domain->dimension;
double nx, ny, nz, vx, vy, vz, dot;
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (status[i] & PHASECHECK) continue;
//if ((status[i] & STATUS_SURFACE) || (status[i] & STATUS_LAYER)) {
if (status[i] & STATUS_SURFACE) {
nx = nsurface[i][0];
ny = nsurface[i][1];
vx = vshift[i][0];
vy = vshift[i][1];
dot = nx * vx + ny * vy;
if (dim == 3) {
nz = nsurface[i][2];
vz = vshift[i][2];
dot += nz * vz;
}
// Allowing shifting into the bulk
if (dot < 0.0) continue;
vshift[i][0] = (1 - nx * nx) * vx - nx * ny * vy;
vshift[i][1] = (1 - ny * ny) * vy - nx * ny * vx;
if (dim == 3) {
vshift[i][0] -= nx * nz * vz;
vshift[i][1] -= ny * nz * vz;
vshift[i][2] = (1 - nz * nz) * vz - nz * ny * vy - nx * nz * vx;
} else {
vshift[i][2] = 0.0;
}
} else if (status[i] & STATUS_SPLASH) {
vshift[i][0] = 0.0;
vshift[i][1] = 0.0;
vshift[i][2] = 0.0;
}
}
}
}
/* ---------------------------------------------------------------------- */
int ComputeRHEOVShift::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++] = vshift[i][0];
buf[m++] = vshift[i][1];
buf[m++] = vshift[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeRHEOVShift::unpack_reverse_comm(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
vshift[j][0] += buf[m++];
vshift[j][1] += buf[m++];
vshift[j][2] += buf[m++];
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeRHEOVShift::memory_usage()
{
double bytes = 3 * nmax_store * sizeof(double);
return bytes;
}

View File

@ -0,0 +1,57 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(RHEO/VSHIFT,ComputeRHEOVShift)
// clang-format on
#else
#ifndef LMP_COMPUTE_RHEO_VSHIFT_H
#define LMP_COMPUTE_RHEO_VSHIFT_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeRHEOVShift : public Compute {
public:
ComputeRHEOVShift(class LAMMPS *, int, char **);
~ComputeRHEOVShift() override;
void init() override;
void init_list(int, class NeighList *) 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;
void correct_surfaces();
double **vshift;
class FixRHEO *fix_rheo;
private:
int nmax_store;
double dtv, cut, cutsq, cutthird;
int surface_flag, interface_flag;
double *rho0;
class NeighList *list;
class ComputeRHEOInterface *compute_interface;
class ComputeRHEOKernel *compute_kernel;
class ComputeRHEOSurface *compute_surface;
};
} // namespace LAMMPS_NS
#endif
#endif

515
src/RHEO/fix_rheo.cpp Normal file
View File

@ -0,0 +1,515 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU), Eric Palermo (CMU)
----------------------------------------------------------------------- */
#include "fix_rheo.h"
#include "atom.h"
#include "citeme.h"
#include "compute_rheo_grad.h"
#include "compute_rheo_interface.h"
#include "compute_rheo_surface.h"
#include "compute_rheo_kernel.h"
#include "compute_rheo_rho_sum.h"
#include "compute_rheo_vshift.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "update.h"
#include "utils.h"
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace FixConst;
static const char cite_rheo[] =
"@article{PalermoInPrep,\n"
" journal = {in prep},\n"
" title = {RHEO: A Hybrid Mesh-Free Model Framework for Dynamic Multi-Phase Flows},\n"
" year = {2024},\n"
" author = {Eric T. Palermo and Ki T. Wolf and Joel T. Clemmer and Thomas C. O'Connor},\n"
"}\n\n";
/* ---------------------------------------------------------------------- */
FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), compute_grad(nullptr), compute_kernel(nullptr), compute_surface(nullptr),
compute_interface(nullptr), compute_rhosum(nullptr), compute_vshift(nullptr), rho0(nullptr), csq(nullptr)
{
time_integrate = 1;
viscosity_fix_defined = 0;
pressure_fix_defined = 0;
thermal_fix_defined = 0;
oxidation_fix_defined = 0;
thermal_flag = 0;
rhosum_flag = 0;
shift_flag = 0;
interface_flag = 0;
surface_flag = 0;
oxidation_flag = 0;
self_mass_flag = 0;
int i;
int n = atom->ntypes;
memory->create(rho0, n + 1, "rheo:rho0");
memory->create(csq, n + 1, "rheo:csq");
for (i = 1; i <= n; i++) {
rho0[i] = 1.0;
csq[i] = 1.0;
}
if (igroup != 0)
error->all(FLERR, "fix rheo command requires group all");
if (atom->pressure_flag != 1)
error->all(FLERR, "fix rheo command requires atom_style with pressure");
if (atom->rho_flag != 1)
error->all(FLERR, "fix rheo command requires atom_style with density");
if (atom->viscosity_flag != 1)
error->all(FLERR, "fix rheo command requires atom_style with viscosity");
if (atom->rheo_status_flag != 1)
error->all(FLERR, "fix rheo command requires atom_style with status");
if (narg < 5)
utils::missing_cmd_args(FLERR, "fix rheo", error);
cut = utils::numeric(FLERR, arg[3], false, lmp);
if (strcmp(arg[4], "quintic") == 0) {
kernel_style = QUINTIC;
} else if (strcmp(arg[4], "wendland/c4") == 0) {
kernel_style = WENDLANDC4;
} else if (strcmp(arg[4], "RK0") == 0) {
kernel_style = RK0;
} else if (strcmp(arg[4], "RK1") == 0) {
kernel_style = RK1;
} else if (strcmp(arg[4], "RK2") == 0) {
kernel_style = RK2;
} else error->all(FLERR, "Unknown kernel style {} in fix rheo", arg[4]);
zmin_kernel = utils::numeric(FLERR, arg[5], false, lmp);
int iarg = 6;
while (iarg < narg){
if (strcmp(arg[iarg], "shift") == 0) {
shift_flag = 1;
} else if (strcmp(arg[iarg], "thermal") == 0) {
thermal_flag = 1;
} else if (strcmp(arg[iarg], "surface/detection") == 0) {
surface_flag = 1;
if(iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo surface/detection", error);
if (strcmp(arg[iarg + 1], "coordination") == 0) {
surface_style = COORDINATION;
zmin_surface = utils::inumeric(FLERR, arg[iarg + 2], false, lmp);
zmin_splash = utils::inumeric(FLERR, arg[iarg + 3], false, lmp);
} else if (strcmp(arg[iarg + 1], "divergence") == 0) {
surface_style = DIVR;
divr_surface = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
zmin_splash = utils::inumeric(FLERR, arg[iarg + 3], false, lmp);
} else {
error->all(FLERR, "Illegal surface/detection option in fix rheo, {}", arg[iarg + 1]);
}
iarg += 3;
} else if (strcmp(arg[iarg], "interface/reconstruct") == 0) {
interface_flag = 1;
} else if (strcmp(arg[iarg], "rho/sum") == 0) {
rhosum_flag = 1;
} else if (strcmp(arg[iarg], "self/mass") == 0) {
self_mass_flag = 1;
} else if (strcmp(arg[iarg], "density") == 0) {
if (iarg + n >= narg) utils::missing_cmd_args(FLERR, "fix rheo density", error);
for (i = 1; i <= n; i++)
rho0[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
iarg += n;
} else if (strcmp(arg[iarg], "speed/sound") == 0) {
if (iarg + n >= narg) utils::missing_cmd_args(FLERR, "fix rheo speed/sound", error);
for (i = 1; i <= n; i++) {
csq[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
csq[i] *= csq[i];
}
iarg += n;
} else {
error->all(FLERR, "Illegal fix rheo command: {}", arg[iarg]);
}
iarg += 1;
}
if (self_mass_flag && (!rhosum_flag))
error->all(FLERR, "Cannot use self/mass setting without rho/sum");
if (lmp->citeme) lmp->citeme->add(cite_rheo);
}
/* ---------------------------------------------------------------------- */
FixRHEO::~FixRHEO()
{
if (compute_kernel) modify->delete_compute("rheo_kernel");
if (compute_grad) modify->delete_compute("rheo_grad");
if (compute_interface) modify->delete_compute("rheo_interface");
if (compute_surface) modify->delete_compute("rheo_surface");
if (compute_rhosum) modify->delete_compute("rheo_rhosum");
if (compute_vshift) modify->delete_compute("rheo_vshift");
memory->destroy(csq);
memory->destroy(rho0);
}
/* ----------------------------------------------------------------------
Create necessary internal computes
------------------------------------------------------------------------- */
void FixRHEO::post_constructor()
{
compute_kernel = dynamic_cast<ComputeRHEOKernel *>(modify->add_compute(
fmt::format("rheo_kernel all RHEO/KERNEL {}", kernel_style)));
compute_kernel->fix_rheo = this;
std::string cmd = "rheo_grad all RHEO/GRAD velocity rho viscosity";
if (thermal_flag) cmd += " energy";
compute_grad = dynamic_cast<ComputeRHEOGrad *>(modify->add_compute(cmd));
compute_grad->fix_rheo = this;
if (rhosum_flag) {
compute_rhosum = dynamic_cast<ComputeRHEORhoSum *>(modify->add_compute(
fmt::format("rheo_rhosum all RHEO/RHO/SUM {}", self_mass_flag)));
compute_rhosum->fix_rheo = this;
}
if (shift_flag) {
compute_vshift = dynamic_cast<ComputeRHEOVShift *>(modify->add_compute(
"rheo_vshift all RHEO/VSHIFT"));
compute_vshift->fix_rheo = this;
}
if (interface_flag) {
compute_interface = dynamic_cast<ComputeRHEOInterface *>(modify->add_compute(
"rheo_interface all RHEO/INTERFACE"));
compute_interface->fix_rheo = this;
}
if (surface_flag) {
compute_surface = dynamic_cast<ComputeRHEOSurface *>(modify->add_compute(
"rheo_surface all RHEO/SURFACE"));
compute_surface->fix_rheo = this;
}
}
/* ---------------------------------------------------------------------- */
int FixRHEO::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= FINAL_INTEGRATE;
mask |= PRE_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRHEO::init()
{
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
if (modify->get_fix_by_style("^rheo$").size() > 1)
error->all(FLERR, "Can only specify one instance of fix rheo");
if (atom->rheo_status_flag != 1)
error->all(FLERR,"fix rheo command requires atom property status");
if (atom->rho_flag != 1)
error->all(FLERR,"fix rheo command requires atom property rho");
if (atom->pressure_flag != 1)
error->all(FLERR,"fix rheo command requires atom property pressure");
if (atom->viscosity_flag != 1)
error->all(FLERR,"fix rheo command requires atom property viscosity");
if (thermal_flag) {
if (atom->esph_flag != 1)
error->all(FLERR,"fix rheo command requires atom property esph with thermal setting");
if (atom->temperature_flag != 1)
error->all(FLERR,"fix rheo command requires atom property temperature with thermal setting");
if (atom->heatflow_flag != 1)
error->all(FLERR,"fix rheo command requires atom property heatflow with thermal setting");
if (atom->conductivity_flag != 1)
error->all(FLERR,"fix rheo command requires atom property conductivity with thermal setting");
}
}
/* ---------------------------------------------------------------------- */
void FixRHEO::setup_pre_force(int /*vflag*/)
{
// Check to confirm accessory fixes do not preceed FixRHEO
// Note: fixes set this flag in setup_pre_force()
if (viscosity_fix_defined || pressure_fix_defined || thermal_fix_defined || oxidation_fix_defined)
error->all(FLERR, "Fix RHEO must be defined before all other RHEO fixes");
// Calculate surfaces
if (surface_flag) {
compute_kernel->compute_coordination();
compute_surface->compute_peratom();
}
pre_force(0);
}
/* ---------------------------------------------------------------------- */
void FixRHEO::setup(int /*vflag*/)
{
// Confirm all accessory fixes are defined
// Note: fixes set this flag in setup_pre_force()
if (!viscosity_fix_defined)
error->all(FLERR, "Missing fix rheo/viscosity");
if (!pressure_fix_defined)
error->all(FLERR, "Missing fix rheo/pressure");
if(thermal_flag && !thermal_fix_defined)
error->all(FLERR, "Missing fix rheo/thermal");
// Reset to zero for future runs
thermal_fix_defined = 0;
viscosity_fix_defined = 0;
pressure_fix_defined = 0;
oxidation_fix_defined = 0;
if (rhosum_flag)
compute_rhosum->compute_peratom();
}
/* ---------------------------------------------------------------------- */
void FixRHEO::initial_integrate(int /*vflag*/)
{
// update v, x and rho of atoms in group
int i, a, b;
double dtfm, divu;
int *type = atom->type;
int *mask = atom->mask;
int *status = atom->rheo_status;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *rho = atom->rho;
double *drho = atom->drho;
double *mass = atom->mass;
double *rmass = atom->rmass;
double **gradr = compute_grad->gradr;
double **gradv = compute_grad->gradv;
double **vshift;
if (shift_flag)
vshift = compute_vshift->vshift;
int nlocal = atom->nlocal;
int rmass_flag = atom->rmass_flag;
int dim = domain->dimension;
if (igroup == atom->firstgroup)
nlocal = atom->nfirst;
//Density Half-step
for (i = 0; i < nlocal; i++) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
if (mask[i] & groupbit) {
if (rmass_flag) {
dtfm = dtf / rmass[i];
} else {
dtfm = dtf / mass[type[i]];
}
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
}
}
// Update gradients and interpolate solid properties
compute_grad->forward_fields(); // also forwards v and rho for chi
if (interface_flag) {
// Need to save, wiped in exchange
compute_interface->store_forces();
compute_interface->compute_peratom();
}
compute_grad->compute_peratom();
// Position half-step
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
for (a = 0; a < dim; a++) {
x[i][a] += dtv * v[i][a];
}
}
}
// Update density using div(u)
if (!rhosum_flag) {
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
if (status[i] & PHASECHECK) continue;
divu = 0;
for (a = 0; a < dim; a++) {
divu += gradv[i][a * (1 + dim)];
}
rho[i] += dtf * (drho[i] - rho[i] * divu);
}
}
}
// Shifting atoms
if (shift_flag) {
for (i = 0; i < nlocal; i++) {
if (status[i] & STATUS_NO_SHIFT) continue;
if (status[i] & PHASECHECK) continue;
if (mask[i] & groupbit) {
for (a = 0; a < dim; a++) {
x[i][a] += dtv * vshift[i][a];
for (b = 0; b < dim; b++) {
v[i][a] += dtv * vshift[i][b] * gradv[i][a * dim + b];
}
}
if (!rhosum_flag) {
if (status[i] & PHASECHECK) continue;
for (a = 0; a < dim; a++) {
rho[i] += dtv * vshift[i][a] * gradr[i][a];
}
}
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixRHEO::pre_force(int /*vflag*/)
{
compute_kernel->compute_coordination(); // Needed for rho sum
if (rhosum_flag)
compute_rhosum->compute_peratom();
compute_kernel->compute_peratom();
if (interface_flag) {
// Note on first setup, have no forces for pressure to reference
compute_interface->compute_peratom();
}
// No need to forward v, rho, or T for compute_grad since already done
compute_grad->compute_peratom();
compute_grad->forward_gradients();
if (shift_flag)
compute_vshift->compute_peratom();
// Remove temporary options
int *mask = atom->mask;
int *status = atom->rheo_status;
int nall = atom->nlocal + atom->nghost;
for (int i = 0; i < nall; i++)
if (mask[i] & groupbit)
status[i] &= OPTIONSMASK;
// Calculate surfaces, update status
if (surface_flag) {
compute_surface->compute_peratom();
if (shift_flag)
compute_vshift->correct_surfaces();
}
}
/* ---------------------------------------------------------------------- */
void FixRHEO::final_integrate()
{
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup)
nlocal = atom->nfirst;
double dtfm, divu;
int i, a;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **gradv = compute_grad->gradv;
double *rho = atom->rho;
double *drho = atom->drho;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int *mask = atom->mask;
int *status = atom->rheo_status;
int rmass_flag = atom->rmass_flag;
int dim = domain->dimension;
// Update velocity
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
if (rmass_flag) {
dtfm = dtf / rmass[i];
} else {
dtfm = dtf / mass[type[i]];
}
for (a = 0; a < dim; a++) {
v[i][a] += dtfm * f[i][a];
}
}
}
// Update density using divu
if (!rhosum_flag) {
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
if (status[i] & PHASECHECK) continue;
divu = 0;
for (a = 0; a < dim; a++) {
divu += gradv[i][a * (1 + dim)];
}
rho[i] += dtf * (drho[i] - rho[i] * divu);
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixRHEO::reset_dt()
{
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
}

108
src/RHEO/fix_rheo.h Normal file
View File

@ -0,0 +1,108 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(rheo,FixRHEO)
// clang-format on
#else
#ifndef LMP_FIX_RHEO_H
#define LMP_FIX_RHEO_H
#include "fix.h"
namespace LAMMPS_NS {
class FixRHEO : public Fix {
public:
FixRHEO(class LAMMPS *, int, char **);
~FixRHEO() override;
int setmask() override;
void post_constructor() override;
void init() override;
void setup_pre_force(int) override;
void setup(int) override;
void pre_force(int) override;
void initial_integrate(int) override;
void final_integrate() override;
void reset_dt() override;
// Model parameters
double cut;
double *rho0, *csq;
int self_mass_flag;
int zmin_kernel, zmin_surface, zmin_splash;
int kernel_style, surface_style;
double divr_surface;
// Accessory fixes/computes
int thermal_flag;
int rhosum_flag;
int shift_flag;
int interface_flag;
int surface_flag;
int oxidation_flag;
int viscosity_fix_defined;
int pressure_fix_defined;
int thermal_fix_defined;
int oxidation_fix_defined;
class ComputeRHEOGrad *compute_grad;
class ComputeRHEOKernel *compute_kernel;
class ComputeRHEOInterface *compute_interface;
class ComputeRHEOSurface *compute_surface;
class ComputeRHEORhoSum *compute_rhosum;
class ComputeRHEOVShift *compute_vshift;
protected:
double dtv, dtf;
};
namespace RHEO_NS {
enum {QUINTIC, WENDLANDC4, RK0, RK1, RK2};
enum {COORDINATION, DIVR};
// Status variables
enum Status{
// Phase status
STATUS_SOLID = 1 << 0,
// Gap for future phase: STATUS_ = 1 << 1,
// Surface status
STATUS_BULK = 1 << 2,
STATUS_LAYER = 1 << 3,
STATUS_SURFACE = 1 << 4,
STATUS_SPLASH = 1 << 5,
// Temporary status options - reset in preforce
STATUS_NO_SHIFT = 1 << 6,
STATUS_NO_INTEGRATION = 1 << 7,
STATUS_FREEZING = 1 << 8,
STATUS_MELTING = 1 << 9
};
// Masks and their inverses
#define PHASEMASK 0xFFFFFFFC // 11111111111111111111111111111100
#define PHASECHECK 0x00000003 // 00000000000000000000000000000011
#define SURFACEMASK 0xFFFFFFC3 // 11111111111111111111111111000011
#define SURFACECHECK 0x0000003C // 00000000000000000000000000111100
#define OPTIONSMASK 0xFFFFFC3F // 11111111111111111111110000111111
} // namespace RHEO_NS
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,296 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "fix_rheo_oxidation.h"
#include "atom.h"
#include "atom_vec.h"
#include "citeme.h"
#include "comm.h"
#include "compute_rheo_surface.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "update.h"
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace FixConst;
enum {NONE, CONSTANT};
static const char cite_rheo_oxide[] =
"@article{ApplMathModel.130.310,\n"
" title = {A hybrid smoothed-particle hydrodynamics model of oxide skins on molten aluminum},\n"
" journal = {Applied Mathematical Modelling},\n"
" volume = {130},\n"
" pages = {310-326},\n"
" year = {2024},\n"
" issn = {0307-904X},\n"
" doi = {https://doi.org/10.1016/j.apm.2024.02.027},\n"
" author = {Joel T. Clemmer and Flint Pierce and Thomas C. O'Connor and Thomas D. Nevins and Elizabeth M.C. Jones and Jeremy B. Lechman and John Tencer},\n"
"}\n\n";
/* ---------------------------------------------------------------------- */
FixRHEOOxidation::FixRHEOOxidation(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), compute_surface(nullptr), fix_rheo(nullptr)
{
if (narg != 6) error->all(FLERR,"Illegal fix command");
force_reneighbor = 1;
next_reneighbor = -1;
comm_forward = 3;
cut = utils::numeric(FLERR, arg[3], false, lmp);
if (cut <= 0.0) error->all(FLERR, "Illegal bond cutoff {} in fix rheo/oxidation", cut);
btype = utils::inumeric(FLERR, arg[4], false, lmp);
if (btype < 1 || btype > atom->nbondtypes) error->all(FLERR, "Illegal value {} for bond type in fix rheo/oxidation", btype);
rsurf = utils::numeric(FLERR, arg[5], false, lmp);
if (rsurf <= 0.0) error->all(FLERR, "Illegal surface distance {} in fix rheo/oxidation", cut);
cutsq = cut * cut;
if (lmp->citeme) lmp->citeme->add(cite_rheo_oxide);
}
/* ---------------------------------------------------------------------- */
FixRHEOOxidation::~FixRHEOOxidation()
{
}
/* ---------------------------------------------------------------------- */
int FixRHEOOxidation::setmask()
{
int mask = 0;
mask |= POST_INTEGRATE;
mask |= PRE_FORCE;
mask |= POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::init()
{
auto fixes = modify->get_fix_by_style("^rheo$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use fix rheo/oxidation");
fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
if (cut > fix_rheo->cut)
error->all(FLERR, "Bonding length exceeds kernel cutoff");
if (rsurf >= fix_rheo->cut)
error->all(FLERR, "Surface distance must be less than kernel cutoff");
if (!force->bond) error->all(FLERR, "Must define a bond style with fix rheo/oxidation");
if (!atom->avec->bonds_allow) error->all(FLERR, "Fix rheo/oxidation requires atom bonds");
int tmp1, tmp2;
index_nb = atom->find_custom("shell_nbond", tmp1, tmp2);
if (index_nb == -1)
error->all(FLERR, "Must use bond style rheo/shell to use fix rheo/oxidation");
nbond = atom->ivector[index_nb];
// need a half neighbor list
auto req = neighbor->add_request(this, NeighConst::REQ_FULL);
req->set_cutoff(cut);
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::setup_pre_force(int /*vflag*/)
{
// Not strictly required that this fix be after FixRHEO,
// but enforce to be consistent with other RHEO fixes
fix_rheo->oxidation_fix_defined = 1;
if (!fix_rheo->surface_flag) error->all(FLERR,
"fix rheo/oxidation requires surface calculation in fix rheo");
compute_surface = fix_rheo->compute_surface;
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::pre_force(int /*vflag*/)
{
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::post_integrate()
{
int i, j, n, ii, jj, inum, jnum, bflag, fluidi, fluidj;
int *ilist, *jlist, *numneigh, **firstneigh;
double delx, dely, delz, rsq;
tagint tagi, tagj;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
tagint *tag = atom->tag;
tagint **bond_atom = atom->bond_atom;
int **bond_type = atom->bond_type;
int *num_bond = atom->num_bond;
int *mask = atom->mask;
int *status = atom->rheo_status;
double *rsurface = compute_surface->rsurface;
double **x = atom->x;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// Forward positions (after inititial integrate, before comm)
// Note: surface designation lags one timestep, acceptable error
comm->forward_comm(this);
int added_bonds = 0;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
if (!(mask[i] & groupbit)) continue;
// Exclude particles that aren't solid or surface
fluidi = !(status[i] & PHASECHECK);
if (fluidi && (rsurface[i] > rsurf)) continue;
tagi = tag[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
if (!(mask[j] & groupbit)) continue;
fluidj = !(status[j] & PHASECHECK);
if (fluidj && (rsurface[j] > rsurf)) continue;
// Skip solid-solid, leaves surface-surface or surface-solid
if ((!fluidi) && (!fluidj)) continue;
tagj = tag[j];
// Ensure pair is always ordered to ensure numerical operations
// are identical to minimize the possibility that a bond straddling
// an mpi grid (newton off) isn't created on one proc but not the other
if (tagi < tagj) {
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];
}
rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq) continue;
// Check if already have an oxide bond
bflag = 0;
for (n = 0; n < num_bond[i]; n++) {
if (bond_type[i][n] == btype && bond_atom[i][n] == tagj) {
bflag = 1;
break;
}
}
if (bflag) continue;
added_bonds += 1;
// Add bonds to owned atoms
// If newton bond off, add to both, otherwise add to whichever has a smaller tag
if (!newton_bond || (tagi < tagj)) {
if (num_bond[i] == atom->bond_per_atom)
error->one(FLERR,"New bond exceeded bonds per atom in fix rheo/oxidation for atom {}", tagi);
bond_type[i][num_bond[i]] = btype;
bond_atom[i][num_bond[i]] = tagj;
num_bond[i]++;
}
}
}
int added_bonds_all;
MPI_Allreduce(&added_bonds, &added_bonds_all, 1, MPI_INT, MPI_SUM, world);
if (added_bonds_all > 0)
next_reneighbor = update->ntimestep;
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::post_force(int /*vflag*/)
{
int *status = atom->rheo_status;
int *num_bond = atom->num_bond;
for (int i = 0; i < atom->nlocal; i++)
if (num_bond[i] != 0)
status[i] |= STATUS_NO_SHIFT;
}
/* ---------------------------------------------------------------------- */
int FixRHEOOxidation::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i, j, k, m;
double **x = atom->x;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = x[j][0];
buf[m++] = x[j][1];
buf[m++] = x[j][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void FixRHEOOxidation::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
double **x = atom->x;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
x[i][0] = buf[m++];
x[i][1] = buf[m++];
x[i][2] = buf[m++];
}
}

View File

@ -0,0 +1,57 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(rheo/oxidation,FixRHEOOxidation)
// clang-format on
#else
#ifndef LMP_FIX_RHEO_OXIDATION_H
#define LMP_FIX_RHEO_OXIDATION_H
#include "fix.h"
#include <vector>
namespace LAMMPS_NS {
class FixRHEOOxidation : public Fix {
public:
FixRHEOOxidation(class LAMMPS *, int, char **);
~FixRHEOOxidation() override;
int setmask() override;
void init() override;
void init_list(int, class NeighList *) override;
void setup_pre_force(int) override;
void post_integrate() override;
void pre_force(int) override;
void post_force(int) override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
int *nbond;
double rsurf, cut;
private:
int btype, index_nb;
double cutsq;
class NeighList *list;
class ComputeRHEOSurface *compute_surface;
class FixRHEO *fix_rheo;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,254 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU)
----------------------------------------------------------------------- */
#include "fix_rheo_pressure.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "memory.h"
#include "modify.h"
#include "update.h"
#include <cmath>
using namespace LAMMPS_NS;
using namespace FixConst;
enum {NONE, LINEAR, CUBIC, TAITWATER, TAITGENERAL};
static constexpr double SEVENTH = 1.0 / 7.0;
/* ---------------------------------------------------------------------- */
FixRHEOPressure::FixRHEOPressure(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), fix_rheo(nullptr), rho0(nullptr), csq(nullptr), rho0inv(nullptr), csqinv(nullptr), c_cubic(nullptr), tpower(nullptr), pbackground(nullptr), pressure_style(nullptr)
{
if (narg < 4) error->all(FLERR,"Illegal fix command");
comm_forward = 1;
// Currently can only have one instance of fix rheo/pressure
if (igroup != 0)
error->all(FLERR,"fix rheo/pressure command requires group all");
int i, nlo, nhi;
int n = atom->ntypes;
memory->create(pressure_style, n + 1, "rheo:pressure_style");
memory->create(c_cubic, n + 1, "rheo:c_cubic");
memory->create(tpower, n + 1, "rheo:tpower");
memory->create(pbackground, n + 1, "rheo:pbackground");
for (i = 1; i <= n; i++) pressure_style[i] = NONE;
int iarg = 3;
while (iarg < narg) {
utils::bounds(FLERR, arg[iarg], 1, n, nlo, nhi, error);
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/pressure", error);
if (strcmp(arg[iarg + 1], "linear") == 0) {
for (i = nlo; i <= nhi; i++)
pressure_style[i] = LINEAR;
} else if (strcmp(arg[iarg + 1], "tait/water") == 0) {
for (i = nlo; i <= nhi; i++)
pressure_style[i] = TAITWATER;
} else if (strcmp(arg[iarg + 1], "tait/general") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/pressure tait", error);
double tpower_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
double pbackground_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
iarg += 2;
for (i = nlo; i <= nhi; i++) {
pressure_style[i] = TAITGENERAL;
tpower[i] = tpower_one;
pbackground[i] = pbackground_one;
}
} else if (strcmp(arg[iarg + 1], "cubic") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/pressure cubic", error);
double c_cubic_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
iarg += 1;
for (i = nlo; i <= nhi; i++) {
pressure_style[i] = CUBIC;
c_cubic[i] = c_cubic_one;
}
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg]);
}
iarg += 2;
}
for (i = 1; i <= n; i++)
if (pressure_style[i] == NONE)
error->all(FLERR,"Must specify pressure for atom type {} in fix/rheo/pressure", i);
}
/* ---------------------------------------------------------------------- */
FixRHEOPressure::~FixRHEOPressure()
{
memory->destroy(pressure_style);
memory->destroy(csqinv);
memory->destroy(rho0inv);
memory->destroy(c_cubic);
memory->destroy(tpower);
memory->destroy(pbackground);
}
/* ---------------------------------------------------------------------- */
int FixRHEOPressure::setmask()
{
int mask = 0;
mask |= PRE_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRHEOPressure::init()
{
auto fixes = modify->get_fix_by_style("^rheo$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use fix rheo/pressure");
fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
csq = fix_rheo->csq;
rho0 = fix_rheo->rho0;
int n = atom->ntypes;
memory->create(csqinv, n + 1, "rheo:rho0inv");
memory->create(rho0inv, n + 1, "rheo:rho0inv");
for (int i = 0; i <= n; i++) {
csqinv[i] = 1.0 / csq[i];
rho0inv[i] = 1.0 / rho0[i];
}
if (modify->get_fix_by_style("rheo/pressure").size() > 1)
error->all(FLERR, "Can only specify one instance of fix rheo/pressure");
}
/* ---------------------------------------------------------------------- */
void FixRHEOPressure::setup_pre_force(int /*vflag*/)
{
fix_rheo->pressure_fix_defined = 1;
pre_force(0);
}
/* ----------------------------------------------------------------------
Update (and forward) pressure every timestep
------------------------------------------------------------------------- */
void FixRHEOPressure::pre_force(int /*vflag*/)
{
int i;
double dr, rr3, rho_ratio;
int *mask = atom->mask;
int *type = atom->type;
double *rho = atom->rho;
double *pressure = atom->pressure;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
pressure[i] = calc_pressure(rho[i], type[i]);
if (comm_forward) comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
int FixRHEOPressure::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i,j,k,m;
double *pressure = atom->pressure;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = pressure[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
void FixRHEOPressure::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *pressure = atom->pressure;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
pressure[i] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
double FixRHEOPressure::calc_pressure(double rho, int type)
{
double p, dr, rr3, rho_ratio;
if (pressure_style[type] == LINEAR) {
p = csq[type] * (rho - rho0[type]);
} else if (pressure_style[type] == CUBIC) {
dr = rho - rho0[type];
p = csq[type] * (dr + c_cubic[type] * dr * dr * dr);
} else if (pressure_style[type] == TAITWATER) {
rho_ratio = rho * rho0inv[type];
rr3 = rho_ratio * rho_ratio * rho_ratio;
p = csq[type] * rho0[type] * SEVENTH * (rr3 * rr3 * rho_ratio - 1.0);
} else if (pressure_style[type] == TAITGENERAL) {
rho_ratio = rho * rho0inv[type];
p = csq[type] * rho0[type] * (pow(rho_ratio, tpower[type]) - 1.0) / tpower[type];
p += pbackground[type];
}
return p;
}
/* ---------------------------------------------------------------------- */
double FixRHEOPressure::calc_rho(double p, int type)
{
double rho, dr, rr3, rho_ratio;
if (pressure_style[type] == LINEAR) {
rho = csqinv[type] * p + rho0[type];
} else if (pressure_style[type] == CUBIC) {
error->one(FLERR, "Rho calculation from pressure not yet supported for cubic pressure equation");
} else if (pressure_style[type] == TAITWATER) {
rho = pow(7.0 * p + csq[type] * rho0[type], SEVENTH);
rho *= pow(rho0[type], 6.0 * SEVENTH);
rho *= pow(csq[type], -SEVENTH);
} else if (pressure_style[type] == TAITGENERAL) {
p -= pbackground[type];
rho = pow(tpower[type] * p + csq[type] * rho0[type], 1.0 / tpower[type]);
rho *= pow(rho0[type], 1.0 - 1.0 / tpower[type]);
rho *= pow(csq[type], -1.0 / tpower[type]);
}
return rho;
}

View File

@ -0,0 +1,50 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(rheo/pressure,FixRHEOPressure)
// clang-format on
#else
#ifndef LMP_FIX_RHEO_PRESSURE_H
#define LMP_FIX_RHEO_PRESSURE_H
#include "fix.h"
namespace LAMMPS_NS {
class FixRHEOPressure : public Fix {
public:
FixRHEOPressure(class LAMMPS *, int, char **);
~FixRHEOPressure() override;
int setmask() override;
void init() override;
void setup_pre_force(int) override;
void pre_force(int) override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
double calc_pressure(double, int);
double calc_rho(double, int);
private:
double *c_cubic, *csq, *csqinv, *rho0, *rho0inv, *tpower, *pbackground;
int *pressure_style;
class FixRHEO *fix_rheo;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,786 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "fix_rheo_thermal.h"
#include "atom.h"
#include "atom_vec.h"
#include "citeme.h"
#include "comm.h"
#include "compute_rheo_grad.h"
#include "compute_rheo_vshift.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "fix_bond_history.h"
#include "fix_update_special_bonds.h"
#include "force.h"
#include "math_extra.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "pair.h"
#include "update.h"
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace FixConst;
enum {NONE, CONSTANT};
static const char cite_rheo_oxide[] =
"@article{ApplMathModel.130.310,\n"
" title = {A hybrid smoothed-particle hydrodynamics model of oxide skins on molten aluminum},\n"
" journal = {Applied Mathematical Modelling},\n"
" volume = {130},\n"
" pages = {310-326},\n"
" year = {2024},\n"
" issn = {0307-904X},\n"
" doi = {https://doi.org/10.1016/j.apm.2024.02.027},\n"
" author = {Joel T. Clemmer and Flint Pierce and Thomas C. O'Connor and Thomas D. Nevins and Elizabeth M.C. Jones and Jeremy B. Lechman and John Tencer},\n"
"}\n\n";
/* ---------------------------------------------------------------------- */
FixRHEOThermal::FixRHEOThermal(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), compute_vshift(nullptr),
Tc(nullptr), kappa(nullptr), cv(nullptr), L(nullptr),
Tc_style(nullptr), kappa_style(nullptr), cv_style(nullptr), L_style(nullptr),
fix_update_special_bonds(nullptr)
{
if (narg < 4) error->all(FLERR,"Illegal fix command");
force_reneighbor = 1;
next_reneighbor = -1;
cut_bond = 0;
comm_forward = 0;
// Currently can only have one instance of fix rheo/thermal
if (igroup != 0)
error->all(FLERR,"fix rheo/thermal command requires group all");
int i, nlo, nhi;
int n = atom->ntypes;
memory->create(Tc_style, n + 1, "rheo:Tc_style");
memory->create(kappa_style, n + 1, "rheo:kappa_style");
memory->create(cv_style, n + 1, "rheo:cv_style");
memory->create(L_style, n + 1, "rheo:L_style");
memory->create(Tc, n + 1, "rheo:Tc");
memory->create(kappa, n + 1, "rheo:kappa");
memory->create(cv, n + 1, "rheo:cv");
memory->create(L, n + 1, "rheo:L");
for (i = 1; i <= n; i++) {
Tc_style[i] = NONE;
kappa_style[i] = NONE;
cv_style[i] = NONE;
L_style[i] = NONE;
}
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg],"conductivity") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal conductivity", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// Conductivity arguments
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal conductivity constant", error);
double kappa_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
if (kappa_one < 0.0) error->all(FLERR, "The conductivity must be positive");
iarg += 2;
for (i = nlo; i <= nhi; i++) {
kappa_style[i] = CONSTANT;
kappa[i] = kappa_one;
}
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg + 2]);
}
iarg += 2;
} else if (strcmp(arg[iarg], "specific/heat") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal specific/heat", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// Cv arguments
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal specific/heat constant", error);
double cv_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
if (cv_one < 0.0) error->all(FLERR, "The specific heat must be positive");
iarg += 2;
for (i = nlo; i <= nhi; i++) {
cv_style[i] = CONSTANT;
cv[i] = cv_one;
}
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg + 2]);
}
iarg += 2;
} else if (strcmp(arg[iarg], "Tfreeze") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal Tfreeze", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// T freeze arguments
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal Tfreeze constant", error);
double Tc_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
iarg += 2;
for (i = nlo; i <= nhi; i++) {
Tc_style[i] = CONSTANT;
Tc[i] = Tc_one;
}
} else {
error->all(FLERR, "Illegal fix command, {}", arg[iarg + 2]);
}
iarg += 2;
} else if (strcmp(arg[iarg], "latent/heat") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal latent/heat", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// Cv arguments
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal latent/heat constant", error);
double L_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
if (L_one < 0.0) error->all(FLERR, "The latent heat must be positive");
iarg += 2;
for (i = nlo; i <= nhi; i++) {
L_style[i] = CONSTANT;
L[i] = L_one;
}
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg + 2]);
}
iarg += 2;
} else if (strcmp(arg[iarg], "react") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal react", error);
cut_bond = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
btype = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
comm_forward = 4;
if (cut_bond <= 0.0) error->all(FLERR, "Illegal max bond length must be greater than zero");\
if (btype < 1 || btype > atom->nbondtypes) error->all(FLERR, "Illegal value for bond type");
cutsq_bond = cut_bond * cut_bond;
iarg += 3;
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg]);
}
}
for (i = 1; i <= n; i++) {
if (cv_style[i] == NONE)
error->all(FLERR, "Must specify specific/heat for atom type {} in fix/rheo/thermal", i);
if (kappa_style[i] == NONE)
error->all(FLERR, "Must specify conductivity for atom type {} in fix/rheo/thermal", i);
if (Tc_style[i] == NONE && L_style[i] != NONE)
error->all(FLERR, "Must specify critical temperature for atom type {} to use latent heat in fix rheo/thermal", i);
}
if (lmp->citeme) lmp->citeme->add(cite_rheo_oxide);
}
/* ---------------------------------------------------------------------- */
FixRHEOThermal::~FixRHEOThermal()
{
// Remove custom property if it exists
int tmp1, tmp2, index;
index = atom->find_custom("rheo_conductivity", tmp1, tmp2);
if (index != -1) atom->remove_custom(index, 1, 0);
memory->destroy(cv_style);
memory->destroy(Tc_style);
memory->destroy(kappa_style);
memory->destroy(L_style);
memory->destroy(cv);
memory->destroy(Tc);
memory->destroy(kappa);
memory->destroy(L);
}
/* ---------------------------------------------------------------------- */
int FixRHEOThermal::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= POST_INTEGRATE;
mask |= POST_NEIGHBOR;
mask |= PRE_FORCE;
mask |= FINAL_INTEGRATE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::init()
{
auto fixes = modify->get_fix_by_style("^rheo$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use fix rheo/viscosity");
fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
cut_kernel = fix_rheo->cut;
if (cut_bond > cut_kernel)
error->all(FLERR, "Bonding length exceeds kernel cutoff");
if (!fix_rheo->thermal_flag)
error->all(FLERR, "Need to define thermal setting in fix rheo");
compute_grad = fix_rheo->compute_grad;
compute_vshift = fix_rheo->compute_vshift;
dt = update->dt;
dth = 0.5 * update->dt;
if (atom->esph_flag != 1)
error->all(FLERR, "fix rheo/thermal command requires atom property esph");
if (atom->temperature_flag != 1)
error->all(FLERR, "fix rheo/thermal command requires atom property temperature");
if (atom->heatflow_flag != 1)
error->all(FLERR, "fix rheo/thermal command requires atom property heatflow");
if (atom->conductivity_flag != 1)
error->all(FLERR, "fix rheo/thermal command requires atom property conductivity");
if (cut_bond > 0.0) {
if (!force->bond) error->all(FLERR, "Must define a bond style to use reactive bond generation with fix rheo/thermal");
if (!atom->avec->bonds_allow) error->all(FLERR, "Reactive bond generation in fix rheo/thermal requires atom bonds");
// all special weights must be 1.0 (no special neighbors) or there must be an instance of fix update/special/bonds
if (force->special_lj[0] != 1.0 || force->special_lj[1] != 1.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) {
auto fixes = modify->get_fix_by_style("UPDATE_SPECIAL_BONDS");
if (fixes.size() == 0) error->all(FLERR, "Without fix update/special/bonds, reactive bond generation in fix rheo/thermal requires special weights of 1.0");
fix_update_special_bonds = dynamic_cast<FixUpdateSpecialBonds *>(fixes[0]);
}
// must have newton off so both processors will search nlist to build bonds
if (force->newton_pair)
error->all(FLERR, "Need Newton off for reactive bond generation");
// need a half neighbor list, built only when particles freeze
auto req = neighbor->add_request(this, NeighConst::REQ_OCCASIONAL);
req->set_cutoff(cut_kernel);
// find instances of bond history to delete/shift data
histories = modify->get_fix_by_style("BOND_HISTORY");
n_histories = histories.size();
}
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::init_list(int /*id*/, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::setup_pre_force(int /*vflag*/)
{
fix_rheo->thermal_fix_defined = 1;
if (modify->get_fix_by_style("rheo/thermal").size() > 1)
error->all(FLERR, "More than one fix rheo/thermal defined");
post_neighbor();
pre_force(0);
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::initial_integrate(int /*vflag*/)
{
// update temperature from shifting
if (!fix_rheo->shift_flag) return;
int i, a;
int *status = atom->rheo_status;
double *energy = atom->esph;
double **grade = compute_grad->grade;
double **vshift = compute_vshift->vshift;
int nlocal = atom->nlocal;
int dim = domain->dimension;
if (igroup == atom->firstgroup)
nlocal = atom->nfirst;
for (i = 0; i < nlocal; i++) {
if (status[i] & STATUS_NO_SHIFT) continue;
for (a = 0; a < dim; a++)
energy[i] += dt * vshift[i][a] * grade[i][a];
}
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::post_integrate()
{
int i, itype;
double cvi, Tci, Ti, Li;
int *status = atom->rheo_status;
double *energy = atom->esph;
double *temperature = atom->temperature;
double *heatflow = atom->heatflow;
int *type = atom->type;
int n_melt = 0;
int n_freeze = 0;
//Integrate energy and check status
for (i = 0; i < atom->nlocal; i++) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
itype = type[i];
cvi = calc_cv(i, itype);
energy[i] += dth * heatflow[i];
temperature[i] = energy[i] / cvi;
if (Tc_style[itype] != NONE) {
Ti = temperature[i];
Tci = calc_Tc(i, itype);
if (L_style[itype] != NONE) {
Li = calc_L(i, itype);
if (Ti > Tci) Ti = MAX(Tci, (energy[i] - Li) / cvi);
temperature[i] = Ti;
}
// Check phase change if Ti != Tci
if (Ti > Tci) {
// If solid, melt
if (status[i] & STATUS_SOLID) {
status[i] &= PHASEMASK;
status[i] |= STATUS_MELTING;
n_melt += 1;
}
}
if (Ti < Tci) {
// If fluid, freeze
if (!(status[i] & STATUS_SOLID)) {
status[i] &= PHASEMASK;
status[i] |= STATUS_SOLID;
status[i] |= STATUS_FREEZING;
n_freeze += 1;
}
}
}
}
int n_melt_all, n_freeze_all;
MPI_Allreduce(&n_melt, &n_melt_all, 1, MPI_INT, MPI_SUM, world);
MPI_Allreduce(&n_freeze, &n_freeze_all, 1, MPI_INT, MPI_SUM, world);
if (cut_bond > 0 && (n_melt_all || n_freeze_all)) {
// If a particle freezes, check if it already has bonds of that type
// If so, assume it was inserted as a solid particle
// Note: inserted solid particle may still shift one timestep
int *num_bond = atom->num_bond;
int **bond_type = atom->bond_type;
for (i = 0; i < atom->nlocal; i++) {
if (status[i] & STATUS_FREEZING) {
for (int n = 0; n < num_bond[i]; n++) {
if (bond_type[i][n] == btype) {
status[i] &= ~STATUS_FREEZING;
break;
}
}
}
}
// Forward status + positions (after inititial integrate, before comm)
comm->forward_comm(this);
if (n_freeze_all) create_bonds();
if (n_melt_all) break_bonds();
next_reneighbor = update->ntimestep;
}
}
/* ----------------------------------------------------------------------
Only need to update non-evolving conductivity styles after atoms exchange
------------------------------------------------------------------------- */
void FixRHEOThermal::post_neighbor()
{
int i, itype;
int *type = atom->type;
double *conductivity = atom->conductivity;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
for (i = 0; i < nall; i++) {
itype = type[i];
if (kappa_style[itype] == CONSTANT)
conductivity[i] = kappa[itype];
}
}
/* ----------------------------------------------------------------------
Calculate temperature
In the future, update & forward evolving conductivity styles every timestep
------------------------------------------------------------------------- */
void FixRHEOThermal::pre_force(int /*vflag*/)
{
int i, itype;
double cvi, Tci, Ti, Li;
double *energy = atom->esph;
double *temperature = atom->temperature;
int *type = atom->type;
int *status = atom->rheo_status;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
// Calculate temperature
for (i = 0; i < nall; i++) {
itype = type[i];
cvi = calc_cv(i, itype);
temperature[i] = energy[i] / cvi;
if (Tc_style[itype] != NONE) {
Ti = temperature[i];
Tci = calc_Tc(i, itype);
if (L_style[itype] != NONE) {
Li = calc_L(i, itype);
if (Ti > Tci) Ti = MAX(Tci, (energy[i] - Li) / cvi);
temperature[i] = Ti;
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::final_integrate()
{
int *status = atom->rheo_status;
double *energy = atom->esph;
double *heatflow = atom->heatflow;
//Integrate energy
for (int i = 0; i < atom->nlocal; i++) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
energy[i] += dth * heatflow[i];
}
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::reset_dt()
{
dt = update->dt;
dth = 0.5 * update->dt;
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::break_bonds()
{
int m, n, nmax, i, j, melti, meltj;
tagint *tag = atom->tag;
int *status = atom->rheo_status;
int **bond_type = atom->bond_type;
tagint **bond_atom = atom->bond_atom;
int *num_bond = atom->num_bond;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
// Delete all bonds for local atoms that melt of a given type
for (int i = 0; i < nlocal; i++) {
melti = status[i] & STATUS_MELTING;
if (!melti) continue;
for (m = (num_bond[i] - 1); m >= 0; m--) {
if (bond_type[i][m] != btype) continue;
j = atom->map(bond_atom[i][m]);
meltj = status[j] & STATUS_MELTING;
nmax = num_bond[i] - 1;
if (m == nmax) {
if (n_histories > 0)
for (auto &ihistory: histories)
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i, m);
} else {
bond_type[i][m] = bond_type[i][nmax];
bond_atom[i][m] = bond_atom[i][nmax];
if (n_histories > 0) {
for (auto &ihistory: histories) {
auto fix_bond_history = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history->shift_history(i, m, nmax);
fix_bond_history->delete_history(i, nmax);
}
}
}
bond_type[i][nmax] = 0;
num_bond[i]--;
// Update special unless two owned atoms melt simultaneously then
// only update for atom with lower tag
if (fix_update_special_bonds) {
if ((i < nlocal) && (j < nlocal) && melti && meltj) {
if (tag[i] < tag[j]) {
fix_update_special_bonds->add_broken_bond(i, j);
}
} else {
fix_update_special_bonds->add_broken_bond(i, j);
}
}
}
}
// Update bond list and break solid-melted bonds
for (n = 0; n < nbondlist; n++) {
// skip bond if not correct type
if (bondlist[n][2] != btype) continue;
i = bondlist[n][0];
j = bondlist[n][1];
melti = status[i] & STATUS_MELTING;
meltj = status[j] & STATUS_MELTING;
if (!melti && !meltj) continue;
bondlist[n][2] = 0;
// Delete bonds for non-melted local atoms (shifting)
if (i < nlocal && !melti) {
for (m = 0; m < num_bond[i]; m++) {
if ((bond_atom[i][m] == tag[j]) && (bond_type[i][m] == btype)) {
nmax = num_bond[i] - 1;
bond_type[i][m] = bond_type[i][nmax];
bond_atom[i][m] = bond_atom[i][nmax];
if (n_histories > 0)
for (auto &ihistory: histories) {
auto fix_bond_history = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history->shift_history(i, m, nmax);
fix_bond_history->delete_history(i, nmax);
}
bond_type[i][nmax] = 0;
num_bond[i]--;
break;
}
}
}
if (j < nlocal && !meltj) {
for (m = 0; m < num_bond[j]; m++) {
if ((bond_atom[j][m] == tag[i]) && (bond_type[j][m] == btype)) {
nmax = num_bond[j] - 1;
bond_type[j][m] = bond_type[j][nmax];
bond_atom[j][m] = bond_atom[j][nmax];
if (n_histories > 0)
for (auto &ihistory: histories) {
auto fix_bond_history = dynamic_cast<FixBondHistory *> (ihistory);
fix_bond_history->shift_history(j, m, nmax);
fix_bond_history->delete_history(j, nmax);
}
bond_type[j][nmax] = 0;
num_bond[j]--;
break;
}
}
}
// Unless both atoms melt simultaneously, need to remove special bond if the melted atom is a ghost
if (melti && meltj) continue;
if (fix_update_special_bonds)
if (((i >= nlocal) && melti) || ((j >= nlocal) && meltj))
fix_update_special_bonds->add_broken_bond(i, j);
}
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::create_bonds()
{
int i, j, ii, jj, inum, jnum;
int *ilist, *jlist, *numneigh, **firstneigh;
double delx, dely, delz, rsq;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
tagint *tag = atom->tag;
tagint **bond_atom = atom->bond_atom;
int *status = atom->rheo_status;
int **bond_type = atom->bond_type;
int *num_bond = atom->num_bond;
double **x = atom->x;
neighbor->build_one(list, 1);
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
// might be faster to do a full list and just act on the atom that freezes
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
if (!(status[i] & STATUS_SOLID)) continue;
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
if (!(status[j] & STATUS_SOLID)) continue;
if (!(status[i] & STATUS_FREEZING) && !(status[j] & STATUS_FREEZING)) continue;
// Ensure pair is always ordered to ensure numerical operations
// are identical to minimize the possibility that a bond straddling
// an mpi grid (newton off) isn't created on one proc but not the other
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];
}
rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_bond) continue;
// Add bonds to owned atoms
// If newton bond off, add to both, otherwise add to whichever has a smaller tag
if ((i < nlocal) && (!newton_bond || (tag[i] < tag[j]))) {
if (num_bond[i] == atom->bond_per_atom)
error->one(FLERR,"New bond exceeded bonds per atom in fix rheo/thermal");
bond_type[i][num_bond[i]] = btype;
bond_atom[i][num_bond[i]] = tag[j];
num_bond[i]++;
}
if ((j < nlocal) && (!newton_bond || (tag[j] < tag[i]))) {
if (num_bond[j] == atom->bond_per_atom)
error->one(FLERR,"New bond exceeded bonds per atom in fix rheo/thermal");
bond_type[j][num_bond[j]] = btype;
bond_atom[j][num_bond[j]] = tag[i];
num_bond[j]++;
}
if (fix_update_special_bonds) fix_update_special_bonds->add_created_bond(i, j);
}
}
}
/* ---------------------------------------------------------------------- */
double FixRHEOThermal::calc_cv(int i, int itype)
{
if (cv_style[itype] == CONSTANT) {
return cv[itype];
}
return 0.0;
}
/* ---------------------------------------------------------------------- */
double FixRHEOThermal::calc_Tc(int i, int itype)
{
if (Tc_style[itype] == CONSTANT) {
return Tc[itype];
}
return 0.0;
}
/* ---------------------------------------------------------------------- */
double FixRHEOThermal::calc_L(int i, int itype)
{
if (L_style[itype] == CONSTANT) {
return L[itype];
}
return 0.0;
}
/* ---------------------------------------------------------------------- */
int FixRHEOThermal::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i, j, k, m;
int *status = atom->rheo_status;
double **x = atom->x;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = ubuf(status[j]).d;
buf[m++] = x[j][0];
buf[m++] = x[j][1];
buf[m++] = x[j][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
int *status = atom->rheo_status;
double **x = atom->x;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
status[i] = (int) ubuf(buf[m++]).i;
x[i][0] = buf[m++];
x[i][1] = buf[m++];
x[i][2] = buf[m++];
}
}

View File

@ -0,0 +1,73 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(rheo/thermal,FixRHEOThermal)
// clang-format on
#else
#ifndef LMP_FIX_RHEO_THERMAL_H
#define LMP_FIX_RHEO_THERMAL_H
#include "fix.h"
#include <vector>
namespace LAMMPS_NS {
class FixRHEOThermal : public Fix {
public:
FixRHEOThermal(class LAMMPS *, int, char **);
~FixRHEOThermal() override;
int setmask() override;
void init() override;
void init_list(int, class NeighList *) override;
void setup_pre_force(int) override;
void initial_integrate(int) override;
void post_integrate() override;
void post_neighbor() override;
void pre_force(int) override;
void final_integrate() override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
void reset_dt() override;
double calc_cv(int, int);
double calc_Tc(int, int);
double calc_L(int, int);
private:
double *cv, *Tc, *kappa, *L;
double dt, dth;
double cut_kernel, cut_bond, cutsq_bond;
int *cv_style, *Tc_style, *kappa_style, *L_style;
int btype;
class NeighList *list;
int n_histories;
std::vector<Fix *> histories;
class FixRHEO *fix_rheo;
class ComputeRHEOGrad *compute_grad;
class ComputeRHEOVShift *compute_vshift;
class FixUpdateSpecialBonds *fix_update_special_bonds;
void grow_array(int);
void break_bonds();
void create_bonds();
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,251 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU)
----------------------------------------------------------------------- */
#include "fix_rheo_viscosity.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_grad.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "memory.h"
#include "modify.h"
#include "update.h"
#include <cmath>
using namespace LAMMPS_NS;
using namespace FixConst;
enum {NONE, CONSTANT, POWER};
/* ---------------------------------------------------------------------- */
FixRHEOViscosity::FixRHEOViscosity(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), eta(nullptr),
npow(nullptr), K(nullptr), gd0(nullptr), tau0(nullptr), viscosity_style(nullptr)
{
if (narg < 4) error->all(FLERR, "Illegal fix command");
comm_forward = 0;
constant_flag = 0;
evolve_flag = 0;
// Currently can only have one instance of fix rheo/viscosity
if (igroup != 0)
error->all(FLERR,"fix rheo/viscosity command requires group all");
int i, nlo, nhi;
int n = atom->ntypes;
memory->create(viscosity_style, n + 1, "rheo:viscosity_style");
memory->create(eta, n + 1, "rheo:eta");
memory->create(gd0, n + 1, "rheo:gd0");
memory->create(K, n + 1, "rheo:K");
memory->create(npow, n + 1, "rheo:npow");
memory->create(tau0, n + 1, "rheo:tau0");
for (i = 1; i <= n; i++) viscosity_style[i] = NONE;
int iarg = 3;
while (iarg < narg) {
utils::bounds(FLERR, arg[iarg], 1, n, nlo, nhi, error);
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity", error);
if (strcmp(arg[iarg + 1], "constant") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity constant", error);
constant_flag = 1;
double eta_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
if (eta_one < 0.0) error->all(FLERR, "The viscosity must be positive");
iarg += 1;
for (i = nlo; i <= nhi; i++) {
viscosity_style[i] = CONSTANT;
eta[i] = eta_one;
}
} else if (strcmp(arg[iarg + 1], "power") == 0) {
if (iarg + 5 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity power", error);
comm_forward = 1;
evolve_flag = 1;
double eta_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
double gd0_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
double K_one = utils::numeric(FLERR, arg[iarg + 4], false, lmp);
double npow_one = utils::numeric(FLERR, arg[iarg + 5], false, lmp);
if (eta_one < 0.0) error->all(FLERR, "The viscosity must be positive");
iarg += 4;
for (i = nlo; i <= nhi; i++) {
viscosity_style[i] = POWER;
eta[i] = eta_one;
gd0[i] = gd0_one;
K[i] = K_one;
npow[i] = npow_one;
tau0[i] = eta[i] * gd0[i] - K[i] * pow(gd0[i], npow[i]);
}
} else {
error->all(FLERR, "Illegal fix command, {}", arg[iarg]);
}
iarg += 2;
}
for (i = 1; i <= n; i++)
if (viscosity_style[i] == NONE)
error->all(FLERR,"Must specify viscosity for atom type {} in fix/rheo/viscosity", i);
}
/* ---------------------------------------------------------------------- */
FixRHEOViscosity::~FixRHEOViscosity()
{
memory->destroy(viscosity_style);
memory->destroy(eta);
memory->destroy(gd0);
memory->destroy(K);
memory->destroy(npow);
memory->destroy(tau0);
}
/* ---------------------------------------------------------------------- */
int FixRHEOViscosity::setmask()
{
int mask = 0;
mask |= POST_NEIGHBOR;
mask |= PRE_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRHEOViscosity::init()
{
auto fixes = modify->get_fix_by_style("^rheo$");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use fix rheo/viscosity");
fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
compute_grad = fix_rheo->compute_grad;
}
/* ---------------------------------------------------------------------- */
void FixRHEOViscosity::setup_pre_force(int /*vflag*/)
{
fix_rheo->viscosity_fix_defined = 1;
if (modify->get_fix_by_style("rheo/viscosity").size() > 1)
error->all(FLERR, "More than one fix rheo/viscosity defined");
post_neighbor();
pre_force(0);
}
/* ----------------------------------------------------------------------
Only need to update non-evolving viscosity styles after atoms exchange
------------------------------------------------------------------------- */
void FixRHEOViscosity::post_neighbor()
{
if (!constant_flag) return;
int i, itype;
int *type = atom->type;
double *viscosity = atom->viscosity;
int nall = atom->nlocal + atom->nghost;
for (i = 0; i < nall; i++) {
itype = type[i];
if (viscosity_style[itype])
viscosity[i] = eta[itype];
}
}
/* ----------------------------------------------------------------------
Update (and forward) evolving viscosity styles every timestep
------------------------------------------------------------------------- */
void FixRHEOViscosity::pre_force(int /*vflag*/)
{
if (!evolve_flag) return;
int i, itype, a, b;
double tmp, gdot;
int *type = atom->type;
double *viscosity = atom->viscosity;
double **gradv = compute_grad->gradv;
int nlocal = atom->nlocal;
int dim = domain->dimension;
for (i = 0; i < nlocal; i++) {
itype = type[i];
if (viscosity_style[itype] == POWER) {
gdot = 0.0;
for (a = 0; a < dim; a++) {
for (b = a; b < dim; b++) {
tmp = gradv[i][a * dim + b] + gradv[i][b * dim + a];
tmp = tmp * tmp;
if (a == b) tmp *= 0.5;
gdot += tmp;
}
}
gdot = sqrt(gdot);
if (gdot <= gd0[itype]) {
viscosity[i] = eta[itype];
} else {
viscosity[i] = K[itype] * pow(gdot, npow[itype] - 1) + tau0[itype] / gdot;
}
}
}
if (comm_forward) comm->forward_comm(this);
}
/* ---------------------------------------------------------------------- */
int FixRHEOViscosity::pack_forward_comm(int n, int *list, double *buf,
int /*pbc_flag*/, int * /*pbc*/)
{
int i, j, k, m;
double *viscosity = atom->viscosity;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = viscosity[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
void FixRHEOViscosity::unpack_forward_comm(int n, int first, double *buf)
{
int i, k, m, last;
double *viscosity = atom->viscosity;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
viscosity[i] = buf[m++];
}
}

View File

@ -0,0 +1,50 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(rheo/viscosity,FixRHEOViscosity)
// clang-format on
#else
#ifndef LMP_FIX_RHEO_VISCOSITY_H
#define LMP_FIX_RHEO_VISCOSITY_H
#include "fix.h"
namespace LAMMPS_NS {
class FixRHEOViscosity : public Fix {
public:
FixRHEOViscosity(class LAMMPS *, int, char **);
~FixRHEOViscosity() override;
int setmask() override;
void init() override;
void setup_pre_force(int) override;
void post_neighbor() override;
void pre_force(int) override;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
private:
double *eta, *npow, *K, *gd0, *tau0;
int *viscosity_style, constant_flag, evolve_flag;
class FixRHEO *fix_rheo;
class ComputeRHEOGrad *compute_grad;
};
} // namespace LAMMPS_NS
#endif
#endif

549
src/RHEO/pair_rheo.cpp Normal file
View File

@ -0,0 +1,549 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL), Thomas O'Connor (CMU)
----------------------------------------------------------------------- */
#include "pair_rheo.h"
#include "atom.h"
#include "comm.h"
#include "compute_rheo_kernel.h"
#include "compute_rheo_grad.h"
#include "compute_rheo_interface.h"
#include "domain.h"
#include "error.h"
#include "fix_rheo.h"
#include "fix_rheo_pressure.h"
#include "force.h"
#include "math_extra.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "utils.h"
#include <cmath>
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace MathExtra;
static constexpr double EPSILON = 1e-2;
/* ---------------------------------------------------------------------- */
PairRHEO::PairRHEO(LAMMPS *lmp) :
Pair(lmp), compute_kernel(nullptr), compute_grad(nullptr), compute_interface(nullptr), fix_rheo(nullptr),
fix_pressure(nullptr), rho0(nullptr), csq(nullptr), cs(nullptr)
{
restartinfo = 0;
single_enable = 0;
artificial_visc_flag = 0;
rho_damp_flag = 0;
thermal_flag = 0;
harmonic_means_flag = 0;
comm_reverse = 3;
}
/* ---------------------------------------------------------------------- */
PairRHEO::~PairRHEO()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
}
memory->destroy(cs);
}
/* ---------------------------------------------------------------------- */
void PairRHEO::compute(int eflag, int vflag)
{
int i, j, a, b, ii, jj, inum, jnum, itype, jtype;
int pair_force_flag, pair_rho_flag, pair_avisc_flag;
int fluidi, fluidj;
double xtmp, ytmp, ztmp, w, wp, Ti, Tj, dT, csq_ave, cs_ave;
double rhoi, rhoj, rho0i, rho0j, voli, volj, Pi, Pj, etai, etaj, kappai, kappaj, eta_ave, kappa_ave, dT_prefactor;
double mu, q, fp_prefactor, drho_damp, fmag, psi_ij, Fij;
double *dWij, *dWji, *dW1ij, *dW1ji;
double dx[3], du[3], dv[3], fv[3], dfp[3], fsolid[3], ft[3], vi[3], vj[3];
int *ilist, *jlist, *numneigh, **firstneigh;
double imass, jmass, rsq, r, rinv;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
int dim = domain->dimension;
ev_init(eflag, vflag);
double **gradv = compute_grad->gradv;
double **gradr = compute_grad->gradr;
double **v = atom->v;
double **x = atom->x;
double **f = atom->f;
double *rho = atom->rho;
double *mass = atom->mass;
double *drho = atom->drho;
double *pressure = atom->pressure;
double *viscosity = atom->viscosity;
double *conductivity = atom->conductivity;
double *temperature = atom->temperature;
double *heatflow = atom->heatflow;
double *special_lj = force->special_lj;
int *type = atom->type;
int *status = atom->rheo_status;
tagint *tag = atom->tag;
double **fp_store, *chi;
if (compute_interface) {
fp_store = compute_interface->fp_store;
chi = compute_interface->chi;
for (i = 0; i < atom->nmax; i++) {
fp_store[i][0] = 0.0;
fp_store[i][1] = 0.0;
fp_store[i][2] = 0.0;
}
}
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
for (a = 0; a < 3; a++) {
vi[a] = 0.0;
vj[a] = 0.0;
du[a] = 0.0;
fv[a] = 0.0;
dfp[a] = 0.0;
fsolid[a] = 0.0;
ft[0] = 0.0;
}
// 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];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
imass = mass[itype];
etai = viscosity[i];
fluidi = !(status[i] & PHASECHECK);
if (thermal_flag) {
kappai = conductivity[i];
Ti = temperature[i];
}
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx[0] = xtmp - x[j][0];
dx[1] = ytmp - x[j][1];
dx[2] = ztmp - x[j][2];
rsq = lensq3(dx);
jtype = type[j];
if (rsq < cutksq) {
r = sqrt(rsq);
rinv = 1 / r;
jmass = mass[jtype];
etaj = viscosity[j];
fluidj = !(status[j] & PHASECHECK);
if (thermal_flag) {
Tj = temperature[j];
kappaj = conductivity[j];
}
cs_ave = 0.5 * (cs[itype] + cs[jtype]);
csq_ave = cs_ave * cs_ave;
pair_rho_flag = 0;
pair_force_flag = 0;
pair_avisc_flag = 0;
if (fluidi || fluidj) {
pair_force_flag = 1;
if (!interface_flag) pair_avisc_flag = 1;
}
if (fluidi && fluidj) {
pair_rho_flag = 1;
pair_avisc_flag = 1;
}
wp = compute_kernel->calc_dw(i, j, dx[0], dx[1], dx[2], r);
dWij = compute_kernel->dWij;
dWji = compute_kernel->dWji;
for (a = 0; a < dim; a++) {
vi[a] = v[i][a];
vj[a] = v[j][a];
}
// Add corrections for walls
rhoi = rho[i];
rhoj = rho[j];
rho0i = rho0[itype];
rho0j = rho0[jtype];
Pi = pressure[i];
Pj = pressure[j];
fmag = 0;
if (interface_flag) {
if (fluidi && (!fluidj)) {
compute_interface->correct_v(vj, vi, j, i);
rhoj = compute_interface->correct_rho(j, i);
Pj = fix_pressure->calc_pressure(rhoj, jtype);
if ((chi[j] > 0.9) && (r < (cutk * 0.5)))
fmag = (chi[j] - 0.9) * (cutk * 0.5 - r) * rho0j * csq_ave * cutk * rinv;
} else if ((!fluidi) && fluidj) {
compute_interface->correct_v(vi, vj, i, j);
rhoi = compute_interface->correct_rho(i, j);
Pi = fix_pressure->calc_pressure(rhoi, itype);
if (chi[i] > 0.9 && r < (cutk * 0.5))
fmag = (chi[i] - 0.9) * (cutk * 0.5 - r) * rho0i * csq_ave * cutk * rinv;
} else if ((!fluidi) && (!fluidj)) {
rhoi = rho0i;
rhoj = rho0j;
}
}
// Repel if close to inner solid particle
scale3(fmag, dx, fsolid);
// Compute volume after reconstructing
voli = imass / rhoi;
volj = jmass / rhoj;
// Thermal Evolution
if (thermal_flag) {
if (harmonic_means_flag) {
kappa_ave = 2.0 * kappai * kappaj / (kappai + kappaj);
} else {
kappa_ave = 0.5 * (kappai + kappaj);
}
dT_prefactor = 2.0 * kappa_ave * (Ti - Tj) * rinv * rinv * voli * volj * 2.0 / (rhoi + rhoj);
dT = dot3(dx, dWij);
heatflow[i] += dT * dT_prefactor;
if (newton_pair || j < nlocal) {
dT = dot3(dx, dWji);
heatflow[j] += dT * dT_prefactor;
}
}
if (pair_force_flag) {
//Hydrostatic pressure forces
fp_prefactor = voli * volj * (Pj + Pi);
sub3(vi, vj, dv);
if (harmonic_means_flag) {
eta_ave = 2.0 * etai * etaj / (etai + etaj);
} else {
eta_ave = 0.5 * (etai + etaj);
}
//Add artificial viscous pressure if required
if (artificial_visc_flag && pair_avisc_flag) {
//Interpolate velocities to midpoint and use this difference for artificial viscosity
copy3(dv, du);
for (a = 0; a < dim; a++)
for (b = 0; b < dim; b++)
du[a] -= 0.5 * (gradv[i][a * dim + b] + gradv[j][a * dim + b]) * dx[b];
mu = dot3(du, dx) * cutkinv3;
mu /= (rsq * cutkinv3 * cutkinv3 + EPSILON);
mu = MIN(0.0, mu);
q = av * (-2.0 * cs_ave * mu + mu * mu);
fp_prefactor += voli * volj * q * (rhoj + rhoi);
}
// -Grad[P + Q]
scale3(-fp_prefactor, dWij, dfp);
// Now compute viscous eta*Lap[v] terms
for (a = 0; a < dim; a++) {
fv[a] = 0.0;
for (b = 0; b < dim; b++)
fv[a] += dv[a] * dx[b] * dWij[b];
fv[a] *= 2.0 * eta_ave * voli * volj * rinv * rinv;
}
add3(fv, dfp, ft);
add3(fsolid, ft, ft);
f[i][0] += ft[0];
f[i][1] += ft[1];
f[i][2] += ft[2];
// Note the virial's definition is hazy, e.g. viscous contributions will depend on rotation
if (evflag)
ev_tally_xyz(i, j, nlocal, newton_pair, 0.0, 0.0, ft[0], ft[1], ft[2], dx[0], dx[1], dx[2]);
if (newton_pair || j < nlocal) {
for (a = 0; a < dim; a ++) {
fv[a] = 0.0;
for (b = 0; b < dim; b++)
fv[a] += (vi[a] - vj[a]) * dx[b] * dWji[b];
fv[a] *= -2.0 * eta_ave * voli * volj * rinv * rinv;
// flip sign here b/c -= at accummulator
}
scale3(fp_prefactor, dWji, dfp);
add3(fv, dfp, ft);
add3(fsolid, ft, ft);
f[j][0] -= ft[0];
f[j][1] -= ft[1];
f[j][2] -= ft[2];
if (evflag)
ev_tally_xyz(i, j, nlocal, newton_pair, 0.0, 0.0, ft[0], ft[1], ft[2], -dx[0], -dx[1], -dx[2]);
}
if (compute_interface) {
fp_store[i][0] += dfp[0];
fp_store[i][1] += dfp[1];
fp_store[i][2] += dfp[2];
if (newton_pair || j < nlocal) {
fp_store[j][0] -= dfp[0];
fp_store[j][1] -= dfp[1];
fp_store[j][2] -= dfp[2];
}
}
}
// Density damping
// conventional for low-order h
// interpolated for RK 1 & 2 (Antuono et al., Computers & Fluids 2021)
if (rho_damp_flag && pair_rho_flag) {
if (laplacian_order >= 1) {
psi_ij = rhoj - rhoi;
Fij = -rinv * rinv * dot3(dx, dWij);
for (a = 0; a < dim; a++)
psi_ij += 0.5 * (gradr[i][a] + gradr[j][a]) * dx[a];
drho[i] += 2 * rho_damp * psi_ij * Fij * volj;
} else {
drho_damp = 2 * rho_damp * ((rhoj - rho0[jtype]) - (rhoi - rho0[itype])) * rinv * wp;
drho[i] -= drho_damp * volj;
}
if (newton_pair || j < nlocal) {
if (laplacian_order >= 1) {
Fij = rinv * rinv * dot3(dx, dWji);
psi_ij *= -1;
drho[j] += 2 * rho_damp * psi_ij * Fij * voli;
} else {
drho[j] += drho_damp * voli;
}
}
}
}
}
}
if (vflag_fdotr) virial_fdotr_compute();
if (compute_interface) {
if (newton_pair) comm->reverse_comm(this);
comm->forward_comm(this);
}
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairRHEO::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag, n + 1, n + 1, "pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq, n + 1, n + 1, "pair:cutsq");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairRHEO::settings(int narg, char **arg)
{
if (narg < 1) error->all(FLERR, "Illegal pair_style command");
cutk = utils::numeric(FLERR, arg[0], false, lmp);
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg], "rho/damp") == 0) {
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "pair rheo rho/damp", error);
rho_damp_flag = 1;
rho_damp = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg++;
} else if (strcmp(arg[iarg], "artificial/visc") == 0) {
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "pair rheo artificial/visc", error);
artificial_visc_flag = 1;
av = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg++;
} else if (strcmp(arg[iarg], "harmonic/means") == 0) {
harmonic_means_flag = 1;
} else error->all(FLERR, "Illegal pair_style command, {}", arg[iarg]);
iarg++;
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairRHEO::coeff(int narg, char **arg)
{
if (narg != 2)
error->all(FLERR, "Incorrect number of args for pair_style rheo 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);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = 0; j <= atom->ntypes; j++) {
setflag[i][j] = 1;
count++;
}
}
if (count == 0)
error->all(FLERR, "Incorrect args for pair rheo coefficients");
}
/* ----------------------------------------------------------------------
setup specific to this pair style
------------------------------------------------------------------------- */
void PairRHEO::setup()
{
auto fixes = modify->get_fix_by_style("rheo");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo to use pair rheo");
fix_rheo = dynamic_cast<FixRHEO *>(fixes[0]);
// Currently only allow one instance of fix rheo/pressure
fixes = modify->get_fix_by_style("rheo/pressure");
if (fixes.size() == 0) error->all(FLERR, "Need to define fix rheo/pressure to use pair rheo");
fix_pressure = dynamic_cast<FixRHEOPressure *>(fixes[0]);
compute_kernel = fix_rheo->compute_kernel;
compute_grad = fix_rheo->compute_grad;
compute_interface = fix_rheo->compute_interface;
thermal_flag = fix_rheo->thermal_flag;
interface_flag = fix_rheo->interface_flag;
csq = fix_rheo->csq;
rho0 = fix_rheo->rho0;
if (cutk != fix_rheo->cut)
error->all(FLERR, "Pair rheo cutoff {} does not agree with fix rheo cutoff {}", cutk, fix_rheo->cut);
cutksq = cutk * cutk;
cutkinv = 1.0 / cutk;
cutkinv3 = cutkinv * 3.0;
laplacian_order = -1;
int n = atom->ntypes;
memory->create(cs, n + 1, "rheo:cs");
for (int i = 1; i <= n; i++)
cs[i] = sqrt(csq[i]);
if (comm->ghost_velocity == 0)
error->all(FLERR, "Pair RHEO requires ghost atoms store velocity");
if (laplacian_order == -1) {
if (fix_rheo->kernel_style == RK2)
laplacian_order = 2;
else if (fix_rheo->kernel_style == RK1)
laplacian_order = 1;
else
laplacian_order = 0;
}
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairRHEO::init_one(int i, int j)
{
if (setflag[i][j] == 0)
error->all(FLERR, "All pair rheo coeffs are not set");
return cutk;
}
/* ---------------------------------------------------------------------- */
int PairRHEO::pack_reverse_comm(int n, int first, double *buf)
{
int i, k, m, last;
double **fp_store = compute_interface->fp_store;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = fp_store[i][0];
buf[m++] = fp_store[i][1];
buf[m++] = fp_store[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void PairRHEO::unpack_reverse_comm(int n, int *list, double *buf)
{
int i, j, k, m;
double **fp_store = compute_interface->fp_store;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
fp_store[j][0] += buf[m++];
fp_store[j][1] += buf[m++];
fp_store[j][2] += buf[m++];
}
}

63
src/RHEO/pair_rheo.h Normal file
View File

@ -0,0 +1,63 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
// clang-format off
PairStyle(rheo,PairRHEO)
// clang-format on
#else
#ifndef LMP_PAIR_RHEO_H
#define LMP_PAIR_RHEO_H
#include "pair.h"
namespace LAMMPS_NS {
class PairRHEO : public Pair {
public:
PairRHEO(class LAMMPS *);
~PairRHEO() override;
void compute(int, int) override;
void settings(int, char **) override;
void coeff(int, char **) override;
void setup() override;
double init_one(int, int) override;
int pack_reverse_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
protected:
double cutk, *csq, *rho0; // From fix RHEO
double *cs, cutksq, cutkinv, cutkinv3, av, rho_damp;
int laplacian_order;
int artificial_visc_flag;
int rho_damp_flag;
int thermal_flag;
int interface_flag;
int harmonic_means_flag;
void allocate();
class ComputeRHEOKernel *compute_kernel;
class ComputeRHEOGrad *compute_grad;
class ComputeRHEOInterface *compute_interface;
class FixRHEO *fix_rheo;
class FixRHEOPressure *fix_pressure;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,359 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors:
Joel Clemmer (SNL)
----------------------------------------------------------------------- */
#include "pair_rheo_solid.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "fix_rheo.h"
#include "force.h"
#include "memory.h"
#include "neigh_list.h"
#include "neighbor.h"
#include <cmath>
using namespace LAMMPS_NS;
using namespace RHEO_NS;
/* ---------------------------------------------------------------------- */
PairRHEOSolid::PairRHEOSolid(LAMMPS *_lmp) : Pair(_lmp)
{
writedata = 1;
}
/* ---------------------------------------------------------------------- */
PairRHEOSolid::~PairRHEOSolid()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(k);
memory->destroy(cut);
memory->destroy(gamma);
}
}
/* ---------------------------------------------------------------------- */
void PairRHEOSolid::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 *status = atom->rheo_status;
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];
if (!(status[i] & STATUS_SOLID)) continue;
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;
if (!(status[j] & STATUS_SOLID)) continue;
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 PairRHEOSolid::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 PairRHEOSolid::settings(int narg, char ** /*arg*/)
{
if (narg != 0) error->all(FLERR, "Illegal pair_style command");
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairRHEOSolid::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 specific to this pair style
------------------------------------------------------------------------- */
void PairRHEOSolid::init_style()
{
if (comm->ghost_velocity == 0)
error->all(FLERR,"Pair rheo/solid requires ghost atoms store velocity");
if (!atom->rheo_status_flag)
error->all(FLERR,"Pair rheo/solid requires atom_style rheo");
neighbor->add_request(this);
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairRHEOSolid::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 PairRHEOSolid::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 PairRHEOSolid::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) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error);
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
if (setflag[i][j]) {
if (me == 0) {
utils::sfread(FLERR, &k[i][j], sizeof(double), 1, fp, nullptr, error);
utils::sfread(FLERR, &cut[i][j], sizeof(double), 1, fp, nullptr, error);
utils::sfread(FLERR, &gamma[i][j], sizeof(double), 1, fp, nullptr, error);
}
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 PairRHEOSolid::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 PairRHEOSolid::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 PairRHEOSolid::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;
int *status = atom->rheo_status;
if (!(status[i] & STATUS_SOLID)) return 0.0;
if (!(status[j] & STATUS_SOLID)) 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;
}

View File

@ -0,0 +1,51 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
// clang-format off
PairStyle(rheo/solid,PairRHEOSolid);
// clang-format on
#else
#ifndef LMP_PAIR_RHEO_SOLID_H
#define LMP_PAIR_RHEO_SOLID_H
#include "pair.h"
namespace LAMMPS_NS {
class PairRHEOSolid : public Pair {
public:
PairRHEOSolid(class LAMMPS *);
~PairRHEOSolid() override;
void compute(int, int) override;
void settings(int, char **) override;
void coeff(int, char **) override;
void init_style() 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

View File

@ -198,6 +198,13 @@ Atom::Atom(LAMMPS *_lmp) : Pointers(_lmp), atom_style(nullptr), avec(nullptr), a
eff_plastic_strain_rate = nullptr;
damage = nullptr;
// RHEO package
rheo_status = nullptr;
conductivity = nullptr;
pressure = nullptr;
viscosity = nullptr;
// SPH package
rho = drho = esph = desph = cv = nullptr;
@ -529,6 +536,13 @@ void Atom::peratom_create()
add_peratom("cc",&cc,DOUBLE,1);
add_peratom("cc_flux",&cc_flux,DOUBLE,1,1); // set per-thread flag
// RHEO package
add_peratom("rheo_status",&rheo_status,INT,0);
add_peratom("conductivity",&conductivity,DOUBLE,0);
add_peratom("pressure",&pressure,DOUBLE,0);
add_peratom("viscosity",&viscosity,DOUBLE,0);
// SPH package
add_peratom("rho",&rho,DOUBLE,0);
@ -634,6 +648,7 @@ void Atom::set_atomflag_defaults()
temperature_flag = heatflow_flag = 0;
vfrac_flag = spin_flag = eradius_flag = ervel_flag = erforce_flag = 0;
cs_flag = csforce_flag = vforce_flag = ervelforce_flag = etag_flag = 0;
rheo_status_flag = conductivity_flag = pressure_flag = viscosity_flag = 0;
rho_flag = esph_flag = cv_flag = vest_flag = 0;
dpd_flag = edpd_flag = tdpd_flag = 0;
sp_flag = 0;
@ -3048,7 +3063,15 @@ void *Atom::extract(const char *name)
if (strcmp(name,"vforce") == 0) return (void *) vforce;
if (strcmp(name,"etag") == 0) return (void *) etag;
// RHEO package
if (strcmp(name,"rheo_status") == 0) return (void *) rheo_status;
if (strcmp(name,"conductivity") == 0) return (void *) conductivity;
if (strcmp(name,"pressure") == 0) return (void *) pressure;
if (strcmp(name,"viscosity") == 0) return (void *) viscosity;
// SPH package
if (strcmp(name,"rho") == 0) return (void *) rho;
if (strcmp(name,"drho") == 0) return (void *) drho;
if (strcmp(name,"esph") == 0) return (void *) esph;
@ -3169,6 +3192,15 @@ int Atom::extract_datatype(const char *name)
if (strcmp(name,"vforce") == 0) return LAMMPS_DOUBLE_2D;
if (strcmp(name,"etag") == 0) return LAMMPS_INT;
// RHEO package
if (strcmp(name,"rheo_status") == 0) return LAMMPS_INT;
if (strcmp(name,"conductivity") == 0) return LAMMPS_DOUBLE;
if (strcmp(name,"pressure") == 0) return LAMMPS_DOUBLE;
if (strcmp(name,"viscosity") == 0) return LAMMPS_DOUBLE;
// SPH package
if (strcmp(name,"rho") == 0) return LAMMPS_DOUBLE;
if (strcmp(name,"drho") == 0) return LAMMPS_DOUBLE;
if (strcmp(name,"esph") == 0) return LAMMPS_DOUBLE;

View File

@ -155,6 +155,13 @@ class Atom : protected Pointers {
double *eff_plastic_strain_rate;
double *damage;
// RHEO package
int *rheo_status;
double *conductivity;
double *pressure;
double *viscosity;
// SPH package
double *rho, *drho, *esph, *desph, *cv;
@ -190,6 +197,7 @@ class Atom : protected Pointers {
int temperature_flag, heatflow_flag;
int vfrac_flag, spin_flag, eradius_flag, ervel_flag, erforce_flag;
int cs_flag, csforce_flag, vforce_flag, ervelforce_flag, etag_flag;
int rheo_status_flag, conductivity_flag, pressure_flag, viscosity_flag;
int rho_flag, esph_flag, cv_flag, vest_flag;
int dpd_flag, edpd_flag, tdpd_flag;
int mesont_flag;

View File

@ -34,6 +34,7 @@ BondHybrid::BondHybrid(LAMMPS *lmp) : Bond(lmp)
nstyles = 0;
has_quartic = -1;
nbondlist = nullptr;
orig_map = nullptr;
maxbond = nullptr;
bondlist = nullptr;
}
@ -81,6 +82,10 @@ void BondHybrid::compute(int eflag, int vflag)
memory->destroy(bondlist[m]);
maxbond[m] = nbondlist[m] + EXTRA;
memory->create(bondlist[m], maxbond[m], 3, "bond_hybrid:bondlist");
if (partial_flag) {
memory->destroy(orig_map[m]);
memory->create(orig_map[m], maxbond[m], "bond_hybrid:orig_map");
}
}
nbondlist[m] = 0;
}
@ -91,6 +96,8 @@ void BondHybrid::compute(int eflag, int vflag)
bondlist[m][n][0] = bondlist_orig[i][0];
bondlist[m][n][1] = bondlist_orig[i][1];
bondlist[m][n][2] = bondlist_orig[i][2];
if (partial_flag)
orig_map[m][n] = i;
nbondlist[m]++;
}
}
@ -135,6 +142,21 @@ void BondHybrid::compute(int eflag, int vflag)
}
}
// If bond style can be deleted by setting type to zero (BPM or quartic), update bondlist_orig
// Otherwise, bond type could be restored back to its original value during reneighboring
// Use orig_map to propagate changes from temporary bondlist array back to original array
if (partial_flag) {
for (m = 0; m < nstyles; m++) {
for (i = 0; i < nbondlist[m]; i++) {
if (bondlist[m][i][2] <= 0) {
n = orig_map[m][i];
bondlist_orig[n][2] = bondlist[m][i][2];
}
}
}
}
// restore ptrs to original bondlist
neighbor->nbondlist = nbondlist_orig;
@ -154,9 +176,11 @@ void BondHybrid::allocate()
nbondlist = new int[nstyles];
maxbond = new int[nstyles];
orig_map = new int *[nstyles];
bondlist = new int **[nstyles];
for (int m = 0; m < nstyles; m++) maxbond[m] = 0;
for (int m = 0; m < nstyles; m++) bondlist[m] = nullptr;
for (int m = 0; m < nstyles; m++) orig_map[m] = nullptr;
}
/* ---------------------------------------------------------------------- */
@ -173,6 +197,8 @@ void BondHybrid::deallocate()
delete[] maxbond;
for (int i = 0; i < nstyles; i++) memory->destroy(bondlist[i]);
delete[] bondlist;
for (int i = 0; i < nstyles; i++) memory->destroy(orig_map[i]);
delete[] orig_map;
}
/* ----------------------------------------------------------------------
@ -260,8 +286,13 @@ void BondHybrid::flags()
if (styles[m]) comm_forward = MAX(comm_forward, styles[m]->comm_forward);
if (styles[m]) comm_reverse = MAX(comm_reverse, styles[m]->comm_reverse);
if (styles[m]) comm_reverse_off = MAX(comm_reverse_off, styles[m]->comm_reverse_off);
if (styles[m]) partial_flag = MAX(partial_flag, styles[m]->partial_flag);
}
for (m = 0; m < nstyles; m++)
if (styles[m]->partial_flag != partial_flag)
error->all(FLERR, "Cannot hybridize bond styles with different topology settings");
init_svector();
}
@ -351,6 +382,7 @@ void BondHybrid::init_style()
// to create an entry for it in the bond type to sub-style map
if (has_quartic >= 0) map[0] = has_quartic;
else map[0] = -1;
}
/* ----------------------------------------------------------------------

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