forked from lijiext/lammps
Merge branch 'collected-small-changes' into doxygen-integration
This commit is contained in:
commit
8137ada848
|
@ -502,7 +502,8 @@ Doc page with :doc:`WARNING messages <Errors_warnings>`
|
|||
*Bond/react: Unknown section in map file*
|
||||
Please ensure reaction map files are properly formatted.
|
||||
|
||||
*Bond/react: Atom affected by reaction too close to template edge*
|
||||
*Bond/react: Atom type affected by reaction too close to template edge*
|
||||
*Bond/react: Bond type affected by reaction too close to template edge*
|
||||
This means an atom which changes type or connectivity during the
|
||||
reaction is too close to an 'edge' atom defined in the map
|
||||
file. This could cause incorrect assignment of bonds, angle, etc.
|
||||
|
|
|
@ -14,19 +14,22 @@ Syntax
|
|||
react react-ID react-group-ID Nevery Rmin Rmax template-ID(pre-reacted) template-ID(post-reacted) map_file individual_keyword values ...
|
||||
...
|
||||
|
||||
* ID, group-ID are documented in :doc:`fix <fix>` command. Group-ID is ignored.
|
||||
* ID, group-ID are documented in :doc:`fix <fix>` command.
|
||||
* bond/react = style name of this fix command
|
||||
* the common keyword/values may be appended directly after 'bond/react'
|
||||
* this applies to all reaction specifications (below)
|
||||
* common_keyword = *stabilization*
|
||||
* common_keyword = *stabilization* or *reset_mol_ids*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*stabilization* values = *no* or *yes* *group-ID* *xmax*
|
||||
*no* = no reaction site stabilization
|
||||
*no* = no reaction site stabilization (default)
|
||||
*yes* = perform reaction site stabilization
|
||||
*group-ID* = user-assigned prefix for the dynamic group of atoms not currently involved in a reaction
|
||||
*xmax* = xmax value that is used by an internally-created :doc:`nve/limit <fix_nve_limit>` integrator
|
||||
*reset_mol_ids* values = *yes* or *no*
|
||||
*yes* = update molecule IDs based on new global topology (default)
|
||||
*no* = do not update molecule IDs
|
||||
|
||||
* react = mandatory argument indicating new reaction specification
|
||||
* react-ID = user-assigned name for the reaction
|
||||
|
@ -50,9 +53,9 @@ Syntax
|
|||
*stabilize_steps* value = timesteps
|
||||
timesteps = number of timesteps to apply the internally-created :doc:`nve/limit <fix_nve_limit>` fix to reacting atoms
|
||||
*update_edges* value = *none* or *charges* or *custom*
|
||||
none = do not update topology near the edges of reaction templates
|
||||
charges = update atomic charges of all atoms in reaction templates
|
||||
custom = force the update of user-specified atomic charges
|
||||
*none* = do not update topology near the edges of reaction templates
|
||||
*charges* = update atomic charges of all atoms in reaction templates
|
||||
*custom* = force the update of user-specified atomic charges
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
|
@ -154,6 +157,13 @@ due to the internal dynamic grouping performed by fix bond/react.
|
|||
If the group-ID is an existing static group, react-group-IDs
|
||||
should also be specified as this static group, or a subset.
|
||||
|
||||
The *reset_mol_ids* keyword invokes the :doc:`reset_mol_ids <reset_mol_ids>`
|
||||
command after a reaction occurs, to ensure that molecule IDs are
|
||||
consistent with the new bond topology. The group-ID used for
|
||||
:doc:`reset_mol_ids <reset_mol_ids>` is the group-ID for this fix.
|
||||
Resetting molecule IDs is necessarily a global operation, and so can
|
||||
be slow for very large systems.
|
||||
|
||||
The following comments pertain to each *react* argument (in other
|
||||
words, can be customized for each reaction, or reaction step):
|
||||
|
||||
|
@ -203,9 +213,10 @@ surrounding topology. As described below, the bonding atom pairs of
|
|||
the pre-reacted template are specified by atom ID in the map file. The
|
||||
pre-reacted molecule template should contain as few atoms as possible
|
||||
while still completely describing the topology of all atoms affected
|
||||
by the reaction. For example, if the force field contains dihedrals,
|
||||
the pre-reacted template should contain any atom within three bonds of
|
||||
reacting atoms.
|
||||
by the reaction (which includes all atoms that change atom type or
|
||||
connectivity, and all bonds that change bond type). For example, if
|
||||
the force field contains dihedrals, the pre-reacted template should
|
||||
contain any atom within three bonds of reacting atoms.
|
||||
|
||||
Some atoms in the pre-reacted template that are not reacting may have
|
||||
missing topology with respect to the simulation. For example, the
|
||||
|
@ -554,7 +565,7 @@ Default
|
|||
"""""""
|
||||
|
||||
The option defaults are stabilization = no, prob = 1.0, stabilize_steps = 60,
|
||||
update_edges = none
|
||||
reset_mol_ids = yes, update_edges = none
|
||||
|
||||
----------
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ on particle *i* due to contact with particle *j* is given by:
|
|||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_{ne, Hooke} = k_N \delta_{ij} \mathbf{n}
|
||||
\mathbf{F}_{ne, Hooke} = k_n \delta_{ij} \mathbf{n}
|
||||
|
||||
Where :math:`\delta_{ij} = R_i + R_j - \|\mathbf{r}_{ij}\|` is the particle
|
||||
overlap, :math:`R_i, R_j` are the particle radii, :math:`\mathbf{r}_{ij} = \mathbf{r}_i - \mathbf{r}_j` is the vector separating the two
|
||||
|
@ -106,7 +106,7 @@ For the *hertz* model, the normal component of force is given by:
|
|||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_{ne, Hertz} = k_N R_{eff}^{1/2}\delta_{ij}^{3/2} \mathbf{n}
|
||||
\mathbf{F}_{ne, Hertz} = k_n R_{eff}^{1/2}\delta_{ij}^{3/2} \mathbf{n}
|
||||
|
||||
Here, :math:`R_{eff} = \frac{R_i R_j}{R_i + R_j}` is the effective
|
||||
radius, denoted for simplicity as *R* from here on. For *hertz*\ , the
|
||||
|
@ -123,7 +123,7 @@ Here, :math:`E_{eff} = E = \left(\frac{1-\nu_i^2}{E_i} + \frac{1-\nu_j^2}{E_j}\r
|
|||
modulus, with :math:`\nu_i, \nu_j` the Poisson ratios of the particles of
|
||||
types *i* and *j*\ . Note that if the elastic modulus and the shear
|
||||
modulus of the two particles are the same, the *hertz/material* model
|
||||
is equivalent to the *hertz* model with :math:`k_N = 4/3 E_{eff}`
|
||||
is equivalent to the *hertz* model with :math:`k_n = 4/3 E_{eff}`
|
||||
|
||||
The *dmt* model corresponds to the
|
||||
:ref:`(Derjaguin-Muller-Toporov) <DMT1975>` cohesive model, where the force
|
||||
|
@ -140,7 +140,7 @@ where the force is computed as:
|
|||
|
||||
\mathbf{F}_{ne, jkr} = \left(\frac{4Ea^3}{3R} - 2\pi a^2\sqrt{\frac{4\gamma E}{\pi a}}\right)\mathbf{n}
|
||||
|
||||
Here, *a* is the radius of the contact zone, related to the overlap
|
||||
Here, :math:`a` is the radius of the contact zone, related to the overlap
|
||||
:math:`\delta` according to:
|
||||
|
||||
.. math::
|
||||
|
@ -167,7 +167,7 @@ following general form:
|
|||
|
||||
\mathbf{F}_{n,damp} = -\eta_n \mathbf{v}_{n,rel}
|
||||
|
||||
Here, :math:`\mathbf{v}_{n,rel} = (\mathbf{v}_j - \mathbf{v}_i) \cdot \mathbf{n} \mathbf{n}` is the component of relative velocity along
|
||||
Here, :math:`\mathbf{v}_{n,rel} = (\mathbf{v}_j - \mathbf{v}_i) \cdot \mathbf{n}\ \mathbf{n}` is the component of relative velocity along
|
||||
:math:`\mathbf{n}`.
|
||||
|
||||
The optional *damping* keyword to the *pair_coeff* command followed by
|
||||
|
@ -259,7 +259,9 @@ tangential model choices and their expected parameters are as follows:
|
|||
1. *linear_nohistory* : :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
2. *linear_history* : :math:`k_t`, :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
3. *mindlin* : :math:`k_t` or NULL, :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
4. *mindlin_rescale* : :math:`k_t` or NULL, :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
4. *mindlin/force* : :math:`k_t` or NULL, :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
5. *mindlin_rescale* : :math:`k_t` or NULL, :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
6. *mindlin_rescale/force* : :math:`k_t` or NULL, :math:`x_{\gamma,t}`, :math:`\mu_s`
|
||||
|
||||
Here, :math:`x_{\gamma,t}` is a dimensionless multiplier for the normal
|
||||
damping :math:`\eta_n` that determines the magnitude of the tangential
|
||||
|
@ -268,11 +270,11 @@ coefficient, and :math:`k_t` is the tangential stiffness coefficient.
|
|||
|
||||
For *tangential linear_nohistory*, a simple velocity-dependent Coulomb
|
||||
friction criterion is used, which mimics the behavior of the *pair
|
||||
gran/hooke* style. The tangential force (\mathbf{F}_t\) is given by:
|
||||
gran/hooke* style. The tangential force :math:`\mathbf{F}_t` is given by:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_t = -min(\mu_t F_{n0}, \|\mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
\mathbf{F}_t = -\min(\mu_t F_{n0}, \|\mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
|
||||
The tangential damping force :math:`\mathbf{F}_\mathrm{t,damp}` is given by:
|
||||
|
||||
|
@ -294,8 +296,8 @@ keyword also affects the tangential damping. The parameter
|
|||
literature use :math:`x_{\gamma,t} = 1` (:ref:`Marshall <Marshall2009>`,
|
||||
:ref:`Tsuji et al <Tsuji1992>`, :ref:`Silbert et al <Silbert2001>`). The relative
|
||||
tangential velocity at the point of contact is given by
|
||||
:math:`\mathbf{v}_{t, rel} = \mathbf{v}_{t} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf{n}`, where :math:`\mathbf{v}_{t} = \mathbf{v}_r - \mathbf{v}_r\cdot\mathbf{n}{n}`,
|
||||
:math:`\mathbf{v}_r = \mathbf{v}_j - \mathbf{v}_i`.
|
||||
:math:`\mathbf{v}_{t, rel} = \mathbf{v}_{t} - (R_i\mathbf{\Omega}_i + R_j\mathbf{\Omega}_j) \times \mathbf{n}`, where :math:`\mathbf{v}_{t} = \mathbf{v}_r - \mathbf{v}_r\cdot\mathbf{n}\ \mathbf{n}`,
|
||||
:math:`\mathbf{v}_r = \mathbf{v}_j - \mathbf{v}_i` .
|
||||
The direction of the applied force is :math:`\mathbf{t} = \mathbf{v_{t,rel}}/\|\mathbf{v_{t,rel}}\|` .
|
||||
|
||||
The normal force value :math:`F_{n0}` used to compute the critical force
|
||||
|
@ -314,21 +316,24 @@ form:
|
|||
|
||||
.. math::
|
||||
|
||||
F_{n0} = \|\mathbf{F}_ne + 2 F_{pulloff}\|
|
||||
F_{n0} = \|\mathbf{F}_{ne} + 2 F_{pulloff}\|
|
||||
|
||||
Where :math:`F_{pulloff} = 3\pi \gamma R` for *jkr*\ , and
|
||||
:math:`F_{pulloff} = 4\pi \gamma R` for *dmt*\ .
|
||||
|
||||
The remaining tangential options all use accumulated tangential
|
||||
displacement (i.e. contact history). This is discussed below in the
|
||||
context of the *linear_history* option, but the same treatment of the
|
||||
accumulated displacement applies to the other options as well.
|
||||
displacement (i.e. contact history), except for the options
|
||||
*mindlin/force* and *mindlin_rescale/force*, that use accumulated
|
||||
tangential force instead, and are discussed further below.
|
||||
The accumulated tangential displacement is discussed in details below
|
||||
in the context of the *linear_history* option. The same treatment of
|
||||
the accumulated displacement applies to the other options as well.
|
||||
|
||||
For *tangential linear_history*, the tangential force is given by:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_t = -min(\mu_t F_{n0}, \|-k_t\mathbf{\xi} + \mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
\mathbf{F}_t = -\min(\mu_t F_{n0}, \|-k_t\mathbf{\xi} + \mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
|
||||
Here, :math:`\mathbf{\xi}` is the tangential displacement accumulated
|
||||
during the entire duration of the contact:
|
||||
|
@ -356,7 +361,7 @@ work:
|
|||
|
||||
.. math::
|
||||
|
||||
\mathbf{\xi} = \left(\mathbf{\xi'} - (\mathbf{n} \cdot \mathbf{\xi'})\mathbf{n}\right) \frac{\|\mathbf{\xi'}\|}{\|\mathbf{\xi'}\| - \mathbf{n}\cdot\mathbf{\xi'}}
|
||||
\mathbf{\xi} = \left(\mathbf{\xi'} - (\mathbf{n} \cdot \mathbf{\xi'})\mathbf{n}\right) \frac{\|\mathbf{\xi'}\|}{\|\mathbf{\xi'} - (\mathbf{n}\cdot\mathbf{\xi'})\mathbf{n}\|}
|
||||
|
||||
Here, :math:`\mathbf{\xi'}` is the accumulated displacement prior to the
|
||||
current time step and :math:`\mathbf{\xi}` is the corrected
|
||||
|
@ -372,7 +377,7 @@ discussion):
|
|||
|
||||
.. math::
|
||||
|
||||
\mathbf{\xi} = -\frac{1}{k_t}\left(\mu_t F_{n0}\mathbf{t} + \mathbf{F}_{t,damp}\right)
|
||||
\mathbf{\xi} = -\frac{1}{k_t}\left(\mu_t F_{n0}\mathbf{t} - \mathbf{F}_{t,damp}\right)
|
||||
|
||||
The tangential force is added to the total normal force (elastic plus
|
||||
damping) to produce the total force on the particle. The tangential
|
||||
|
@ -387,27 +392,68 @@ overlap region) to induce a torque on each particle according to:
|
|||
|
||||
\mathbf{\tau}_j = -(R_j - 0.5 \delta) \mathbf{n} \times \mathbf{F}_t
|
||||
|
||||
For *tangential mindlin*\ , the :ref:`Mindlin <Mindlin1949>` no-slip solution is used, which differs from the *linear_history*
|
||||
option by an additional factor of *a*\ , the radius of the contact region. The tangential force is given by:
|
||||
For *tangential mindlin*\ , the :ref:`Mindlin <Mindlin1949>` no-slip solution
|
||||
is used which differs from the *linear_history* option by an additional factor
|
||||
of :math:`a`, the radius of the contact region. The tangential force is given by:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_t = -min(\mu_t F_{n0}, \|-k_t a \mathbf{\xi} + \mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
\mathbf{F}_t = -\min(\mu_t F_{n0}, \|-k_t a \mathbf{\xi} + \mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
|
||||
Here, *a* is the radius of the contact region, given by :math:`a =\sqrt{R\delta}`
|
||||
|
||||
Here, :math:`a` is the radius of the contact region, given by :math:`a =\sqrt{R\delta}`
|
||||
for all normal contact models, except for *jkr*\ , where it is given
|
||||
implicitly by :math:`\delta = a^2/R - 2\sqrt{\pi \gamma a/E}`, see
|
||||
discussion above. To match the Mindlin solution, one should set :math:`k_t = 4G/(2-\nu)`, where :math:`G` is the shear modulus, related to Young's modulus
|
||||
:math:`E` by :math:`G = E/(2(1+\nu))`, where :math:`\nu` is Poisson's ratio. This
|
||||
can also be achieved by specifying *NULL* for :math:`k_t`, in which case a
|
||||
discussion above. To match the Mindlin solution, one should set
|
||||
:math:`k_t = 8G_{eff}`, where :math:`G_{eff}` is the effective shear modulus given by:
|
||||
|
||||
.. math::
|
||||
|
||||
G_{eff} = \left(\frac{2-\nu_i}{G_i} + \frac{2-\nu_j}{G_j}\right)^{-1}
|
||||
|
||||
where :math:`G` is the shear modulus, related to Young's modulus :math:`E`
|
||||
and Poisson's ratio :math:`\nu` by :math:`G = E/(2(1+\nu))`. This can also be
|
||||
achieved by specifying *NULL* for :math:`k_t`, in which case a
|
||||
normal contact model that specifies material parameters :math:`E` and
|
||||
:math:`\nu` is required (e.g. *hertz/material*\ , *dmt* or *jkr*\ ). In this
|
||||
case, mixing of the shear modulus for different particle types *i* and
|
||||
*j* is done according to:
|
||||
*j* is done according to the formula above.
|
||||
|
||||
.. note::
|
||||
|
||||
The radius of the contact region :math:`a` depends on the normal overlap.
|
||||
As a result, the tangential force for *mindlin* can change due to
|
||||
a variation in normal overlap, even with no change in tangential displacement.
|
||||
|
||||
For *tangential mindlin/force*, the accumulated elastic tangential force
|
||||
characterizes the contact history, instead of the accumulated tangential
|
||||
displacement. This prevents the dependence of the tangential force on the
|
||||
normal overlap as noted above. The tangential force is given by:
|
||||
|
||||
.. math::
|
||||
|
||||
1/G = 2(2-\nu_i)(1+\nu_i)/E_i + 2(2-\nu_j)(1+\nu_j)/E_j
|
||||
\mathbf{F}_t = -\min(\mu_t F_{n0}, \|\mathbf{F}_{te} + \mathbf{F}_\mathrm{t,damp}\|) \mathbf{t}
|
||||
|
||||
The increment of the elastic component of the tangential force
|
||||
:math:`\mathbf{F}_{te}` is given by:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathrm{d}\mathbf{F}_{te} = -k_t a \mathbf{v}_{t,rel} \mathrm{d}\tau
|
||||
|
||||
The changes in frame of reference of the contacting pair of particles during
|
||||
contact are accounted for by the same formula as above, replacing the
|
||||
accumulated tangential displacement :math:`\xi`, by the accumulated tangential
|
||||
elastic force :math:`F_{te}`. When the tangential force exceeds the critical
|
||||
force, the tangential force is directly re-scaled to match the value for
|
||||
the critical force:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_{te} = - \mu_t F_{n0}\mathbf{t} + \mathbf{F}_{t,damp}
|
||||
|
||||
The same rules as those described for *mindlin* apply regarding the tangential
|
||||
stiffness and mixing of the shear modulus for different particle types.
|
||||
|
||||
The *mindlin_rescale* option uses the same form as *mindlin*\ , but the
|
||||
magnitude of the tangential displacement is re-scaled as the contact
|
||||
|
@ -421,9 +467,32 @@ Here, :math:`t_{n-1}` indicates the value at the previous time
|
|||
step. This rescaling accounts for the fact that a decrease in the
|
||||
contact area upon unloading leads to the contact being unable to
|
||||
support the previous tangential loading, and spurious energy is
|
||||
created without the rescaling above (:ref:`Walton <WaltonPC>` ). See also
|
||||
discussion in :ref:`Thornton et al, 2013 <Thornton2013>` , particularly
|
||||
equation 18(b) of that work and associated discussion.
|
||||
created without the rescaling above (:ref:`Walton <WaltonPC>` ).
|
||||
|
||||
.. note::
|
||||
|
||||
For *mindlin*, a decrease in the tangential force already occurs as the
|
||||
contact unloads, due to the dependence of the tangential force on the normal
|
||||
force described above. By re-scaling :math:`\xi`, *mindlin_rescale*
|
||||
effectively re-scales the tangential force twice, i.e., proportionally to
|
||||
:math:`a^2`. This peculiar behavior results from use of the accumulated
|
||||
tangential displacement to characterize the contact history. Although
|
||||
*mindlin_rescale* remains available for historic reasons and backward
|
||||
compatibility purposes, it should be avoided in favor of *mindlin_rescale/force*.
|
||||
|
||||
The *mindlin_rescale/force* option uses the same form as *mindlin/force*,
|
||||
but the magnitude of the tangential elastic force is re-scaled as the contact
|
||||
unloads, i.e. if :math:`a < a_{t_{n-1}}`:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_{te} = \mathbf{F}_{te, t_{n-1}} \frac{a}{a_{t_{n-1}}}
|
||||
|
||||
This approach provides a better approximation of the :ref:`Mindlin-Deresiewicz <Mindlin1953>`
|
||||
laws and is more consistent than *mindlin_rescale*. See discussions in
|
||||
:ref:`Thornton et al, 2013 <Thornton2013>`, particularly equation 18(b) of that
|
||||
work and associated discussion, and :ref:`Agnolin and Roux, 2007 <AgnolinRoux2007>`,
|
||||
particularly Appendix A.
|
||||
|
||||
----------
|
||||
|
||||
|
@ -460,7 +529,7 @@ exceeds a critical value:
|
|||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_{roll} = min(\mu_{roll} F_{n,0}, \|\mathbf{F}_{roll,0}\|)\mathbf{k}
|
||||
\mathbf{F}_{roll} = \min(\mu_{roll} F_{n,0}, \|\mathbf{F}_{roll,0}\|)\mathbf{k}
|
||||
|
||||
Here, :math:`\mathbf{k} = \mathbf{v}_{roll}/\|\mathbf{v}_{roll}\|` is the direction of
|
||||
the pseudo-force. As with tangential displacement, the rolling
|
||||
|
@ -512,7 +581,7 @@ is then truncated according to:
|
|||
|
||||
.. math::
|
||||
|
||||
\tau_{twist} = min(\mu_{twist} F_{n,0}, \tau_{twist,0})
|
||||
\tau_{twist} = \min(\mu_{twist} F_{n,0}, \tau_{twist,0})
|
||||
|
||||
Similar to the sliding and rolling displacement, the angular
|
||||
displacement is rescaled so that it corresponds to the critical value
|
||||
|
@ -763,3 +832,15 @@ Technology, 233, 30-46.
|
|||
.. _WaltonPC:
|
||||
|
||||
**(Otis R. Walton)** Walton, O.R., Personal Communication
|
||||
|
||||
.. _Mindlin1953:
|
||||
|
||||
**(Mindlin and Deresiewicz, 1953)** Mindlin, R.D., & Deresiewicz, H (1953).
|
||||
Elastic Spheres in Contact under Varying Oblique Force.
|
||||
J. Appl. Mech., ASME 20, 327-344.
|
||||
|
||||
.. _AgnolinRoux2007:
|
||||
|
||||
**(Agnolin and Roux 2007)** Agnolin, I. & Roux, J-N. (2007).
|
||||
Internal states of model isotropic granular packings.
|
||||
I. Assembling process, geometry, and contact networks. Phys. Rev. E, 76, 061302.
|
||||
|
|
|
@ -43,6 +43,7 @@ Afshar
|
|||
agilio
|
||||
Agilio
|
||||
agni
|
||||
Agnolin
|
||||
Ai
|
||||
Aidan
|
||||
aij
|
||||
|
@ -599,6 +600,7 @@ Dequidt
|
|||
der
|
||||
dereference
|
||||
derekt
|
||||
Deresiewicz
|
||||
Derjagin
|
||||
Derjaguin
|
||||
Derlet
|
||||
|
@ -2219,6 +2221,7 @@ oxdna
|
|||
oxrna
|
||||
oxDNA
|
||||
oxRNA
|
||||
packings
|
||||
padua
|
||||
Padua
|
||||
palegoldenrod
|
||||
|
|
|
@ -55,7 +55,8 @@ using namespace MathSpecial;
|
|||
enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR};
|
||||
enum {VELOCITY, MASS_VELOCITY, VISCOELASTIC, TSUJI};
|
||||
enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY,
|
||||
TANGENTIAL_MINDLIN, TANGENTIAL_MINDLIN_RESCALE};
|
||||
TANGENTIAL_MINDLIN, TANGENTIAL_MINDLIN_RESCALE,
|
||||
TANGENTIAL_MINDLIN_FORCE, TANGENTIAL_MINDLIN_RESCALE_FORCE};
|
||||
enum {TWIST_NONE, TWIST_SDS, TWIST_MARSHALL};
|
||||
enum {ROLL_NONE, ROLL_SDS};
|
||||
|
||||
|
@ -175,7 +176,8 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
double signtwist, magtwist, magtortwist, Mtcrit;
|
||||
double tortwist1, tortwist2, tortwist3;
|
||||
|
||||
double shrmag,rsht;
|
||||
double shrmag,rsht,prjmag;
|
||||
bool frameupdate;
|
||||
int *ilist,*jlist,*numneigh,**firstneigh;
|
||||
int *touch,**firsttouch;
|
||||
double *history,*allhistory,**firsthistory;
|
||||
|
@ -372,6 +374,12 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
// tangential force, including history effects
|
||||
//****************************************
|
||||
|
||||
// For linear, mindlin, mindlin_rescale:
|
||||
// history = cumulative tangential displacement
|
||||
//
|
||||
// For mindlin/force, mindlin_rescale/force:
|
||||
// history = cumulative tangential elastic force
|
||||
|
||||
// tangential component
|
||||
vt1 = vr1 - vn1;
|
||||
vt2 = vr2 - vn2;
|
||||
|
@ -414,12 +422,15 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
damp_normal_prefactor;
|
||||
|
||||
if (tangential_history) {
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN) {
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_FORCE) {
|
||||
k_tangential *= a;
|
||||
} else if (tangential_model[itype][jtype] ==
|
||||
TANGENTIAL_MINDLIN_RESCALE) {
|
||||
TANGENTIAL_MINDLIN_RESCALE ||
|
||||
tangential_model[itype][jtype] ==
|
||||
TANGENTIAL_MINDLIN_RESCALE_FORCE) {
|
||||
k_tangential *= a;
|
||||
// on unloading, rescale the shear displacements
|
||||
// on unloading, rescale the shear displacements/force
|
||||
if (a < history[3]) {
|
||||
double factor = a/history[3];
|
||||
history[0] *= factor;
|
||||
|
@ -427,37 +438,66 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
history[2] *= factor;
|
||||
}
|
||||
}
|
||||
// rotate and update displacements.
|
||||
// rotate and update displacements / force.
|
||||
// see e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235
|
||||
if (historyupdate) {
|
||||
rsht = history[0]*nx + history[1]*ny + history[2]*nz;
|
||||
if (fabs(rsht) < EPSILON) rsht = 0;
|
||||
if (rsht > 0) {
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_FORCE ||
|
||||
tangential_model[itype][jtype] ==
|
||||
TANGENTIAL_MINDLIN_RESCALE_FORCE)
|
||||
frameupdate = fabs(rsht) < EPSILON*Fscrit;
|
||||
else
|
||||
frameupdate = fabs(rsht)*k_tangential < EPSILON*Fscrit;
|
||||
if (frameupdate) {
|
||||
shrmag = sqrt(history[0]*history[0] + history[1]*history[1] +
|
||||
history[2]*history[2]);
|
||||
// if rsht == shrmag, contacting pair has rotated 90 deg
|
||||
// in one step, in which case you deserve a crash!
|
||||
scalefac = shrmag/(shrmag - rsht);
|
||||
// projection
|
||||
history[0] -= rsht*nx;
|
||||
history[1] -= rsht*ny;
|
||||
history[2] -= rsht*nz;
|
||||
|
||||
// also rescale to preserve magnitude
|
||||
prjmag = sqrt(history[0]*history[0] + history[1]*history[1] +
|
||||
history[2]*history[2]);
|
||||
if (prjmag > 0) scalefac = shrmag/prjmag;
|
||||
else scalefac = 0;
|
||||
history[0] *= scalefac;
|
||||
history[1] *= scalefac;
|
||||
history[2] *= scalefac;
|
||||
}
|
||||
// update history
|
||||
history[0] += vtr1*dt;
|
||||
history[1] += vtr2*dt;
|
||||
history[2] += vtr3*dt;
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE)
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_HISTORY ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) {
|
||||
// tangential displacement
|
||||
history[0] += vtr1*dt;
|
||||
history[1] += vtr2*dt;
|
||||
history[2] += vtr3*dt;
|
||||
} else {
|
||||
// tangential force
|
||||
// see e.g. eq. 18 of Thornton et al, Pow. Tech. 2013, v223,p30-46
|
||||
history[0] -= k_tangential*vtr1*dt;
|
||||
history[1] -= k_tangential*vtr2*dt;
|
||||
history[2] -= k_tangential*vtr3*dt;
|
||||
}
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE ||
|
||||
tangential_model[itype][jtype] ==
|
||||
TANGENTIAL_MINDLIN_RESCALE_FORCE)
|
||||
history[3] = a;
|
||||
}
|
||||
|
||||
// tangential forces = history + tangential velocity damping
|
||||
fs1 = -k_tangential*history[0] - damp_tangential*vtr1;
|
||||
fs2 = -k_tangential*history[1] - damp_tangential*vtr2;
|
||||
fs3 = -k_tangential*history[2] - damp_tangential*vtr3;
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_HISTORY ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) {
|
||||
fs1 = -k_tangential*history[0] - damp_tangential*vtr1;
|
||||
fs2 = -k_tangential*history[1] - damp_tangential*vtr2;
|
||||
fs3 = -k_tangential*history[2] - damp_tangential*vtr3;
|
||||
} else {
|
||||
fs1 = history[0] - damp_tangential*vtr1;
|
||||
fs2 = history[1] - damp_tangential*vtr2;
|
||||
fs3 = history[2] - damp_tangential*vtr3;
|
||||
}
|
||||
|
||||
// rescale frictional displacements and forces if needed
|
||||
fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
|
||||
|
@ -465,12 +505,21 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
shrmag = sqrt(history[0]*history[0] + history[1]*history[1] +
|
||||
history[2]*history[2]);
|
||||
if (shrmag != 0.0) {
|
||||
history[0] = -1.0/k_tangential*(Fscrit*fs1/fs +
|
||||
damp_tangential*vtr1);
|
||||
history[1] = -1.0/k_tangential*(Fscrit*fs2/fs +
|
||||
damp_tangential*vtr2);
|
||||
history[2] = -1.0/k_tangential*(Fscrit*fs3/fs +
|
||||
damp_tangential*vtr3);
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_HISTORY ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN ||
|
||||
tangential_model[itype][jtype] ==
|
||||
TANGENTIAL_MINDLIN_RESCALE) {
|
||||
history[0] = -1.0/k_tangential*(Fscrit*fs1/fs +
|
||||
damp_tangential*vtr1);
|
||||
history[1] = -1.0/k_tangential*(Fscrit*fs2/fs +
|
||||
damp_tangential*vtr2);
|
||||
history[2] = -1.0/k_tangential*(Fscrit*fs3/fs +
|
||||
damp_tangential*vtr3);
|
||||
} else {
|
||||
history[0] = Fscrit*fs1/fs + damp_tangential*vtr1;
|
||||
history[1] = Fscrit*fs2/fs + damp_tangential*vtr2;
|
||||
history[2] = Fscrit*fs3/fs + damp_tangential*vtr3;
|
||||
}
|
||||
fs1 *= Fscrit/fs;
|
||||
fs2 *= Fscrit/fs;
|
||||
fs3 *= Fscrit/fs;
|
||||
|
@ -512,18 +561,27 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
int rhist1 = rhist0 + 1;
|
||||
int rhist2 = rhist1 + 1;
|
||||
|
||||
rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz;
|
||||
k_roll = roll_coeffs[itype][jtype][0];
|
||||
damp_roll = roll_coeffs[itype][jtype][1];
|
||||
Frcrit = roll_coeffs[itype][jtype][2] * Fncrit;
|
||||
|
||||
if (historyupdate) {
|
||||
if (fabs(rolldotn) < EPSILON) rolldotn = 0;
|
||||
if (rolldotn > 0) { // rotate into tangential plane
|
||||
rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz;
|
||||
frameupdate = fabs(rolldotn)*k_roll < EPSILON*Frcrit;
|
||||
if (frameupdate) { // rotate into tangential plane
|
||||
rollmag = sqrt(history[rhist0]*history[rhist0] +
|
||||
history[rhist1]*history[rhist1] +
|
||||
history[rhist2]*history[rhist2]);
|
||||
scalefac = rollmag/(rollmag - rolldotn);
|
||||
// projection
|
||||
history[rhist0] -= rolldotn*nx;
|
||||
history[rhist1] -= rolldotn*ny;
|
||||
history[rhist2] -= rolldotn*nz;
|
||||
// also rescale to preserve magnitude
|
||||
prjmag = sqrt(history[rhist0]*history[rhist0] +
|
||||
history[rhist1]*history[rhist1] +
|
||||
history[rhist2]*history[rhist2]);
|
||||
if (prjmag > 0) scalefac = rollmag/prjmag;
|
||||
else scalefac = 0;
|
||||
history[rhist0] *= scalefac;
|
||||
history[rhist1] *= scalefac;
|
||||
history[rhist2] *= scalefac;
|
||||
|
@ -533,14 +591,11 @@ void PairGranular::compute(int eflag, int vflag)
|
|||
history[rhist2] += vrl3*dt;
|
||||
}
|
||||
|
||||
k_roll = roll_coeffs[itype][jtype][0];
|
||||
damp_roll = roll_coeffs[itype][jtype][1];
|
||||
fr1 = -k_roll*history[rhist0] - damp_roll*vrl1;
|
||||
fr2 = -k_roll*history[rhist1] - damp_roll*vrl2;
|
||||
fr3 = -k_roll*history[rhist2] - damp_roll*vrl3;
|
||||
|
||||
// rescale frictional displacements and forces if needed
|
||||
Frcrit = roll_coeffs[itype][jtype][2] * Fncrit;
|
||||
|
||||
fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3);
|
||||
if (fr > Frcrit) {
|
||||
|
@ -734,7 +789,8 @@ void PairGranular::coeff(int narg, char **arg)
|
|||
|
||||
//Defaults
|
||||
normal_model_one = tangential_model_one = -1;
|
||||
roll_model_one = twist_model_one = 0;
|
||||
roll_model_one = ROLL_NONE;
|
||||
twist_model_one = TWIST_NONE;
|
||||
damping_model_one = VISCOELASTIC;
|
||||
|
||||
int iarg = 2;
|
||||
|
@ -820,7 +876,9 @@ void PairGranular::coeff(int narg, char **arg)
|
|||
iarg += 4;
|
||||
} else if ((strcmp(arg[iarg+1], "linear_history") == 0) ||
|
||||
(strcmp(arg[iarg+1], "mindlin") == 0) ||
|
||||
(strcmp(arg[iarg+1], "mindlin_rescale") == 0)) {
|
||||
(strcmp(arg[iarg+1], "mindlin_rescale") == 0) ||
|
||||
(strcmp(arg[iarg+1], "mindlin/force") == 0) ||
|
||||
(strcmp(arg[iarg+1], "mindlin_rescale/force") == 0)) {
|
||||
if (iarg + 4 >= narg)
|
||||
error->all(FLERR,"Illegal pair_coeff command, "
|
||||
"not enough parameters provided for tangential model");
|
||||
|
@ -830,9 +888,15 @@ void PairGranular::coeff(int narg, char **arg)
|
|||
tangential_model_one = TANGENTIAL_MINDLIN;
|
||||
else if (strcmp(arg[iarg+1], "mindlin_rescale") == 0)
|
||||
tangential_model_one = TANGENTIAL_MINDLIN_RESCALE;
|
||||
else if (strcmp(arg[iarg+1], "mindlin/force") == 0)
|
||||
tangential_model_one = TANGENTIAL_MINDLIN_FORCE;
|
||||
else if (strcmp(arg[iarg+1], "mindlin_rescale/force") == 0)
|
||||
tangential_model_one = TANGENTIAL_MINDLIN_RESCALE_FORCE;
|
||||
tangential_history = 1;
|
||||
if ((tangential_model_one == TANGENTIAL_MINDLIN ||
|
||||
tangential_model_one == TANGENTIAL_MINDLIN_RESCALE) &&
|
||||
tangential_model_one == TANGENTIAL_MINDLIN_RESCALE ||
|
||||
tangential_model_one == TANGENTIAL_MINDLIN_FORCE ||
|
||||
tangential_model_one == TANGENTIAL_MINDLIN_RESCALE_FORCE) &&
|
||||
(strcmp(arg[iarg+2], "NULL") == 0)) {
|
||||
if (normal_model_one == HERTZ || normal_model_one == HOOKE) {
|
||||
error->all(FLERR, "NULL setting for Mindlin tangential "
|
||||
|
@ -1014,7 +1078,8 @@ void PairGranular::init_style()
|
|||
}
|
||||
for (int i = 1; i <= atom->ntypes; i++)
|
||||
for (int j = i; j <= atom->ntypes; j++)
|
||||
if (tangential_model[i][j] == TANGENTIAL_MINDLIN_RESCALE) {
|
||||
if (tangential_model[i][j] == TANGENTIAL_MINDLIN_RESCALE ||
|
||||
tangential_model[i][j] == TANGENTIAL_MINDLIN_RESCALE_FORCE) {
|
||||
size_history += 1;
|
||||
roll_history_index += 1;
|
||||
twist_history_index += 1;
|
||||
|
@ -1484,6 +1549,12 @@ double PairGranular::single(int i, int j, int itype, int jtype,
|
|||
// tangential force, including history effects
|
||||
//****************************************
|
||||
|
||||
// For linear, mindlin, mindlin_rescale:
|
||||
// history = cumulative tangential displacement
|
||||
//
|
||||
// For mindlin/force, mindlin_rescale/force:
|
||||
// history = cumulative tangential elastic force
|
||||
|
||||
// tangential component
|
||||
vt1 = vr1 - vn1;
|
||||
vt2 = vr2 - vn2;
|
||||
|
@ -1519,9 +1590,7 @@ double PairGranular::single(int i, int j, int itype, int jtype,
|
|||
damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor;
|
||||
|
||||
if (tangential_history) {
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN) {
|
||||
k_tangential *= a;
|
||||
} else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) {
|
||||
if (tangential_model[itype][jtype] != TANGENTIAL_HISTORY) {
|
||||
k_tangential *= a;
|
||||
}
|
||||
|
||||
|
@ -1529,9 +1598,17 @@ double PairGranular::single(int i, int j, int itype, int jtype,
|
|||
history[2]*history[2]);
|
||||
|
||||
// tangential forces = history + tangential velocity damping
|
||||
fs1 = -k_tangential*history[0] - damp_tangential*vtr1;
|
||||
fs2 = -k_tangential*history[1] - damp_tangential*vtr2;
|
||||
fs3 = -k_tangential*history[2] - damp_tangential*vtr3;
|
||||
if (tangential_model[itype][jtype] == TANGENTIAL_HISTORY ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN ||
|
||||
tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) {
|
||||
fs1 = -k_tangential*history[0] - damp_tangential*vtr1;
|
||||
fs2 = -k_tangential*history[1] - damp_tangential*vtr2;
|
||||
fs3 = -k_tangential*history[2] - damp_tangential*vtr3;
|
||||
} else {
|
||||
fs1 = history[0] - damp_tangential*vtr1;
|
||||
fs2 = history[1] - damp_tangential*vtr2;
|
||||
fs3 = history[2] - damp_tangential*vtr3;
|
||||
}
|
||||
|
||||
// rescale frictional forces if needed
|
||||
fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
|
||||
|
@ -1540,7 +1617,7 @@ double PairGranular::single(int i, int j, int itype, int jtype,
|
|||
fs1 *= Fscrit/fs;
|
||||
fs2 *= Fscrit/fs;
|
||||
fs3 *= Fscrit/fs;
|
||||
fs *= Fscrit/fs;
|
||||
fs *= Fscrit/fs;
|
||||
} else fs1 = fs2 = fs3 = fs = 0.0;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ Contributing Author: Jacob Gissinger (jacob.gissinger@colorado.edu)
|
|||
#include "neigh_list.h"
|
||||
#include "neigh_request.h"
|
||||
#include "random_mars.h"
|
||||
#include "reset_mol_ids.h"
|
||||
#include "molecule.h"
|
||||
#include "group.h"
|
||||
#include "citeme.h"
|
||||
|
@ -92,6 +93,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
fix1 = NULL;
|
||||
fix2 = NULL;
|
||||
fix3 = NULL;
|
||||
reset_mol_ids = NULL;
|
||||
|
||||
if (narg < 8) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"too few arguments");
|
||||
|
@ -144,7 +146,8 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
|
||||
int iarg = 3;
|
||||
stabilization_flag = 0;
|
||||
int num_common_keywords = 1;
|
||||
reset_mol_ids_flag = 1;
|
||||
int num_common_keywords = 2;
|
||||
for (int m = 0; m < num_common_keywords; m++) {
|
||||
if (strcmp(arg[iarg],"stabilization") == 0) {
|
||||
if (strcmp(arg[iarg+1],"no") == 0) {
|
||||
|
@ -162,11 +165,23 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
nve_limit_xmax = arg[iarg+3];
|
||||
iarg += 4;
|
||||
}
|
||||
} else if (strcmp(arg[iarg],"reset_mol_ids") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'reset_mol_ids' keyword has too few arguments");
|
||||
if (strcmp(arg[iarg+1],"yes") == 0) ; // default
|
||||
if (strcmp(arg[iarg+1],"no") == 0) reset_mol_ids_flag = 0;
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"react") == 0) {
|
||||
break;
|
||||
} else error->all(FLERR,"Illegal fix bond/react command: unknown keyword");
|
||||
}
|
||||
|
||||
if (reset_mol_ids_flag) {
|
||||
delete reset_mol_ids;
|
||||
reset_mol_ids = new ResetMolIDs(lmp);
|
||||
reset_mol_ids->create_computes(id,group->names[igroup]);
|
||||
}
|
||||
|
||||
// set up common variables as vectors of length 'nreacts'
|
||||
// nevery, cutoff, onemol, twomol, superimpose file
|
||||
|
||||
|
@ -229,11 +244,11 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
|
||||
int n = strlen(arg[iarg]) + 1;
|
||||
if (n > MAXLINE) error->all(FLERR,"Reaction name (react-ID) is too long (limit: 256 characters)");
|
||||
strncpy(rxn_name[rxn],arg[iarg++],n);
|
||||
strcpy(rxn_name[rxn],arg[iarg++]);
|
||||
|
||||
int igroup = group->find(arg[iarg++]);
|
||||
if (igroup == -1) error->all(FLERR,"Could not find fix group ID");
|
||||
groupbits[rxn] = group->bitmask[igroup];
|
||||
int groupid = group->find(arg[iarg++]);
|
||||
if (groupid == -1) error->all(FLERR,"Could not find fix group ID");
|
||||
groupbits[rxn] = group->bitmask[groupid];
|
||||
|
||||
if (strncmp(arg[iarg],"v_",2) == 0) {
|
||||
n = strlen(&arg[iarg][2]) + 1;
|
||||
|
@ -499,6 +514,8 @@ FixBondReact::~FixBondReact()
|
|||
}
|
||||
delete [] random;
|
||||
|
||||
delete reset_mol_ids;
|
||||
|
||||
memory->destroy(partner);
|
||||
memory->destroy(finalpartner);
|
||||
memory->destroy(ncreate);
|
||||
|
@ -623,9 +640,9 @@ void FixBondReact::post_constructor()
|
|||
group->assign(cmd);
|
||||
|
||||
if (stabilization_flag == 1) {
|
||||
int igroup = group->find(exclude_group);
|
||||
int groupid = group->find(exclude_group);
|
||||
// create exclude_group if not already existing, or use as parent group if static
|
||||
if (igroup == -1 || group->dynamic[igroup] == 0) {
|
||||
if (groupid == -1 || group->dynamic[groupid] == 0) {
|
||||
// create stabilization per-atom property
|
||||
cmd = std::string("bond_react_stabilization_internal");
|
||||
id_fix3 = new char[cmd.size()+1];
|
||||
|
@ -655,7 +672,7 @@ void FixBondReact::post_constructor()
|
|||
strcat(exclude_group,"_REACT");
|
||||
|
||||
group->find_or_create(exclude_group);
|
||||
if (igroup == -1)
|
||||
if (groupid == -1)
|
||||
cmd = fmt::format("{} dynamic all property statted_tags",exclude_group);
|
||||
else
|
||||
cmd = fmt::format("{} dynamic {} property statted_tags",exclude_group,exclude_PARENT_group);
|
||||
|
@ -2061,7 +2078,7 @@ void FixBondReact::find_landlocked_atoms(int myrxn)
|
|||
for (int i = 0; i < twomol->natoms; i++) {
|
||||
if (twomol->type[i] != onemol->type[equivalences[i][1][myrxn]-1] && landlocked_atoms[i][myrxn] == 0) {
|
||||
char str[128];
|
||||
snprintf(str,128,"Bond/react: Atom affected by reaction %s too close to template edge",rxn_name[myrxn]);
|
||||
snprintf(str,128,"Bond/react: Atom type affected by reaction %s too close to template edge",rxn_name[myrxn]);
|
||||
error->all(FLERR,str);
|
||||
}
|
||||
}
|
||||
|
@ -2080,7 +2097,7 @@ void FixBondReact::find_landlocked_atoms(int myrxn)
|
|||
if (onemol_batom == equivalences[twomol_atomj-1][1][myrxn]) {
|
||||
if (twomol->bond_type[i][j] != onemol->bond_type[onemol_atomi-1][m]) {
|
||||
char str[128];
|
||||
snprintf(str,128,"Bond/react: Atom affected by reaction %s too close to template edge",rxn_name[myrxn]);
|
||||
snprintf(str,128,"Bond/react: Bond type affected by reaction %s too close to template edge",rxn_name[myrxn]);
|
||||
error->all(FLERR,str);
|
||||
}
|
||||
}
|
||||
|
@ -2092,7 +2109,7 @@ void FixBondReact::find_landlocked_atoms(int myrxn)
|
|||
if (onemol_batom == equivalences[i][1][myrxn]) {
|
||||
if (twomol->bond_type[i][j] != onemol->bond_type[onemol_atomj-1][m]) {
|
||||
char str[128];
|
||||
snprintf(str,128,"Bond/react: Atom affected by reaction %s too close to template edge",rxn_name[myrxn]);
|
||||
snprintf(str,128,"Bond/react: Bond type affected by reaction %s too close to template edge",rxn_name[myrxn]);
|
||||
error->all(FLERR,str);
|
||||
}
|
||||
}
|
||||
|
@ -2503,7 +2520,7 @@ void FixBondReact::ghost_glovecast()
|
|||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
update charges, types, special lists and all topology
|
||||
update molecule IDs, charges, types, special lists and all topology
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondReact::update_everything()
|
||||
|
@ -3042,6 +3059,9 @@ void FixBondReact::update_everything()
|
|||
atom->natoms -= ndel;
|
||||
// done deleting atoms
|
||||
|
||||
// reset mol ids
|
||||
if (reset_mol_ids_flag) reset_mol_ids->reset();
|
||||
|
||||
// something to think about: this could done much more concisely if
|
||||
// all atom-level info (bond,angles, etc...) were kinda inherited from a common data struct --JG
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ class FixBondReact : public Fix {
|
|||
int *max_rxn,*nlocalskips,*nghostlyskips;
|
||||
tagint lastcheck;
|
||||
int stabilization_flag;
|
||||
int reset_mol_ids_flag;
|
||||
int custom_exclude_flag;
|
||||
int *stabilize_steps_flag;
|
||||
int *update_edges_flag;
|
||||
|
@ -93,6 +94,7 @@ class FixBondReact : public Fix {
|
|||
class RanMars **random; // random number for 'prob' keyword
|
||||
class RanMars **rrhandom; // random number for Arrhenius constraint
|
||||
class NeighList *list;
|
||||
class ResetMolIDs *reset_mol_ids; // class for resetting mol IDs
|
||||
|
||||
int *reacted_mol,*unreacted_mol;
|
||||
int *limit_duration; // indicates how long to relax
|
||||
|
@ -240,8 +242,10 @@ E: Bond/react: Invalid template atom ID in map file
|
|||
Atom IDs in molecule templates range from 1 to the number of atoms in the template.
|
||||
|
||||
E or W: Bond/react: Atom affected by reaction %s too close to template edge
|
||||
Bond/react: Atom type affected by reaction %s too close to template edge
|
||||
Bond/react: Bond type affected by reaction %s too close to template edge
|
||||
|
||||
This means an atom which changes type or connectivity during the
|
||||
This means an atom (or bond) that changes type or connectivity during the
|
||||
reaction is too close to an 'edge' atom defined in the map file. This
|
||||
could cause incorrect assignment of bonds, angle, etc. Generally, this
|
||||
means you must include more atoms in your templates, such that there
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "reset_mol_ids.h"
|
||||
#include <mpi.h>
|
||||
#include <string>
|
||||
#include "atom.h"
|
||||
#include "domain.h"
|
||||
#include "comm.h"
|
||||
|
@ -33,10 +32,32 @@ using namespace LAMMPS_NS;
|
|||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
ResetMolIDs::ResetMolIDs(LAMMPS *lmp) : Pointers(lmp) {}
|
||||
ResetMolIDs::ResetMolIDs(LAMMPS *lmp) : Pointers(lmp) {
|
||||
cfa = NULL;
|
||||
cca = NULL;
|
||||
|
||||
// default settings
|
||||
|
||||
compressflag = 1;
|
||||
singleflag = 0;
|
||||
offset = -1;
|
||||
|
||||
idfrag.clear();
|
||||
idchunk.clear();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
ResetMolIDs::~ResetMolIDs()
|
||||
{
|
||||
if (!idfrag.empty()) modify->delete_compute(idfrag);
|
||||
if (compressflag && !idchunk.empty()) modify->delete_compute(idchunk);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
called as reset_mol_ids command in input script
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void ResetMolIDs::command(int narg, char **arg)
|
||||
{
|
||||
if (domain->box_exist == 0)
|
||||
|
@ -49,13 +70,7 @@ void ResetMolIDs::command(int narg, char **arg)
|
|||
// process args
|
||||
|
||||
if (narg < 1) error->all(FLERR,"Illegal reset_mol_ids command");
|
||||
int igroup = group->find(arg[0]);
|
||||
if (igroup == -1) error->all(FLERR,"Could not find reset_mol_ids group ID");
|
||||
int groupbit = group->bitmask[igroup];
|
||||
|
||||
int compressflag = 1;
|
||||
int singleflag = 0;
|
||||
tagint offset = -1;
|
||||
char *groupid = arg[0];
|
||||
|
||||
int iarg = 1;
|
||||
while (iarg < narg) {
|
||||
|
@ -86,20 +101,6 @@ void ResetMolIDs::command(int narg, char **arg)
|
|||
MPI_Barrier(world);
|
||||
double time1 = MPI_Wtime();
|
||||
|
||||
// create instances of compute fragment/atom, compute reduce (if needed),
|
||||
// and compute chunk/atom. all use the group-ID for this command
|
||||
|
||||
const std::string idfrag = "reset_mol_ids_FRAGMENT_ATOM";
|
||||
if (singleflag)
|
||||
modify->add_compute(fmt::format("{} {} fragment/atom single yes",idfrag,arg[0]));
|
||||
else
|
||||
modify->add_compute(fmt::format("{} {} fragment/atom single no",idfrag,arg[0]));
|
||||
|
||||
const std::string idchunk = "reset_mol_ids_CHUNK_ATOM";
|
||||
if (compressflag)
|
||||
modify->add_compute(fmt::format("{} {} chunk/atom molecule compress yes",
|
||||
idchunk,arg[0]));
|
||||
|
||||
// initialize system since comm->borders() will be invoked
|
||||
|
||||
lmp->init();
|
||||
|
@ -116,12 +117,73 @@ void ResetMolIDs::command(int narg, char **arg)
|
|||
comm->borders();
|
||||
if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
|
||||
|
||||
// create computes
|
||||
|
||||
create_computes((char *) "COMMAND",groupid);
|
||||
|
||||
// reset molecule IDs
|
||||
|
||||
reset();
|
||||
|
||||
// total time
|
||||
|
||||
MPI_Barrier(world);
|
||||
|
||||
if (comm->me == 0) {
|
||||
if (nchunk < 0)
|
||||
utils::logmesg(lmp,fmt::format(" number of new molecule IDs = unknown\n"));
|
||||
else
|
||||
utils::logmesg(lmp,fmt::format(" number of new molecule IDs = {}\n",nchunk));
|
||||
utils::logmesg(lmp,fmt::format(" reset_mol_ids CPU = {:.3f} seconds\n",
|
||||
MPI_Wtime()-time1));
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
create computes used by reset_mol_ids
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void ResetMolIDs::create_computes(char *fixid, char *groupid)
|
||||
{
|
||||
int igroup = group->find(groupid);
|
||||
if (igroup == -1) error->all(FLERR,"Could not find reset_mol_ids group ID");
|
||||
groupbit = group->bitmask[igroup];
|
||||
|
||||
// create instances of compute fragment/atom, compute reduce (if needed),
|
||||
// and compute chunk/atom. all use the group-ID for this command.
|
||||
// 'fixid' allows for creating independent instances of the computes
|
||||
|
||||
idfrag = fmt::format("{}_reset_mol_ids_FRAGMENT_ATOM",fixid);
|
||||
if (singleflag)
|
||||
modify->add_compute(fmt::format("{} {} fragment/atom single yes",idfrag,groupid));
|
||||
else
|
||||
modify->add_compute(fmt::format("{} {} fragment/atom single no",idfrag,groupid));
|
||||
|
||||
idchunk = fmt::format("{}_reset_mol_ids_CHUNK_ATOM",fixid);
|
||||
if (compressflag)
|
||||
modify->add_compute(fmt::format("{} {} chunk/atom molecule compress yes",
|
||||
idchunk,groupid));
|
||||
|
||||
int icompute = modify->find_compute(idfrag);
|
||||
cfa = (ComputeFragmentAtom *) modify->compute[icompute];
|
||||
|
||||
|
||||
if (compressflag) {
|
||||
icompute = modify->find_compute(idchunk);
|
||||
cca = (ComputeChunkAtom *) modify->compute[icompute];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
called from command() and directly from fixes that update molecules
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void ResetMolIDs::reset()
|
||||
{
|
||||
// invoke peratom method of compute fragment/atom
|
||||
// walks bond connectivity and assigns each atom a fragment ID
|
||||
// if singleflag = 0, atoms w/out bonds will be assigned fragID = 0
|
||||
|
||||
int icompute = modify->find_compute(idfrag);
|
||||
ComputeFragmentAtom *cfa = (ComputeFragmentAtom *) modify->compute[icompute];
|
||||
cfa->compute_peratom();
|
||||
double *fragIDs = cfa->vector_atom;
|
||||
|
||||
|
@ -138,15 +200,13 @@ void ResetMolIDs::command(int narg, char **arg)
|
|||
// if compressflag = 0, done
|
||||
// set nchunk = -1 since cannot easily determine # of new molecule IDs
|
||||
|
||||
int nchunk = -1;
|
||||
nchunk = -1;
|
||||
|
||||
// if compressflag = 1, invoke peratom method of compute chunk/atom
|
||||
// will compress new molecule IDs to be contiguous 1 to Nmol
|
||||
// NOTE: use of compute chunk/atom limits Nmol to a 32-bit int
|
||||
|
||||
if (compressflag) {
|
||||
icompute = modify->find_compute(idchunk);
|
||||
ComputeChunkAtom *cca = (ComputeChunkAtom *) modify->compute[icompute];
|
||||
cca->compute_peratom();
|
||||
double *chunkIDs = cca->vector_atom;
|
||||
nchunk = cca->nchunk;
|
||||
|
@ -193,22 +253,4 @@ void ResetMolIDs::command(int narg, char **arg)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
|
||||
modify->delete_compute(idfrag);
|
||||
if (compressflag) modify->delete_compute(idchunk);
|
||||
|
||||
// total time
|
||||
|
||||
MPI_Barrier(world);
|
||||
|
||||
if (comm->me == 0) {
|
||||
if (nchunk < 0)
|
||||
utils::logmesg(lmp,fmt::format(" number of new molecule IDs = unknown\n"));
|
||||
else
|
||||
utils::logmesg(lmp,fmt::format(" number of new molecule IDs = {}\n",nchunk));
|
||||
utils::logmesg(lmp,fmt::format(" reset_mol_ids CPU = {:.3f} seconds\n",
|
||||
MPI_Wtime()-time1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,28 @@ CommandStyle(reset_mol_ids,ResetMolIDs)
|
|||
#define LMP_RESET_MOL_IDS_H
|
||||
|
||||
#include "pointers.h"
|
||||
#include <string>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class ResetMolIDs : protected Pointers {
|
||||
public:
|
||||
ResetMolIDs(class LAMMPS *);
|
||||
~ResetMolIDs();
|
||||
void command(int, char **);
|
||||
void create_computes(char *, char *);
|
||||
void reset();
|
||||
|
||||
private:
|
||||
std::string idfrag, idchunk;
|
||||
int nchunk;
|
||||
int groupbit;
|
||||
int compressflag; // 1 = contiguous values for new IDs
|
||||
int singleflag; // 0 = mol IDs of single atoms set to 0
|
||||
tagint offset; // offset for contiguous mol ID values
|
||||
|
||||
class ComputeFragmentAtom *cfa;
|
||||
class ComputeChunkAtom *cca;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -352,7 +352,7 @@ tagint utils::tnumeric(const char *file, int line, const char *str,
|
|||
Return string without leading or trailing whitespace
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::trim(const std::string & line) {
|
||||
std::string utils::trim(const std::string &line) {
|
||||
int beg = re_match(line.c_str(),"\\S+");
|
||||
int end = re_match(line.c_str(),"\\s+$");
|
||||
if (beg < 0) beg = 0;
|
||||
|
@ -365,7 +365,7 @@ std::string utils::trim(const std::string & line) {
|
|||
Return string without trailing # comment
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::trim_comment(const std::string & line) {
|
||||
std::string utils::trim_comment(const std::string &line) {
|
||||
auto end = line.find_first_of("#");
|
||||
if (end != std::string::npos) {
|
||||
return line.substr(0, end);
|
||||
|
@ -377,7 +377,7 @@ std::string utils::trim_comment(const std::string & line) {
|
|||
return number of words
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
size_t utils::count_words(const char * text) {
|
||||
size_t utils::count_words(const char *text) {
|
||||
size_t count = 0;
|
||||
const char * buf = text;
|
||||
char c = *buf;
|
||||
|
@ -406,7 +406,7 @@ size_t utils::count_words(const char * text) {
|
|||
return number of words
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
size_t utils::count_words(const std::string & text) {
|
||||
size_t utils::count_words(const std::string &text) {
|
||||
return utils::count_words(text.c_str());
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ size_t utils::count_words(const std::string & text) {
|
|||
Return number of words
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
size_t utils::count_words(const std::string & text, const std::string & separators) {
|
||||
size_t utils::count_words(const std::string &text, const std::string &separators) {
|
||||
size_t count = 0;
|
||||
size_t start = text.find_first_not_of(separators);
|
||||
|
||||
|
@ -435,7 +435,7 @@ size_t utils::count_words(const std::string & text, const std::string & separato
|
|||
Trim comment from string and return number of words
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
size_t utils::trim_and_count_words(const std::string & text, const std::string & separators) {
|
||||
size_t utils::trim_and_count_words(const std::string &text, const std::string &separators) {
|
||||
return utils::count_words(utils::trim_comment(text), separators);
|
||||
}
|
||||
|
||||
|
@ -526,7 +526,7 @@ std::vector<std::string> utils::split_words(const std::string &text)
|
|||
Return whether string is a valid integer number
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
bool utils::is_integer(const std::string & str) {
|
||||
bool utils::is_integer(const std::string &str) {
|
||||
if (str.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ bool utils::is_integer(const std::string & str) {
|
|||
Return whether string is a valid floating-point number
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
bool utils::is_double(const std::string & str) {
|
||||
bool utils::is_double(const std::string &str) {
|
||||
if (str.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -560,7 +560,7 @@ bool utils::is_double(const std::string & str) {
|
|||
strip off leading part of path, return just the filename
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::path_basename(const std::string & path) {
|
||||
std::string utils::path_basename(const std::string &path) {
|
||||
#if defined(_WIN32)
|
||||
size_t start = path.find_last_of("/\\");
|
||||
#else
|
||||
|
@ -580,7 +580,7 @@ std::string utils::path_basename(const std::string & path) {
|
|||
join two paths
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::path_join(const std::string & a, const std::string & b) {
|
||||
std::string utils::path_join(const std::string &a, const std::string &b) {
|
||||
#if defined(_WIN32)
|
||||
return fmt::format("{}\\{}", a, b);
|
||||
#else
|
||||
|
@ -592,7 +592,7 @@ std::string utils::path_join(const std::string & a, const std::string & b) {
|
|||
try to open file for reading
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
bool utils::file_is_readable(const std::string & path) {
|
||||
bool utils::file_is_readable(const std::string &path) {
|
||||
FILE * fp = fopen(path.c_str(), "r");
|
||||
if(fp) {
|
||||
fclose(fp);
|
||||
|
@ -607,7 +607,7 @@ bool utils::file_is_readable(const std::string & path) {
|
|||
specified
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::get_potential_file_path(const std::string& path) {
|
||||
std::string utils::get_potential_file_path(const std::string &path) {
|
||||
std::string filepath = path;
|
||||
std::string filename = utils::path_basename(path);
|
||||
|
||||
|
@ -634,7 +634,7 @@ std::string utils::get_potential_file_path(const std::string& path) {
|
|||
if it has a DATE field, return the following word
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::get_potential_date(const std::string & path, const std::string & potential_name) {
|
||||
std::string utils::get_potential_date(const std::string &path, const std::string &potential_name) {
|
||||
TextFileReader reader(path, potential_name);
|
||||
reader.ignore_comments = false;
|
||||
|
||||
|
@ -657,7 +657,7 @@ std::string utils::get_potential_date(const std::string & path, const std::strin
|
|||
if it has UNITS field, return following word
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string utils::get_potential_units(const std::string & path, const std::string & potential_name) {
|
||||
std::string utils::get_potential_units(const std::string &path, const std::string &potential_name) {
|
||||
TextFileReader reader(path, potential_name);
|
||||
reader.ignore_comments = false;
|
||||
|
||||
|
@ -710,7 +710,7 @@ double utils::get_conversion_factor(const int property, const int conversion)
|
|||
the strings "off" and "unlimited" result in -1.0;
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double utils::timespec2seconds(const std::string & timespec)
|
||||
double utils::timespec2seconds(const std::string ×pec)
|
||||
{
|
||||
double vals[3];
|
||||
int i = 0;
|
||||
|
@ -728,7 +728,7 @@ double utils::timespec2seconds(const std::string & timespec)
|
|||
if (!values.has_next()) break;
|
||||
vals[i] = values.next_int();
|
||||
}
|
||||
} catch (TokenizerException & e) {
|
||||
} catch (TokenizerException &e) {
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
|
|
130
src/utils.h
130
src/utils.h
|
@ -29,7 +29,7 @@ namespace LAMMPS_NS {
|
|||
|
||||
namespace utils {
|
||||
|
||||
/** \brief Match text against a simplified regex pattern
|
||||
/** Match text against a simplified regex pattern
|
||||
*
|
||||
* \param text the text to be matched against the pattern
|
||||
* \param pattern the search pattern, which may contain regexp markers
|
||||
|
@ -37,14 +37,14 @@ namespace LAMMPS_NS {
|
|||
*/
|
||||
bool strmatch(const std::string &text, const std::string &pattern);
|
||||
|
||||
/** \brief Send message to screen and logfile, if available
|
||||
/** Send message to screen and logfile, if available
|
||||
*
|
||||
* \param lmp pointer to LAMMPS class instance
|
||||
* \param mesg message to be printed
|
||||
*/
|
||||
void logmesg(LAMMPS *lmp, const std::string &mesg);
|
||||
|
||||
/** \brief return a string representing the current system error status
|
||||
/** return a string representing the current system error status
|
||||
*
|
||||
* This is a wrapper around calling strerror(errno).
|
||||
*
|
||||
|
@ -52,7 +52,7 @@ namespace LAMMPS_NS {
|
|||
*/
|
||||
std::string getsyserror();
|
||||
|
||||
/** \brief safe wrapper around fgets() which aborts on errors
|
||||
/** safe wrapper around fgets() which aborts on errors
|
||||
* or EOF and prints a suitable error message to help debugging
|
||||
*
|
||||
* \param srcname name of the calling source file (from FLERR macro)
|
||||
|
@ -66,7 +66,7 @@ namespace LAMMPS_NS {
|
|||
void sfgets(const char *srcname, int srcline, char *s, int size,
|
||||
FILE *fp, const char *filename, Error *error);
|
||||
|
||||
/** \brief safe wrapper around fread() which aborts on errors
|
||||
/** safe wrapper around fread() which aborts on errors
|
||||
* or EOF and prints a suitable error message to help debugging
|
||||
*
|
||||
* \param srcname name of the calling source file (from FLERR macro)
|
||||
|
@ -81,7 +81,7 @@ namespace LAMMPS_NS {
|
|||
void sfread(const char *srcname, int srcline, void *s, size_t size,
|
||||
size_t num, FILE *fp, const char *filename, Error *error);
|
||||
|
||||
/** \brief Report if a requested style is in a package or may have a typo
|
||||
/** Report if a requested style is in a package or may have a typo
|
||||
*
|
||||
* \param style type of style that is to be checked for
|
||||
* \param name name of style that was not found
|
||||
|
@ -91,8 +91,8 @@ namespace LAMMPS_NS {
|
|||
std::string check_packages_for_style(const std::string &style,
|
||||
const std::string &name, LAMMPS *lmp);
|
||||
|
||||
/** \brief Convert a string to a floating point number while checking
|
||||
if it is a valid floating point or integer number
|
||||
/** Convert a string to a floating point number while checking
|
||||
* if it is a valid floating point or integer number
|
||||
*
|
||||
* \param file name of source file for error message
|
||||
* \param line in source file for error message
|
||||
|
@ -104,8 +104,8 @@ namespace LAMMPS_NS {
|
|||
double numeric(const char *file, int line, const char *str,
|
||||
bool do_abort, LAMMPS *lmp);
|
||||
|
||||
/** \brief Convert a string to an integer number while checking
|
||||
if it is a valid integer number (regular int)
|
||||
/** Convert a string to an integer number while checking
|
||||
* if it is a valid integer number (regular int)
|
||||
*
|
||||
* \param file name of source file for error message
|
||||
* \param line in source file for error message
|
||||
|
@ -117,8 +117,8 @@ namespace LAMMPS_NS {
|
|||
int inumeric(const char *file, int line, const char *str,
|
||||
bool do_abort, LAMMPS *lmp);
|
||||
|
||||
/** \brief Convert a string to an integer number while checking
|
||||
if it is a valid integer number (bigint)
|
||||
/** Convert a string to an integer number while checking
|
||||
* if it is a valid integer number (bigint)
|
||||
*
|
||||
* \param file name of source file for error message
|
||||
* \param line in source file for error message
|
||||
|
@ -130,8 +130,8 @@ namespace LAMMPS_NS {
|
|||
bigint bnumeric(const char *file, int line, const char *str,
|
||||
bool do_abort, LAMMPS *lmp);
|
||||
|
||||
/** \brief Convert a string to an integer number while checking
|
||||
if it is a valid integer number (tagint)
|
||||
/** Convert a string to an integer number while checking
|
||||
* if it is a valid integer number (tagint)
|
||||
*
|
||||
* \param file name of source file for error message
|
||||
* \param line in source file for error message
|
||||
|
@ -143,54 +143,51 @@ namespace LAMMPS_NS {
|
|||
tagint tnumeric(const char *file, int line, const char *str,
|
||||
bool do_abort, LAMMPS *lmp);
|
||||
|
||||
/**
|
||||
* \brief Trim leading and trailing whitespace. Like TRIM() in Fortran.
|
||||
/** Trim leading and trailing whitespace. Like TRIM() in Fortran.
|
||||
*
|
||||
* \param line string that should be trimmed
|
||||
* \return new string without whitespace (string)
|
||||
*/
|
||||
std::string trim(const std::string &line);
|
||||
|
||||
/**
|
||||
* \brief Trim anything from '#' onward
|
||||
/** Trim anything from '#' onward
|
||||
*
|
||||
* \param line string that should be trimmed
|
||||
* \return new string without comment (string)
|
||||
*/
|
||||
std::string trim_comment(const std::string &line);
|
||||
|
||||
/**
|
||||
* \brief Count words in string
|
||||
/** Count words in string
|
||||
*
|
||||
* \param text string that should be searched
|
||||
* \param separators string containing characters that will be treated as whitespace
|
||||
* \return number of words found
|
||||
*/
|
||||
size_t count_words(const std::string & text, const std::string & separators);
|
||||
size_t count_words(const std::string &text, const std::string &separators);
|
||||
|
||||
/**
|
||||
* \brief Count words in string, ignore any whitespace matching " \t\r\n\f"
|
||||
/** Count words in string, ignore any whitespace matching " \t\r\n\f"
|
||||
*
|
||||
* \param text string that should be searched
|
||||
* \param separators string containing characters that will be treated as whitespace
|
||||
* \return number of words found
|
||||
*/
|
||||
size_t count_words(const std::string & text);
|
||||
size_t count_words(const std::string &text);
|
||||
|
||||
/**
|
||||
* \brief Count words in C-string, ignore any whitespace matching " \t\r\n\f"
|
||||
/** Count words in C-string, ignore any whitespace matching " \t\r\n\f"
|
||||
*
|
||||
* \param text string that should be searched
|
||||
* \param separators string containing characters that will be treated as whitespace
|
||||
* \return number of words found
|
||||
*/
|
||||
size_t count_words(const char * text);
|
||||
size_t count_words(const char *text);
|
||||
|
||||
/**
|
||||
* \brief Count words in a single line, trim anything from '#' onward
|
||||
/** Count words in a single line, trim anything from '#' onward
|
||||
*
|
||||
* \param text string that should be trimmed and searched
|
||||
* \param separators string containing characters that will be treated as whitespace
|
||||
* \return number of words found
|
||||
*/
|
||||
size_t trim_and_count_words(const std::string & text, const std::string & separators = " \t\r\n\f");
|
||||
size_t trim_and_count_words(const std::string &text, const std::string &separators = " \t\r\n\f");
|
||||
|
||||
/**
|
||||
* \brief Take text and split into non-whitespace words.
|
||||
/** Take text and split into non-whitespace words.
|
||||
*
|
||||
* This can handle single and double quotes, escaped quotes,
|
||||
* and escaped codes within quotes, but due to using an STL
|
||||
|
@ -203,21 +200,21 @@ namespace LAMMPS_NS {
|
|||
*/
|
||||
std::vector<std::string> split_words(const std::string &text);
|
||||
|
||||
/**
|
||||
* \brief Check if string can be converted to valid integer
|
||||
* \param text string that should be checked
|
||||
/** Check if string can be converted to valid integer
|
||||
*
|
||||
* \param str string that should be checked
|
||||
* \return true, if string contains valid integer, false otherwise
|
||||
*/
|
||||
bool is_integer(const std::string & str);
|
||||
bool is_integer(const std::string &str);
|
||||
|
||||
/**
|
||||
* \brief Check if string can be converted to valid floating-point number
|
||||
* \param text string that should be checked
|
||||
/** Check if string can be converted to valid floating-point number
|
||||
*
|
||||
* \param str string that should be checked
|
||||
* \return true, if string contains valid floating-point number, false otherwise
|
||||
*/
|
||||
bool is_double(const std::string & str);
|
||||
bool is_double(const std::string &str);
|
||||
|
||||
/** \brief try to detect pathname from FILE pointer.
|
||||
/** Try to detect pathname from FILE pointer.
|
||||
*
|
||||
* Currently only supported on Linux, otherwise will report "(unknown)".
|
||||
*
|
||||
|
@ -228,12 +225,12 @@ namespace LAMMPS_NS {
|
|||
*/
|
||||
const char *guesspath(char *buf, int len, FILE *fp);
|
||||
|
||||
/**
|
||||
* \brief Strip off leading part of path, return just the filename
|
||||
/** Strip off leading part of path, return just the filename
|
||||
*
|
||||
* \param path file path
|
||||
* \return file name
|
||||
*/
|
||||
std::string path_basename(const std::string & path);
|
||||
std::string path_basename(const std::string &path);
|
||||
|
||||
/**
|
||||
* \brief Join two paths
|
||||
|
@ -241,64 +238,65 @@ namespace LAMMPS_NS {
|
|||
* \param b second path
|
||||
* \return combined path
|
||||
*/
|
||||
std::string path_join(const std::string & a, const std::string & b);
|
||||
std::string path_join(const std::string &a, const std::string &b);
|
||||
|
||||
/**
|
||||
* \brief Check if file exists and is readable
|
||||
* \param path file path
|
||||
* \return true if file exists and is readable
|
||||
*/
|
||||
bool file_is_readable(const std::string & path);
|
||||
bool file_is_readable(const std::string &path);
|
||||
|
||||
/**
|
||||
* \brief Determine full path of potential file
|
||||
* If file is not found in current directory, search LAMMPS_POTENTIALS folder
|
||||
/** Determine full path of potential file. If file is not found in current directory,
|
||||
* search LAMMPS_POTENTIALS folder
|
||||
*
|
||||
* \param path file path
|
||||
* \return full path to potential file
|
||||
*/
|
||||
std::string get_potential_file_path(const std::string& path);
|
||||
std::string get_potential_file_path(const std::string &path);
|
||||
|
||||
/**
|
||||
* \brief Read potential file and return DATE field if it is present
|
||||
/** Read potential file and return DATE field if it is present
|
||||
*
|
||||
* \param path file path
|
||||
* \param potential_name name of potential that is being read
|
||||
* \return DATE field if present
|
||||
*/
|
||||
std::string get_potential_date(const std::string & path, const std::string & potential_name);
|
||||
std::string get_potential_date(const std::string &path, const std::string &potential_name);
|
||||
|
||||
/**
|
||||
* \brief Read potential file and return UNITS field if it is present
|
||||
/** Read potential file and return UNITS field if it is present
|
||||
*
|
||||
* \param path file path
|
||||
* \param potential_name name of potential that is being read
|
||||
* \return UNITS field if present
|
||||
*/
|
||||
std::string get_potential_units(const std::string & path, const std::string & potential_name);
|
||||
std::string get_potential_units(const std::string &path, const std::string &potential_name);
|
||||
|
||||
enum { NOCONVERT = 0, METAL2REAL = 1, REAL2METAL = 1<<1 };
|
||||
enum { UNKNOWN = 0, ENERGY };
|
||||
|
||||
/**
|
||||
* \brief Return bitmask of available conversion factors for a given propert
|
||||
/** Return bitmask of available conversion factors for a given property
|
||||
*
|
||||
* \param property property to be converted
|
||||
* \return bitmask indicating available conversions
|
||||
*/
|
||||
int get_supported_conversions(const int property);
|
||||
|
||||
/**
|
||||
* \brief Return unit conversion factor for given property and selected from/to units
|
||||
/** Return unit conversion factor for given property and selected from/to units
|
||||
*
|
||||
* \param property property to be converted
|
||||
* \param conversion constant indicating the conversion
|
||||
* \return conversion factor
|
||||
*/
|
||||
double get_conversion_factor(const int property, const int conversion);
|
||||
|
||||
/**
|
||||
* \brief Convert a time string to seconds
|
||||
* The strings "off" and "unlimited" result in -1
|
||||
/** Convert a time string to seconds
|
||||
*
|
||||
* The strings "off" and "unlimited" result in -1
|
||||
*
|
||||
* \param timespec a string in the following format: ([[HH:]MM:]SS)
|
||||
* \return total in seconds
|
||||
*/
|
||||
double timespec2seconds(const std::string & timespec);
|
||||
double timespec2seconds(const std::string ×pec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
lammps_version: 21 Aug 2020
|
||||
date_generated: Sun Aug 23 06:35:54 202
|
||||
epsilon: 5e-12
|
||||
epsilon: 7.5e-12
|
||||
prerequisites: ! |
|
||||
pair reax/c
|
||||
fix qeq/reax
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
lammps_version: 21 Aug 2020
|
||||
date_generated: Sun Aug 23 06:41:04 202
|
||||
epsilon: 5e-11
|
||||
epsilon: 1e-10
|
||||
prerequisites: ! |
|
||||
pair reax/c
|
||||
fix qeq/reax
|
||||
|
|
Loading…
Reference in New Issue