enable per-atom custom arrays in addition to vectors
This commit is contained in:
@ -465,12 +465,18 @@ atom-style variables can reference the position of a particle, its
|
||||
velocity, the volume of its Voronoi cell, etc.
|
||||
|
||||
The *store* weight style does not compute a weight factor. Instead it
|
||||
stores the current accumulated weights in a custom per-atom property
|
||||
specified by *name*\ . This must be a property defined as *d_name* via
|
||||
the :doc:`fix property/atom <fix_property_atom>` command. Note that
|
||||
these custom per-atom properties can be output in a :doc:`dump <dump>`
|
||||
file, so this is a way to examine, debug, or visualize the
|
||||
per-particle weights computed during the load-balancing operation.
|
||||
stores the current accumulated weights in a custom per-atom vector
|
||||
specified by *name*\ . This must be a vector defined as *d_name* via
|
||||
the :doc:`fix property/atom <fix_property_atom>` command. This means
|
||||
the values in the vector can be read as part of a data file with the
|
||||
:doc:`read_data <read_data>` command or specified with the :doc:`set
|
||||
<set>` command. These weights can also be output in a :doc:`dump
|
||||
<dump>` file, so this is a way to examine, debug, or visualize the
|
||||
per-particle weights used during the load-balancing operation.
|
||||
|
||||
Note that the name of the custom per-atom vector is specified just
|
||||
as *name*, not as *d_name* as it is for other commands that use
|
||||
different kinds of custom atom vectors or arrays as arguments.
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -20,7 +20,8 @@ Syntax
|
||||
x, y, z, xs, ys, zs, xu, yu, zu, ix, iy, iz,
|
||||
vx, vy, vz, fx, fy, fz,
|
||||
q, mux, muy, muz, mu,
|
||||
sp, spx, spy, spz, fmx, fmy, fmz,
|
||||
spx, spy, spz, sp, fmx, fmy, fmz,
|
||||
nbonds,
|
||||
radius, diameter, omegax, omegay, omegaz,
|
||||
angmomx, angmomy, angmomz,
|
||||
shapex,shapey, shapez,
|
||||
@ -29,42 +30,42 @@ Syntax
|
||||
corner1x, corner1y, corner1z,
|
||||
corner2x, corner2y, corner2z,
|
||||
corner3x, corner3y, corner3z,
|
||||
nbonds,
|
||||
buckling,
|
||||
vfrac, s0,
|
||||
spin, eradius, ervel, erforce,
|
||||
rho, drho, e, de, cv,
|
||||
i_name, d_name
|
||||
i_name, d_name, i2_name[I], d2_name[I],
|
||||
vfrac, s0, spin, eradius, ervel, erforce,
|
||||
rho, drho, e, de, cv, buckling
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
id = atom ID
|
||||
mol = molecule ID
|
||||
proc = ID of processor that owns atom
|
||||
type = atom type
|
||||
mass = atom mass
|
||||
x,y,z = unscaled atom coordinates
|
||||
xs,ys,zs = scaled atom coordinates
|
||||
xu,yu,zu = unwrapped atom coordinates
|
||||
ix,iy,iz = box image that the atom is in
|
||||
vx,vy,vz = atom velocities
|
||||
fx,fy,fz = forces on atoms
|
||||
q = atom charge
|
||||
mux,muy,muz = orientation of dipole moment of atom
|
||||
mu = magnitude of dipole moment of atom
|
||||
sp = atomic magnetic spin moment
|
||||
spx, spy, spz = direction of the atomic magnetic spin
|
||||
fmx, fmy, fmz = magnetic force
|
||||
radius,diameter = radius,diameter of spherical particle
|
||||
omegax,omegay,omegaz = angular velocity of spherical particle
|
||||
angmomx,angmomy,angmomz = angular momentum of aspherical particle
|
||||
shapex,shapey,shapez = 3 diameters of aspherical particle
|
||||
quatw,quati,quatj,quatk = quaternion components for aspherical or body particles
|
||||
tqx,tqy,tqz = torque on finite-size particles
|
||||
end12x, end12y, end12z = end points of line segment
|
||||
corner123x, corner123y, corner123z = corner points of triangle
|
||||
nbonds = number of bonds assigned to an atom
|
||||
buckling = buckling flag used in mesoscopic simulation of nanotubes
|
||||
*id* = atom ID
|
||||
*mol* = molecule ID
|
||||
*proc* = ID of processor that owns atom
|
||||
*type* = atom type
|
||||
*mass* = atom mass
|
||||
*x,y,z* = unscaled atom coordinates
|
||||
*xs,ys,zs* = scaled atom coordinates
|
||||
*xu,yu,zu* = unwrapped atom coordinates
|
||||
*ix,iy,iz* = box image that the atom is in
|
||||
*vx,vy,vz* = atom velocities
|
||||
*fx,fy,fz* = forces on atoms
|
||||
*q* = atom charge
|
||||
*mux,muy,muz* = orientation of dipole moment of atom
|
||||
*mu* = magnitude of dipole moment of atom
|
||||
*spx, spy, spz* = direction of the atomic magnetic spin
|
||||
*sp* = magintude of atomic magnetic spin moment
|
||||
*fmx, fmy, fmz* = magnetic force
|
||||
*nbonds* = number of bonds assigned to an atom
|
||||
*radius,diameter* = radius,diameter of spherical particle
|
||||
*omegax,omegay,omegaz* = angular velocity of spherical particle
|
||||
*angmomx,angmomy,angmomz* = angular momentum of aspherical particle
|
||||
*shapex,shapey,shapez* = 3 diameters of aspherical particle
|
||||
*quatw,quati,quatj,quatk* = quaternion components for aspherical or body particles
|
||||
*tqx,tqy,tqz* = torque on finite-size particles
|
||||
*end12x, end12y, end12z* = end points of line segment
|
||||
*corner123x, corner123y, corner123z* = corner points of triangle
|
||||
*i_name* = custom integer vector with name
|
||||
*d_name* = custom floating point vector with name
|
||||
*i2_name[I]* = Ith column of custom integer array with name
|
||||
*d2_name[I]* = Ith column of custom floating-point array with name
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -91,9 +92,8 @@ Syntax
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
:doc:`fix property/atom <fix_property_atom>` per-atom properties:
|
||||
i_name = custom integer vector with name
|
||||
d_name = custom integer vector with name
|
||||
USER-MESONT package per-atom properties:
|
||||
buckling = buckling flag used in mesoscopic simulation of nanotubes
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
@ -104,6 +104,7 @@ Examples
|
||||
compute 2 all property/atom type
|
||||
compute 1 all property/atom ix iy iz
|
||||
compute 3 all property/atom sp spx spy spz
|
||||
compute 1 all property/atom i_myFlag d_Sxyz[1] d_Sxyz[3]
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
@ -116,20 +117,37 @@ 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.
|
||||
|
||||
The list of possible attributes is the same as that used by the
|
||||
:doc:`dump custom <dump>` command, which describes their meaning, with
|
||||
some additional quantities that are only defined for certain
|
||||
:doc:`atom styles <atom_style>`. Basically, this augmented list gives
|
||||
an input script access to any per-atom quantity stored by LAMMPS.
|
||||
The list of possible attributes is essentially the same as that used
|
||||
by the :doc:`dump custom <dump>` command, which describes their
|
||||
meaning, with some additional quantities that are only defined for
|
||||
certain :doc:`atom styles <atom_style>`. The goal of this augmented
|
||||
list gives an input script access to any per-atom quantity stored by
|
||||
LAMMPS.
|
||||
|
||||
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
|
||||
(e.g. *shapex* if the particle is not an ellipsoid).
|
||||
|
||||
Attributes *i_name*, *d_name*, *i2_name*, *d2_name* refer to custom
|
||||
per-atom integer and floating-point vectors or arrays that have been
|
||||
added via the :doc:`fix property/atom <fix_property_atom>` command.
|
||||
When that command is used specific names are given to each attribute
|
||||
which are the "name" portion of these attributes. For arrays *i2_name*
|
||||
and *d2_name*, the column of the array must also be included following
|
||||
the name in brackets: e.g. d2_xyz[2], i2_mySpin[3].
|
||||
|
||||
The additional quantities only accessible via this command, and not
|
||||
directly via the :doc:`dump custom <dump>` command, are as follows.
|
||||
|
||||
*Nbonds* is available for all molecular atom styles and refers to the
|
||||
number of explicit bonds assigned to an atom. Note that if the
|
||||
:doc:`newton bond <newton>` command is set to *on*\ , which is the
|
||||
default, then every bond in the system is assigned to only one of the
|
||||
two atoms in the bond. Thus a bond between atoms I,J may be tallied
|
||||
for either atom I or atom J. If :doc:`newton bond off <newton>` is
|
||||
set, it will be tallied with both atom I and atom J.
|
||||
|
||||
*Shapex*\ , *shapey*\ , and *shapez* are defined for ellipsoidal particles
|
||||
and define the 3d shape of each particle.
|
||||
|
||||
@ -146,19 +164,8 @@ line segment.
|
||||
*corner2z*\ , *corner3x*\ , *corner3y*\ , *corner3z*\ , are defined for
|
||||
triangular particles and define the corner points of each triangle.
|
||||
|
||||
*Nbonds* is available for all molecular atom styles and refers to the
|
||||
number of explicit bonds assigned to an atom. Note that if the
|
||||
:doc:`newton bond <newton>` command is set to *on*\ , which is the
|
||||
default, then every bond in the system is assigned to only one of the
|
||||
two atoms in the bond. Thus a bond between atoms I,J may be tallied
|
||||
for either atom I or atom J. If :doc:`newton bond off <newton>` is
|
||||
set, it will be tallied with both atom I and atom J.
|
||||
|
||||
The *i_name* and *d_name* attributes refer to custom integer and
|
||||
floating-point properties that have been added to each atom via the
|
||||
:doc:`fix property/atom <fix_property_atom>` command. When that
|
||||
command is used specific names are given to each attribute which are
|
||||
what is specified as the "name" portion of *i_name* or *d_name*.
|
||||
In addition, the various per-atom quantities listed above for specific
|
||||
packages are only accessible by this command.
|
||||
|
||||
Output info
|
||||
"""""""""""
|
||||
|
||||
@ -78,7 +78,8 @@ Syntax
|
||||
q, mux, muy, muz, mu,
|
||||
radius, diameter, omegax, omegay, omegaz,
|
||||
angmomx, angmomy, angmomz, tqx, tqy, tqz,
|
||||
c_ID, c_ID[N], f_ID, f_ID[N], v_name
|
||||
c_ID, c_ID[I], f_ID, f_ID[I], v_name,
|
||||
i_name, d_name, i2_name[I], d2_name[I]
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -108,8 +109,10 @@ Syntax
|
||||
f_ID = per-atom vector calculated by a fix with ID
|
||||
f_ID[I] = Ith column of per-atom array calculated by a fix with ID, I can include wildcard (see below)
|
||||
v_name = per-atom vector calculated by an atom-style variable with name
|
||||
d_name = per-atom floating point vector with name, managed by fix property/atom
|
||||
i_name = per-atom integer vector with name, managed by fix property/atom
|
||||
i_name = custom integer vector with name
|
||||
d_name = custom floating point vector with name
|
||||
i2_name[I] = Ith column of custom integer array with name, I can include wildcard (see below)
|
||||
d2_name[I] = Ith column of custom floating point vector with name, I can include wildcard (see below)
|
||||
|
||||
* *local* args = list of local attributes
|
||||
|
||||
@ -134,7 +137,7 @@ Examples
|
||||
dump 2 subgroup atom 50 dump.run.mpiio.bin
|
||||
dump 4a all custom 100 dump.myforce.* id type x y vx fx
|
||||
dump 4b flow custom 100 dump.%.myforce id type c_myF[3] v_ke
|
||||
dump 4b flow custom 100 dump.%.myforce id type c_myF[\*] v_ke
|
||||
dump 4b flow custom 100 dump.%.myforce id type c_myF[*] v_ke
|
||||
dump 2 inner cfg 10 dump.snap.*.cfg mass type xs ys zs vx vy vz
|
||||
dump snap all cfg 100 dump.config.*.cfg mass type xs ys zs id type c_Stress[2]
|
||||
dump 1 all xtc 1000 file.xtc
|
||||
@ -465,16 +468,15 @@ styles.
|
||||
----------
|
||||
|
||||
Note that in the discussion which follows, for styles which can
|
||||
reference values from a compute or fix, like the *custom*\ , *cfg*\ , or
|
||||
*local* styles, the bracketed index I can be specified using a
|
||||
wildcard asterisk with the index to effectively specify multiple
|
||||
values. This takes the form "\*" or "\*n" or "n\*" or "m\*n". If N = the
|
||||
size of the vector (for *mode* = scalar) or the number of columns in
|
||||
the array (for *mode* = vector), then an asterisk with no numeric
|
||||
values means all indices from 1 to N. A leading asterisk means all
|
||||
indices from 1 to n (inclusive). A trailing asterisk means all
|
||||
indices from n to N (inclusive). A middle asterisk means all indices
|
||||
from m to n (inclusive).
|
||||
reference values from a compute or fix or custom atom property, like
|
||||
the *custom*\ , *cfg*\ , or *local* styles, the bracketed index I can
|
||||
be specified using a wildcard asterisk with the index to effectively
|
||||
specify multiple values. This takes the form "\*" or "\*n" or "n\*"
|
||||
or "m\*n". If N = the number of columns in the array, then an
|
||||
asterisk with no numeric values means all column indices from 1 to N.
|
||||
A leading asterisk means all indices from 1 to n (inclusive). A
|
||||
trailing asterisk means all indices from n to N (inclusive). A middle
|
||||
asterisk means all indices from m to n (inclusive).
|
||||
|
||||
Using a wildcard is the same as if the individual columns of the array
|
||||
had been listed one by one. E.g. these 2 dump commands are
|
||||
@ -512,8 +514,9 @@ bonds and angles.
|
||||
|
||||
Note that computes which calculate global or per-atom quantities, as
|
||||
opposed to local quantities, cannot be output in a dump local command.
|
||||
Instead, global quantities can be output by the :doc:`thermo_style custom <thermo_style>` command, and per-atom quantities can be
|
||||
output by the dump custom command.
|
||||
Instead, global quantities can be output by the :doc:`thermo_style
|
||||
custom <thermo_style>` command, and per-atom quantities can be output
|
||||
by the dump custom command.
|
||||
|
||||
If *c_ID* is used as a attribute, then the local vector calculated by
|
||||
the compute is printed. If *c_ID[I]* is used, then I must be in the
|
||||
@ -660,9 +663,13 @@ invoke other computes, fixes, or variables when they are evaluated, so
|
||||
this is a very general means of creating quantities to output to a
|
||||
dump file.
|
||||
|
||||
The *d_name* and *i_name* attributes allow to output custom per atom
|
||||
floating point or integer properties that are managed by
|
||||
:doc:`fix property/atom <fix_property_atom>`.
|
||||
The *i_name*, *d_name*, *i2_name*, *d2_name* attributes refer to
|
||||
per-atom integer and floating-point vectors or arrays that have been
|
||||
added via the :doc:`fix property/atom <fix_property_atom>` command.
|
||||
When that command is used specific names are given to each attribute
|
||||
which are the "name" portion of these keywords. For arrays *i2_name*
|
||||
and *d2_name*, the column of the array must also be included following
|
||||
the name in brackets: e.g. d2_xyz[2], i2_mySpin[3].
|
||||
|
||||
See the :doc:`Modify <Modify>` doc page for information on how to add
|
||||
new compute and fix styles to LAMMPS to calculate per-atom quantities
|
||||
|
||||
@ -11,11 +11,11 @@ Syntax
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
fix ID group-ID property/atom vec1 vec2 ... keyword value ...
|
||||
fix ID group-ID property/atom name1 name2 ... keyword value ...
|
||||
|
||||
* ID, group-ID are documented in :doc:`fix <fix>` command
|
||||
* property/atom = style name of this fix command
|
||||
* vec1,vec2,... = *mol* or *q* or *rmass* or *i_name* or *d_name*
|
||||
* name1,name2,... = *mol* or *q* or *rmass* or *i_name* or *d_name* or *i2_name* or *d2_name*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -24,6 +24,10 @@ Syntax
|
||||
*rmass* = per-atom mass
|
||||
*i_name* = new integer vector referenced by name
|
||||
*d_name* = new floating-point vector referenced by name
|
||||
*i2_name* = new integer array referenced by name
|
||||
i2_name arg = N = number of columns in the array
|
||||
*d2_name* = new floating-point array referenced by name
|
||||
d2_name arg = N = number of columns in the array
|
||||
|
||||
* zero of more keyword/value pairs may be appended
|
||||
* keyword = *ghost*
|
||||
@ -39,58 +43,64 @@ Examples
|
||||
|
||||
fix 1 all property/atom mol
|
||||
fix 1 all property/atom i_myflag1 i_myflag2
|
||||
fix 1 all property/atom d_sx d_sy d_sz
|
||||
fix 1 all property/atom d2_sxyz 3 ghost yes
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
|
||||
Create one or more additional per-atom vectors to store information
|
||||
about atoms and to use during a simulation. The specified *group-ID*
|
||||
is ignored by this fix.
|
||||
Create one or more additional per-atom vectors or arrays to store
|
||||
information about atoms and to use during a simulation. The specified
|
||||
*group-ID* is ignored by this fix.
|
||||
|
||||
The atom style used for a simulation defines a set of per-atom
|
||||
properties, as explained on the :doc:`atom_style <atom_style>` and
|
||||
:doc:`read_data <read_data>` doc pages. The latter command allows these
|
||||
properties to be defined for each atom in the system when a data file
|
||||
is read. This fix will augment the set of properties with new custom
|
||||
:doc:`read_data <read_data>` doc pages. The latter command defines
|
||||
these properties for each atom in the system when a data file is read.
|
||||
This fix augments the set of per-atom properties with new custom
|
||||
ones. This can be useful in several scenarios.
|
||||
|
||||
If the atom style does not define molecule IDs, per-atom charge,
|
||||
or per-atom mass, they can be added using the *mol*\ , *q* or *rmass*
|
||||
keywords. This can be useful, e.g, to define "molecules" to use as
|
||||
rigid bodies with the :doc:`fix rigid <fix_rigid>` command, or just to
|
||||
carry around an extra flag with the atoms (stored as a molecule ID)
|
||||
that can be used to group atoms without having to use the group
|
||||
If the atom style does not define molecule IDs, per-atom charge, or
|
||||
per-atom mass, they can be added using the *mol*\ , *q* or *rmass*
|
||||
keywords. This ciykd be useful to define "molecules" to use as rigid
|
||||
bodies with the :doc:`fix rigid <fix_rigid>` command, or to carry
|
||||
around an extra flag with atoms (stored as a molecule ID) that can be
|
||||
used by various commands like :doc:`compute chunk/atom
|
||||
<compute_chunk_atom>` to group atoms without having to use the group
|
||||
command (which is limited to a total of 32 groups including *all*\ ).
|
||||
|
||||
Another application would be to use the *rmass* flag in order to have
|
||||
per-atom masses instead of per-type masses, for example this can be
|
||||
useful to study isotope effects with partial isotope substitution.
|
||||
Please :ref:`see below <isotopes>` for an example of simulating a mixture
|
||||
of light and heavy water with the TIP4P water potential.
|
||||
Another application is to use the *rmass* flag in order to have
|
||||
per-atom masses instead of per-type masses. This could be used to
|
||||
study isotope effects with partial isotope substitution. :ref:`See
|
||||
below <isotopes>` for an example of simulating a mixture of light and
|
||||
heavy water with the TIP4P water potential.
|
||||
|
||||
An alternative to using fix *property/atom* in these ways is to
|
||||
An alternative to using fix *property/atom* for these examples is to
|
||||
use an atom style that does define molecule IDs or charge or per-atom
|
||||
mass (indirectly via diameter and density) or to use a hybrid atom
|
||||
style that combines two or more atom styles
|
||||
to provide the union of all atom properties. However, this has two
|
||||
practical drawbacks: first, it typically necessitates changing the
|
||||
format of the data file, which can be tedious for large systems;
|
||||
and second, it may define additional properties that are not needed
|
||||
such as bond lists, which has some overhead when there are no bonds.
|
||||
style that combines two or more atom styles to provide the union of
|
||||
all their atom properties. However, this has two practical drawbacks:
|
||||
first, it typically necessitates changing the format of the Atoms
|
||||
section in the data file and second, it may define additional
|
||||
properties that are not needed such as bond lists, which incurs some
|
||||
overhead when there are no bonds.
|
||||
|
||||
In the future, we may add additional per-atom properties similar to
|
||||
*mol*\ , *q* or *rmass*\ , which "turn-on" specific properties defined
|
||||
by some atom styles, so they can be used by atom styles that do not
|
||||
define them.
|
||||
In the future, we may add additional existing per-atom properties to
|
||||
fix property/atom, similar to *mol*\ , *q* or *rmass*\ , which
|
||||
"turn-on" specific properties defined by some atom styles, so they can
|
||||
be easily used by atom styles that do not define them.
|
||||
|
||||
More generally, the *i_name* and *d_name* vectors allow one or more
|
||||
new custom per-atom properties to be defined. Each name must be
|
||||
unique and can use alphanumeric or underscore characters. These
|
||||
vectors can store whatever values you decide are useful in your
|
||||
simulation. As explained below there are several ways to initialize
|
||||
and access and output these values, both via input script commands and
|
||||
in new code that you add to LAMMPS.
|
||||
More generally, the *i_name* and *d_name* options allow one or more
|
||||
new custom per-atom vectors to be defined. Likewise the *i2_name* and
|
||||
*d2_name* options allow one or more custom per-atom arrays to be
|
||||
defined. The *i2_name* and *d2_name* options take an argument *N*
|
||||
which specifies the number of columns in the per-atom array, i.e. the
|
||||
number of attributes associated with each atom. *N* >= 1 is required.
|
||||
|
||||
Each name must be unique and can use alphanumeric or underscore
|
||||
characters. These vectors and arrays can store whatever values you
|
||||
decide are useful in your simulation. As explained below there are
|
||||
several ways to initialize, access, and output these values, via input
|
||||
script commands, data files, and in new code you add to LAMMPS.
|
||||
|
||||
This is effectively a simple way to add per-atom properties to a model
|
||||
without needing to write code for a new :doc:`atom style <atom_style>`
|
||||
@ -107,42 +117,38 @@ new properties are also defined for the ghost atoms.
|
||||
|
||||
.. note::
|
||||
|
||||
If you use this command with the *mol*\ , *q* or *rmass* vectors,
|
||||
then you most likely want to set *ghost* yes, since these properties
|
||||
are stored with ghost atoms if you use an :doc:`atom_style <atom_style>`
|
||||
that defines them, and many LAMMPS operations that use molecule IDs or
|
||||
charge, such as neighbor lists and pair styles, will expect ghost
|
||||
atoms to have these values. LAMMPS will issue a warning it you define
|
||||
those vectors but do not set *ghost* yes.
|
||||
If you use the *mol*\ , *q* or *rmass* names, you most likely want
|
||||
to set *ghost* yes, since these properties are stored with ghost
|
||||
atoms if you use an :doc:`atom_style <atom_style>` that defines
|
||||
them. Many LAMMPS operations that use molecule IDs or charge, such
|
||||
as neighbor lists and pair styles, will expect ghost atoms to have
|
||||
these values. LAMMPS will issue a warning it you define those
|
||||
vectors but do not set *ghost* yes.
|
||||
|
||||
.. note::
|
||||
|
||||
The properties for ghost atoms are not updated every timestep,
|
||||
but only once every few steps when neighbor lists are re-built. Thus
|
||||
the *ghost* keyword is suitable for static properties, like molecule
|
||||
IDs, but not for dynamic properties that change every step. For the
|
||||
latter, the code you add to LAMMPS to change the properties will also
|
||||
need to communicate their new values to/from ghost atoms, an operation
|
||||
that can be invoked from within a :doc:`pair style <pair_style>` or
|
||||
:doc:`fix <fix>` or :doc:`compute <compute>` that you write.
|
||||
|
||||
.. note::
|
||||
|
||||
If this fix is defined **after** the simulation box is created,
|
||||
a 'run 0' command should be issued to properly initialize the storage
|
||||
created by this fix.
|
||||
The specified properties for ghost atoms are not updated every
|
||||
timestep, but only once every few steps when neighbor lists are
|
||||
re-built. Thus the *ghost* keyword is suitable for static
|
||||
properties, like molecule IDs, but not for dynamic properties that
|
||||
change every step. For the latter, the code you add to LAMMPS to
|
||||
change the properties will also need to communicate their new
|
||||
values to/from ghost atoms, an operation that can be invoked from
|
||||
within a :doc:`pair style <pair_style>` or :doc:`fix <fix>` or
|
||||
:doc:`compute <compute>` that you write.
|
||||
|
||||
----------
|
||||
|
||||
This fix is one of a small number that can be defined in an input
|
||||
script before the simulation box is created or atoms are defined.
|
||||
This is so it can be used with the :doc:`read_data <read_data>` command
|
||||
as described below.
|
||||
This is so it can be used with the :doc:`read_data <read_data>`
|
||||
command as described next.
|
||||
|
||||
Per-atom properties that are defined by the :doc:`atom style <atom_style>` are initialized when atoms are created, e.g. by
|
||||
the :doc:`read_data <read_data>` or :doc:`create_atoms <create_atoms>`
|
||||
Per-atom properties that are defined by the :doc:`atom style
|
||||
<atom_style>` are initialized when atoms are created, e.g. by the
|
||||
:doc:`read_data <read_data>` or :doc:`create_atoms <create_atoms>`
|
||||
commands. The per-atom properties defined by this fix are not. So
|
||||
you need to initialize them explicitly. This can be done by the
|
||||
you need to initialize them explicitly. One way to do thisis
|
||||
:doc:`read_data <read_data>` command, using its *fix* keyword and
|
||||
passing it the fix-ID of this fix.
|
||||
|
||||
@ -167,15 +173,22 @@ would allow a data file to have a section like this:
|
||||
...
|
||||
N 763 4.5
|
||||
|
||||
where N is the number of atoms, and the first field on each line is
|
||||
the atom-ID, followed by a molecule-ID and a floating point value that
|
||||
will be stored in a new property called "flag". Note that the list of
|
||||
per-atom properties can be in any order.
|
||||
where N is the number of atoms, the first field on each line is the
|
||||
atom-ID, the next two are a molecule-ID and a floating point value
|
||||
that will be stored in a new property called "flag". If a per-atom
|
||||
array was specified in the fix property/atom commmand then the *N*
|
||||
values for that array must be specified consecutively for that
|
||||
property on each line.
|
||||
|
||||
Another way of initializing the new properties is via the
|
||||
:doc:`set <set>` command. For example, if you wanted molecules
|
||||
defined for every set of 10 atoms, based on their atom-IDs,
|
||||
these commands could be used:
|
||||
Note that the the lines of per-atom properties can be listed in any
|
||||
order. Also note that all the per-atom properties specified by the
|
||||
fix ID (prop in this case) must be included on each line in the
|
||||
specified data file section (Molecules in this case).
|
||||
|
||||
Another way of initializing the new properties is via the :doc:`set
|
||||
<set>` command. For example, if you wanted molecules defined for
|
||||
every set of 10 atoms, based on their atom-IDs, these commands could
|
||||
be used:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
@ -185,53 +198,59 @@ these commands could be used:
|
||||
|
||||
The :doc:`atom-style variable <variable>` will create values for atoms
|
||||
with IDs 31,32,33,...40 that are 4.0,4.1,4.2,...,4.9. When the
|
||||
:doc:`set <set>` commands assigns them to the molecule ID for each atom,
|
||||
they will be truncated to an integer value, so atoms 31-40 will all be
|
||||
assigned a molecule ID of 4.
|
||||
:doc:`set <set>` commands assigns them to the molecule ID for each
|
||||
atom, they will be truncated to an integer value, so atoms 31-40 will
|
||||
all be assigned a molecule ID of 4.
|
||||
|
||||
Note that :doc:`atomfile-style variables <variable>` can also be used in
|
||||
place of atom-style variables, which means in this case that the
|
||||
Note that :doc:`atomfile-style variables <variable>` can also be used
|
||||
in place of atom-style variables, which means in this case that the
|
||||
molecule IDs could be read-in from a separate file and assigned by the
|
||||
:doc:`set <set>` command. This allows you to initialize new per-atom
|
||||
properties in a completely general fashion.
|
||||
|
||||
----------
|
||||
|
||||
For new atom properties specified as *i_name* or *d_name*, the
|
||||
:doc:`compute property/atom <compute_property_atom>` command can access
|
||||
their values. This means that the values can be output via the :doc:`dump custom <dump>` command, accessed by fixes like :doc:`fix ave/atom <fix_ave_atom>`, accessed by other computes like :doc:`compute reduce <compute_reduce>`, or used in :doc:`atom-style variables <variable>`.
|
||||
For new atom properties specified as *i_name*, *d_name*, *i2_name*, or
|
||||
*d2_name*, the :doc:`dump custom <dump>` and :doc:`compute
|
||||
property/atom <compute_property_atom>` commands can access their
|
||||
values. This means that the values can be used accessed by fixes like
|
||||
:doc:`fix ave/atom <fix_ave_atom>`, accessed by other computes like
|
||||
:doc:`compute reduce <compute_reduce>`, or used in :doc:`atom-style
|
||||
variables <variable>`.
|
||||
|
||||
For example, these commands will output two new properties to a custom
|
||||
dump file:
|
||||
For example, these commands will output both the instantanous and
|
||||
time-averaged values of two new properties to a custom dump file:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
fix prop all property/atom i_flag1 d_flag2
|
||||
fix myprops all property/atom i_flag1 d_flag2
|
||||
compute 1 all property/atom i_flag1 d_flag2
|
||||
dump 1 all custom 100 tmp.dump id x y z c_1[1] c_1[2]
|
||||
fix 1 all ave/atom 10 10 100 c_1[1] c_1[2]
|
||||
dump 1 all custom 100 tmp.dump id x y z i_flag1 d_flag2 f_1[1] f_1[2]
|
||||
|
||||
----------
|
||||
|
||||
If you wish to add new :doc:`pair styles <pair_style>`,
|
||||
:doc:`fixes <fix>`, or :doc:`computes <compute>` that use the per-atom
|
||||
properties defined by this fix, see the :doc:`Modify atom <Modify_atom>`
|
||||
doc page which has details on how the properties can be accessed from
|
||||
added classes.
|
||||
If you wish to add new :doc:`pair styles <pair_style>`, :doc:`fixes
|
||||
<fix>`, or :doc:`computes <compute>` that use the per-atom properties
|
||||
defined by this fix, see the :doc:`Modify atom <Modify_atom>` doc page
|
||||
which has details on how the custom properties of this fix can be
|
||||
accessed from added classes.
|
||||
|
||||
----------
|
||||
|
||||
.. _isotopes:
|
||||
|
||||
Example for using per-atom masses with TIP4P water to
|
||||
study isotope effects. When setting up simulations with the :doc:`TIP4P pair styles <Howto_tip4p>` for water, you have to provide exactly
|
||||
one atom type each to identify the water oxygen and hydrogen
|
||||
atoms. Since the atom mass is normally tied to the atom type, this
|
||||
makes it impossible to study multiple isotopes in the same simulation.
|
||||
With *fix property/atom rmass* however, the per-type masses are
|
||||
replaced by per-atom masses. Asumming you have a working input deck
|
||||
for regular TIP4P water, where water oxygen is atom type 1 and water
|
||||
hydrogen is atom type 2, the following lines of input script convert
|
||||
this to using per-atom masses:
|
||||
Here is an example of using per-atom masses with TIP4P water to study
|
||||
isotope effects. When setting up simulations with the :doc:`TIP4P pair
|
||||
styles <Howto_tip4p>` for water, you have to provide exactly one atom
|
||||
type each to identify the water oxygen and hydrogen atoms. Since the
|
||||
atom mass is normally tied to the atom type, this makes it impossible
|
||||
to study multiple isotopes in the same simulation. With *fix
|
||||
property/atom rmass* however, the per-type masses are replaced by
|
||||
per-atom masses. Asumming you have a working input deck for regular
|
||||
TIP4P water, where water oxygen is atom type 1 and water hydrogen is
|
||||
atom type 2, the following lines of input script convert this to using
|
||||
per-atom masses:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
@ -239,22 +258,22 @@ this to using per-atom masses:
|
||||
set type 1 mass 15.9994
|
||||
set type 2 mass 1.008
|
||||
|
||||
When writing out the system data with the :doc:`write_data <write_data>`
|
||||
command, there will be a new section named with the fix-ID
|
||||
(i.e. *Isotopes* in this case). Alternatively, you can take an
|
||||
existing data file and just add this *Isotopes* section with
|
||||
one line per atom containing atom-ID and mass. Either way, the
|
||||
extended data file can be read back with:
|
||||
When writing out the system data with the :doc:`write_data
|
||||
<write_data>` command, there will be a new section named with the
|
||||
fix-ID (i.e. *Isotopes* in this case). Alternatively, you can take an
|
||||
existing data file and just add this *Isotopes* section with one line
|
||||
per atom containing atom-ID and mass. Either way, the extended data
|
||||
file can be read back with:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
fix Isotopes all property/atom rmass ghost yes
|
||||
read_data tip4p-isotopes.data fix Isotopes NULL Isotopes
|
||||
|
||||
Please note that the first *Isotopes* refers to the fix-ID
|
||||
and the second to the name of the section. The following input
|
||||
script code will now change the first 100 water molecules in this
|
||||
example to heavy water:
|
||||
Please note that the first *Isotopes* refers to the fix-ID and the
|
||||
second to the name of the section. The following input script code
|
||||
will now change the first 100 water molecules in this example to heavy
|
||||
water:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
@ -271,17 +290,19 @@ example to heavy water:
|
||||
Restart, fix_modify, output, run start/stop, minimize info
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
This fix writes the per-atom values it stores to :doc:`binary restart files <restart>`, so that the values can be restored when a
|
||||
simulation is restarted. See the :doc:`read_restart <read_restart>`
|
||||
command for info on how to re-specify a fix in an input script that
|
||||
reads a restart file, so that the operation of the fix continues in an
|
||||
This fix writes the per-atom values it stores to :doc:`binary restart
|
||||
files <restart>`, so that the values can be restored when a simulation
|
||||
is restarted. See the :doc:`read_restart <read_restart>` command for
|
||||
info on how to re-specify a fix in an input script that reads a
|
||||
restart file, so that the operation of the fix continues in an
|
||||
uninterrupted fashion.
|
||||
|
||||
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
|
||||
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>`.
|
||||
:doc:`run <run>` command. This fix is not invoked during :doc:`energy
|
||||
minimization <minimize>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
@ -290,9 +311,10 @@ Restrictions
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
|
||||
:doc:`read_data <read_data>`, :doc:`set <set>`, :doc:`compute property/atom <compute_property_atom>`
|
||||
:doc:`read_data <read_data>`, :doc:`set <set>`,
|
||||
:doc:`compute property/atom <compute_property_atom>`
|
||||
|
||||
Default
|
||||
"""""""
|
||||
|
||||
The default keyword values are ghost = no.
|
||||
The default keyword value is ghost = no.
|
||||
|
||||
@ -23,8 +23,8 @@ Syntax
|
||||
q, mux, muy, muz, mu,
|
||||
radius, diameter, omegax, omegay, omegaz,
|
||||
angmomx, angmomy, angmomz, tqx, tqy, tqz,
|
||||
c_ID, c_ID[N], f_ID, f_ID[N], v_name,
|
||||
d_name, i_name
|
||||
c_ID, c_ID[I], f_ID, f_ID[I], v_name,
|
||||
d_name, i_name, i2_name[I], d2_name[I],
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -46,13 +46,15 @@ Syntax
|
||||
omegax,omegay,omegaz = angular velocity of spherical particle
|
||||
angmomx,angmomy,angmomz = angular momentum of aspherical particle
|
||||
tqx,tqy,tqz = torque on finite-size particles
|
||||
c_ID = per-atom vector calculated by a compute with ID
|
||||
c_ID[I] = Ith column of per-atom array calculated by a compute with ID
|
||||
f_ID = per-atom vector calculated by a fix with ID
|
||||
f_ID[I] = Ith column of per-atom array calculated by a fix with ID
|
||||
v_name = per-atom vector calculated by an atom-style variable with name
|
||||
d_name = per-atom floating point vector name, managed by fix property/atom
|
||||
i_name = per-atom integer vector name, managed by fix property/atom
|
||||
*c_ID* = per-atom vector calculated by a compute with ID
|
||||
*c_ID[I]* = Ith column of per-atom array calculated by a compute with ID
|
||||
*f_ID* = per-atom vector calculated by a fix with ID
|
||||
*f_ID[I]* = Ith column of per-atom array calculated by a fix with ID
|
||||
*v_name* = per-atom vector calculated by an atom-style variable with name
|
||||
*i_name* = custom integer vector with name
|
||||
*d_name* = custom floating point vector with name
|
||||
*i2_name[I]* = Ith column of custom integer array with name
|
||||
*d2_name[I]* = Ith column of custom floating-point array with name
|
||||
|
||||
* zero or more keyword/value pairs may be appended
|
||||
* keyword = *com*
|
||||
@ -92,7 +94,8 @@ steps.
|
||||
those attributes may require quantities that are not defined in
|
||||
between runs.
|
||||
|
||||
The list of possible attributes is the same as that used by the :doc:`dump custom <dump>` command, which describes their meaning.
|
||||
The list of possible attributes is the same as that used by the
|
||||
:doc:`dump custom <dump>` command, which describes their meaning.
|
||||
|
||||
If the *com* keyword is set to *yes* then the *xu*\ , *yu*\ , and *zu*
|
||||
inputs store the position of each atom relative to the center-of-mass
|
||||
@ -105,10 +108,11 @@ group.
|
||||
Restart, fix_modify, output, run start/stop, minimize info
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
This fix writes the per-atom values it stores to :doc:`binary restart files <restart>`, so that the values can be restored when a
|
||||
simulation is restarted. See the :doc:`read_restart <read_restart>`
|
||||
command for info on how to re-specify a fix in an input script that
|
||||
reads a restart file, so that the operation of the fix continues in an
|
||||
This fix writes the per-atom values it stores to :doc:`binary restart
|
||||
files <restart>`, so that the values can be restored when a simulation
|
||||
is restarted. See the :doc:`read_restart <read_restart>` command for
|
||||
info on how to re-specify a fix in an input script that reads a
|
||||
restart file, so that the operation of the fix continues in an
|
||||
uninterrupted fashion.
|
||||
|
||||
None of the :doc:`fix_modify <fix_modify>` options are relevant to this
|
||||
@ -121,7 +125,8 @@ can be accessed by various :doc:`output commands <Howto_output>`. The
|
||||
per-atom values be accessed on any timestep.
|
||||
|
||||
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>`.
|
||||
the :doc:`run <run>` command. This fix is not invoked during
|
||||
:doc:`energy minimization <minimize>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
|
||||
@ -41,7 +41,7 @@ Syntax
|
||||
keyword = *region* or *var* or *every*
|
||||
*region* value = region-ID
|
||||
*var* value = name of variable
|
||||
*property* value = name of per-atom property
|
||||
*property* value = name of custom integer or floating point vector
|
||||
*every* value = N = update group every this many timesteps
|
||||
*static* = no args
|
||||
|
||||
@ -226,18 +226,33 @@ simulation runs. This is in contrast to static groups where atoms are
|
||||
permanently assigned to the group. The way the assignment occurs is
|
||||
as follows. Only atoms in the group specified as the parent group via
|
||||
the parent-ID are assigned to the dynamic group before the following
|
||||
conditions are applied. If the *region* keyword is used, atoms not in
|
||||
the specified region are removed from the dynamic group. If the *var*
|
||||
keyword is used, the variable name must be an atom-style or
|
||||
atomfile-style variable. The variable is evaluated and atoms whose
|
||||
per-atom values are 0.0, are removed from the dynamic group. If the *property*
|
||||
keyword is used, the per-atom property name must be a previously defined
|
||||
per-atom property. The per-atom property is evaluated and atoms whose
|
||||
values are 0.0 are removed from the dynamic group.
|
||||
conditions are applied.
|
||||
|
||||
If the *region* keyword is used, atoms not in the specified region are
|
||||
removed from the dynamic group.
|
||||
|
||||
If the *var* keyword is used, the variable name must be an atom-style
|
||||
or atomfile-style variable. The variable is evaluated and atoms whose
|
||||
per-atom values are 0.0, are removed from the dynamic group.
|
||||
|
||||
If the *property* keyword is used, the name refers to a custom integer
|
||||
or floating point per-atom vector defined via the :doc:`fix
|
||||
property/atom <fix_property_atom>` command. This means the values in
|
||||
the vector can be read as part of a data file with the :doc:`read_data
|
||||
<read_data>` command or specified with the :doc:`set <set>` command.
|
||||
Or accessed and changed via the :doc:`library interface to LAMMPS
|
||||
<Howto_library>`, or by styles you add to LAMMPS (pair, fix, compute,
|
||||
etc) which access the custom vector and modify its values. Which
|
||||
means the values can be modified between or during simulations. Atoms
|
||||
whose values in the custom vector are zero are removed from the
|
||||
dynamic group. Note that the name of the custom per-atom vector is
|
||||
specified just as *name*, not as *i_name* or *d_name* as it is for
|
||||
other commands that use different kinds of custom atom vectors or
|
||||
arrays as arguments.
|
||||
|
||||
The assignment of atoms to a dynamic group is done at the beginning of
|
||||
each run and on every timestep that is a multiple of *N*\ , which is the
|
||||
argument for the *every* keyword (N = 1 is the default). For an
|
||||
each run and on every timestep that is a multiple of *N*\ , which is
|
||||
the argument for the *every* keyword (N = 1 is the default). For an
|
||||
energy minimization, via the :doc:`minimize <minimize>` command, an
|
||||
assignment is made at the beginning of the minimization, but not
|
||||
during the iterations of the minimizer.
|
||||
|
||||
@ -13,7 +13,17 @@ Syntax
|
||||
* style = *atom* or *type* or *mol* or *group* or *region*
|
||||
* ID = atom ID range or type range or mol ID range or group ID or region ID
|
||||
* one or more keyword/value pairs may be appended
|
||||
* keyword = *type* or *type/fraction* or *type/ratio* or *type/subset* or *mol* or *x* or *y* or *z* or *charge* or *dipole* or *dipole/random* or *quat* or *spin* or *spin/random* or *quat* or *quat/random* or *diameter* or *shape* or *length* or *tri* or *theta* or *theta/random* or *angmom* or *omega* or *mass* or *density* or *density/disc* or *volume* or *image* or *bond* or *angle* or *dihedral* or *improper* or *sph/e* or *sph/cv* or *sph/rho* or *smd/contact/radius* or *smd/mass/density* or *dpd/theta* or *edpd/temp* or *edpd/cv* or *cc* or *i_name* or *d_name*
|
||||
* keyword = *type* or *type/fraction* or *type/ratio* or *type/subset*
|
||||
or *mol* or *x* or *y* or *z* or *charge* or *dipole* or
|
||||
*dipole/random* or *quat* or *spin* or *spin/random* or
|
||||
*quat* or *quat/random* or *diameter* or *shape* or
|
||||
*length* or *tri* or *theta* or *theta/random* or *angmom* or
|
||||
*omega* or *mass* or *density* or *density/disc* or
|
||||
*volume* or *image* or *bond* or *angle* or *dihedral* or
|
||||
*improper* or *sph/e* or *sph/cv* or *sph/rho* or
|
||||
*smd/contact/radius* or *smd/mass/density* or *dpd/theta* or
|
||||
*edpd/temp* or *edpd/cv* or *cc* or
|
||||
*i_name* or *d_name* or *i2_name* or *d2_name*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -114,8 +124,12 @@ Syntax
|
||||
*cc* values = index cc
|
||||
index = index of a chemical species (1 to Nspecies)
|
||||
cc = chemical concentration of tDPD particles for a species (mole/volume units)
|
||||
*i_name* value = value for custom integer vector with name
|
||||
*d_name* value = value for custom floating-point vector with name
|
||||
*i_name* value = custom integer vector with name
|
||||
*d_name* value = custom floating-point vector with name
|
||||
*i2_name* value = column of a custom integer array with name
|
||||
column specified as i2_name[N] where N is 1 to Ncol
|
||||
*d2_name* value = column of a custom floating-point array with name
|
||||
column specified as d2_name[N] where N is 1 to Ncol
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
@ -132,6 +146,8 @@ Examples
|
||||
set atom 100*200 x 0.5 y 1.0
|
||||
set atom 100 vx 0.0 vy 0.0 vz -1.0
|
||||
set atom 1492 type 3
|
||||
set atom * i_myVal 5
|
||||
set atom * d2_Sxyz[1] 6.4
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
@ -473,11 +489,13 @@ attribute. An integer for "index" selects a chemical species (1 to
|
||||
Nspecies) where Nspecies is set by the atom_style command. The value
|
||||
for the chemical concentration must be >= 0.0.
|
||||
|
||||
Keywords *i_name* and *d_name* refer to custom integer and
|
||||
floating-point properties that have been added to each atom via the
|
||||
:doc:`fix property/atom <fix_property_atom>` command. When that command
|
||||
is used specific names are given to each attribute which are what is
|
||||
specified as the "name" portion of *i_name* or *d_name*.
|
||||
Keywords *i_name*, *d_name*, *i2_name*, *d2_name* refer to custom
|
||||
per-atom integer and floating-point vectors or arrays that have been
|
||||
added via the :doc:`fix property/atom <fix_property_atom>` command.
|
||||
When that command is used specific names are given to each attribute
|
||||
which are the "name" portion of these keywords. For arrays *i2_name*
|
||||
and *d2_name*, the column of the array must also be included following
|
||||
the name in brackets: e.g. d2_xyz[2], i2_mySpin[3].
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
|
||||
@ -260,6 +260,7 @@ clean:
|
||||
|
||||
clean-all:
|
||||
rm -rf Obj_*
|
||||
rm style_*.h packages_*.h lmpgitversion.h lmpinstalledpkgs.h
|
||||
|
||||
clean-%:
|
||||
@if [ $@ = "clean-serial" ]; \
|
||||
|
||||
202
src/atom.cpp
202
src/atom.cpp
@ -178,10 +178,13 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
|
||||
|
||||
// custom atom arrays
|
||||
|
||||
nivector = ndvector = 0;
|
||||
nivector = ndvector = niarray = ndarray = 0;
|
||||
ivector = NULL;
|
||||
dvector = NULL;
|
||||
iname = dname = NULL;
|
||||
iarray = NULL;
|
||||
darray = NULL;
|
||||
icols = dcols = NULL;
|
||||
ivname = dvname = ianame = daname = NULL;
|
||||
|
||||
// initialize atom style and array existence flags
|
||||
|
||||
@ -262,20 +265,32 @@ Atom::~Atom()
|
||||
// delete custom atom arrays
|
||||
|
||||
for (int i = 0; i < nivector; i++) {
|
||||
delete [] iname[i];
|
||||
delete [] ivname[i];
|
||||
memory->destroy(ivector[i]);
|
||||
}
|
||||
if (dvector != NULL) {
|
||||
for (int i = 0; i < ndvector; i++) {
|
||||
delete [] dname[i];
|
||||
memory->destroy(dvector[i]);
|
||||
}
|
||||
for (int i = 0; i < ndvector; i++) {
|
||||
delete [] dvname[i];
|
||||
memory->destroy(dvector[i]);
|
||||
}
|
||||
for (int i = 0; i < niarray; i++) {
|
||||
delete [] ianame[i];
|
||||
memory->destroy(iarray[i]);
|
||||
}
|
||||
for (int i = 0; i < ndarray; i++) {
|
||||
delete [] daname[i];
|
||||
memory->destroy(darray[i]);
|
||||
}
|
||||
|
||||
memory->sfree(iname);
|
||||
memory->sfree(dname);
|
||||
memory->sfree(ivname);
|
||||
memory->sfree(dvname);
|
||||
memory->sfree(ianame);
|
||||
memory->sfree(daname);
|
||||
memory->sfree(ivector);
|
||||
memory->sfree(dvector);
|
||||
memory->sfree(iarray);
|
||||
memory->sfree(darray);
|
||||
memory->sfree(icols);
|
||||
memory->sfree(dcols);
|
||||
|
||||
// delete user-defined molecules
|
||||
|
||||
@ -2282,23 +2297,41 @@ void Atom::update_callback(int ifix)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
find custom per-atom vector with name
|
||||
return index if found, and flag = 0/1 for int/double
|
||||
return -1 if not found
|
||||
return index if found, -1 if not found
|
||||
lists of names can have NULL entries if previously removed
|
||||
return flag = 0/1 for int/double
|
||||
return cols = 0/N for vector/array where N = # of columns
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Atom::find_custom(const char *name, int &flag)
|
||||
int Atom::find_custom(const char *name, int &flag, int &cols)
|
||||
{
|
||||
if(name == NULL) return -1;
|
||||
if (name == NULL) return -1;
|
||||
|
||||
for (int i = 0; i < nivector; i++)
|
||||
if (iname[i] && strcmp(iname[i],name) == 0) {
|
||||
if (ivname[i] && strcmp(ivname[i],name) == 0) {
|
||||
flag = 0;
|
||||
cols = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ndvector; i++)
|
||||
if (dname[i] && strcmp(dname[i],name) == 0) {
|
||||
if (dvname[i] && strcmp(dvname[i],name) == 0) {
|
||||
flag = 1;
|
||||
cols = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < niarray; i++)
|
||||
if (ianame[i] && strcmp(ianame[i],name) == 0) {
|
||||
flag = 0;
|
||||
cols = icols[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ndarray; i++)
|
||||
if (daname[i] && strcmp(daname[i],name) == 0) {
|
||||
flag = 1;
|
||||
cols = dcols[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -2306,60 +2339,107 @@ int Atom::find_custom(const char *name, int &flag)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
add a custom variable with name of type flag = 0/1 for int/double
|
||||
add a custom variable with name
|
||||
flag = 0/1 for int/double, cols = 0/N for vector/array where N = # of columns
|
||||
assumes name does not already exist
|
||||
return index in ivector or dvector of its location
|
||||
vectors of names and data ptrs are always incremented by one
|
||||
return index in vector/array lists of its location
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Atom::add_custom(const char *name, int flag)
|
||||
int Atom::add_custom(const char *name, int flag, int cols)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (flag == 0) {
|
||||
if (flag == 0 && cols == 0) {
|
||||
index = nivector;
|
||||
nivector++;
|
||||
iname = (char **) memory->srealloc(iname,nivector*sizeof(char *),
|
||||
"atom:iname");
|
||||
ivname = (char **) memory->srealloc(ivname,nivector*sizeof(char *),
|
||||
"atom:ivname");
|
||||
int n = strlen(name) + 1;
|
||||
iname[index] = new char[n];
|
||||
strcpy(iname[index],name);
|
||||
ivname[index] = new char[n];
|
||||
strcpy(ivname[index],name);
|
||||
ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *),
|
||||
"atom:ivector");
|
||||
memory->create(ivector[index],nmax,"atom:ivector");
|
||||
} else {
|
||||
|
||||
} else if (flag == 1 && cols == 0) {
|
||||
index = ndvector;
|
||||
ndvector++;
|
||||
dname = (char **) memory->srealloc(dname,ndvector*sizeof(char *),
|
||||
"atom:dname");
|
||||
dvname = (char **) memory->srealloc(dvname,ndvector*sizeof(char *),
|
||||
"atom:dvname");
|
||||
int n = strlen(name) + 1;
|
||||
dname[index] = new char[n];
|
||||
strcpy(dname[index],name);
|
||||
dvname[index] = new char[n];
|
||||
strcpy(dvname[index],name);
|
||||
dvector = (double **) memory->srealloc(dvector,ndvector*sizeof(double *),
|
||||
"atom:dvector");
|
||||
memory->create(dvector[index],nmax,"atom:dvector");
|
||||
}
|
||||
|
||||
} else if (flag == 0 && cols) {
|
||||
index = niarray;
|
||||
niarray++;
|
||||
ianame = (char **) memory->srealloc(ianame,niarray*sizeof(char *),
|
||||
"atom:ianame");
|
||||
int n = strlen(name) + 1;
|
||||
ianame[index] = new char[n];
|
||||
strcpy(ianame[index],name);
|
||||
iarray = (int ***) memory->srealloc(iarray,niarray*sizeof(int **),
|
||||
"atom:iarray");
|
||||
memory->create(iarray[index],nmax,cols,"atom:iarray");
|
||||
|
||||
icols = (int *) memory->srealloc(icols,niarray*sizeof(int),"atom:icols");
|
||||
icols[index] = cols;
|
||||
|
||||
} else if (flag == 1 && cols) {
|
||||
index = ndarray;
|
||||
ndarray++;
|
||||
daname = (char **) memory->srealloc(daname,ndarray*sizeof(char *),
|
||||
"atom:daname");
|
||||
int n = strlen(name) + 1;
|
||||
daname[index] = new char[n];
|
||||
strcpy(daname[index],name);
|
||||
darray = (double ***) memory->srealloc(darray,ndarray*sizeof(double **),
|
||||
"atom:darray");
|
||||
memory->create(darray[index],nmax,cols,"atom:darray");
|
||||
|
||||
dcols = (int *) memory->srealloc(dcols,ndarray*sizeof(int),"atom:dcols");
|
||||
dcols[index] = cols;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
remove a custom variable of type flag = 0/1 for int/double at index
|
||||
free memory for vector and name and set ptrs to NULL
|
||||
ivector/dvector and iname/dname lists never shrink
|
||||
remove a custom variable stored at index
|
||||
flag = 0/1 for int/double, cols = 0/1 for vector/array or N for array columns
|
||||
free memory for vector/array and name and set ptrs to NULL
|
||||
vector/array lists and name lists never shrink
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Atom::remove_custom(int flag, int index)
|
||||
void Atom::remove_custom(int index, int flag, int cols)
|
||||
{
|
||||
if (flag == 0) {
|
||||
if (flag == 0 && cols == 0) {
|
||||
memory->destroy(ivector[index]);
|
||||
ivector[index] = NULL;
|
||||
delete [] iname[index];
|
||||
iname[index] = NULL;
|
||||
} else {
|
||||
delete [] ivname[index];
|
||||
ivname[index] = NULL;
|
||||
|
||||
} else if (flag == 1 && cols == 0) {
|
||||
memory->destroy(dvector[index]);
|
||||
dvector[index] = NULL;
|
||||
delete [] dname[index];
|
||||
dname[index] = NULL;
|
||||
delete [] dvname[index];
|
||||
dvname[index] = NULL;
|
||||
|
||||
} else if (flag == 0 && cols) {
|
||||
memory->destroy(iarray[index]);
|
||||
iarray[index] = NULL;
|
||||
delete [] ianame[index];
|
||||
ianame[index] = NULL;
|
||||
|
||||
} else if (flag == 1 && cols) {
|
||||
memory->destroy(darray[index]);
|
||||
darray[index] = NULL;
|
||||
delete [] daname[index];
|
||||
daname[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2372,7 +2452,8 @@ void *Atom::extract(char *name)
|
||||
{
|
||||
// --------------------------------------------------------------------
|
||||
// 4th customization section: customize by adding new variable name
|
||||
|
||||
// if new variable is from a package, add package comment
|
||||
|
||||
if (strcmp(name,"mass") == 0) return (void *) mass;
|
||||
|
||||
if (strcmp(name,"id") == 0) return (void *) tag;
|
||||
@ -2415,10 +2496,30 @@ void *Atom::extract(char *name)
|
||||
if (strcmp(name,"cv") == 0) return (void *) cv;
|
||||
if (strcmp(name,"vest") == 0) return (void *) vest;
|
||||
|
||||
// USER-MESONT package
|
||||
if (strcmp(name,"length") == 0) return (void *) length;
|
||||
if (strcmp(name,"buckling") == 0) return (void *) buckling;
|
||||
if (strcmp(name,"bond_nt") == 0) return (void *) bond_nt;
|
||||
// custom vectors and arrays
|
||||
|
||||
if (strstr(name,"i_") == name || strstr(name,"d_") == name ||
|
||||
strstr(name,"i2_") == name || strstr(name,"d2_") == name) {
|
||||
int which = 0;
|
||||
if (name[0] == 'd') which = 1;
|
||||
int array = 0;
|
||||
if (name[1] == '2') array = 1;
|
||||
|
||||
int index,flag,cols;
|
||||
if (!array) index = find_custom(&name[2],flag,cols);
|
||||
else index = find_custom(&name[3],flag,cols);
|
||||
|
||||
if (index < 0) return NULL;
|
||||
if (which != flag) return NULL;
|
||||
if ((!array && cols) || (array && !cols)) return NULL;
|
||||
|
||||
if (!which && !array) return (void *) ivector[index];
|
||||
if (which && !array) return (void *) dvector[index];
|
||||
if (!which && array) return (void *) iarray[index];
|
||||
if (which && array) return (void *) darray[index];
|
||||
}
|
||||
|
||||
// USER-SMD package
|
||||
|
||||
if (strcmp(name, "contact_radius") == 0) return (void *) contact_radius;
|
||||
if (strcmp(name, "smd_data_9") == 0) return (void *) smd_data_9;
|
||||
@ -2429,9 +2530,20 @@ void *Atom::extract(char *name)
|
||||
return (void *) eff_plastic_strain_rate;
|
||||
if (strcmp(name, "damage") == 0) return (void *) damage;
|
||||
|
||||
// USER-DPD package
|
||||
|
||||
if (strcmp(name,"dpdTheta") == 0) return (void *) dpdTheta;
|
||||
|
||||
// USER-MESO package
|
||||
|
||||
if (strcmp(name,"edpd_temp") == 0) return (void *) edpd_temp;
|
||||
|
||||
// USER-MESONT package
|
||||
|
||||
if (strcmp(name,"length") == 0) return (void *) length;
|
||||
if (strcmp(name,"buckling") == 0) return (void *) buckling;
|
||||
if (strcmp(name,"bond_nt") == 0) return (void *) bond_nt;
|
||||
|
||||
// end of customization section
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
|
||||
17
src/atom.h
17
src/atom.h
@ -206,12 +206,13 @@ class Atom : protected Pointers {
|
||||
PerAtom *peratom;
|
||||
int nperatom,maxperatom;
|
||||
|
||||
// custom arrays used by fix property/atom
|
||||
// custom vectors and arrays used by fix property/atom
|
||||
|
||||
int **ivector;
|
||||
double **dvector;
|
||||
char **iname,**dname;
|
||||
int nivector,ndvector;
|
||||
int **ivector,***iarray;
|
||||
double **dvector,***darray;
|
||||
int *icols,*dcols;
|
||||
char **ivname,**dvname,**ianame,**daname;
|
||||
int nivector,ndvector,niarray,ndarray;
|
||||
|
||||
// molecule templates
|
||||
// each template can be a set of consecutive molecules
|
||||
@ -321,9 +322,9 @@ class Atom : protected Pointers {
|
||||
void delete_callback(const char *, int);
|
||||
void update_callback(int);
|
||||
|
||||
int find_custom(const char *, int &);
|
||||
virtual int add_custom(const char *, int);
|
||||
virtual void remove_custom(int, int);
|
||||
int find_custom(const char *, int &, int &);
|
||||
virtual int add_custom(const char *, int, int);
|
||||
virtual void remove_custom(int, int, int);
|
||||
|
||||
virtual void sync_modify(ExecutionSpace, unsigned int, unsigned int) {}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "update.h"
|
||||
#include "domain.h"
|
||||
#include "comm.h"
|
||||
#include "utils.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
@ -33,7 +34,7 @@ using namespace LAMMPS_NS;
|
||||
|
||||
ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
Compute(lmp, narg, arg),
|
||||
index(NULL), pack_choice(NULL)
|
||||
index(NULL), colindex(NULL), pack_choice(NULL)
|
||||
{
|
||||
if (narg < 4) error->all(FLERR,"Illegal compute property/atom command");
|
||||
|
||||
@ -47,6 +48,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
pack_choice = new FnPtrPack[nvalues];
|
||||
index = new int[nvalues];
|
||||
colindex = new int[nvalues];
|
||||
|
||||
int i;
|
||||
for (int iarg = 3; iarg < narg; iarg++) {
|
||||
@ -141,7 +143,10 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_mu;
|
||||
} else if (strcmp(arg[iarg],"spx") == 0) { // pack magnetic variables
|
||||
|
||||
// pack magnetic variables
|
||||
|
||||
} else if (strcmp(arg[iarg],"spx") == 0) {
|
||||
if (!atom->sp_flag)
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
@ -176,6 +181,17 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_fmz;
|
||||
|
||||
// bond count
|
||||
|
||||
} else if (strcmp(arg[iarg],"nbonds") == 0) {
|
||||
if (!atom->molecule_flag)
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_nbonds;
|
||||
|
||||
// finite-size particles
|
||||
|
||||
} else if (strcmp(arg[iarg],"radius") == 0) {
|
||||
if (!atom->radius_flag)
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
@ -329,6 +345,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_corner2x;
|
||||
|
||||
} else if (strcmp(arg[iarg],"corner2y") == 0) {
|
||||
avec_tri = (AtomVecTri *) atom->style_match("tri");
|
||||
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
|
||||
@ -355,40 +372,59 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_corner3z;
|
||||
|
||||
} else if (strcmp(arg[iarg],"nbonds") == 0) {
|
||||
if (!atom->molecule_flag)
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_nbonds;
|
||||
|
||||
// custom per-atom vectors
|
||||
|
||||
} else if (strstr(arg[iarg],"i_") == arg[iarg]) {
|
||||
int flag;
|
||||
index[i] = atom->find_custom(&arg[iarg][2],flag);
|
||||
if (index[i] < 0 || flag != 0)
|
||||
error->all(FLERR,"Compute property/atom integer "
|
||||
"vector does not exist");
|
||||
int flag,cols;
|
||||
index[i] = atom->find_custom(&arg[iarg][2],flag,cols);
|
||||
if (index[i] < 0 || flag || cols)
|
||||
error->all(FLERR,"Compute property/atom custom vector does not exist");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_iname;
|
||||
} else if (strstr(arg[iarg],"d_") == arg[iarg]) {
|
||||
int flag;
|
||||
index[i] = atom->find_custom(&arg[iarg][2],flag);
|
||||
if (index[i] < 0 || flag != 1)
|
||||
error->all(FLERR,"Compute property/atom floating point "
|
||||
"vector does not exist");
|
||||
int flag,cols;
|
||||
index[i] = atom->find_custom(&arg[iarg][2],flag,cols);
|
||||
if (index[i] < 0 || !flag || cols)
|
||||
error->all(FLERR,"Compute property/atom custom vector does not exist");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_dname;
|
||||
}
|
||||
|
||||
else if (strcmp(arg[iarg],"buckling") == 0) {
|
||||
if (!atom->mesont_flag)
|
||||
error->all(FLERR,"Compute property/atom for "
|
||||
"atom property that isn't allocated");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_buckling;
|
||||
// check if atom style recognizes keyword
|
||||
// custom per-atom arrays, must include bracketed index
|
||||
|
||||
} else if (strstr(arg[iarg],"i2_") == arg[iarg] ||
|
||||
strstr(arg[iarg],"d2_") == arg[iarg]) {
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
|
||||
int n = strlen(arg[iarg]);
|
||||
char *suffix = new char[n];
|
||||
strcpy(suffix,&arg[iarg][3]);
|
||||
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in set command");
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
colindex[i] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else error->all(FLERR,"Compute property/atom custom array is not indexed");
|
||||
|
||||
int flag,cols;
|
||||
index[i] = atom->find_custom(suffix,flag,cols);
|
||||
delete [] suffix;
|
||||
|
||||
if ((!which && (index[i] < 0 || flag || !cols)) ||
|
||||
(which && (index[i] < 0 || !flag || !cols)))
|
||||
error->all(FLERR,"Compute property/atom custom array does not exist");
|
||||
|
||||
if (!which) pack_choice[i] = &ComputePropertyAtom::pack_i2name;
|
||||
else pack_choice[i] = &ComputePropertyAtom::pack_d2name;
|
||||
|
||||
// anything else must be recognized by atom style
|
||||
|
||||
} else {
|
||||
index[i] = atom->avec->property_atom(arg[iarg]);
|
||||
if (index[i] < 0)
|
||||
error->all(FLERR,"Invalid keyword in compute property/atom command");
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_property_atom;
|
||||
pack_choice[i] = &ComputePropertyAtom::pack_atom_style;
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,6 +437,7 @@ ComputePropertyAtom::~ComputePropertyAtom()
|
||||
{
|
||||
delete [] pack_choice;
|
||||
delete [] index;
|
||||
delete [] colindex;
|
||||
memory->destroy(vector_atom);
|
||||
memory->destroy(array_atom);
|
||||
}
|
||||
@ -413,6 +450,9 @@ void ComputePropertyAtom::init()
|
||||
avec_line = (AtomVecLine *) atom->style_match("line");
|
||||
avec_tri = (AtomVecTri *) atom->style_match("tri");
|
||||
avec_body = (AtomVecBody *) atom->style_match("body");
|
||||
|
||||
// NOTE: could reset custom vector/array indices here, like dump custom does
|
||||
// in case have been deleted
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -1145,6 +1185,21 @@ void ComputePropertyAtom::pack_fmz(int n)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_nbonds(int n)
|
||||
{
|
||||
int *num_bond = atom->num_bond;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) buf[n] = num_bond[i];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_radius(int n)
|
||||
{
|
||||
double *radius = atom->radius;
|
||||
@ -1780,36 +1835,6 @@ void ComputePropertyAtom::pack_corner3z(int n)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_buckling(int n)
|
||||
{
|
||||
int *buckling = atom->buckling;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) buf[n] = static_cast<double>(buckling[i]);
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_nbonds(int n)
|
||||
{
|
||||
int *num_bond = atom->num_bond;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) buf[n] = num_bond[i];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_iname(int n)
|
||||
{
|
||||
int *ivector = atom->ivector[index[n]];
|
||||
@ -1840,7 +1865,39 @@ void ComputePropertyAtom::pack_dname(int n)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_property_atom(int n)
|
||||
void ComputePropertyAtom::pack_i2name(int n)
|
||||
{
|
||||
int **iarray = atom->iarray[index[n]];
|
||||
int icol = colindex[n] - 1;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) buf[n] = iarray[i][icol];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_d2name(int n)
|
||||
{
|
||||
double **darray = atom->darray[index[n]];
|
||||
int icol = colindex[n] - 1;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) buf[n] = darray[i][icol];
|
||||
else buf[n] = 0.0;
|
||||
n += nvalues;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ComputePropertyAtom::pack_atom_style(int n)
|
||||
{
|
||||
atom->avec->pack_property_atom(index[n],&buf[n],nvalues,groupbit);
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ class ComputePropertyAtom : public Compute {
|
||||
private:
|
||||
int nvalues;
|
||||
int nmax;
|
||||
int *index;
|
||||
int *index,*colindex;
|
||||
double *buf;
|
||||
class AtomVecEllipsoid *avec_ellipsoid;
|
||||
class AtomVecLine *avec_line;
|
||||
@ -81,10 +81,6 @@ class ComputePropertyAtom : public Compute {
|
||||
void pack_muy(int);
|
||||
void pack_muz(int);
|
||||
void pack_mu(int);
|
||||
void pack_radius(int);
|
||||
void pack_diameter(int);
|
||||
|
||||
// pack magnetic variables
|
||||
|
||||
void pack_spx(int);
|
||||
void pack_spy(int);
|
||||
@ -94,12 +90,17 @@ class ComputePropertyAtom : public Compute {
|
||||
void pack_fmy(int);
|
||||
void pack_fmz(int);
|
||||
|
||||
void pack_nbonds(int);
|
||||
|
||||
void pack_radius(int);
|
||||
void pack_diameter(int);
|
||||
void pack_omegax(int);
|
||||
void pack_omegay(int);
|
||||
void pack_omegaz(int);
|
||||
void pack_angmomx(int);
|
||||
void pack_angmomy(int);
|
||||
void pack_angmomz(int);
|
||||
|
||||
void pack_shapex(int);
|
||||
void pack_shapey(int);
|
||||
void pack_shapez(int);
|
||||
@ -110,12 +111,14 @@ class ComputePropertyAtom : public Compute {
|
||||
void pack_tqx(int);
|
||||
void pack_tqy(int);
|
||||
void pack_tqz(int);
|
||||
|
||||
void pack_end1x(int);
|
||||
void pack_end1y(int);
|
||||
void pack_end1z(int);
|
||||
void pack_end2x(int);
|
||||
void pack_end2y(int);
|
||||
void pack_end2z(int);
|
||||
|
||||
void pack_corner1x(int);
|
||||
void pack_corner1y(int);
|
||||
void pack_corner1z(int);
|
||||
@ -125,14 +128,13 @@ class ComputePropertyAtom : public Compute {
|
||||
void pack_corner3x(int);
|
||||
void pack_corner3y(int);
|
||||
void pack_corner3z(int);
|
||||
void pack_buckling(int);
|
||||
|
||||
void pack_nbonds(int);
|
||||
|
||||
void pack_iname(int);
|
||||
void pack_dname(int);
|
||||
void pack_i2name(int);
|
||||
void pack_d2name(int);
|
||||
|
||||
void pack_property_atom(int);
|
||||
void pack_atom_style(int);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "update.h"
|
||||
#include "variable.h"
|
||||
#include "fmt/format.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
@ -44,7 +45,7 @@ enum{ID,MOL,PROC,PROCP1,TYPE,ELEMENT,MASS,
|
||||
Q,MUX,MUY,MUZ,MU,RADIUS,DIAMETER,
|
||||
OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ,
|
||||
TQX,TQY,TQZ,
|
||||
COMPUTE,FIX,VARIABLE,INAME,DNAME};
|
||||
COMPUTE,FIX,VARIABLE,IVEC,DVEC,IARRAY,DARRAY};
|
||||
enum{LT,LE,GT,GE,EQ,NEQ,XOR};
|
||||
|
||||
#define INVOKED_PERATOM 8
|
||||
@ -60,7 +61,7 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
|
||||
earg(NULL), vtype(NULL), vformat(NULL), columns(NULL), choose(NULL),
|
||||
dchoose(NULL), clist(NULL), field2index(NULL), argindex(NULL), id_compute(NULL),
|
||||
compute(NULL), id_fix(NULL), fix(NULL), id_variable(NULL), variable(NULL),
|
||||
vbuf(NULL), id_custom(NULL), flag_custom(NULL), typenames(NULL),
|
||||
vbuf(NULL), id_custom(NULL), custom(NULL), custom_flag(NULL), typenames(NULL),
|
||||
pack_choice(NULL)
|
||||
{
|
||||
if (narg == 5) error->all(FLERR,"No dump custom arguments specified");
|
||||
@ -119,7 +120,8 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
ncustom = 0;
|
||||
id_custom = NULL;
|
||||
flag_custom = NULL;
|
||||
custom = NULL;
|
||||
custom_flag = NULL;
|
||||
|
||||
// process attributes
|
||||
// ioptional = start of additional optional args in expanded args
|
||||
@ -236,7 +238,8 @@ DumpCustom::~DumpCustom()
|
||||
|
||||
for (int i = 0; i < ncustom; i++) delete [] id_custom[i];
|
||||
memory->sfree(id_custom);
|
||||
delete [] flag_custom;
|
||||
delete [] custom;
|
||||
delete [] custom_flag;
|
||||
|
||||
memory->destroy(choose);
|
||||
memory->destroy(dchoose);
|
||||
@ -324,7 +327,7 @@ void DumpCustom::init_style()
|
||||
else if (buffer_flag == 1) write_choice = &DumpCustom::write_string;
|
||||
else write_choice = &DumpCustom::write_lines;
|
||||
|
||||
// find current ptr for each compute,fix,variable
|
||||
// find current ptr for each compute,fix,variable and custom atom property
|
||||
// check that fix frequency is acceptable
|
||||
|
||||
int icompute;
|
||||
@ -353,9 +356,15 @@ void DumpCustom::init_style()
|
||||
|
||||
int icustom;
|
||||
for (int i = 0; i < ncustom; i++) {
|
||||
icustom = atom->find_custom(id_custom[i],flag_custom[i]);
|
||||
int flag,cols;
|
||||
icustom = atom->find_custom(id_custom[i],flag,cols);
|
||||
if (icustom < 0)
|
||||
error->all(FLERR,"Could not find custom per-atom property ID");
|
||||
error->all(FLERR,"Could not find dump custom atom property name");
|
||||
custom[i] = icustom;
|
||||
if (!flag && !cols) custom_flag[i] = IVEC;
|
||||
else if (flag && !cols) custom_flag[i] = DVEC;
|
||||
else if (!flag && cols) custom_flag[i] = IARRAY;
|
||||
else if (flag && cols) custom_flag[i] = DARRAY;
|
||||
}
|
||||
|
||||
// set index and check validity of region
|
||||
@ -1036,23 +1045,37 @@ int DumpCustom::count()
|
||||
ptr = vbuf[field2index[i]];
|
||||
nstride = 1;
|
||||
|
||||
} else if (thresh_array[ithresh] == DNAME) {
|
||||
int iwhich,tmp;
|
||||
} else if (thresh_array[ithresh] == IVEC) {
|
||||
i = nfield + ithresh;
|
||||
iwhich = atom->find_custom(id_custom[field2index[i]],tmp);
|
||||
ptr = atom->dvector[iwhich];
|
||||
nstride = 1;
|
||||
|
||||
} else if (thresh_array[ithresh] == INAME) {
|
||||
int iwhich,tmp;
|
||||
i = nfield + ithresh;
|
||||
iwhich = atom->find_custom(id_custom[field2index[i]],tmp);
|
||||
|
||||
int iwhich = custom[field2index[i]];
|
||||
int *ivector = atom->ivector[iwhich];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
dchoose[i] = ivector[i];
|
||||
ptr = dchoose;
|
||||
nstride = 1;
|
||||
|
||||
} else if (thresh_array[ithresh] == DVEC) {
|
||||
i = nfield + ithresh;
|
||||
int iwhich = custom[field2index[i]];
|
||||
ptr = atom->dvector[iwhich];
|
||||
nstride = 1;
|
||||
|
||||
} else if (thresh_array[ithresh] == IARRAY) {
|
||||
i = nfield + ithresh;
|
||||
int iwhich = custom[field2index[i]];
|
||||
int **iarray = atom->iarray[iwhich];
|
||||
int icol = argindex[i] - 1;
|
||||
for (i = 0; i < nlocal; i++)
|
||||
dchoose[i] = iarray[i][icol];
|
||||
ptr = dchoose;
|
||||
nstride = 1;
|
||||
|
||||
} else if (thresh_array[ithresh] == DARRAY) {
|
||||
i = nfield + ithresh;
|
||||
int iwhich = custom[field2index[i]];
|
||||
double **darray = atom->darray[iwhich];
|
||||
ptr = &darray[0][argindex[i]-1];
|
||||
nstride = atom->dcols[iwhich];
|
||||
}
|
||||
|
||||
// unselect atoms that don't meet threshold criterion
|
||||
@ -1257,7 +1280,7 @@ int DumpCustom::parse_fields(int narg, char **arg)
|
||||
int i;
|
||||
for (int iarg = 0; iarg < narg; iarg++) {
|
||||
i = iarg;
|
||||
|
||||
|
||||
if (strcmp(arg[iarg],"id") == 0) {
|
||||
pack_choice[i] = &DumpCustom::pack_id;
|
||||
if (sizeof(tagint) == sizeof(smallint)) vtype[i] = Dump::INT;
|
||||
@ -1455,7 +1478,8 @@ int DumpCustom::parse_fields(int narg, char **arg)
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in dump custom command");
|
||||
argindex[i] = atoi(ptr+1);
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[i] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else argindex[i] = 0;
|
||||
|
||||
@ -1491,7 +1515,8 @@ int DumpCustom::parse_fields(int narg, char **arg)
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in dump custom command");
|
||||
argindex[i] = atoi(ptr+1);
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[i] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else argindex[i] = 0;
|
||||
|
||||
@ -1530,48 +1555,66 @@ int DumpCustom::parse_fields(int narg, char **arg)
|
||||
field2index[i] = add_variable(suffix);
|
||||
delete [] suffix;
|
||||
|
||||
// custom per-atom floating point value = d_ID
|
||||
// custom per-atom vector = i_ID or d_ID
|
||||
|
||||
} else if (strncmp(arg[iarg],"d_",2) == 0) {
|
||||
} else if (strncmp(arg[iarg],"i_",2) == 0 ||
|
||||
strncmp(arg[iarg],"d_",2) == 0) {
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
|
||||
pack_choice[i] = &DumpCustom::pack_custom;
|
||||
vtype[i] = Dump::DOUBLE;
|
||||
if (!which) vtype[i] = Dump::INT;
|
||||
else vtype[i] = Dump::DOUBLE;
|
||||
|
||||
int n = strlen(arg[iarg]);
|
||||
char *suffix = new char[n];
|
||||
strcpy(suffix,&arg[iarg][2]);
|
||||
argindex[i] = 0;
|
||||
|
||||
int tmp = -1;
|
||||
n = atom->find_custom(suffix,tmp);
|
||||
if (n < 0)
|
||||
error->all(FLERR,"Could not find custom per-atom property ID");
|
||||
int flag,cols;
|
||||
n = atom->find_custom(suffix,flag,cols);
|
||||
if ((!which && (n < 0 || flag || cols)) ||
|
||||
(which && (n < 0 || !flag || cols)))
|
||||
error->all(FLERR,"Dump custom per-atom custom vector does not exist");
|
||||
|
||||
if (tmp != 1)
|
||||
error->all(FLERR,"Custom per-atom property ID is not floating point");
|
||||
|
||||
field2index[i] = add_custom(suffix,1);
|
||||
field2index[i] = add_custom(suffix);
|
||||
delete [] suffix;
|
||||
|
||||
// custom per-atom integer value = i_ID
|
||||
// custom per-atom array = i2_ID or d2_ID, must include bracketed index
|
||||
|
||||
} else if (strncmp(arg[iarg],"i2_",3) == 0 ||
|
||||
strncmp(arg[iarg],"d2_",3) == 0) {
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
|
||||
} else if (strncmp(arg[iarg],"i_",2) == 0) {
|
||||
pack_choice[i] = &DumpCustom::pack_custom;
|
||||
vtype[i] = Dump::INT;
|
||||
if (!which) vtype[i] = Dump::INT;
|
||||
else vtype[i] = Dump::DOUBLE;
|
||||
|
||||
int n = strlen(arg[iarg]);
|
||||
char *suffix = new char[n];
|
||||
strcpy(suffix,&arg[iarg][2]);
|
||||
argindex[i] = 0;
|
||||
strcpy(suffix,&arg[iarg][3]);
|
||||
|
||||
int tmp = -1;
|
||||
n = atom->find_custom(suffix,tmp);
|
||||
if (n < 0)
|
||||
error->all(FLERR,"Could not find custom per-atom property ID");
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in dump custom command");
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[i] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else error->all(FLERR,"Dump custom per-atom custom array is not indexed");
|
||||
|
||||
if (tmp != 0)
|
||||
error->all(FLERR,"Custom per-atom property ID is not integer");
|
||||
int flag,cols;
|
||||
n = atom->find_custom(suffix,flag,cols);
|
||||
|
||||
if ((!which && (n < 0 || flag || !cols)) ||
|
||||
(which && (n < 0 || !flag || !cols)))
|
||||
error->all(FLERR,"Dump custom per-atom custom array does not exist");
|
||||
if (argindex[i] <= 0 || argindex[i] > cols)
|
||||
error->all(FLERR,
|
||||
"Dump custom per-atom custom array is accessed out-of-range");
|
||||
|
||||
field2index[i] = add_custom(suffix,0);
|
||||
field2index[i] = add_custom(suffix);
|
||||
delete [] suffix;
|
||||
|
||||
} else return iarg;
|
||||
@ -1645,7 +1688,7 @@ int DumpCustom::add_variable(char *id)
|
||||
|
||||
id_variable = (char **)
|
||||
memory->srealloc(id_variable,(nvariable+1)*sizeof(char *),
|
||||
"dump:id_variable");
|
||||
"d<ump:id_variable");
|
||||
delete [] variable;
|
||||
variable = new int[nvariable+1];
|
||||
delete [] vbuf;
|
||||
@ -1661,27 +1704,28 @@ int DumpCustom::add_variable(char *id)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
add custom atom property to list used by dump
|
||||
return index of where this property is in list
|
||||
return index of where this property is in Atom class custom lists
|
||||
if already in list, do not add, just return index, else add to list
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int DumpCustom::add_custom(char *id, int flag)
|
||||
int DumpCustom::add_custom(char *id)
|
||||
{
|
||||
int icustom;
|
||||
for (icustom = 0; icustom < ncustom; icustom++)
|
||||
if ((strcmp(id,id_custom[icustom]) == 0)
|
||||
&& (flag == flag_custom[icustom])) break;
|
||||
if (strcmp(id,id_custom[icustom]) == 0) break;
|
||||
if (icustom < ncustom) return icustom;
|
||||
|
||||
id_custom = (char **)
|
||||
memory->srealloc(id_custom,(ncustom+1)*sizeof(char *),"dump:id_custom");
|
||||
flag_custom = (int *)
|
||||
memory->srealloc(flag_custom,(ncustom+1)*sizeof(int),"dump:flag_custom");
|
||||
|
||||
delete [] custom;
|
||||
custom = new int[ncustom+1];
|
||||
delete [] custom_flag;
|
||||
custom_flag = new int[ncustom+1];
|
||||
|
||||
int n = strlen(id) + 1;
|
||||
id_custom[ncustom] = new char[n];
|
||||
strcpy(id_custom[ncustom],id);
|
||||
flag_custom[ncustom] = flag;
|
||||
|
||||
ncustom++;
|
||||
return ncustom-1;
|
||||
@ -1777,7 +1821,7 @@ int DumpCustom::modify_param(int narg, char **arg)
|
||||
if (narg < 2) error->all(FLERR,"Illegal dump_modify command");
|
||||
if (strncmp(arg[1],"c_",2) != 0)
|
||||
error->all(FLERR,"Illegal dump_modify command");
|
||||
if (refreshflag) error->all(FLERR,"Dump modify can only have one refresh");
|
||||
if (refreshflag) error->all(FLERR,"Dump_modify can only have one refresh");
|
||||
|
||||
refreshflag = 1;
|
||||
int n = strlen(arg[1]);
|
||||
@ -1914,28 +1958,29 @@ int DumpCustom::modify_param(int narg, char **arg)
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in dump modify command");
|
||||
argindex[nfield+nthresh] = atoi(ptr+1);
|
||||
error->all(FLERR,"Invalid attribute in dump_modify command");
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[nfield+nthresh] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else argindex[nfield+nthresh] = 0;
|
||||
|
||||
n = modify->find_compute(suffix);
|
||||
if (n < 0) error->all(FLERR,"Could not find dump modify compute ID");
|
||||
if (n < 0) error->all(FLERR,"Could not find dump_modify compute ID");
|
||||
|
||||
if (modify->compute[n]->peratom_flag == 0)
|
||||
error->all(FLERR,
|
||||
"Dump modify compute ID does not compute per-atom info");
|
||||
"Dump_modify compute ID does not compute per-atom info");
|
||||
if (argindex[nfield+nthresh] == 0 &&
|
||||
modify->compute[n]->size_peratom_cols > 0)
|
||||
error->all(FLERR,
|
||||
"Dump modify compute ID does not compute per-atom vector");
|
||||
"Dump_modify compute ID does not compute per-atom vector");
|
||||
if (argindex[nfield+nthresh] > 0 &&
|
||||
modify->compute[n]->size_peratom_cols == 0)
|
||||
error->all(FLERR,
|
||||
"Dump modify compute ID does not compute per-atom array");
|
||||
"Dump_modify compute ID does not compute per-atom array");
|
||||
if (argindex[nfield+nthresh] > 0 &&
|
||||
argindex[nfield+nthresh] > modify->compute[n]->size_peratom_cols)
|
||||
error->all(FLERR,"Dump modify compute ID vector is not large enough");
|
||||
error->all(FLERR,"Dump_modify compute ID vector is not large enough");
|
||||
|
||||
field2index[nfield+nthresh] = add_compute(suffix);
|
||||
delete [] suffix;
|
||||
@ -1955,25 +2000,26 @@ int DumpCustom::modify_param(int narg, char **arg)
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in dump modify command");
|
||||
argindex[nfield+nthresh] = atoi(ptr+1);
|
||||
error->all(FLERR,"Invalid attribute in dump_modify command");
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[nfield+nthresh] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else argindex[nfield+nthresh] = 0;
|
||||
|
||||
n = modify->find_fix(suffix);
|
||||
if (n < 0) error->all(FLERR,"Could not find dump modify fix ID");
|
||||
if (n < 0) error->all(FLERR,"Could not find dump_modify fix ID");
|
||||
|
||||
if (modify->fix[n]->peratom_flag == 0)
|
||||
error->all(FLERR,"Dump modify fix ID does not compute per-atom info");
|
||||
error->all(FLERR,"Dump_modify fix ID does not compute per-atom info");
|
||||
if (argindex[nfield+nthresh] == 0 &&
|
||||
modify->fix[n]->size_peratom_cols > 0)
|
||||
error->all(FLERR,"Dump modify fix ID does not compute per-atom vector");
|
||||
error->all(FLERR,"Dump_modify fix ID does not compute per-atom vector");
|
||||
if (argindex[nfield+nthresh] > 0 &&
|
||||
modify->fix[n]->size_peratom_cols == 0)
|
||||
error->all(FLERR,"Dump modify fix ID does not compute per-atom array");
|
||||
error->all(FLERR,"Dump_modify fix ID does not compute per-atom array");
|
||||
if (argindex[nfield+nthresh] > 0 &&
|
||||
argindex[nfield+nthresh] > modify->fix[n]->size_peratom_cols)
|
||||
error->all(FLERR,"Dump modify fix ID vector is not large enough");
|
||||
error->all(FLERR,"Dump_modify fix ID vector is not large enough");
|
||||
|
||||
field2index[nfield+nthresh] = add_fix(suffix);
|
||||
delete [] suffix;
|
||||
@ -1992,18 +2038,23 @@ int DumpCustom::modify_param(int narg, char **arg)
|
||||
argindex[nfield+nthresh] = 0;
|
||||
|
||||
n = input->variable->find(suffix);
|
||||
if (n < 0) error->all(FLERR,"Could not find dump modify variable name");
|
||||
if (n < 0) error->all(FLERR,"Could not find dump_modify variable name");
|
||||
if (input->variable->atomstyle(n) == 0)
|
||||
error->all(FLERR,"Dump modify variable is not atom-style variable");
|
||||
error->all(FLERR,"Dump_modify variable is not atom-style variable");
|
||||
|
||||
field2index[nfield+nthresh] = add_variable(suffix);
|
||||
delete [] suffix;
|
||||
|
||||
// custom per atom floating point value = d_ID
|
||||
// custom per-atom vector = i_ID or d_ID
|
||||
// must grow field2index and argindex arrays, since access is beyond nfield
|
||||
|
||||
} else if (strncmp(arg[1],"d_",2) == 0) {
|
||||
thresh_array[nthresh] = DNAME;
|
||||
} else if (strncmp(arg[1],"i_",2) == 0 ||
|
||||
strncmp(arg[1],"d_",2) == 0) {
|
||||
int which = 0;
|
||||
if (arg[1][0] == 'd') which = 1;
|
||||
|
||||
if (!which) thresh_array[nthresh] = IVEC;
|
||||
else thresh_array[nthresh] = DVEC;
|
||||
memory->grow(field2index,nfield+nthresh+1,"dump:field2index");
|
||||
memory->grow(argindex,nfield+nthresh+1,"dump:argindex");
|
||||
int n = strlen(arg[1]);
|
||||
@ -2011,34 +2062,51 @@ int DumpCustom::modify_param(int narg, char **arg)
|
||||
strcpy(suffix,&arg[1][2]);
|
||||
argindex[nfield+nthresh] = 0;
|
||||
|
||||
int tmp = -1;
|
||||
n = atom->find_custom(suffix,tmp);
|
||||
if ((n < 0) || (tmp != 1))
|
||||
error->all(FLERR,"Could not find dump modify "
|
||||
"custom atom floating point property ID");
|
||||
|
||||
field2index[nfield+nthresh] = add_custom(suffix,1);
|
||||
int flag,cols;
|
||||
n = atom->find_custom(suffix,flag,cols);
|
||||
if ((!which && (n < 0 || flag || cols)) ||
|
||||
(which && (n < 0 || !flag || cols)))
|
||||
error->all(FLERR,"Could not find dump_modify per-atom custom vector");
|
||||
field2index[nfield+nthresh] = add_custom(suffix);
|
||||
delete [] suffix;
|
||||
|
||||
// custom per atom integer value = i_ID
|
||||
// custom per-atom array = i2_ID or d2_ID, must include bracketed index
|
||||
// must grow field2index and argindex arrays, since access is beyond nfield
|
||||
|
||||
} else if (strncmp(arg[1],"i_",2) == 0) {
|
||||
thresh_array[nthresh] = INAME;
|
||||
} else if (strncmp(arg[1],"i2_",3) == 0 ||
|
||||
strncmp(arg[1],"d2_",3) == 0) {
|
||||
int which = 0;
|
||||
if (arg[1][0] == 'd') which = 1;
|
||||
|
||||
if (!which) thresh_array[nthresh] = IARRAY;
|
||||
else thresh_array[nthresh] = DARRAY;
|
||||
memory->grow(field2index,nfield+nthresh+1,"dump:field2index");
|
||||
memory->grow(argindex,nfield+nthresh+1,"dump:argindex");
|
||||
|
||||
int n = strlen(arg[1]);
|
||||
char *suffix = new char[n];
|
||||
strcpy(suffix,&arg[1][2]);
|
||||
argindex[nfield+nthresh] = 0;
|
||||
strcpy(suffix,&arg[1][3]);
|
||||
|
||||
int tmp = -1;
|
||||
n = atom->find_custom(suffix,tmp);
|
||||
if ((n < 0) || (tmp != 0))
|
||||
error->all(FLERR,"Could not find dump modify "
|
||||
"custom atom integer property ID");
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in dump custom command");
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[nfield+nthresh] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else error->all(FLERR,"Dump_modify per-atom custom array is not indexed");
|
||||
|
||||
field2index[nfield+nthresh] = add_custom(suffix,0);
|
||||
int flag,cols;
|
||||
n = atom->find_custom(suffix,flag,cols);
|
||||
|
||||
if ((!which && (n < 0 || flag || !cols)) ||
|
||||
(which && (n < 0 || !flag || !cols)))
|
||||
error->all(FLERR,"Could not find dump_modify per-atom custom array");
|
||||
if (argindex[nfield+nthresh] <= 0 || argindex[nfield+nthresh] > cols)
|
||||
error->all(FLERR,
|
||||
"Dump_modify per-atom custom array is accessed out-of-range");
|
||||
|
||||
field2index[nfield+nthresh] = add_custom(suffix);
|
||||
delete [] suffix;
|
||||
|
||||
} else error->all(FLERR,"Invalid dump_modify thresh attribute");
|
||||
@ -2165,27 +2233,36 @@ void DumpCustom::pack_variable(int n)
|
||||
|
||||
void DumpCustom::pack_custom(int n)
|
||||
{
|
||||
|
||||
int index = field2index[n];
|
||||
|
||||
if (flag_custom[index] == 0) { // integer
|
||||
int iwhich,tmp;
|
||||
iwhich = atom->find_custom(id_custom[index],tmp);
|
||||
|
||||
int flag = custom_flag[field2index[n]];
|
||||
int iwhich = custom[field2index[n]];
|
||||
int index = argindex[n];
|
||||
|
||||
if (flag == IVEC) {
|
||||
int *ivector = atom->ivector[iwhich];
|
||||
for (int i = 0; i < nchoose; i++) {
|
||||
buf[n] = ivector[clist[i]];
|
||||
n += size_one;
|
||||
}
|
||||
} else if (flag_custom[index] == 1) { // double
|
||||
int iwhich,tmp;
|
||||
iwhich = atom->find_custom(id_custom[index],tmp);
|
||||
|
||||
} else if (flag == DVEC) {
|
||||
double *dvector = atom->dvector[iwhich];
|
||||
for (int i = 0; i < nchoose; i++) {
|
||||
buf[n] = dvector[clist[i]];
|
||||
n += size_one;
|
||||
}
|
||||
} else if (flag == IARRAY) {
|
||||
index--;
|
||||
int **iarray = atom->iarray[iwhich];
|
||||
for (int i = 0; i < nchoose; i++) {
|
||||
buf[n] = iarray[clist[i]][index];
|
||||
n += size_one;
|
||||
}
|
||||
} else if (flag == DARRAY) {
|
||||
index--;
|
||||
double **darray = atom->darray[iwhich];
|
||||
for (int i = 0; i < nchoose; i++) {
|
||||
buf[n] = darray[clist[i]][index];
|
||||
n += size_one;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -70,29 +70,30 @@ class DumpCustom : public Dump {
|
||||
int nfield; // # of keywords listed by user
|
||||
int ioptional; // index of start of optional args
|
||||
|
||||
int *field2index; // which compute,fix,variable calcs this field
|
||||
int *argindex; // index into compute,fix scalar_atom,vector_atom
|
||||
// 0 for scalar_atom, 1-N for vector_atom values
|
||||
int *field2index; // which compute,fix,variable,custom calcs this field
|
||||
int *argindex; // index into compute,fix,custom per-atom data
|
||||
// 0 for per-atom vector, 1-N for cols of per-atom array
|
||||
|
||||
int ncompute; // # of Compute objects used by dump
|
||||
int ncompute; // # of Computes accessed by dump
|
||||
char **id_compute; // their IDs
|
||||
class Compute **compute; // list of ptrs to the Compute objects
|
||||
class Compute **compute; // list of ptrs to the Computes
|
||||
|
||||
int nfix; // # of Fix objects used by dump
|
||||
int nfix; // # of Fixes used by dump
|
||||
char **id_fix; // their IDs
|
||||
class Fix **fix; // list of ptrs to the Fix objects
|
||||
class Fix **fix; // list of ptrs to the Fixes
|
||||
|
||||
int nvariable; // # of Variables used by dump
|
||||
char **id_variable; // their names
|
||||
int *variable; // list of indices for the Variables
|
||||
int *variable; // list of Variable indices in Variable class
|
||||
double **vbuf; // local storage for variable evaluation
|
||||
|
||||
int ncustom; // # of custom atom properties
|
||||
int ncustom; // # of Custom atom properties used by dump
|
||||
char **id_custom; // their names
|
||||
int *flag_custom; // their data type
|
||||
int *custom; // list of Custom indices in Atom class
|
||||
int *custom_flag; // list of IVEC,DVEC,IARRAY,DARRAY styles
|
||||
|
||||
int ntypes; // # of atom types
|
||||
char **typenames; // array of element names for each type
|
||||
char **typenames; // array of element names for each type
|
||||
|
||||
// private methods
|
||||
|
||||
@ -108,7 +109,7 @@ class DumpCustom : public Dump {
|
||||
int add_compute(char *);
|
||||
int add_fix(char *);
|
||||
int add_variable(char *);
|
||||
int add_custom(char *, int);
|
||||
int add_custom(char *);
|
||||
virtual int modify_param(int, char **);
|
||||
|
||||
void header_format_binary();
|
||||
|
||||
@ -64,6 +64,7 @@ idregion(NULL), idvar(NULL), idprop(NULL)
|
||||
idregion = new char[n];
|
||||
strcpy(idregion,arg[iarg+1]);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"var") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal group command");
|
||||
if (input->variable->find(arg[iarg+1]) < 0)
|
||||
@ -74,16 +75,21 @@ idregion(NULL), idvar(NULL), idprop(NULL)
|
||||
idvar = new char[n];
|
||||
strcpy(idvar,arg[iarg+1]);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"property") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal group command");
|
||||
if (atom->find_custom(arg[iarg+1],typeflag) < 0)
|
||||
error->all(FLERR,"Per atom property for group dynamic does not exist");
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal group command");
|
||||
int flag,cols;
|
||||
iprop = atom->find_custom(arg[iarg+1],flag,cols);
|
||||
if (iprop < 1 || cols)
|
||||
error->all(FLERR,"Custom per-atom vector for group dynamic "
|
||||
"does not exist");
|
||||
propflag = 1;
|
||||
delete [] idprop;
|
||||
int n = strlen(arg[iarg+1]) + 1;
|
||||
idprop = new char[n];
|
||||
strcpy(idprop,arg[iarg+1]);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"every") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal group command");
|
||||
nevery = force->inumeric(FLERR,arg[iarg+1]);
|
||||
@ -125,7 +131,7 @@ void FixGroup::init()
|
||||
if (strstr(update->integrate_style,"respa"))
|
||||
nlevels_respa = ((Respa *) update->integrate)->nlevels;
|
||||
|
||||
// set current indices for region and variable
|
||||
// set current indices for region and variable and custom property
|
||||
|
||||
if (regionflag) {
|
||||
iregion = domain->find_region(idregion);
|
||||
@ -143,9 +149,10 @@ void FixGroup::init()
|
||||
}
|
||||
|
||||
if (propflag) {
|
||||
iprop = atom->find_custom(idprop,typeflag);
|
||||
if (iprop < 0)
|
||||
error->all(FLERR,"Per-atom property for group dynamic does not exist");
|
||||
int cols;
|
||||
iprop = atom->find_custom(idprop,proptype,cols);
|
||||
if (iprop < 0 || cols)
|
||||
error->all(FLERR,"Group dynamic command custom property vector does not exist");
|
||||
}
|
||||
|
||||
// warn if any FixGroup is not at tail end of all post_integrate fixes
|
||||
@ -222,11 +229,10 @@ void FixGroup::set_group()
|
||||
update->post_integrate = 0;
|
||||
}
|
||||
|
||||
// invoke per-atom property if defined
|
||||
// set ptr to custom atom vector
|
||||
|
||||
if (propflag && !typeflag) ivector = atom->ivector[iprop]; //check nlocal > 0?
|
||||
|
||||
if (propflag && typeflag) dvector = atom->dvector[iprop]; //check nlocal > 0?
|
||||
if (propflag && !proptype) ivector = atom->ivector[iprop];
|
||||
if (propflag && proptype) dvector = atom->dvector[iprop];
|
||||
|
||||
// update region in case it has a variable dependence or is dynamic
|
||||
|
||||
@ -246,8 +252,10 @@ void FixGroup::set_group()
|
||||
inflag = 1;
|
||||
if (regionflag && !region->match(x[i][0],x[i][1],x[i][2])) inflag = 0;
|
||||
if (varflag && var[i] == 0.0) inflag = 0;
|
||||
if (propflag && !typeflag && ivector[i] == 0) inflag = 0;
|
||||
if (propflag && typeflag && dvector[i] == 0) inflag = 0;
|
||||
if (propflag) {
|
||||
if (!proptype && ivector[i] == 0) inflag = 0;
|
||||
if (proptype && dvector[i] == 0.0) inflag = 0;
|
||||
}
|
||||
} else inflag = 0;
|
||||
|
||||
if (inflag) mask[i] |= gbit;
|
||||
|
||||
@ -37,7 +37,7 @@ class FixGroup : public Fix {
|
||||
|
||||
private:
|
||||
int gbit,gbitinverse;
|
||||
int regionflag,varflag,propflag,typeflag;
|
||||
int regionflag,varflag,propflag,proptype;
|
||||
int iregion,ivar,iprop;
|
||||
char *idregion,*idvar,*idprop;
|
||||
class Region *region;
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
enum{MOLECULE,CHARGE,RMASS,INTEGER,DOUBLE};
|
||||
enum{MOLECULE,CHARGE,RMASS,IVEC,DVEC,IARRAY,DARRAY};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -40,6 +40,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
int iarg = 3;
|
||||
nvalue = narg-iarg;
|
||||
style = new int[nvalue];
|
||||
cols = new int[nvalue];
|
||||
index = new int[nvalue];
|
||||
|
||||
molecule_flag = 0;
|
||||
@ -47,6 +48,8 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
rmass_flag = 0;
|
||||
|
||||
nvalue = 0;
|
||||
values_peratom = 0;
|
||||
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"mol") == 0) {
|
||||
if (atom->molecule_flag)
|
||||
@ -55,8 +58,11 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (molecule_flag)
|
||||
error->all(FLERR,"Fix property/atom cannot specify mol twice");
|
||||
style[nvalue] = MOLECULE;
|
||||
cols[nvalue] = 0;
|
||||
atom->molecule_flag = molecule_flag = 1;
|
||||
values_peratom++;
|
||||
nvalue++;
|
||||
iarg++;
|
||||
} else if (strcmp(arg[iarg],"q") == 0) {
|
||||
if (atom->q_flag)
|
||||
error->all(FLERR,"Fix property/atom q when atom_style "
|
||||
@ -64,8 +70,11 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (q_flag)
|
||||
error->all(FLERR,"Fix property/atom cannot specify q twice");
|
||||
style[nvalue] = CHARGE;
|
||||
cols[nvalue] = 0;
|
||||
atom->q_flag = q_flag = 1;
|
||||
values_peratom++;
|
||||
nvalue++;
|
||||
iarg++;
|
||||
} else if (strcmp(arg[iarg],"rmass") == 0) {
|
||||
if (atom->rmass_flag)
|
||||
error->all(FLERR,"Fix property/atom rmass when atom_style "
|
||||
@ -73,27 +82,45 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (rmass_flag)
|
||||
error->all(FLERR,"Fix property/atom cannot specify rmass twice");
|
||||
style[nvalue] = RMASS;
|
||||
cols[nvalue] = 0;
|
||||
atom->rmass_flag = rmass_flag = 1;
|
||||
values_peratom++;
|
||||
nvalue++;
|
||||
} else if (strstr(arg[iarg],"i_") == arg[iarg]) {
|
||||
style[nvalue] = INTEGER;
|
||||
int tmp;
|
||||
index[nvalue] = atom->find_custom(&arg[iarg][2],tmp);
|
||||
iarg++;
|
||||
} else if (strstr(arg[iarg],"i_") == arg[iarg] ||
|
||||
strstr(arg[iarg],"d_") == arg[iarg]) {
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
if (which == 0) style[nvalue] = IVEC;
|
||||
else style[nvalue] = DVEC;
|
||||
int tmp1,tmp2;
|
||||
index[nvalue] = atom->find_custom(&arg[iarg][2],tmp1,tmp2);
|
||||
if (index[nvalue] >= 0)
|
||||
error->all(FLERR,"Fix property/atom vector name already exists");
|
||||
index[nvalue] = atom->add_custom(&arg[iarg][2],0);
|
||||
cols[nvalue] = 0;
|
||||
index[nvalue] = atom->add_custom(&arg[iarg][2],which,cols[nvalue]);
|
||||
values_peratom++;
|
||||
nvalue++;
|
||||
} else if (strstr(arg[iarg],"d_") == arg[iarg]) {
|
||||
style[nvalue] = DOUBLE;
|
||||
int tmp;
|
||||
index[nvalue] = atom->find_custom(&arg[iarg][2],tmp);
|
||||
iarg++;
|
||||
} else if (strstr(arg[iarg],"i2_") == arg[iarg] ||
|
||||
strstr(arg[iarg],"d2_") == arg[iarg]) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix property/atom command");
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
if (which == 0) style[nvalue] = IARRAY;
|
||||
else style[nvalue] = DARRAY;
|
||||
int tmp1,tmp2;
|
||||
index[nvalue] = atom->find_custom(&arg[iarg][3],tmp1,tmp2);
|
||||
if (index[nvalue] >= 0)
|
||||
error->all(FLERR,"Fix property/atom vector name already exists");
|
||||
index[nvalue] = atom->add_custom(&arg[iarg][2],1);
|
||||
error->all(FLERR,"Fix property/atom array name already exists");
|
||||
cols[nvalue] = utils::inumeric(FLERR,arg[iarg+1],true,lmp);
|
||||
if (cols[nvalue] < 1)
|
||||
error->all(FLERR,"Invalid array columns in fix property/atom");
|
||||
index[nvalue] = atom->add_custom(&arg[iarg][3],which,cols[nvalue]);
|
||||
values_peratom += cols[nvalue];
|
||||
nvalue++;
|
||||
iarg += 2;
|
||||
} else break;
|
||||
|
||||
iarg++;
|
||||
}
|
||||
|
||||
// optional args
|
||||
@ -109,7 +136,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
} else error->all(FLERR,"Illegal fix property/atom command");
|
||||
}
|
||||
|
||||
if (border) comm_border = nvalue;
|
||||
if (border) comm_border = values_peratom;
|
||||
|
||||
// warn if mol or charge keyword used without ghost yes
|
||||
|
||||
@ -134,8 +161,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
// register with Atom class
|
||||
|
||||
nmax_old = 0;
|
||||
if (!lmp->kokkos)
|
||||
grow_arrays(atom->nmax);
|
||||
if (!lmp->kokkos) grow_arrays(atom->nmax);
|
||||
atom->add_callback(0);
|
||||
atom->add_callback(1);
|
||||
if (border) atom->add_callback(2);
|
||||
@ -154,27 +180,32 @@ FixPropertyAtom::~FixPropertyAtom()
|
||||
// deallocate per-atom vectors in Atom class
|
||||
// set ptrs to NULL, so they no longer exist for Atom class
|
||||
|
||||
for (int m = 0; m < nvalue; m++) {
|
||||
if (style[m] == MOLECULE) {
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) {
|
||||
atom->molecule_flag = 0;
|
||||
memory->destroy(atom->molecule);
|
||||
atom->molecule = NULL;
|
||||
} else if (style[m] == CHARGE) {
|
||||
} else if (style[nv] == CHARGE) {
|
||||
atom->q_flag = 0;
|
||||
memory->destroy(atom->q);
|
||||
atom->q = NULL;
|
||||
} else if (style[m] == RMASS) {
|
||||
} else if (style[nv] == RMASS) {
|
||||
atom->rmass_flag = 0;
|
||||
memory->destroy(atom->rmass);
|
||||
atom->rmass = NULL;
|
||||
} else if (style[m] == INTEGER) {
|
||||
atom->remove_custom(0,index[m]);
|
||||
} else if (style[m] == DOUBLE) {
|
||||
atom->remove_custom(1,index[m]);
|
||||
} else if (style[nv] == IVEC) {
|
||||
atom->remove_custom(index[nv],0,cols[nv]);
|
||||
} else if (style[nv] == DVEC) {
|
||||
atom->remove_custom(index[nv],1,cols[nv]);
|
||||
} else if (style[nv] == IARRAY) {
|
||||
atom->remove_custom(index[nv],0,cols[nv]);
|
||||
} else if (style[nv] == DARRAY) {
|
||||
atom->remove_custom(index[nv],1,cols[nv]);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] style;
|
||||
delete [] cols;
|
||||
delete [] index;
|
||||
delete [] astyle;
|
||||
}
|
||||
@ -206,7 +237,7 @@ void FixPropertyAtom::init()
|
||||
void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf,
|
||||
tagint id_offset)
|
||||
{
|
||||
int j,m;
|
||||
int j,k,m,iword,ncol,nv;
|
||||
tagint itag;
|
||||
char *next;
|
||||
|
||||
@ -222,7 +253,7 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf,
|
||||
int nwords = utils::trim_and_count_words(buf);
|
||||
*next = '\n';
|
||||
|
||||
if (nwords != nvalue+1)
|
||||
if (nwords != values_peratom+1)
|
||||
error->all(FLERR,fmt::format("Incorrect {} format in data file",keyword));
|
||||
|
||||
char **values = new char*[nwords];
|
||||
@ -254,16 +285,27 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf,
|
||||
"data file",itag, keyword));
|
||||
|
||||
// assign words in line to per-atom vectors
|
||||
|
||||
// iword = position in vector of words
|
||||
|
||||
if ((m = atom->map(itag)) >= 0) {
|
||||
for (j = 0; j < nvalue; j++) {
|
||||
if (style[j] == MOLECULE) atom->molecule[m] = ATOTAGINT(values[j+1]);
|
||||
else if (style[j] == CHARGE) atom->q[m] = atof(values[j+1]);
|
||||
else if (style[j] == RMASS) atom->rmass[m] = atof(values[j+1]);
|
||||
else if (style[j] == INTEGER)
|
||||
atom->ivector[index[j]][m] = atoi(values[j+1]);
|
||||
else if (style[j] == DOUBLE)
|
||||
atom->dvector[index[j]][m] = atof(values[j+1]);
|
||||
iword = 1;
|
||||
for (nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) atom->molecule[m] = ATOTAGINT(values[iword++]);
|
||||
else if (style[nv] == CHARGE) atom->q[m] = atof(values[iword++]);
|
||||
else if (style[nv] == RMASS) atom->rmass[m] = atof(values[iword++]);
|
||||
else if (style[nv] == IVEC)
|
||||
atom->ivector[index[nv]][m] = atoi(values[iword++]);
|
||||
else if (style[nv] == DVEC)
|
||||
atom->dvector[index[nv]][m] = atof(values[iword++]);
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->iarray[index[nv]][m][k] = atoi(values[iword++]);
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->darray[index[nv]][m][k] = atof(values[iword++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,13 +333,13 @@ bigint FixPropertyAtom::read_data_skip_lines(char * /*keyword*/)
|
||||
return size I own for Mth data section
|
||||
# of data sections = 1 for this fix
|
||||
nx = # of local atoms
|
||||
ny = columns = tag + nvalues
|
||||
ny = columns = tag + values_peratom
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixPropertyAtom::write_data_section_size(int /*mth*/, int &nx, int &ny)
|
||||
{
|
||||
nx = atom->nlocal;
|
||||
ny = nvalue + 1;
|
||||
ny = values_peratom + 1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -307,7 +349,7 @@ void FixPropertyAtom::write_data_section_size(int /*mth*/, int &nx, int &ny)
|
||||
|
||||
void FixPropertyAtom::write_data_section_pack(int /*mth*/, double **buf)
|
||||
{
|
||||
int i;
|
||||
int i,k,ncol;
|
||||
|
||||
// 1st column = atom tag
|
||||
// rest of columns = per-atom values
|
||||
@ -317,23 +359,42 @@ void FixPropertyAtom::write_data_section_pack(int /*mth*/, double **buf)
|
||||
|
||||
for (i = 0; i < nlocal; i++) buf[i][0] = ubuf(tag[i]).d;
|
||||
|
||||
for (int m = 0; m < nvalue; m++) {
|
||||
int mp1 = m+1;
|
||||
if (style[m] == MOLECULE) {
|
||||
int icol = 1;
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) {
|
||||
tagint *molecule = atom->molecule;
|
||||
for (i = 0; i < nlocal; i++) buf[i][mp1] = ubuf(molecule[i]).d;
|
||||
} else if (style[m] == CHARGE) {
|
||||
for (i = 0; i < nlocal; i++) buf[i][icol] = ubuf(molecule[i]).d;
|
||||
icol++;
|
||||
} else if (style[nv] == CHARGE) {
|
||||
double *q = atom->q;
|
||||
for (i = 0; i < nlocal; i++) buf[i][mp1] = q[i];
|
||||
} else if (style[m] == RMASS) {
|
||||
for (i = 0; i < nlocal; i++) buf[i][icol] = q[i];
|
||||
icol++;
|
||||
} else if (style[nv] == RMASS) {
|
||||
double *rmass = atom->rmass;
|
||||
for (i = 0; i < nlocal; i++) buf[i][mp1] = rmass[i];
|
||||
} else if (style[m] == INTEGER) {
|
||||
int *ivec = atom->ivector[index[m]];
|
||||
for (i = 0; i < nlocal; i++) buf[i][mp1] = ubuf(ivec[i]).d;
|
||||
} else if (style[m] == DOUBLE) {
|
||||
double *dvec = atom->dvector[index[m]];
|
||||
for (i = 0; i < nlocal; i++) buf[i][mp1] = dvec[i];
|
||||
for (i = 0; i < nlocal; i++) buf[i][icol] = rmass[i];
|
||||
icol++;
|
||||
} else if (style[nv] == IVEC) {
|
||||
int *ivec = atom->ivector[index[nv]];
|
||||
for (i = 0; i < nlocal; i++) buf[i][icol] = ubuf(ivec[i]).d;
|
||||
icol++;
|
||||
} else if (style[nv] == DVEC) {
|
||||
double *dvec = atom->dvector[index[nv]];
|
||||
for (i = 0; i < nlocal; i++) buf[i][icol] = dvec[i];
|
||||
icol++;
|
||||
} else if (style[nv] == IARRAY) {
|
||||
int **iarray = atom->iarray[index[nv]];
|
||||
ncol = cols[nv];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[i][icol+k] = ubuf(iarray[i][k]).d;
|
||||
icol += ncol;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
double **darray = atom->darray[index[nv]];
|
||||
ncol = cols[nv];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[i][icol+k] = ubuf(darray[i][k]).d;
|
||||
icol += ncol;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -361,16 +422,33 @@ void FixPropertyAtom::write_data_section_keyword(int /*mth*/, FILE *fp)
|
||||
void FixPropertyAtom::write_data_section(int /*mth*/, FILE *fp,
|
||||
int n, double **buf, int /*index*/)
|
||||
{
|
||||
int m;
|
||||
int k,icol,ncol,nv;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
fprintf(fp,TAGINT_FORMAT,(tagint) ubuf(buf[i][0]).i);
|
||||
for (m = 0; m < nvalue; m++) {
|
||||
if (style[m] == MOLECULE)
|
||||
fprintf(fp," " TAGINT_FORMAT,(tagint) ubuf(buf[i][m+1]).i);
|
||||
else if (style[m] == INTEGER)
|
||||
fprintf(fp," %d",(int) ubuf(buf[i][m+1]).i);
|
||||
else fprintf(fp," %g",buf[i][m+1]);
|
||||
icol = 1;
|
||||
for (nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE)
|
||||
fprintf(fp," " TAGINT_FORMAT,(tagint) ubuf(buf[i][icol++]).i);
|
||||
else if (style[nv] == CHARGE)
|
||||
fprintf(fp," %g",buf[i][icol++]);
|
||||
else if (style[nv] == RMASS)
|
||||
fprintf(fp," %g",buf[i][icol++]);
|
||||
else if (style[nv] == IVEC)
|
||||
fprintf(fp," %d",(int) ubuf(buf[i][icol++]).i);
|
||||
else if (style[nv] == DVEC)
|
||||
fprintf(fp," %g",buf[i][icol++]);
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
fprintf(fp," %d",(int) ubuf(buf[i][icol+k]).i);
|
||||
icol += ncol;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
fprintf(fp," %g",buf[i][icol+k]);
|
||||
icol += ncol;
|
||||
}
|
||||
}
|
||||
fprintf(fp,"\n");
|
||||
}
|
||||
@ -387,42 +465,52 @@ double FixPropertyAtom::memory_usage()
|
||||
if (style[m] == MOLECULE) bytes = atom->nmax * sizeof(tagint);
|
||||
else if (style[m] == CHARGE) bytes = atom->nmax * sizeof(double);
|
||||
else if (style[m] == RMASS) bytes = atom->nmax * sizeof(double);
|
||||
else if (style[m] == INTEGER) bytes = atom->nmax * sizeof(int);
|
||||
else if (style[m] == DOUBLE) bytes = atom->nmax * sizeof(double);
|
||||
else if (style[m] == IVEC) bytes = atom->nmax * sizeof(int);
|
||||
else if (style[m] == DVEC) bytes = atom->nmax * sizeof(double);
|
||||
else if (style[m] == IARRAY) bytes = atom->nmax * cols[m] * sizeof(int);
|
||||
else if (style[m] == DARRAY) bytes = atom->nmax * cols[m] * sizeof(double);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
allocate atom-based arrays
|
||||
initialize new values to 0,
|
||||
since AtomVec class won't do it as atoms are added,
|
||||
e.g. in create_atom() or data_atom()
|
||||
also initialize new values to 0
|
||||
since AtomVec class won't do it as atoms are added,
|
||||
e.g. in create_atom() or data_atom()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixPropertyAtom::grow_arrays(int nmax)
|
||||
{
|
||||
for (int m = 0; m < nvalue; m++) {
|
||||
if (style[m] == MOLECULE) {
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) {
|
||||
memory->grow(atom->molecule,nmax,"atom:molecule");
|
||||
size_t nbytes = (nmax-nmax_old) * sizeof(tagint);
|
||||
memset(&atom->molecule[nmax_old],0,nbytes);
|
||||
} else if (style[m] == CHARGE) {
|
||||
} else if (style[nv] == CHARGE) {
|
||||
memory->grow(atom->q,nmax,"atom:q");
|
||||
size_t nbytes = (nmax-nmax_old) * sizeof(double);
|
||||
memset(&atom->q[nmax_old],0,nbytes);
|
||||
} else if (style[m] == RMASS) {
|
||||
} else if (style[nv] == RMASS) {
|
||||
memory->grow(atom->rmass,nmax,"atom:rmass");
|
||||
size_t nbytes = (nmax-nmax_old) * sizeof(double);
|
||||
memset(&atom->rmass[nmax_old],0,nbytes);
|
||||
} else if (style[m] == INTEGER) {
|
||||
memory->grow(atom->ivector[index[m]],nmax,"atom:ivector");
|
||||
} else if (style[nv] == IVEC) {
|
||||
memory->grow(atom->ivector[index[nv]],nmax,"atom:ivector");
|
||||
size_t nbytes = (nmax-nmax_old) * sizeof(int);
|
||||
memset(&atom->ivector[index[m]][nmax_old],0,nbytes);
|
||||
} else if (style[m] == DOUBLE) {
|
||||
memory->grow(atom->dvector[index[m]],nmax,"atom:dvector");
|
||||
memset(&atom->ivector[index[nv]][nmax_old],0,nbytes);
|
||||
} else if (style[nv] == DVEC) {
|
||||
memory->grow(atom->dvector[index[nv]],nmax,"atom:dvector");
|
||||
size_t nbytes = (nmax-nmax_old) * sizeof(double);
|
||||
memset(&atom->dvector[index[m]][nmax_old],0,nbytes);
|
||||
memset(&atom->dvector[index[nv]][nmax_old],0,nbytes);
|
||||
} else if (style[nv] == IARRAY) {
|
||||
memory->grow(atom->iarray[index[nv]],nmax,cols[nv],"atom:iarray");
|
||||
size_t nbytes = (nmax-nmax_old) * cols[nv] * sizeof(int);
|
||||
if (nbytes) memset(&atom->iarray[index[nv]][nmax_old][0],0,nbytes);
|
||||
} else if (style[nv] == DARRAY) {
|
||||
memory->grow(atom->darray[index[nv]],nmax,cols[nv],"atom:darray");
|
||||
size_t nbytes = (nmax-nmax_old) * cols[nv] * sizeof(double);
|
||||
if (nbytes) memset(&atom->darray[index[nv]][nmax_old][0],0,nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,17 +523,28 @@ void FixPropertyAtom::grow_arrays(int nmax)
|
||||
|
||||
void FixPropertyAtom::copy_arrays(int i, int j, int /*delflag*/)
|
||||
{
|
||||
for (int m = 0; m < nvalue; m++) {
|
||||
if (style[m] == MOLECULE)
|
||||
int k,ncol;
|
||||
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE)
|
||||
atom->molecule[j] = atom->molecule[i];
|
||||
else if (style[m] == CHARGE)
|
||||
else if (style[nv] == CHARGE)
|
||||
atom->q[j] = atom->q[i];
|
||||
else if (style[m] == RMASS)
|
||||
else if (style[nv] == RMASS)
|
||||
atom->rmass[j] = atom->rmass[i];
|
||||
else if (style[m] == INTEGER)
|
||||
atom->ivector[index[m]][j] = atom->ivector[index[m]][i];
|
||||
else if (style[m] == DOUBLE)
|
||||
atom->dvector[index[m]][j] = atom->dvector[index[m]][i];
|
||||
else if (style[nv] == IVEC)
|
||||
atom->ivector[index[nv]][j] = atom->ivector[index[nv]][i];
|
||||
else if (style[nv] == DVEC)
|
||||
atom->dvector[index[nv]][j] = atom->dvector[index[nv]][i];
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->iarray[index[nv]][j][k] = atom->iarray[index[nv]][i][k];
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->darray[index[nv]][j][k] = atom->darray[index[nv]][i][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,40 +554,56 @@ void FixPropertyAtom::copy_arrays(int i, int j, int /*delflag*/)
|
||||
|
||||
int FixPropertyAtom::pack_border(int n, int *list, double *buf)
|
||||
{
|
||||
int i,j,k;
|
||||
int i,j,k,ncol;
|
||||
|
||||
int m = 0;
|
||||
for (k = 0; k < nvalue; k++) {
|
||||
if (style[k] == MOLECULE) {
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) {
|
||||
tagint *molecule = atom->molecule;
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
buf[m++] = ubuf(molecule[j]).d;
|
||||
}
|
||||
} else if (style[k] == CHARGE) {
|
||||
} else if (style[nv] == CHARGE) {
|
||||
double *q = atom->q;
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
buf[m++] = q[j];
|
||||
}
|
||||
} else if (style[k] == RMASS) {
|
||||
} else if (style[nv] == RMASS) {
|
||||
double *rmass = atom->rmass;
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
buf[m++] = rmass[j];
|
||||
}
|
||||
} else if (style[k] == INTEGER) {
|
||||
int *ivector = atom->ivector[index[k]];
|
||||
} else if (style[nv] == IVEC) {
|
||||
int *ivector = atom->ivector[index[nv]];
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
buf[m++] = ubuf(ivector[j]).d;
|
||||
}
|
||||
} else if (style[k] == DOUBLE) {
|
||||
double *dvector = atom->dvector[index[k]];
|
||||
} else if (style[nv] == DVEC) {
|
||||
double *dvector = atom->dvector[index[nv]];
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
buf[m++] = dvector[j];
|
||||
}
|
||||
} else if (style[nv] == IARRAY) {
|
||||
int **iarray = atom->iarray[index[nv]];
|
||||
ncol = cols[nv];
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[m++] = ubuf(iarray[j][k]).d;
|
||||
}
|
||||
} else if (style[nv] == DARRAY) {
|
||||
double **darray = atom->darray[index[nv]];
|
||||
ncol = cols[nv];
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[m++] = darray[j][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,35 +616,49 @@ int FixPropertyAtom::pack_border(int n, int *list, double *buf)
|
||||
|
||||
int FixPropertyAtom::unpack_border(int n, int first, double *buf)
|
||||
{
|
||||
int i,k,last;
|
||||
int i,k,last,ncol;
|
||||
|
||||
int m = 0;
|
||||
for (k = 0; k < nvalue; k++) {
|
||||
if (style[k] == MOLECULE) {
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) {
|
||||
tagint *molecule = atom->molecule;
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
molecule[i] = (tagint) ubuf(buf[m++]).i;
|
||||
} else if (style[k] == CHARGE) {
|
||||
} else if (style[nv] == CHARGE) {
|
||||
double *q = atom->q;
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
q[i] = buf[m++];
|
||||
} else if (style[k] == RMASS) {
|
||||
} else if (style[nv] == RMASS) {
|
||||
double *rmass = atom->rmass;
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
rmass[i] = buf[m++];
|
||||
} else if (style[k] == INTEGER) {
|
||||
int *ivector = atom->ivector[index[k]];
|
||||
} else if (style[nv] == IVEC) {
|
||||
int *ivector = atom->ivector[index[nv]];
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
ivector[i] = (int) ubuf(buf[m++]).i;
|
||||
} else if (style[k] == DOUBLE) {
|
||||
double *dvector = atom->dvector[index[k]];
|
||||
} else if (style[nv] == DVEC) {
|
||||
double *dvector = atom->dvector[index[nv]];
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
dvector[i] = buf[m++];
|
||||
} else if (style[nv] == IARRAY) {
|
||||
int **iarray = atom->iarray[index[nv]];
|
||||
ncol = cols[nv];
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
for (k = 0; k < ncol; k++)
|
||||
iarray[i][k] = (int) ubuf(buf[m++]).i;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
double **darray = atom->darray[index[nv]];
|
||||
ncol = cols[nv];
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++)
|
||||
for (k = 0; k < ncol; k++)
|
||||
darray[i][k] = buf[m++];
|
||||
}
|
||||
}
|
||||
|
||||
@ -542,14 +671,27 @@ int FixPropertyAtom::unpack_border(int n, int first, double *buf)
|
||||
|
||||
int FixPropertyAtom::pack_exchange(int i, double *buf)
|
||||
{
|
||||
for (int m = 0; m < nvalue; m++) {
|
||||
if (style[m] == MOLECULE) buf[m] = ubuf(atom->molecule[i]).d;
|
||||
else if (style[m] == CHARGE) buf[m] = atom->q[i];
|
||||
else if (style[m] == RMASS) buf[m] = atom->rmass[i];
|
||||
else if (style[m] == INTEGER) buf[m] = ubuf(atom->ivector[index[m]][i]).d;
|
||||
else if (style[m] == DOUBLE) buf[m] = atom->dvector[index[m]][i];
|
||||
int k,ncol;
|
||||
|
||||
int m = 0;
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) buf[m++] = ubuf(atom->molecule[i]).d;
|
||||
else if (style[nv] == CHARGE) buf[m++] = atom->q[i];
|
||||
else if (style[nv] == RMASS) buf[m++] = atom->rmass[i];
|
||||
else if (style[nv] == IVEC) buf[m++] = ubuf(atom->ivector[index[nv]][i]).d;
|
||||
else if (style[nv] == DVEC) buf[m++] = atom->dvector[index[nv]][i];
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[m++] = ubuf(atom->iarray[index[nv]][i][k]).d;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[m++] = atom->darray[index[nv]][i][k];
|
||||
}
|
||||
}
|
||||
return nvalue;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -558,19 +700,32 @@ int FixPropertyAtom::pack_exchange(int i, double *buf)
|
||||
|
||||
int FixPropertyAtom::unpack_exchange(int nlocal, double *buf)
|
||||
{
|
||||
for (int m = 0; m < nvalue; m++) {
|
||||
if (style[m] == MOLECULE)
|
||||
atom->molecule[nlocal] = (tagint) ubuf(buf[m]).i;
|
||||
else if (style[m] == CHARGE)
|
||||
atom->q[nlocal] = buf[m];
|
||||
else if (style[m] == RMASS)
|
||||
atom->rmass[nlocal] = buf[m];
|
||||
else if (style[m] == INTEGER)
|
||||
atom->ivector[index[m]][nlocal] = (int) ubuf(buf[m]).i;
|
||||
else if (style[m] == DOUBLE)
|
||||
atom->dvector[index[m]][nlocal] = buf[m];
|
||||
int k,ncol;
|
||||
|
||||
int m = 0;
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE)
|
||||
atom->molecule[nlocal] = (tagint) ubuf(buf[m++]).i;
|
||||
else if (style[nv] == CHARGE)
|
||||
atom->q[nlocal] = buf[m++];
|
||||
else if (style[nv] == RMASS)
|
||||
atom->rmass[nlocal] = buf[m++];
|
||||
else if (style[nv] == IVEC)
|
||||
atom->ivector[index[nv]][nlocal] = (int) ubuf(buf[m++]).i;
|
||||
else if (style[nv] == DVEC)
|
||||
atom->dvector[index[nv]][nlocal] = buf[m++];
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->iarray[index[nv]][nlocal][k] = (int) ubuf(buf[m++]).i;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->darray[index[nv]][nlocal][k] = buf[m++];
|
||||
}
|
||||
}
|
||||
return nvalue;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -579,19 +734,31 @@ int FixPropertyAtom::unpack_exchange(int nlocal, double *buf)
|
||||
|
||||
int FixPropertyAtom::pack_restart(int i, double *buf)
|
||||
{
|
||||
int k,ncol;
|
||||
|
||||
// pack buf[0] this way because other fixes unpack it
|
||||
buf[0] = nvalue+1;
|
||||
|
||||
buf[0] = values_peratom+1;
|
||||
|
||||
int m = 1;
|
||||
for (int j = 0; j < nvalue; j++) {
|
||||
if (style[j] == MOLECULE) buf[m++] = ubuf(atom->molecule[i]).d;
|
||||
else if (style[j] == CHARGE) buf[m++] = atom->q[i];
|
||||
else if (style[j] == RMASS) buf[m++] = atom->rmass[i];
|
||||
else if (style[j] == INTEGER) buf[m++] = ubuf(atom->ivector[index[j]][i]).d;
|
||||
else if (style[j] == DOUBLE) buf[m++] = atom->dvector[index[j]][i];
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE) buf[m++] = ubuf(atom->molecule[i]).d;
|
||||
else if (style[nv] == CHARGE) buf[m++] = atom->q[i];
|
||||
else if (style[nv] == RMASS) buf[m++] = atom->rmass[i];
|
||||
else if (style[nv] == IVEC) buf[m++] = ubuf(atom->ivector[index[nv]][i]).d;
|
||||
else if (style[nv] == DVEC) buf[m++] = atom->dvector[index[nv]][i];
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[m++] = ubuf(atom->iarray[index[nv]][i][k]).d;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
buf[m++] = atom->darray[index[nv]][i][k];
|
||||
}
|
||||
}
|
||||
|
||||
return nvalue+1;
|
||||
return values_peratom+1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -600,6 +767,7 @@ int FixPropertyAtom::pack_restart(int i, double *buf)
|
||||
|
||||
void FixPropertyAtom::unpack_restart(int nlocal, int nth)
|
||||
{
|
||||
int k,ncol;
|
||||
double **extra = atom->extra;
|
||||
|
||||
// skip to Nth set of extra values
|
||||
@ -609,17 +777,26 @@ void FixPropertyAtom::unpack_restart(int nlocal, int nth)
|
||||
for (int i = 0; i < nth; i++) m += static_cast<int> (extra[nlocal][m]);
|
||||
m++;
|
||||
|
||||
for (int i = 0; i < nvalue; i++) {
|
||||
if (style[i] == MOLECULE)
|
||||
for (int nv = 0; nv < nvalue; nv++) {
|
||||
if (style[nv] == MOLECULE)
|
||||
atom->molecule[nlocal] = (tagint) ubuf(extra[nlocal][m++]).i;
|
||||
else if (style[i] == CHARGE)
|
||||
else if (style[nv] == CHARGE)
|
||||
atom->q[nlocal] = extra[nlocal][m++];
|
||||
else if (style[i] == RMASS)
|
||||
else if (style[nv] == RMASS)
|
||||
atom->rmass[nlocal] = extra[nlocal][m++];
|
||||
else if (style[i] == INTEGER)
|
||||
atom->ivector[index[i]][nlocal] = (int) ubuf(extra[nlocal][m++]).i;
|
||||
else if (style[i] == DOUBLE)
|
||||
atom->dvector[index[i]][nlocal] = extra[nlocal][m++];
|
||||
else if (style[nv] == IVEC)
|
||||
atom->ivector[index[nv]][nlocal] = (int) ubuf(extra[nlocal][m++]).i;
|
||||
else if (style[nv] == DVEC)
|
||||
atom->dvector[index[nv]][nlocal] = extra[nlocal][m++];
|
||||
else if (style[nv] == IARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->iarray[index[nv]][nlocal][k] = (int) ubuf(extra[nlocal][m++]).i;
|
||||
} else if (style[nv] == DARRAY) {
|
||||
ncol = cols[nv];
|
||||
for (k = 0; k < ncol; k++)
|
||||
atom->darray[index[nv]][nlocal][k] = extra[nlocal][m++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,7 +806,7 @@ void FixPropertyAtom::unpack_restart(int nlocal, int nth)
|
||||
|
||||
int FixPropertyAtom::maxsize_restart()
|
||||
{
|
||||
return nvalue+1;
|
||||
return values_peratom+1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -638,5 +815,5 @@ int FixPropertyAtom::maxsize_restart()
|
||||
|
||||
int FixPropertyAtom::size_restart(int /*nlocal*/)
|
||||
{
|
||||
return nvalue+1;
|
||||
return values_peratom+1;
|
||||
}
|
||||
|
||||
@ -52,10 +52,13 @@ class FixPropertyAtom : public Fix {
|
||||
|
||||
protected:
|
||||
int nvalue,border;
|
||||
int molecule_flag,q_flag,rmass_flag;
|
||||
int *style,*index;
|
||||
char *astyle;
|
||||
int molecule_flag,q_flag,rmass_flag; // flags for specific fields
|
||||
int *style; // style of each value, see enum
|
||||
int *index; // indices into atom custom data structs
|
||||
int *cols; // columns per value, for arrays
|
||||
char *astyle; // atom style at instantiation
|
||||
|
||||
int values_peratom; // # of values per atom, including multiple for arrays
|
||||
int nmax_old; // length of peratom arrays the last time they grew
|
||||
};
|
||||
|
||||
|
||||
@ -20,17 +20,18 @@
|
||||
#include "group.h"
|
||||
#include "modify.h"
|
||||
#include "compute.h"
|
||||
#include "force.h"
|
||||
#include "fix.h"
|
||||
#include "input.h"
|
||||
#include "variable.h"
|
||||
#include "utils.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
enum{KEYWORD,COMPUTE,FIX,VARIABLE,DNAME,INAME};
|
||||
enum{KEYWORD,COMPUTE,FIX,VARIABLE,IVEC,DVEC,IARRAY,DARRAY};
|
||||
|
||||
#define INVOKED_PERATOM 8
|
||||
|
||||
@ -224,15 +225,11 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) :
|
||||
pack_choice[nvalues++] = &FixStoreState::pack_tqz;
|
||||
|
||||
} else if (strncmp(arg[iarg],"c_",2) == 0 ||
|
||||
strncmp(arg[iarg],"d_",2) == 0 ||
|
||||
strncmp(arg[iarg],"f_",2) == 0 ||
|
||||
strncmp(arg[iarg],"i_",2) == 0 ||
|
||||
strncmp(arg[iarg],"v_",2) == 0) {
|
||||
cfv_any = 1;
|
||||
if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
|
||||
else if (arg[iarg][0] == 'd') which[nvalues] = DNAME;
|
||||
else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
|
||||
else if (arg[iarg][0] == 'i') which[nvalues] = INAME;
|
||||
else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
|
||||
|
||||
int n = strlen(arg[iarg]);
|
||||
@ -241,11 +238,50 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (which[nvalues] == VARIABLE)
|
||||
error->all(FLERR,"Illegal fix store/state command");
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Illegal fix store/state command");
|
||||
argindex[nvalues] = atoi(ptr+1);
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[nvalues] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else argindex[nvalues] = 0;
|
||||
|
||||
n = strlen(suffix) + 1;
|
||||
ids[nvalues] = new char[n];
|
||||
strcpy(ids[nvalues],suffix);
|
||||
nvalues++;
|
||||
delete [] suffix;
|
||||
|
||||
} else if (strncmp(arg[iarg],"i_",2) == 0 ||
|
||||
strncmp(arg[iarg],"d_",2) == 0 ||
|
||||
strncmp(arg[iarg],"i2_",3) == 0 ||
|
||||
strncmp(arg[iarg],"d2_",3) == 0) {
|
||||
if (strncmp(arg[iarg],"i_",2) == 0) which[nvalues] = IVEC;
|
||||
else if (strncmp(arg[iarg],"d_",2) == 0) which[nvalues] = DVEC;
|
||||
else if (strncmp(arg[iarg],"i2_",3) == 0) which[nvalues] = IARRAY;
|
||||
else if (strncmp(arg[iarg],"d2_",3) == 0) which[nvalues] = DARRAY;
|
||||
|
||||
int n = strlen(arg[iarg]);
|
||||
char *suffix = new char[n];
|
||||
if (which[nvalues] == IVEC || which[nvalues] == DVEC)
|
||||
strcpy(suffix,&arg[iarg][2]);
|
||||
else strcpy(suffix,&arg[iarg][3]);
|
||||
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (which[nvalues] == IVEC || which[nvalues] == DVEC)
|
||||
error->all(FLERR,"Illegal fix store/state command");
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Illegal fix store/state command");
|
||||
suffix[strlen(suffix)-1] = '\0';
|
||||
argindex[nvalues] = utils::inumeric(FLERR,ptr+1,true,lmp);
|
||||
*ptr = '\0';
|
||||
} else {
|
||||
if (which[nvalues] == IARRAY || which[nvalues] == DARRAY)
|
||||
error->all(FLERR,"Illegal fix store/state command");
|
||||
argindex[nvalues] = 0;
|
||||
}
|
||||
|
||||
n = strlen(suffix) + 1;
|
||||
ids[nvalues] = new char[n];
|
||||
@ -274,68 +310,79 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
// error check
|
||||
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
if (which[i] == COMPUTE) {
|
||||
int icompute = modify->find_compute(ids[i]);
|
||||
for (int m = 0; m < nvalues; m++) {
|
||||
if (which[m] == COMPUTE) {
|
||||
int icompute = modify->find_compute(ids[m]);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Compute ID for fix store/state does not exist");
|
||||
if (modify->compute[icompute]->peratom_flag == 0)
|
||||
error->all(FLERR,"Fix store/state compute "
|
||||
"does not calculate per-atom values");
|
||||
if (argindex[i] == 0 &&
|
||||
if (argindex[m] == 0 &&
|
||||
modify->compute[icompute]->size_peratom_cols != 0)
|
||||
error->all(FLERR,"Fix store/state compute does not "
|
||||
"calculate a per-atom vector");
|
||||
if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
|
||||
if (argindex[m] && modify->compute[icompute]->size_peratom_cols == 0)
|
||||
error->all(FLERR,
|
||||
"Fix store/state compute does not "
|
||||
"calculate a per-atom array");
|
||||
if (argindex[i] &&
|
||||
argindex[i] > modify->compute[icompute]->size_peratom_cols)
|
||||
if (argindex[m] &&
|
||||
argindex[m] > modify->compute[icompute]->size_peratom_cols)
|
||||
error->all(FLERR,
|
||||
"Fix store/state compute array is accessed out-of-range");
|
||||
|
||||
} else if (which[i] == INAME) {
|
||||
int icustom,iflag;
|
||||
icustom = atom->find_custom(ids[i],iflag);
|
||||
if ((icustom < 0) || (iflag != 0))
|
||||
error->all(FLERR,
|
||||
"Custom integer vector for fix store/state does not exist");
|
||||
|
||||
} else if (which[i] == DNAME) {
|
||||
int icustom,iflag;
|
||||
icustom = atom->find_custom(ids[i],iflag);
|
||||
if ((icustom < 0) || (iflag != 1))
|
||||
error->all(FLERR,
|
||||
"Custom floating point vector for fix store/state does not exist");
|
||||
|
||||
} else if (which[i] == FIX) {
|
||||
int ifix = modify->find_fix(ids[i]);
|
||||
|
||||
} else if (which[m] == FIX) {
|
||||
int ifix = modify->find_fix(ids[m]);
|
||||
if (ifix < 0)
|
||||
error->all(FLERR,
|
||||
"Fix ID for fix store/state does not exist");
|
||||
if (modify->fix[ifix]->peratom_flag == 0)
|
||||
error->all(FLERR,
|
||||
"Fix store/state fix does not calculate per-atom values");
|
||||
if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0)
|
||||
if (argindex[m] == 0 && modify->fix[ifix]->size_peratom_cols != 0)
|
||||
error->all(FLERR,
|
||||
"Fix store/state fix does not calculate a per-atom vector");
|
||||
if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
|
||||
if (argindex[m] && modify->fix[ifix]->size_peratom_cols == 0)
|
||||
error->all(FLERR,
|
||||
"Fix store/state fix does not calculate a per-atom array");
|
||||
if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols)
|
||||
if (argindex[m] && argindex[m] > modify->fix[ifix]->size_peratom_cols)
|
||||
error->all(FLERR,
|
||||
"Fix store/state fix array is accessed out-of-range");
|
||||
if (nevery % modify->fix[ifix]->peratom_freq)
|
||||
error->all(FLERR,
|
||||
"Fix for fix store/state not computed at compatible time");
|
||||
|
||||
} else if (which[i] == VARIABLE) {
|
||||
int ivariable = input->variable->find(ids[i]);
|
||||
} else if (which[m] == VARIABLE) {
|
||||
int ivariable = input->variable->find(ids[m]);
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Variable name for fix store/state does not exist");
|
||||
if (input->variable->atomstyle(ivariable) == 0)
|
||||
error->all(FLERR,"Fix store/state variable is not atom-style variable");
|
||||
|
||||
} else if (which[m] == IVEC) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if ((icustom < 0) || flag || cols)
|
||||
error->all(FLERR,
|
||||
"Custom integer vector for fix store/state does not exist");
|
||||
} else if (which[m] == DVEC) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if ((icustom < 0) || !flag || cols)
|
||||
error->all(FLERR,
|
||||
"Custom floating point vector for fix store/state does not exist");
|
||||
} else if (which[m] == IARRAY) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if ((icustom < 0) || flag || !cols)
|
||||
error->all(FLERR,
|
||||
"Custom integer array for fix store/state does not exist");
|
||||
} else if (which[m] == DARRAY) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if ((icustom < 0) || !flag || !cols)
|
||||
error->all(FLERR,
|
||||
"Custom floating point array for fix store/state does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,22 +460,6 @@ void FixStoreState::init()
|
||||
error->all(FLERR,"Compute ID for fix store/state does not exist");
|
||||
value2index[m] = icompute;
|
||||
|
||||
} else if (which[m] == INAME) {
|
||||
int icustom,iflag;
|
||||
icustom = atom->find_custom(ids[m],iflag);
|
||||
if ((icustom < 0) || (iflag != 0))
|
||||
error->all(FLERR,
|
||||
"Custom integer vector for fix store/state does not exist");
|
||||
value2index[m] = icustom;
|
||||
|
||||
} else if (which[m] == DNAME) {
|
||||
int icustom,iflag;
|
||||
icustom = atom->find_custom(ids[m],iflag);
|
||||
if ((icustom < 0) || (iflag != 1))
|
||||
error->all(FLERR,
|
||||
"Custom floating point vector for fix store/state does not exist");
|
||||
value2index[m] = icustom;
|
||||
|
||||
} else if (which[m] == FIX) {
|
||||
int ifix = modify->find_fix(ids[m]);
|
||||
if (ifix < 0)
|
||||
@ -440,6 +471,35 @@ void FixStoreState::init()
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Variable name for fix store/state does not exist");
|
||||
value2index[m] = ivariable;
|
||||
|
||||
} else if (which[m] == IVEC) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if (icustom < 0 || flag || cols)
|
||||
error->all(FLERR,
|
||||
"Custom integer vector for fix store/state does not exist");
|
||||
value2index[m] = icustom;
|
||||
} else if (which[m] == DVEC) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if (icustom < 0 || !flag || cols)
|
||||
error->all(FLERR,
|
||||
"Custom floating point vector for fix store/state does not exist");
|
||||
value2index[m] = icustom;
|
||||
} else if (which[m] == IARRAY) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if (icustom < 0 || flag || !cols)
|
||||
error->all(FLERR,
|
||||
"Custom integer array for fix store/state does not exist");
|
||||
value2index[m] = icustom;
|
||||
} else if (which[m] == DARRAY) {
|
||||
int icustom,flag,cols;
|
||||
icustom = atom->find_custom(ids[m],flag,cols);
|
||||
if (icustom < 0 || !flag || !cols)
|
||||
error->all(FLERR,
|
||||
"Custom floating point array for fix store/state does not exist");
|
||||
value2index[m] = icustom;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -525,22 +585,33 @@ void FixStoreState::end_of_step()
|
||||
if (mask[i] & groupbit) values[i][m] = fix_array[i][jm1];
|
||||
}
|
||||
|
||||
// access custom atom property fields
|
||||
|
||||
} else if (which[m] == INAME) {
|
||||
int *ivector = atom->ivector[n];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) values[i][m] = ivector[i];
|
||||
|
||||
} else if (which[m] == DNAME) {
|
||||
double *dvector = atom->dvector[n];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) values[i][m] = dvector[i];
|
||||
|
||||
// evaluate atom-style variable
|
||||
|
||||
} else if (which[m] == VARIABLE) {
|
||||
input->variable->compute_atom(n,igroup,&values[0][m],nvalues,0);
|
||||
|
||||
// access custom atom property fields
|
||||
|
||||
} else if (which[m] == IVEC) {
|
||||
int *ivector = atom->ivector[n];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) values[i][m] = ivector[i];
|
||||
} else if (which[m] == DVEC) {
|
||||
double *dvector = atom->dvector[n];
|
||||
for (i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) values[i][m] = dvector[i];
|
||||
} else if (which[m] == IARRAY) {
|
||||
int **iarray = atom->iarray[n];
|
||||
int jm1 = j - 1;
|
||||
for (i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit)
|
||||
values[i][m] = iarray[i][jm1];
|
||||
} else if (which[m] == DARRAY) {
|
||||
double **darray = atom->darray[n];
|
||||
int jm1 = j - 1;
|
||||
for (i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit)
|
||||
values[i][m] = darray[i][jm1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,18 +47,17 @@ int ImbalanceStore::options(int narg, char **arg)
|
||||
|
||||
void ImbalanceStore::compute(double *weight)
|
||||
{
|
||||
int dflag = 0;
|
||||
int idx = atom->find_custom(name,dflag);
|
||||
int flag,cols;
|
||||
int index = atom->find_custom(name,flag,cols);
|
||||
|
||||
// property does not exist
|
||||
|
||||
if (idx < 0 || dflag != 1) return;
|
||||
if (index < 0 || flag != 1 || cols)
|
||||
error->all(FLERR,"Balance weight store vector does not exist");
|
||||
|
||||
double *prop = atom->dvector[idx];
|
||||
double *prop = atom->dvector[index];
|
||||
const int nlocal = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < nlocal; ++i)
|
||||
prop[i] = weight[i];
|
||||
for (int i = 0; i < nlocal; ++i) prop[i] = weight[i];
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
@ -600,8 +600,9 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
expand arg to earg, for arguments with syntax c_ID[*] or f_ID[*]
|
||||
expand arg to earg, for args with syntax c_ID[*], f_ID[*], i2_ID[*], d2_ID[*]
|
||||
fields to consider in input arg range from iarg to narg
|
||||
mode = 0 for args = vectors, mode = 1 for args = arrays
|
||||
return new expanded # of values, and copy them w/out "*" into earg
|
||||
if any expansion occurs, earg is new allocation, must be freed by caller
|
||||
if no expansion occurs, earg just points to arg, caller need not free
|
||||
@ -609,7 +610,7 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
|
||||
int Input::expand_args(int narg, char **arg, int mode, char **&earg)
|
||||
{
|
||||
int n,iarg,index,nlo,nhi,nmax,expandflag,icompute,ifix;
|
||||
int n,iarg,index,nlo,nhi,nmax,expandflag;
|
||||
char *ptr1,*ptr2,*str;
|
||||
|
||||
ptr1 = NULL;
|
||||
@ -633,7 +634,9 @@ int Input::expand_args(int narg, char **arg, int mode, char **&earg)
|
||||
expandflag = 0;
|
||||
|
||||
if (strncmp(arg[iarg],"c_",2) == 0 ||
|
||||
strncmp(arg[iarg],"f_",2) == 0) {
|
||||
strncmp(arg[iarg],"f_",2) == 0 ||
|
||||
strncmp(arg[iarg],"i2_",3) == 0 ||
|
||||
strncmp(arg[iarg],"d2_",3) == 0) {
|
||||
|
||||
ptr1 = strchr(&arg[iarg][2],'[');
|
||||
if (ptr1) {
|
||||
@ -641,9 +644,10 @@ int Input::expand_args(int narg, char **arg, int mode, char **&earg)
|
||||
if (ptr2) {
|
||||
*ptr2 = '\0';
|
||||
if (strchr(ptr1,'*')) {
|
||||
|
||||
if (arg[iarg][0] == 'c') {
|
||||
*ptr1 = '\0';
|
||||
icompute = modify->find_compute(&arg[iarg][2]);
|
||||
int icompute = modify->find_compute(&arg[iarg][2]);
|
||||
*ptr1 = '[';
|
||||
|
||||
// check for global vector/array, peratom array, local array
|
||||
@ -665,9 +669,10 @@ int Input::expand_args(int narg, char **arg, int mode, char **&earg)
|
||||
expandflag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (arg[iarg][0] == 'f') {
|
||||
*ptr1 = '\0';
|
||||
ifix = modify->find_fix(&arg[iarg][2]);
|
||||
int ifix = modify->find_fix(&arg[iarg][2]);
|
||||
*ptr1 = '[';
|
||||
|
||||
// check for global vector/array, peratom array, local array
|
||||
@ -689,10 +694,40 @@ int Input::expand_args(int narg, char **arg, int mode, char **&earg)
|
||||
expandflag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2 = ']';
|
||||
}
|
||||
|
||||
} else if (arg[iarg][0] == 'i') {
|
||||
*ptr1 = '\0';
|
||||
int flag,cols;
|
||||
int icustom = atom->find_custom(&arg[iarg][3],flag,cols);
|
||||
*ptr1 = '[';
|
||||
|
||||
// check for custom per-atom integer array
|
||||
|
||||
if (icustom >= 0) {
|
||||
if (mode == 1 && !flag && cols) {
|
||||
nmax = cols;
|
||||
expandflag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (arg[iarg][0] == 'd') {
|
||||
*ptr1 = '\0';
|
||||
int flag,cols;
|
||||
int icustom = atom->find_custom(&arg[iarg][3],flag,cols);
|
||||
*ptr1 = '[';
|
||||
|
||||
// check for custom per-atom floating point array
|
||||
|
||||
if (icustom >= 0) {
|
||||
if (mode == 1 && flag && cols) {
|
||||
nmax = cols;
|
||||
expandflag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2 = ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
88
src/set.cpp
88
src/set.cpp
@ -45,12 +45,12 @@ using namespace MathConst;
|
||||
enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT};
|
||||
|
||||
enum{TYPE,TYPE_FRACTION,TYPE_RATIO,TYPE_SUBSET,
|
||||
MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI,
|
||||
MOLECULE,X,Y,Z,VX,VY,VZ,CHARGE,MASS,SHAPE,LENGTH,TRI,
|
||||
DIPOLE,DIPOLE_RANDOM,SPIN,SPIN_RANDOM,QUAT,QUAT_RANDOM,
|
||||
THETA,THETA_RANDOM,ANGMOM,OMEGA,
|
||||
DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER,
|
||||
SPH_E,SPH_CV,SPH_RHO,EDPD_TEMP,EDPD_CV,CC,SMD_MASS_DENSITY,
|
||||
SMD_CONTACT_RADIUS,DPDTHETA,INAME,DNAME,VX,VY,VZ};
|
||||
SMD_CONTACT_RADIUS,DPDTHETA,IVEC,DVEC,IARRAY,DARRAY};
|
||||
|
||||
#define BIG INT_MAX
|
||||
|
||||
@ -573,28 +573,63 @@ void Set::command(int narg, char **arg)
|
||||
set(DPDTHETA);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strstr(arg[iarg],"i_") == arg[iarg]) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
|
||||
else ivalue = force->inumeric(FLERR,arg[iarg+1]);
|
||||
int flag;
|
||||
index_custom = atom->find_custom(&arg[iarg][2],flag);
|
||||
if (index_custom < 0 || flag != 0)
|
||||
error->all(FLERR,"Set command integer vector does not exist");
|
||||
set(INAME);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strstr(arg[iarg],"d_") == arg[iarg]) {
|
||||
// custom per-atom vector
|
||||
|
||||
} else if (strstr(arg[iarg],"i_") == arg[iarg] ||
|
||||
strstr(arg[iarg],"d_") == arg[iarg]) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
|
||||
else if (!which) ivalue = force->inumeric(FLERR,arg[iarg+1]);
|
||||
else dvalue = force->numeric(FLERR,arg[iarg+1]);
|
||||
int flag;
|
||||
index_custom = atom->find_custom(&arg[iarg][2],flag);
|
||||
if (index_custom < 0 || flag != 1)
|
||||
error->all(FLERR,"Set command floating point vector does not exist");
|
||||
set(DNAME);
|
||||
|
||||
int flag,cols;
|
||||
index_custom = atom->find_custom(&arg[iarg][2],flag,cols);
|
||||
if ((!which && (index_custom < 0 || flag || cols)) ||
|
||||
(which && (index_custom < 0 || !flag || cols)))
|
||||
error->all(FLERR,"Set command per-atom custom vector does not exist");
|
||||
if (!which) set(IVEC);
|
||||
else set(DVEC);
|
||||
iarg += 2;
|
||||
|
||||
// custom per-atom array, must include bracketed index
|
||||
|
||||
} else if (strstr(arg[iarg],"i2_") == arg[iarg] ||
|
||||
strstr(arg[iarg],"d2_") == arg[iarg]) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
|
||||
int which = 0;
|
||||
if (arg[iarg][0] == 'd') which = 1;
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
|
||||
else if (!which) ivalue = force->inumeric(FLERR,arg[iarg+1]);
|
||||
else dvalue = force->numeric(FLERR,arg[iarg+1]);
|
||||
|
||||
int n = strlen(arg[iarg]);
|
||||
char *suffix = new char[n];
|
||||
strcpy(suffix,&arg[iarg][3]);
|
||||
|
||||
char *ptr = strchr(suffix,'[');
|
||||
if (ptr) {
|
||||
if (suffix[strlen(suffix)-1] != ']')
|
||||
error->all(FLERR,"Invalid attribute in set command");
|
||||
icol_custom = atoi(ptr+1);
|
||||
*ptr = '\0';
|
||||
} else error->all(FLERR,"Set command per-atom custom array is not indexed");
|
||||
|
||||
int flag,cols;
|
||||
index_custom = atom->find_custom(suffix,flag,cols);
|
||||
delete [] suffix;
|
||||
|
||||
if ((!which && (index_custom < 0 || flag || !cols)) ||
|
||||
(which && (index_custom < 0 || !flag || !cols)))
|
||||
error->all(FLERR,"Set command per-atom custom array does not exist");
|
||||
if (icol_custom <= 0 || icol_custom > cols)
|
||||
error->all(FLERR,"Set command per-atom custom array is accessed out-of-range");
|
||||
|
||||
if (!which) set(IARRAY);
|
||||
else set(DARRAY);
|
||||
iarg += 2;
|
||||
|
||||
} else error->all(FLERR,"Illegal set command");
|
||||
|
||||
// statistics
|
||||
@ -970,20 +1005,29 @@ void Set::set(int keyword)
|
||||
(((imageint) (zbox + IMGMAX) & IMGMASK) << IMG2BITS);
|
||||
}
|
||||
|
||||
// set value for custom integer or double vector
|
||||
// set value for custom vector or array
|
||||
|
||||
else if (keyword == INAME) {
|
||||
else if (keyword == IVEC) {
|
||||
atom->ivector[index_custom][i] = ivalue;
|
||||
}
|
||||
|
||||
else if (keyword == DNAME) {
|
||||
else if (keyword == DVEC) {
|
||||
atom->dvector[index_custom][i] = dvalue;
|
||||
}
|
||||
|
||||
else if (keyword == IARRAY) {
|
||||
atom->iarray[index_custom][i][icol_custom-1] = ivalue;
|
||||
}
|
||||
|
||||
else if (keyword == DARRAY) {
|
||||
atom->darray[index_custom][i][icol_custom-1] = dvalue;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// update bonus data numbers
|
||||
|
||||
if (keyword == SHAPE) {
|
||||
bigint nlocal_bonus = avec_ellipsoid->nlocal_bonus;
|
||||
MPI_Allreduce(&nlocal_bonus,&atom->nellipsoids,1,
|
||||
|
||||
Reference in New Issue
Block a user