From d1442b0538d85e5890edbc52b512c356fb611143 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 4 Sep 2020 11:33:49 -0600 Subject: [PATCH 01/36] enable per-atom custom arrays in addition to vectors --- doc/src/balance.rst | 18 +- doc/src/compute_property_atom.rst | 117 ++++---- doc/src/dump.rst | 45 +-- doc/src/fix_property_atom.rst | 258 +++++++++-------- doc/src/fix_store_state.rst | 35 ++- doc/src/group.rst | 37 ++- doc/src/set.rst | 34 ++- src/Makefile | 1 + src/atom.cpp | 202 ++++++++++--- src/atom.h | 17 +- src/compute_property_atom.cpp | 171 +++++++---- src/compute_property_atom.h | 20 +- src/dump_custom.cpp | 279 +++++++++++------- src/dump_custom.h | 25 +- src/fix_group.cpp | 34 ++- src/fix_group.h | 2 +- src/fix_property_atom.cpp | 453 +++++++++++++++++++++--------- src/fix_property_atom.h | 9 +- src/fix_store_state.cpp | 199 ++++++++----- src/imbalance_store.cpp | 13 +- src/input.cpp | 53 +++- src/set.cpp | 88 ++++-- src/set.h | 2 +- 23 files changed, 1390 insertions(+), 722 deletions(-) diff --git a/doc/src/balance.rst b/doc/src/balance.rst index e023b6f2f0..afa43cbc2f 100644 --- a/doc/src/balance.rst +++ b/doc/src/balance.rst @@ -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 ` command. Note that -these custom per-atom properties can be output in a :doc:`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 ` command. This means +the values in the vector can be read as part of a data file with the +:doc:`read_data ` command or specified with the :doc:`set +` command. These weights can also be output in a :doc:`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. ---------- diff --git a/doc/src/compute_property_atom.rst b/doc/src/compute_property_atom.rst index ec9322bb7b..b455b7ae53 100644 --- a/doc/src/compute_property_atom.rst +++ b/doc/src/compute_property_atom.rst @@ -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 ` 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 `, :doc:`fix ave/histo `, :doc:`fix ave/chunk `, and :doc:`atom-style variable ` commands. -The list of possible attributes is the same as that used by the -:doc:`dump custom ` command, which describes their meaning, with -some additional quantities that are only defined for certain -:doc:`atom styles `. 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 ` command, which describes their +meaning, with some additional quantities that are only defined for +certain :doc:`atom styles `. 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 ` 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 ` 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 ` 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 ` 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 ` 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 ` 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 ` 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 """"""""""" diff --git a/doc/src/dump.rst b/doc/src/dump.rst index 36a20defb6..2b7e6d7bae 100644 --- a/doc/src/dump.rst +++ b/doc/src/dump.rst @@ -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 ` 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 ` 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 `. +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 ` 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 ` doc page for information on how to add new compute and fix styles to LAMMPS to calculate per-atom quantities diff --git a/doc/src/fix_property_atom.rst b/doc/src/fix_property_atom.rst index eaf246c1a3..584451cba1 100644 --- a/doc/src/fix_property_atom.rst +++ b/doc/src/fix_property_atom.rst @@ -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 ` 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 ` and -:doc:`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 ` 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 ` 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 ` 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 +` 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 ` 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 ` 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 ` @@ -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 ` - 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 ` 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 ` or - :doc:`fix ` or :doc:`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 ` or :doc:`fix ` or + :doc:`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 ` command -as described below. +This is so it can be used with the :doc:`read_data ` +command as described next. -Per-atom properties that are defined by the :doc:`atom style ` are initialized when atoms are created, e.g. by -the :doc:`read_data ` or :doc:`create_atoms ` +Per-atom properties that are defined by the :doc:`atom style +` are initialized when atoms are created, e.g. by the +:doc:`read_data ` or :doc:`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 ` 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 ` 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 +` 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 ` 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 ` 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 ` 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 ` can also be used in -place of atom-style variables, which means in this case that the +Note that :doc:`atomfile-style variables ` 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 ` 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 ` command can access -their values. This means that the values can be output via the :doc:`dump custom ` command, accessed by fixes like :doc:`fix ave/atom `, accessed by other computes like :doc:`compute reduce `, or used in :doc:`atom-style variables `. +For new atom properties specified as *i_name*, *d_name*, *i2_name*, or +*d2_name*, the :doc:`dump custom ` and :doc:`compute +property/atom ` commands can access their +values. This means that the values can be used accessed by fixes like +:doc:`fix ave/atom `, accessed by other computes like +:doc:`compute reduce `, or used in :doc:`atom-style +variables `. -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 `, -:doc:`fixes `, or :doc:`computes ` that use the per-atom -properties defined by this fix, see the :doc:`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 `, :doc:`fixes +`, or :doc:`computes ` that use the per-atom properties +defined by this fix, see the :doc:`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 ` 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 ` 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 ` -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 +` 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 `, so that the values can be restored when a -simulation is restarted. See the :doc:`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 `, so that the values can be restored when a simulation +is restarted. See the :doc:`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 ` options are relevant to this -fix. No global or per-atom quantities are stored by this fix for +None of the :doc:`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 `. No parameter of this fix can be used with the *start/stop* keywords of the -:doc:`run ` command. This fix is not invoked during :doc:`energy minimization `. +:doc:`run ` command. This fix is not invoked during :doc:`energy +minimization `. Restrictions """""""""""" @@ -290,9 +311,10 @@ Restrictions Related commands """""""""""""""" -:doc:`read_data `, :doc:`set `, :doc:`compute property/atom ` +:doc:`read_data `, :doc:`set `, +:doc:`compute property/atom ` Default """"""" -The default keyword values are ghost = no. +The default keyword value is ghost = no. diff --git a/doc/src/fix_store_state.rst b/doc/src/fix_store_state.rst index 5f42e3ef5d..dee46e2086 100644 --- a/doc/src/fix_store_state.rst +++ b/doc/src/fix_store_state.rst @@ -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 ` command, which describes their meaning. +The list of possible attributes is the same as that used by the +:doc:`dump custom ` 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 `, so that the values can be restored when a -simulation is restarted. See the :doc:`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 `, so that the values can be restored when a simulation +is restarted. See the :doc:`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 ` options are relevant to this @@ -121,7 +125,8 @@ can be accessed by various :doc:`output commands `. 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 ` command. This fix is not invoked during :doc:`energy minimization `. +the :doc:`run ` command. This fix is not invoked during +:doc:`energy minimization `. Restrictions """""""""""" diff --git a/doc/src/group.rst b/doc/src/group.rst index 6371a030ee..61690c4d42 100644 --- a/doc/src/group.rst +++ b/doc/src/group.rst @@ -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 ` command. This means the values in +the vector can be read as part of a data file with the :doc:`read_data +` command or specified with the :doc:`set ` command. +Or accessed and changed via the :doc:`library interface to LAMMPS +`, 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 ` command, an assignment is made at the beginning of the minimization, but not during the iterations of the minimizer. diff --git a/doc/src/set.rst b/doc/src/set.rst index f830149569..82b577ca9f 100644 --- a/doc/src/set.rst +++ b/doc/src/set.rst @@ -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 ` 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 ` 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 """""""""""" diff --git a/src/Makefile b/src/Makefile index 4528c027cf..80d0a91a98 100644 --- a/src/Makefile +++ b/src/Makefile @@ -260,6 +260,7 @@ clean: clean-all: rm -rf Obj_* + rm style_*.h packages_*.h lmpgitversion.h lmpinstalledpkgs.h clean-%: @if [ $@ = "clean-serial" ]; \ diff --git a/src/atom.cpp b/src/atom.cpp index e930a0255e..4e2b82fb30 100644 --- a/src/atom.cpp +++ b/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 // -------------------------------------------------------------------- diff --git a/src/atom.h b/src/atom.h index 4dac15d758..a2e69e06f2 100644 --- a/src/atom.h +++ b/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) {} diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 9c637edc1e..173665154c 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -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(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); } diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h index cab9d3ea1b..2b087204d2 100644 --- a/src/compute_property_atom.h +++ b/src/compute_property_atom.h @@ -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); }; } diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 3297ecb4e7..2f89991c93 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -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"); + "dsrealloc(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; + } } } diff --git a/src/dump_custom.h b/src/dump_custom.h index 0f63eac8de..d800acf525 100644 --- a/src/dump_custom.h +++ b/src/dump_custom.h @@ -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(); diff --git a/src/fix_group.cpp b/src/fix_group.cpp index d2eea9f781..17f1d3c60b 100644 --- a/src/fix_group.cpp +++ b/src/fix_group.cpp @@ -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; diff --git a/src/fix_group.h b/src/fix_group.h index f3fecac316..56e4ade06d 100644 --- a/src/fix_group.h +++ b/src/fix_group.h @@ -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; diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 374d0069fd..2b004a0ba8 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -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 (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; } diff --git a/src/fix_property_atom.h b/src/fix_property_atom.h index 9e0236f61e..3e491ea861 100644 --- a/src/fix_property_atom.h +++ b/src/fix_property_atom.h @@ -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 }; diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index e1e2aab663..cdda399fff 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -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]; } } } diff --git a/src/imbalance_store.cpp b/src/imbalance_store.cpp index 919d1f3f61..f42e8df031 100644 --- a/src/imbalance_store.cpp +++ b/src/imbalance_store.cpp @@ -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]; } /* -------------------------------------------------------------------- */ diff --git a/src/input.cpp b/src/input.cpp index dd640f18b0..1069cbf944 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -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 = ']'; + } } } diff --git a/src/set.cpp b/src/set.cpp index 01176f68c0..d7a8337f81 100644 --- a/src/set.cpp +++ b/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, diff --git a/src/set.h b/src/set.h index 6788849677..bbbe08bc47 100644 --- a/src/set.h +++ b/src/set.h @@ -32,7 +32,7 @@ class Set : protected Pointers { private: char *id; int *select; - int style,ivalue,newtype,count,index_custom; + int style,ivalue,newtype,count,index_custom,icol_custom; int ximage,yimage,zimage,ximageflag,yimageflag,zimageflag; int cc_index; bigint nsubset; From 76725731fdea07180a6a1e2f7d79df26ff02047a Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 8 Sep 2020 13:48:41 -0600 Subject: [PATCH 02/36] changes in package files to match new find_custom() syntax --- doc/src/fix_rigid.rst | 21 +++---- src/RIGID/fix_rigid.cpp | 12 ++-- src/RIGID/fix_rigid_small.cpp | 13 ++-- src/USER-REACTION/fix_bond_react.cpp | 36 +++++------ src/USER-VTK/dump_vtk.cpp | 90 ++++++++++++++++++---------- 5 files changed, 95 insertions(+), 77 deletions(-) diff --git a/doc/src/fix_rigid.rst b/doc/src/fix_rigid.rst index a143817303..3811cc2be1 100644 --- a/doc/src/fix_rigid.rst +++ b/doc/src/fix_rigid.rst @@ -64,7 +64,7 @@ Syntax *single* args = none *molecule* args = none *custom* args = *i_propname* or *v_varname* - i_propname = an integer property defined via fix property/atom + i_propname = a custom integer vector defined via fix property/atom v_varname = an atom-style or atomfile-style variable *group* args = N groupID1 groupID2 ... N = # of groups @@ -287,15 +287,16 @@ includes atoms you want to be part of rigid bodies. Bodystyle *custom* is similar to bodystyle *molecule* except that it is more flexible in using other per-atom properties to define the sets -of atoms that form rigid bodies. An integer vector defined by the -:doc:`fix property/atom ` command can be used. Or an -:doc:`atom-style or atomfile-style variable ` can be used; the -floating-point value produced by the variable is rounded to an -integer. As with bodystyle *molecule*\ , each set of atoms in the fix -groups with the same integer value is treated as a different rigid -body. Since fix property/atom vectors and atom-style variables -produce values for all atoms, you should be careful to use a fix group -that only includes atoms you want to be part of rigid bodies. +of atoms that form rigid bodies. A custom per-atom integer vector +defined by the :doc:`fix property/atom ` command +can be used. Or an :doc:`atom-style or atomfile-style variable +` can be used; the floating-point value produced by the +variable is rounded to an integer. As with bodystyle *molecule*\ , +each set of atoms in the fix groups with the same integer value is +treated as a different rigid body. Since fix property/atom custom +vectors and atom-style variables produce values for all atoms, you +should be careful to use a fix group that only includes atoms you want +to be part of rigid bodies. .. note:: diff --git a/src/RIGID/fix_rigid.cpp b/src/RIGID/fix_rigid.cpp index 0d15f22090..5e6f48e2cb 100644 --- a/src/RIGID/fix_rigid.cpp +++ b/src/RIGID/fix_rigid.cpp @@ -129,14 +129,10 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // determine whether atom-style variable or atom property is used if (strstr(arg[4],"i_") == arg[4]) { - int is_double=0; - int custom_index = atom->find_custom(arg[4]+2,is_double); - if (custom_index == -1) - error->all(FLERR,"Fix rigid custom requires " - "previously defined property/atom"); - else if (is_double) - error->all(FLERR,"Fix rigid custom requires " - "integer-valued property/atom"); + int flag,cols; + int custom_index = atom->find_custom(arg[4]+2,flag,cols); + if (custom_index < 0 || !flag || cols) + error->all(FLERR,"Fix rigid custom requires custom integer vector"); int minval = INT_MAX; int *value = atom->ivector[custom_index]; for (i = 0; i < nlocal; i++) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index f12c53bf3a..ff31ce9e2a 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -113,15 +113,10 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : // determine whether atom-style variable or atom property is used if (strstr(arg[4],"i_") == arg[4]) { - int is_double=0; - int custom_index = atom->find_custom(arg[4]+2,is_double); - if (custom_index == -1) - error->all(FLERR,"Fix rigid/small custom requires " - "previously defined property/atom"); - else if (is_double) - error->all(FLERR,"Fix rigid/small custom requires " - "integer-valued property/atom"); - + int flag,cols; + int custom_index = atom->find_custom(arg[4]+2,flag,cols); + if (custom_index < 0 || !flag || cols) + error->all(FLERR,"Fix rigid custom requires custom integer vector"); int minval = INT_MAX; int *value = atom->ivector[custom_index]; for (i = 0; i < nlocal; i++) diff --git a/src/USER-REACTION/fix_bond_react.cpp b/src/USER-REACTION/fix_bond_react.cpp index 29aa476148..38760a8c98 100644 --- a/src/USER-REACTION/fix_bond_react.cpp +++ b/src/USER-REACTION/fix_bond_react.cpp @@ -683,8 +683,8 @@ void FixBondReact::post_constructor() // initialize per-atom statted_flags to 1 // (only if not already initialized by restart) if (fix3->restart_reset != 1) { - int flag; - int index = atom->find_custom("statted_tags",flag); + int flag,cols; + int index = atom->find_custom("statted_tags",flag,cols); int *i_statted_tags = atom->ivector[index]; for (int i = 0; i < atom->nlocal; i++) @@ -715,8 +715,8 @@ void FixBondReact::post_constructor() // initialize per-atom statted_tags to 1 // need to correct for smooth restarts - //int flag; - //int index = atom->find_custom(statted_id,flag); + //int flag,cols; + //int index = atom->find_custom(statted_id,flag,cols); //int *i_statted_tags = atom->ivector[index]; //for (int i = 0; i < atom->nlocal; i++) // i_statted_tags[i] = 1; @@ -1021,8 +1021,8 @@ void FixBondReact::far_partner() firstneigh = list->firstneigh; // per-atom property indicating if in bond/react master group - int flag; - int index1 = atom->find_custom("limit_tags",flag); + int flag,cols; + int index1 = atom->find_custom("limit_tags",flag,cols); int *i_limit_tags = atom->ivector[index1]; int i,j; @@ -1108,8 +1108,8 @@ void FixBondReact::close_partner() int *mask = atom->mask; // per-atom property indicating if in bond/react master group - int flag; - int index1 = atom->find_custom("limit_tags",flag); + int flag,cols; + int index1 = atom->find_custom("limit_tags",flag,cols); int *i_limit_tags = atom->ivector[index1]; // loop over special list @@ -1377,8 +1377,8 @@ void FixBondReact::make_a_guess() int nfirst_neighs = onemol_nxspecial[pion][0]; // per-atom property indicating if in bond/react master group - int flag; - int index1 = atom->find_custom("limit_tags",flag); + int flag,cols; + int index1 = atom->find_custom("limit_tags",flag,cols); int *i_limit_tags = atom->ivector[index1]; if (status == GUESSFAIL && avail_guesses == 0) { @@ -2341,17 +2341,17 @@ void FixBondReact::limit_bond(int limit_bond_mode) // we must keep our own list of limited atoms // this will be a new per-atom property! - int flag; - int index1 = atom->find_custom("limit_tags",flag); + int flag,cols; + int index1 = atom->find_custom("limit_tags",flag,cols); int *i_limit_tags = atom->ivector[index1]; int *i_statted_tags; if (stabilization_flag == 1) { - int index2 = atom->find_custom(statted_id,flag); + int index2 = atom->find_custom(statted_id,flag,cols); i_statted_tags = atom->ivector[index2]; } - int index3 = atom->find_custom("react_tags",flag); + int index3 = atom->find_custom("react_tags",flag,cols); int *i_react_tags = atom->ivector[index3]; for (int i = 0; i < temp_limit_num; i++) { @@ -2374,17 +2374,17 @@ void FixBondReact::unlimit_bond() //let's now unlimit in terms of i_limit_tags //we just run through all nlocal, looking for > limit_duration //then we return i_limit_tag to 0 (which removes from dynamic group) - int flag; - int index1 = atom->find_custom("limit_tags",flag); + int flag,cols; + int index1 = atom->find_custom("limit_tags",flag,cols); int *i_limit_tags = atom->ivector[index1]; int *i_statted_tags; if (stabilization_flag == 1) { - int index2 = atom->find_custom(statted_id,flag); + int index2 = atom->find_custom(statted_id,flag,cols); i_statted_tags = atom->ivector[index2]; } - int index3 = atom->find_custom("react_tags",flag); + int index3 = atom->find_custom("react_tags",flag,cols); int *i_react_tags = atom->ivector[index3]; for (int i = 0; i < atom->nlocal; i++) { diff --git a/src/USER-VTK/dump_vtk.cpp b/src/USER-VTK/dump_vtk.cpp index 7f1443c654..b10a8cec41 100644 --- a/src/USER-VTK/dump_vtk.cpp +++ b/src/USER-VTK/dump_vtk.cpp @@ -237,9 +237,15 @@ void DumpVTK::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 vtk 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 @@ -1511,6 +1517,7 @@ int DumpVTK::parse_fields(int narg, char **arg) name[Z] = "z"; // customize by adding to if statement + int i; for (int iarg = 5; iarg < narg; iarg++) { i = iarg-5; @@ -1825,49 +1832,67 @@ int DumpVTK::parse_fields(int narg, char **arg) name[ATTRIBUTES+i] = suffix; delete [] suffix; - // custom per-atom floating point value = d_ID + // custom per-atom integer value = i_ID or d_ID + + } else if (strncmp(arg[iarg],"i_",2) == 0 || + strncmp(arg[iarg],"d_",2) == 0) { + int which = 0; + if (arg[iarg][0] == 'd') which = 1; - } else if (strncmp(arg[iarg],"d_",2) == 0) { pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_custom; - vtype[ATTRIBUTES+i] = Dump::DOUBLE; + if (!which) vtype[ATTRIBUTES+i] = Dump::INT; + else vtype[ATTRIBUTES+i] = Dump::DOUBLE; int n = strlen(arg[iarg]); char *suffix = new char[n]; strcpy(suffix,&arg[iarg][2]); argindex[ATTRIBUTES+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 vtk per-atom custom vector does not exist"); - if (tmp != 1) - error->all(FLERR,"Custom per-atom property ID is not floating point"); - - field2index[ATTRIBUTES+i] = add_custom(suffix,1); + field2index[ATTRIBUTES+i] = add_custom(suffix); name[ATTRIBUTES+i] = 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[ATTRIBUTES+i] = &DumpVTK::pack_custom; - vtype[ATTRIBUTES+i] = Dump::INT; + if (!which) vtype[ATTRIBUTES+i] = Dump::INT; + else vtype[ATTRIBUTES+i] = Dump::DOUBLE; int n = strlen(arg[iarg]); char *suffix = new char[n]; - strcpy(suffix,&arg[iarg][2]); - argindex[ATTRIBUTES+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[ATTRIBUTES+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 vtk per-atom custom array does not exist"); + if (argindex[i] <= 0 || argindex[i] > cols) + error->all(FLERR, + "Dump vtk per-atom custom array is accessed out-of-range"); - field2index[ATTRIBUTES+i] = add_custom(suffix,0); + field2index[i] = add_custom(suffix); name[ATTRIBUTES+i] = suffix; delete [] suffix; @@ -2006,27 +2031,28 @@ int DumpVTK::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 DumpVTK::add_custom(char *id, int flag) +int DumpVTK::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; From 64257393b9de5df9d00bea933eb848a4d6259fdb Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 9 Sep 2020 10:21:59 -0600 Subject: [PATCH 03/36] remove custom vector usage from USER-DPD:fix_rx.cpp --- src/USER-DPD/fix_rx.cpp | 42 ----------------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index 77efd1842b..809535ea77 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -1327,10 +1327,6 @@ void FixRX::odeDiagnostics(void) TimerType now = getTimeStamp(); - // Query the fix database and look for rx_weight for the balance fix. - int type_flag = -1; - int rx_weight_index = atom->find_custom( "rx_weight", /*0:int, 1:float*/ type_flag ); - // Compute the average # of neighbors. double averageNumNeighbors = 0; { @@ -1349,44 +1345,6 @@ void FixRX::odeDiagnostics(void) printf("me= %d nst= %g nfc= %g time= %g nlocal= %g lmpnst= %g weight_idx= %d 1st= %d aveNeigh= %g\n", comm->me, this->diagnosticCounter[0], this->diagnosticCounter[1], this->diagnosticCounter[2], this->diagnosticCounter[3], this->diagnosticCounter[4], rx_weight_index, firstStep, averageNumNeighbors); - if (rx_weight_index != -1 && !firstStep && 0) - { - double *rx_weight = atom->dvector[rx_weight_index]; - - const int nlocal = atom->nlocal; - const int *mask = atom->mask; - - if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) - { - const double total_time = getElapsedTime( oldTimeStamp, now ); - const double fixrx_time = this->diagnosticCounter[TimeSum]; - const double time_ratio = fixrx_time / total_time; - - double tsum = 0.0; - double tmin = 100000, tmax = 0; - for (int i = 0; i < nlocal; ++i) - if (mask[i] & groupbit) - { - double nfunc_ratio = double( diagnosticCounterPerODE[FuncSum][i] ) / diagnosticCounter[FuncSum]; - rx_weight[i] = nfunc_ratio * fixrx_time + (total_time - fixrx_time) / nlocal; - tmin = fmin( tmin, rx_weight[i] ); - tmax = fmax( tmax, rx_weight[i] ); - tsum += rx_weight[i]; - //rx_weight[i] = (double) diagnosticCounterPerODE[FuncSum][i]; - } - - printf("me= %d total= %g fixrx= %g ratio= %g tsum= %g %g %g %g\n", comm->me, total_time, fixrx_time, time_ratio, tsum, (total_time - fixrx_time) / nlocal, tmin, tmax); - } - else - { - error->warning(FLERR, "Dynamic load balancing enabled but per-atom weights not available."); - - for (int i = 0; i < nlocal; ++i) - if (mask[i] & groupbit) - rx_weight[i] = 1.0; - } - } - firstStep = false; oldTimeStamp = now; } From bddd26ba6c43d4871c8033c822a35520317d2cc2 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 11 Jan 2021 17:26:00 -0700 Subject: [PATCH 04/36] additional changes needed to merge with current master --- src/library.cpp | 283 +++++++++++++++++++++++++++++++++--------------- src/set.cpp | 8 +- src/utils.cpp | 5 +- 3 files changed, 201 insertions(+), 95 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index 7d3f2f8996..2630973c3d 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2650,9 +2650,10 @@ void lammps_scatter_atoms_subset(void *handle, char *name, int type, int count, see gather_concat() to return data for all atoms, unordered see gather_subset() to return data for only a subset of atoms name = "x" , "f" or other atom properties - "d_name" or "i_name" for fix property/atom quantities - "f_fix", "c_compute" for fixes / computes - will return error if fix/compute doesn't isn't atom-based + "f_fix", "c_compute" for fixes / computes + "d_name" or "i_name" for fix property/atom vectors with count = 1 + "d2_name" or "i2_name" for fix property/atom arrays with count > 1 + will return error if fix/compute isn't atom-based type = 0 for integer values, 1 for double values count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f use count = 3 with "image" if want single image flag unpacked into xyz @@ -2673,12 +2674,13 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) BEGIN_CAPTURE { #if defined(LAMMPS_BIGBIG) - lmp->error->all(FLERR,"Library function lammps_gather" - " not compatible with -DLAMMPS_BIGBIG"); + lmp->error->all(FLERR,"Library function lammps_gather" + " not compatible with -DLAMMPS_BIGBIG"); #else - int i,j,offset,fcid,ltype; + int i,j,offset,fcid,ltype,icol; // error if tags are not defined or not consecutive + int flag = 0; if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) flag = 1; @@ -2690,10 +2692,11 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) } int natoms = static_cast (lmp->atom->natoms); - void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && strstr(name,"f_") == name) { // fix + // fix + + if (vptr==nullptr && strstr(name,"f_") == name) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -2726,7 +2729,9 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) else vptr = (void *) lmp->modify->fix[fcid]->array_atom; } - if (vptr==nullptr && strstr(name,"c_") == name) { // compute + // compute + + if (vptr==nullptr && strstr(name,"c_") == name) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -2753,41 +2758,58 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) if (count==1) vptr = (void *) lmp->modify->compute[fcid]->vector_atom; else vptr = (void *) lmp->modify->compute[fcid]->array_atom; - - } - // property / atom - if ( (vptr == nullptr) && ((strstr(name,"d_") == name) - || (strstr(name,"i_") == name))) { - fcid = lmp->atom->find_custom(&name[2], ltype); + + // property/atom + + if ((vptr == nullptr) && + ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || + (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + + if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather: unknown property/atom id"); return; } + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom type"); return; } - if (count != 1) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather: property/atom has count=1"); + lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom count"); return; } - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (count > 1 && icol != count) { + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom count"); + return; + } + + if (count == 1) { + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; + } else { + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; + } } if (vptr == nullptr) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather: unknown property name"); + lmp->error->warning(FLERR,"lammps_gather: undefined property name"); return; } - + // copy = Natom length vector of per-atom values // use atom ID to insert each atom's values into copy // MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID + if (type==0) { int *vector = nullptr; int **array = nullptr; @@ -2829,7 +2851,6 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) lmp->memory->destroy(copy); } else { - double *vector = nullptr; double **array = nullptr; if (count == 1) vector = (double *) vptr; @@ -2869,9 +2890,10 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) see gather() to return data ordered by consecutive atom IDs see gather_subset() to return data for only a subset of atoms name = "x" , "f" or other atom properties - "d_name" or "i_name" for fix property/atom quantities - "f_fix", "c_compute" for fixes / computes - will return error if fix/compute doesn't isn't atom-based + "f_fix", "c_compute" for fixes / computes + "d_name" or "i_name" for fix property/atom vectors with count = 1 + "d2_name" or "i2_name" for fix property/atom arrays with count > 1 + will return error if fix/compute isn't atom-based type = 0 for integer values, 1 for double values count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f use count = 3 with "image" if want single image flag unpacked into xyz @@ -2895,9 +2917,10 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d lmp->error->all(FLERR,"Library function lammps_gather_concat" " not compatible with -DLAMMPS_BIGBIG"); #else - int i,offset,fcid,ltype; + int i,offset,fcid,ltype,icol; // error if tags are not defined or not consecutive + int flag = 0; if (lmp->atom->tag_enable == 0) flag = 1; if (lmp->atom->natoms > MAXSMALLINT) flag = 1; @@ -2907,12 +2930,12 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d return; } - int natoms = static_cast (lmp->atom->natoms); - void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && strstr(name,"f_") == name) { // fix + // fix + + if (vptr==nullptr && strstr(name,"f_") == name) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -2933,8 +2956,6 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d " count != values peratom for fix"); return; } - - if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { if (lmp->comm->me == 0) lmp->error->all(FLERR,"lammps_gather_concat:" @@ -2946,7 +2967,9 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d else vptr = (void *) lmp->modify->fix[fcid]->array_atom; } - if (vptr==nullptr && strstr(name,"c_") == name) { // compute + // compute + + if (vptr==nullptr && strstr(name,"c_") == name) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -2973,39 +2996,55 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if (count==1) vptr = (void *) lmp->modify->compute[fcid]->vector_atom; else vptr = (void *) lmp->modify->compute[fcid]->array_atom; - - } - if (vptr==nullptr && strstr(name,"d_") == name) { // property / atom + // property/atom - fcid = lmp->atom->find_custom(&name[2], ltype); + if ((vptr==nullptr) && + ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || + (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + + if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_concat: " - "unknown property/atom id"); + "unknown property/atom id"); return; } + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_concat: " - "mismatch property/atom type"); + "mismatch property/atom type"); return; } - if (count != 1) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_concat: " - "property/atom has count=1"); + "mismatch property/atom count"); + return; + } + if (count > 1 && icol != count) { + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: " + "mismatch property/atom count"); return; } - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (count == 1) { + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; + } else { + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; + } } if (vptr == nullptr) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: unknown property name"); + lmp->error->warning(FLERR,"lammps_gather_concat: undefined property name"); return; } @@ -3020,6 +3059,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if (type == 0) { int *vector = nullptr; int **array = nullptr; + const int imgunpack = (count == 3) && (strcmp(name,"image") == 0); if ((count == 1) || imgunpack) vector = (int *) vptr; @@ -3111,9 +3151,10 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d see gather() to return data ordered by consecutive atom IDs see gather_concat() to return data for all atoms, unordered name = "x" , "f" or other atom properties - "d_name" or "i_name" for fix property/atom quantities - "f_fix", "c_compute" for fixes / computes - will return error if fix/compute doesn't isn't atom-based + "f_fix", "c_compute" for fixes / computes + "d_name" or "i_name" for fix property/atom vectors with count = 1 + "d2_name" or "i2_name" for fix property/atom arrays with count > 1 + will return error if fix/compute isn't atom-based type = 0 for integer values, 1 for double values count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f use count = 3 with "image" if want single image flag unpacked into xyz @@ -3136,13 +3177,14 @@ void lammps_gather_subset(void *handle, char *name, BEGIN_CAPTURE { #if defined(LAMMPS_BIGBIG) - lmp->error->all(FLERR,"Library function lammps_gather_subset() " + lmp->error->all(FLERR,"Library function lammps_gather_subset() " "is not compatible with -DLAMMPS_BIGBIG"); #else - int i,j,m,offset,fcid,ltype; + int i,j,m,offset,fcid,ltype,icol; tagint id; // error if tags are not defined or not consecutive + int flag = 0; if (lmp->atom->tag_enable == 0) flag = 1; if (lmp->atom->natoms > MAXSMALLINT) flag = 1; @@ -3154,7 +3196,9 @@ void lammps_gather_subset(void *handle, char *name, void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && strstr(name,"f_") == name) { // fix + // fix + + if (vptr==nullptr && strstr(name,"f_") == name) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3169,13 +3213,11 @@ void lammps_gather_subset(void *handle, char *name, " fix does not return peratom data"); return; } - if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { lmp->error->warning(FLERR,"lammps_gather_subset:" - " count != values peratom for fix"); + " count != values peratom for fix"); return; } - if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { if (lmp->comm->me == 0) lmp->error->all(FLERR,"lammps_gather_subset:" @@ -3187,7 +3229,9 @@ void lammps_gather_subset(void *handle, char *name, else vptr = (void *) lmp->modify->fix[fcid]->array_atom; } - if (vptr==nullptr && strstr(name,"c_") == name) { // compute + // compute + + if (vptr==nullptr && strstr(name,"c_") == name) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3214,39 +3258,56 @@ void lammps_gather_subset(void *handle, char *name, if (count==1) vptr = (void *) lmp->modify->compute[fcid]->vector_atom; else vptr = (void *) lmp->modify->compute[fcid]->array_atom; - - } - if (vptr==nullptr && strstr(name,"d_") == name) { // property / atom + // property/atom - fcid = lmp->atom->find_custom(&name[2], ltype); + if ((vptr == nullptr) && + ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || + (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + + if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_subset: " "unknown property/atom id"); return; } + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_subset: " "mismatch property/atom type"); return; } - if (count != 1) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_subset: " - "property/atom has count=1"); + "mismatch property/atom count"); return; } - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (count > 1 && icol != count) { + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: " + "mismatch property/atom count"); + return; + } + + if (count == 1) { + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; + } else { + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; + } } + if (vptr == nullptr) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: " - "unknown property name"); + lmp->error->warning(FLERR,"lammps_gather_subset: undefined property name"); return; } @@ -3304,6 +3365,7 @@ void lammps_gather_subset(void *handle, char *name, } else { double *vector = nullptr; double **array = nullptr; + if (count == 1) vector = (double *) vptr; else array = (double **) vptr; @@ -3346,9 +3408,10 @@ void lammps_gather_subset(void *handle, char *name, requirement for consecutive atom IDs (1 to N) see scatter_subset() to scatter data for some (or all) atoms, unordered name = "x" , "f" or other atom properties - "d_name" or "i_name" for fix property/atom quantities - "f_fix", "c_compute" for fixes / computes - will return error if fix/compute doesn't isn't atom-based + "f_fix", "c_compute" for fixes / computes + "d_name" or "i_name" for fix property/atom vectors with count = 1 + "d2_name" or "i2_name" for fix property/atom arrays with count > 1 + will return error if fix/compute isn't atom-based type = 0 for integer values, 1 for double values count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f use count = 3 with "image" if want single image flag unpacked into xyz @@ -3372,7 +3435,7 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) lmp->error->all(FLERR,"Library function lammps_scatter() " "is not compatible with -DLAMMPS_BIGBIG"); #else - int i,j,m,offset,fcid,ltype; + int i,j,m,offset,fcid,ltype,icol; // error if tags are not defined or not consecutive or no atom map // NOTE: test that name = image or ids is not a 64-bit int in code? @@ -3389,10 +3452,11 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) } int natoms = static_cast (lmp->atom->natoms); - void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && strstr(name,"f_") == name) { // fix + // fix + + if (vptr==nullptr && strstr(name,"f_") == name) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3418,7 +3482,9 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) else vptr = (void *) lmp->modify->fix[fcid]->array_atom; } - if (vptr==nullptr && strstr(name,"c_") == name) { // compute + // compute + + if (vptr==nullptr && strstr(name,"c_") == name) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3445,31 +3511,46 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) if (count==1) vptr = (void *) lmp->modify->compute[fcid]->vector_atom; else vptr = (void *) lmp->modify->compute[fcid]->array_atom; - - } - if (vptr==nullptr && strstr(name,"d_") == name) { // property / atom + // property/atom + + if ((vptr == nullptr) && + ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || + (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { - fcid = lmp->atom->find_custom(&name[2], ltype); + if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter: unknown property/atom id"); return; } + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter: mismatch property/atom type"); return; } - if (count != 1) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_scatter: property/atom has count=1"); + lmp->error->warning(FLERR,"lammps_scatter: mismatch property/atom count"); + return; + } + if (count > 1 && icol != count) { + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter: mismatch property/atom count"); return; } - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (count == 1) { + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; + } else { + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; + } } if (vptr == nullptr) { @@ -3548,7 +3629,10 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) data is ordered by provided atom IDs no requirement for consecutive atom IDs (1 to N) see scatter_atoms() to scatter data for all atoms, ordered by consecutive IDs - name = desired quantity, e.g. x or charge + name = "x" , "f" or other atom properties + "d_name" or "i_name" for fix property/atom quantities + "f_fix", "c_compute" for fixes / computes + will return error if fix/compute doesn't isn't atom-based type = 0 for integer values, 1 for double values count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f use count = 3 with "image" for xyz to be packed into single image flag @@ -3572,7 +3656,7 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, lmp->error->all(FLERR,"Library function lammps_scatter_subset() " "is not compatible with -DLAMMPS_BIGBIG"); #else - int i,j,m,offset,fcid,ltype; + int i,j,m,offset,fcid,ltype,icol; tagint id; // error if tags are not defined or no atom map @@ -3590,7 +3674,9 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && strstr(name,"f_") == name) { // fix + // fix + + if (vptr==nullptr && strstr(name,"f_") == name) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3616,7 +3702,9 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, else vptr = (void *) lmp->modify->fix[fcid]->array_atom; } - if (vptr==nullptr && strstr(name,"c_") == name) { // compute + // compute + + if (vptr==nullptr && strstr(name,"c_") == name) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3645,29 +3733,46 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, else vptr = (void *) lmp->modify->compute[fcid]->array_atom; } - if (vptr==nullptr && strstr(name,"d_") == name) { // property / atom + // property/atom + + if ((vptr == nullptr) && + ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || + (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { - fcid = lmp->atom->find_custom(&name[2], ltype); + if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter_subset: " "unknown property/atom id"); return; } + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter_subset: " "mismatch property/atom type"); return; } - if (count != 1) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_scatter_subset: " - "property/atom has count=1"); + lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom count"); return; } - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (count > 1 && icol != count) { + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom count"); + return; + } + + if (count == 1) { + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; + } else { + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; + } } if (vptr == nullptr) { diff --git a/src/set.cpp b/src/set.cpp index 98b8afb9c8..f83bf6d78d 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -579,8 +579,8 @@ void Set::command(int narg, char **arg) 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]); + else if (!which) ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); int flag,cols; index_custom = atom->find_custom(&arg[iarg][2],flag,cols); @@ -599,8 +599,8 @@ void Set::command(int narg, char **arg) 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]); + else if (!which) ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); int n = strlen(arg[iarg]); char *suffix = new char[n]; diff --git a/src/utils.cpp b/src/utils.cpp index 154f35410e..8fdc5b87e6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -13,6 +13,7 @@ #include "utils.h" +#include "atom.h" #include "comm.h" #include "compute.h" #include "error.h" @@ -503,7 +504,7 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, } else if (arg[iarg][0] == 'i') { *ptr1 = '\0'; int flag,cols; - int icustom = atom->find_custom(&arg[iarg][3],flag,cols); + int icustom = lmp->atom->find_custom(&arg[iarg][3],flag,cols); *ptr1 = '['; // check for custom per-atom integer array @@ -518,7 +519,7 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, } else if (arg[iarg][0] == 'd') { *ptr1 = '\0'; int flag,cols; - int icustom = atom->find_custom(&arg[iarg][3],flag,cols); + int icustom = lmp->atom->find_custom(&arg[iarg][3],flag,cols); *ptr1 = '['; // check for custom per-atom floating point array From 386fe6158a04bc1c686ac2141c321706c9f8f621 Mon Sep 17 00:00:00 2001 From: Plimpton Date: Tue, 12 Jan 2021 09:07:23 -0700 Subject: [PATCH 05/36] edits to doc pages, including per-atom variables --- doc/src/fix_property_atom.rst | 9 +++ doc/src/fix_store_state.rst | 2 +- doc/src/read_data.rst | 12 +++- src/atom.cpp | 102 ++++++++++++++++++++++++---------- 4 files changed, 92 insertions(+), 33 deletions(-) diff --git a/doc/src/fix_property_atom.rst b/doc/src/fix_property_atom.rst index 71e1a52eaf..c7bf3f8c37 100644 --- a/doc/src/fix_property_atom.rst +++ b/doc/src/fix_property_atom.rst @@ -299,6 +299,15 @@ 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. +.. warning:: + + When reading data from a restart file, this fix command has to be specified + **exactly** the same way as before. LAMMPS will only check whether a + fix is of the same style and has the same fix ID and in case of a match + will then try to initialize the fix with the data stored in the binary + restart file. If the fix property/atom command does not match exactly, + data can be corrupted or LAMMPS may crash. + None of the :doc:`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 `. No parameter diff --git a/doc/src/fix_store_state.rst b/doc/src/fix_store_state.rst index 2a0fda4774..756e32162a 100644 --- a/doc/src/fix_store_state.rst +++ b/doc/src/fix_store_state.rst @@ -117,7 +117,7 @@ uninterrupted fashion. .. warning:: - When reading data from a restart, the fix command has to be specified + When reading data from a restart file, this fix command has to be specified **exactly** the same way as before. LAMMPS will only check whether a fix is of the same style and has the same fix ID and in case of a match will then try to initialize the fix with the data stored in the binary diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 5d74d9c28b..dc98924ee1 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -633,12 +633,14 @@ of analysis. - atom-ID molecule-ID atom-type lineflag density x y z * - mdpd - atom-ID atom-type rho x y z + * - mesont + - atom-ID molecule-ID atom-type bond_nt mass mradius mlength buckling x y z * - molecular - atom-ID molecule-ID atom-type x y z * - peri - atom-ID atom-type volume density x y z * - smd - - atom-ID atom-type molecule volume mass kernel-radius contact-radius x0 y0 z0 x y z + - atom-ID atom-type molecule volume mass kradius cradius x0 y0 z0 x y z * - sph - atom-ID atom-type rho esph cv x y z * - sphere @@ -661,8 +663,10 @@ The per-atom values have these meanings and units, listed alphabetically: * atom-ID = integer ID of atom * atom-type = type of atom (1-Ntype) * bodyflag = 1 for body particles, 0 for point particles +* bond_nt = bond NT factor for MESONT particles (?? units) +* buckling = buckling factor for MESONT particles (?? units) * ccN = chemical concentration for tDPD particles for each species (mole/volume units) -* contact-radius = ??? (distance units) +* cradius = contact radius for SMD particles (distance units) * cs_re,cs_im = real/imaginary parts of wave packet coefficients * cv = heat capacity (need units) for SPH particles * density = density of particle (mass/distance\^3 or mass/distance\^2 or mass/distance units, depending on dimensionality of particle) @@ -673,10 +677,12 @@ The per-atom values have these meanings and units, listed alphabetically: * ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles * eradius = electron radius (or fixed-core radius) * etag = integer ID of electron that each wave packet belongs to -* kernel-radius = ??? (distance units) +* kradius = kernel radius for SMD particles (distance units) * lineflag = 1 for line segment particles, 0 for point or spherical particles * mass = mass of particle (mass units) +* mlength = ?? length for MESONT particles (distance units) * molecule-ID = integer ID of molecule the atom belongs to +* mradius = ?? radius for MESONT particles (distance units) * mux,muy,muz = components of dipole moment of atom (dipole units) * q = charge on atom (charge units) * rho = density (need units) for SPH particles diff --git a/src/atom.cpp b/src/atom.cpp index d4aa742fb8..741b2c6821 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2599,6 +2599,22 @@ length of the data area, and a short description. - int - 1 - 1 if the particle is a body particle, 0 if not + * - i_name + - int + - 1 + - single integer value defined by fix property/atom vector name + * - d_name + - double + - 1 + - single double value defined by fix property/atom vector name + * - i2_name + - int + - n + - N integer values defined by fix property/atom array name + * - d2_name + - double + - n + - N double values defined by fix property/atom array name *See also* :cpp:func:`lammps_extract_atom` @@ -2660,29 +2676,6 @@ void *Atom::extract(const char *name) if (strcmp(name,"cv") == 0) return (void *) cv; if (strcmp(name,"vest") == 0) return (void *) vest; - // 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; @@ -2708,13 +2701,35 @@ void *Atom::extract(const char *name) 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]; + } + // end of customization section // -------------------------------------------------------------------- return nullptr; } - /** Provide data type info about internal data of the Atom class * \verbatim embed:rst @@ -2776,11 +2791,8 @@ int Atom::extract_datatype(const char *name) if (strcmp(name,"cv") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"vest") == 0) return LAMMPS_DOUBLE_2D; - // USER-MESONT package - if (strcmp(name,"length") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"buckling") == 0) return LAMMPS_INT; - if (strcmp(name,"bond_nt") == 0) return LAMMPS_TAGINT_2D; - + // USER-SMD package + if (strcmp(name, "contact_radius") == 0) return LAMMPS_DOUBLE; if (strcmp(name, "smd_data_9") == 0) return LAMMPS_DOUBLE_2D; if (strcmp(name, "smd_stress") == 0) return LAMMPS_DOUBLE_2D; @@ -2788,9 +2800,41 @@ int Atom::extract_datatype(const char *name) if (strcmp(name, "eff_plastic_strain_rate") == 0) return LAMMPS_DOUBLE; if (strcmp(name, "damage") == 0) return LAMMPS_DOUBLE; + // USER-DPD package + if (strcmp(name,"dpdTheta") == 0) return LAMMPS_DOUBLE; + + // USER-MESO package + if (strcmp(name,"edpd_temp") == 0) return LAMMPS_DOUBLE; + // USER-MESONT package + + if (strcmp(name,"length") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"buckling") == 0) return LAMMPS_INT; + if (strcmp(name,"bond_nt") == 0) return LAMMPS_TAGINT_2D; + + // 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 -1; + if (which != flag) return -1; + if ((!array && cols) || (array && !cols)) return -1; + + if (which == 0) return LAMMPS_INT; + else return LAMMPS_DOUBLE; + } + // end of customization section // -------------------------------------------------------------------- From 6f4d6570619fc4e0d229204a2fa7d01909d52521 Mon Sep 17 00:00:00 2001 From: Plimpton Date: Tue, 12 Jan 2021 12:28:06 -0700 Subject: [PATCH 06/36] enable pair table/rx for new custom vector syntax --- src/USER-DPD/pair_table_rx.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index cefbe5a73d..4d412d7481 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -329,7 +329,7 @@ void PairTableRX::coeff(int narg, char **arg) int ispecies; for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; + if (strcmp(site1,&atom->dvname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); @@ -339,7 +339,7 @@ void PairTableRX::coeff(int narg, char **arg) strcpy(site2,arg[5]); for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(site2,&atom->dname[ispecies][0]) == 0) break; + if (strcmp(site2,&atom->dvname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) error->all(FLERR,"Site2 name not recognized in pair coefficients"); @@ -406,7 +406,7 @@ void PairTableRX::coeff(int narg, char **arg) isite1 = nspecies; for (int k = 0; k < nspecies; k++) { - if (strcmp(site1, atom->dname[k]) == 0) { + if (strcmp(site1, atom->dvname[k]) == 0) { isite1 = k; break; } @@ -421,7 +421,7 @@ void PairTableRX::coeff(int narg, char **arg) isite2 = nspecies; for (int k = 0; k < nspecies; k++) { - if (strcmp(site2, atom->dname[k]) == 0) { + if (strcmp(site2, atom->dvname[k]) == 0) { isite2 = ispecies; break; } From fc792805482452f699e3c983f31ed7c6d66d68fe Mon Sep 17 00:00:00 2001 From: Plimpton Date: Tue, 12 Jan 2021 12:37:50 -0700 Subject: [PATCH 07/36] other USER-DPD uses of dname vs new dvname --- src/USER-DPD/fix_eos_table_rx.cpp | 4 ++-- src/USER-DPD/fix_rx.cpp | 12 ++++++------ src/USER-DPD/pair_exp6_rx.cpp | 14 +++++++------- src/USER-DPD/pair_multi_lucy_rx.cpp | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/USER-DPD/fix_eos_table_rx.cpp b/src/USER-DPD/fix_eos_table_rx.cpp index 28cd4eb4c3..b1928caebc 100644 --- a/src/USER-DPD/fix_eos_table_rx.cpp +++ b/src/USER-DPD/fix_eos_table_rx.cpp @@ -369,7 +369,7 @@ void FixEOStableRX::read_file(char *file) while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; for (ispecies = 0; ispecies < nspecies; ispecies++) - if (strcmp(words[0],&atom->dname[ispecies][0]) == 0) break; + if (strcmp(words[0],&atom->dvname[ispecies][0]) == 0) break; if (ispecies < nspecies) { dHf[ispecies] = atof(words[1]); @@ -583,7 +583,7 @@ void FixEOStableRX::param_extract(Table *tb, char *line) if (rx_flag) { while (word) { for (ispecies = 0; ispecies < nspecies; ispecies++) - if (strcmp(word,&atom->dname[ispecies][0]) == 0) { + if (strcmp(word,&atom->dvname[ispecies][0]) == 0) { eosSpecies[ncolumn] = ispecies; ncolumn++; break; diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index 00c2452e81..d38a13b69b 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -410,7 +410,7 @@ void FixRX::initSparse() if (comm->me == 0 and Verbosity > 1) { for (int k = 0; k < nspecies; ++k) - printf("atom->dname[%d]= %s\n", k, atom->dname[k]); + printf("atom->dvname[%d]= %s\n", k, atom->dvname[k]); printf("stoich[][]\n"); for (int i = 0; i < nreactions; ++i) { @@ -470,7 +470,7 @@ void FixRX::initSparse() char digit[6]; sprintf(digit, "%4.1f ", stoichReactants[i][k]); rstr += digit; - rstr += atom->dname[k]; + rstr += atom->dvname[k]; } if (stoichProducts[i][k] > 0.0) { allAreIntegral &= (std::fmod( stoichProducts[i][k], 1.0 ) == 0.0); @@ -482,7 +482,7 @@ void FixRX::initSparse() char digit[6]; sprintf(digit, "%4.1f ", stoichProducts[i][k]); pstr += digit; - pstr += atom->dname[k]; + pstr += atom->dvname[k]; } } if (comm->me == 0 and Verbosity > 1) @@ -596,7 +596,7 @@ void FixRX::initSparse() else sprintf(digit,"%4.1f ", sparseKinetics_nu[i][kk]); rstr += digit; - rstr += atom->dname[k]; + rstr += atom->dvname[k]; } } @@ -612,7 +612,7 @@ void FixRX::initSparse() else sprintf(digit,"%4.1f ", sparseKinetics_nu[i][kk]); pstr += digit; - pstr += atom->dname[k]; + pstr += atom->dvname[k]; } } if (comm->me == 0 and Verbosity > 1) @@ -950,7 +950,7 @@ void FixRX::read_file(char *file) tmpStoich = atof(word); word = strtok(nullptr, " \t\n\r\f"); for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(word,&atom->dname[ispecies][0]) == 0) { + if (strcmp(word,&atom->dvname[ispecies][0]) == 0) { stoich[nreactions][ispecies] += sign*tmpStoich; if (sign<0.0) stoichReactants[nreactions][ispecies] += tmpStoich; diff --git a/src/USER-DPD/pair_exp6_rx.cpp b/src/USER-DPD/pair_exp6_rx.cpp index d387ffa3c5..0882825203 100644 --- a/src/USER-DPD/pair_exp6_rx.cpp +++ b/src/USER-DPD/pair_exp6_rx.cpp @@ -602,7 +602,7 @@ void PairExp6rx::coeff(int narg, char **arg) int ispecies; for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; + if (strcmp(site1,&atom->dvname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); @@ -612,7 +612,7 @@ void PairExp6rx::coeff(int narg, char **arg) strcpy(site2,arg[4]); for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(site2,&atom->dname[ispecies][0]) == 0) break; + if (strcmp(site2,&atom->dvname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) error->all(FLERR,"Site2 name not recognized in pair coefficients"); @@ -626,7 +626,7 @@ void PairExp6rx::coeff(int narg, char **arg) { int isp; for (isp = 0; isp < nspecies; isp++) - if (strcmp(site1, &atom->dname[isp][0]) == 0) break; + if (strcmp(site1, &atom->dvname[isp][0]) == 0) break; if (isp == nspecies) error->all(FLERR,"Site1 name not recognized in pair coefficients"); @@ -640,7 +640,7 @@ void PairExp6rx::coeff(int narg, char **arg) { int isp; for (isp = 0; isp < nspecies; isp++) - if (strcmp(site2, &atom->dname[isp][0]) == 0) break; + if (strcmp(site2, &atom->dvname[isp][0]) == 0) break; if (isp == nspecies) error->all(FLERR,"Site2 name not recognized in pair coefficients"); @@ -788,7 +788,7 @@ void PairExp6rx::read_file(char *file) while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; for (ispecies = 0; ispecies < nspecies; ispecies++) - if (strcmp(words[0],&atom->dname[ispecies][0]) == 0) break; + if (strcmp(words[0],&atom->dvname[ispecies][0]) == 0) break; if (ispecies == nspecies) continue; // load up parameter settings and error check their values @@ -806,9 +806,9 @@ void PairExp6rx::read_file(char *file) params[nparams].ispecies = ispecies; - n = strlen(&atom->dname[ispecies][0]) + 1; + n = strlen(&atom->dvname[ispecies][0]) + 1; params[nparams].name = new char[n]; - strcpy(params[nparams].name,&atom->dname[ispecies][0]); + strcpy(params[nparams].name,&atom->dvname[ispecies][0]); n = strlen(words[1]) + 1; params[nparams].potential = new char[n]; diff --git a/src/USER-DPD/pair_multi_lucy_rx.cpp b/src/USER-DPD/pair_multi_lucy_rx.cpp index e1a263b7dc..33a9039ccd 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.cpp +++ b/src/USER-DPD/pair_multi_lucy_rx.cpp @@ -442,7 +442,7 @@ void PairMultiLucyRX::coeff(int narg, char **arg) else { isite1 = nspecies; for (int ispecies = 0; ispecies < nspecies; ++ispecies) - if (strcmp(site1, atom->dname[ispecies]) == 0) { + if (strcmp(site1, atom->dvname[ispecies]) == 0) { isite1 = ispecies; break; } @@ -456,7 +456,7 @@ void PairMultiLucyRX::coeff(int narg, char **arg) else { isite2 = nspecies; for (int ispecies = 0; ispecies < nspecies; ++ispecies) - if (strcmp(site2, atom->dname[ispecies]) == 0) { + if (strcmp(site2, atom->dvname[ispecies]) == 0) { isite2 = ispecies; break; } From b2f96d92df865d14f4f781a12c4e5bf6e4fd3f64 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 13 Jan 2021 10:31:03 -0700 Subject: [PATCH 08/36] remove print statement --- src/USER-DPD/fix_rx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index d38a13b69b..e0c34fd9fd 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -1343,7 +1343,7 @@ void FixRX::odeDiagnostics(void) averageNumNeighbors /= inum; } - printf("me= %d nst= %g nfc= %g time= %g nlocal= %g lmpnst= %g weight_idx= %d 1st= %d aveNeigh= %g\n", comm->me, this->diagnosticCounter[0], this->diagnosticCounter[1], this->diagnosticCounter[2], this->diagnosticCounter[3], this->diagnosticCounter[4], rx_weight_index, firstStep, averageNumNeighbors); + //printf("me= %d nst= %g nfc= %g time= %g nlocal= %g lmpnst= %g weight_idx= %d 1st= %d aveNeigh= %g\n", comm->me, this->diagnosticCounter[0], this->diagnosticCounter[1], this->diagnosticCounter[2], this->diagnosticCounter[3], this->diagnosticCounter[4], rx_weight_index, firstStep, averageNumNeighbors); firstStep = false; oldTimeStamp = now; From 6d3a5a6eb98ed710a2ac1eef34af9a10e1f64337 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Wed, 21 Jul 2021 17:05:56 -0600 Subject: [PATCH 09/36] Port custom changes to atom_kokkos --- src/KOKKOS/atom_kokkos.cpp | 93 ++++++++++++++++++++++++++++---------- src/KOKKOS/atom_kokkos.h | 4 +- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index c41a42c99a..0962b11c20 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -248,56 +248,101 @@ void AtomKokkos::grow(unsigned int mask) { return index in ivector or dvector of its location ------------------------------------------------------------------------- */ -int AtomKokkos::add_custom(const char *name, int flag) +int AtomKokkos::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"); this->sync(Device,DVECTOR_MASK); memoryKK->grow_kokkos(k_dvector,dvector,ndvector,nmax, "atom:dvector"); this->modified(Device,DVECTOR_MASK); - } + } 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 a null pointer - ivector/dvector and iname/dname lists never shrink + free memory for vector/array and name and set ptrs to a null pointer + these lists never shrink ------------------------------------------------------------------------- */ -void AtomKokkos::remove_custom(int flag, int index) +void AtomKokkos::remove_custom(int index, int flag, int cols) { - if (flag == 0) { + if (flag == 0 && cols == 0) { memory->destroy(ivector[index]); - ivector[index] = nullptr; - delete [] iname[index]; - iname[index] = nullptr; - } else { - //memoryKK->destroy_kokkos(dvector); - dvector[index] = nullptr; - delete [] dname[index]; - dname[index] = nullptr; + ivector[index] = NULL; + delete [] ivname[index]; + ivname[index] = NULL; + + } else if (flag == 1 && cols == 0) { + dvector[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; } } diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index c875817a70..09442e2c60 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -69,8 +69,8 @@ class AtomKokkos : public Atom { void sync_overlapping_device(const ExecutionSpace space, unsigned int mask); virtual void sort(); virtual void grow(unsigned int mask); - int add_custom(const char *, int); - void remove_custom(int, int); + int add_custom(const char *, int, int); + void remove_custom(int, int, int); virtual void deallocate_topology(); void sync_modify(ExecutionSpace, unsigned int, unsigned int); private: From d5ba7b25784cc6c3406e5c93cc33e132c9ed1e54 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 22 Jul 2021 08:10:42 -0600 Subject: [PATCH 10/36] Propagate variable rename --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 6 +++--- src/KOKKOS/pair_table_rx_kokkos.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 5c1a3b3589..000f9dcc7d 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -1787,7 +1787,7 @@ void PairExp6rxKokkos::read_file(char *file) while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; for (ispecies = 0; ispecies < nspecies; ispecies++) - if (strcmp(words[0],&atom->dname[ispecies][0]) == 0) break; + if (strcmp(words[0],&atom->dvname[ispecies][0]) == 0) break; if (ispecies == nspecies) continue; // load up parameter settings and error check their values @@ -1801,9 +1801,9 @@ void PairExp6rxKokkos::read_file(char *file) params[nparams].ispecies = ispecies; - n = strlen(&atom->dname[ispecies][0]) + 1; + n = strlen(&atom->dvname[ispecies][0]) + 1; params[nparams].name = new char[n]; - strcpy(params[nparams].name,&atom->dname[ispecies][0]); + strcpy(params[nparams].name,&atom->dvname[ispecies][0]); n = strlen(words[1]) + 1; params[nparams].potential = new char[n]; diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index b672b126ef..d5eaa7af3f 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -1047,7 +1047,7 @@ void PairTableRXKokkos::coeff(int narg, char **arg) int ispecies; for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; + if (strcmp(site1,&atom->dvname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); @@ -1057,7 +1057,7 @@ void PairTableRXKokkos::coeff(int narg, char **arg) strcpy(site2,arg[5]); for (ispecies = 0; ispecies < nspecies; ispecies++) { - if (strcmp(site2,&atom->dname[ispecies][0]) == 0) break; + if (strcmp(site2,&atom->dvname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) error->all(FLERR,"Site2 name not recognized in pair coefficients"); @@ -1124,7 +1124,7 @@ void PairTableRXKokkos::coeff(int narg, char **arg) isite1 = nspecies; for (int k = 0; k < nspecies; k++) { - if (strcmp(site1, atom->dname[k]) == 0) { + if (strcmp(site1, atom->dvname[k]) == 0) { isite1 = k; break; } @@ -1139,7 +1139,7 @@ void PairTableRXKokkos::coeff(int narg, char **arg) isite2 = nspecies; for (int k = 0; k < nspecies; k++) { - if (strcmp(site2, atom->dname[k]) == 0) { + if (strcmp(site2, atom->dvname[k]) == 0) { isite2 = ispecies; break; } From 2bf9fa91dba1c91866f5933c1e657c16211e28fb Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 17 Aug 2021 14:03:58 -0600 Subject: [PATCH 11/36] more changes to merge with current master --- src/compute_property_atom.cpp | 50 ++++---- src/compute_property_atom.h | 4 +- src/dump_custom.cpp | 228 +++++++++++++--------------------- src/fix_property_atom.cpp | 24 ++-- src/fix_store_state.cpp | 175 ++++++++++---------------- src/library.cpp | 4 +- src/set.cpp | 12 +- src/utils.cpp | 5 +- 8 files changed, 202 insertions(+), 300 deletions(-) diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 3c695ab303..a7eb4bf144 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -380,29 +380,23 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_nbonds; - } 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; - // custom per-atom vector } else if (utils::strmatch(arg[iarg],"^i_")) { - int flag,icol; - index[i] = atom->find_custom(&arg[iarg][2],flag,icol); - if (index[i] < 0 || flag || icol) + 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 integer " "vector does not exist"); pack_choice[i] = &ComputePropertyAtom::pack_iname; + } else if (utils::strmatch(arg[iarg],"^d_")) { - int flag; - index[i] = atom->find_custom(&arg[iarg][2],flag,icol); - if (index[i] < 0 || flag || icol1) + 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 floating point " "vector does not exist"); pack_choice[i] = &ComputePropertyAtom::pack_dname; - } // custom per-atom arrays, must include bracketed index // OLDSTYLE code @@ -1203,21 +1197,6 @@ 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; @@ -1853,6 +1832,21 @@ void ComputePropertyAtom::pack_corner3z(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_iname(int n) { int *ivector = atom->ivector[index[n]]; diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h index 810a12b680..19f8b73451 100644 --- a/src/compute_property_atom.h +++ b/src/compute_property_atom.h @@ -90,8 +90,6 @@ 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); @@ -129,6 +127,8 @@ class ComputePropertyAtom : public Compute { void pack_corner3y(int); void pack_corner3z(int); + void pack_nbonds(int); + void pack_iname(int); void pack_dname(int); void pack_i2name(int); diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 4a2778e981..68a2ab4a57 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -1444,54 +1444,15 @@ int DumpCustom::parse_fields(int narg, char **arg) } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) error->all(FLERR,"Dumping an atom property that isn't allocated"); - pack_choice[i] = &DumpCustom::pack_tqz; - vtype[i] = Dump::DOUBLE; - - // custom per-atom array = i2_ID or d2_ID, must include bracketed index - // OLDSTYLE code - remove this after extend ArgInfo for i2/d2 arrays - - } else if (strncmp(arg[iarg],"i2_",3) == 0 || - strncmp(arg[iarg],"d2_",3) == 0) { - int which = 0; - if (arg[iarg][0] == 'd') which = 1; - - pack_choice[i] = &DumpCustom::pack_custom; - 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][3]); - - 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"); - - 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,which); - delete [] suffix; + pack_choice[iarg] = &DumpCustom::pack_tqz; + vtype[iarg] = Dump::DOUBLE; // compute or fix or variable or custom vector/array - // NEWSTYLE code - add ArgInfo returns for IVEC, DVEC, IARRAY, DARRAY } else { - int n,tmp; + int n,flag,cols; ArgInfo argi(arg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE - |ArgInfo::DVEC|ArgInfo::IVEC); + |ArgInfo::DNAME|ArgInfo::INAME); argindex[iarg] = argi.get_index1(); auto name = argi.get_name(); @@ -1559,50 +1520,58 @@ int DumpCustom::parse_fields(int narg, char **arg) field2index[iarg] = add_variable(name); break; - // custom per-atom floating point vector = d_ID + // custom per-atom floating point vector or array - case ArgInfo::DVEC: + case ArgInfo::DNAME: pack_choice[iarg] = &DumpCustom::pack_custom; vtype[iarg] = Dump::DOUBLE; - tmp = -1; - n = atom->find_custom(name,tmp); + n = atom->find_custom(name,flag,cols); + if (n < 0) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); - - if (tmp != 1) - error->all(FLERR,"Custom per-atom property ID {} is not floating point", name); + if (argindex[iarg] == 0) { + if (!flag || cols) + error->all(FLERR, + "Property double vector for dump custom does not exist"); + } else { + if (!flag || !cols) + error->all(FLERR, + "Property double array for dump custom does not exist"); + if (argindex[iarg] > atom->dcols[n]) + error->all(FLERR, + "Dump custom property array is accessed out-of-range"); + } field2index[iarg] = add_custom(name,1); break; - // custom per-atom integer vector = i_ID + // custom per-atom integer vector or array - case ArgInfo::IVEC: + case ArgInfo::INAME: pack_choice[iarg] = &DumpCustom::pack_custom; vtype[iarg] = Dump::INT; - tmp = -1; - n = atom->find_custom(name,tmp); + n = atom->find_custom(name,flag,cols); + if (n < 0) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); - - if (tmp != 0) - error->all(FLERR,"Custom per-atom property ID {} is not integer", name); + if (argindex[iarg] == 0) { + if (flag || cols) + error->all(FLERR, + "Property integer vector for dump custom does not exist"); + } else { + if (flag || !cols) + error->all(FLERR, + "Property integer array for dump custom does not exist"); + if (argindex[iarg] > atom->icols[n]) + error->all(FLERR, + "Dump custom property array is accessed out-of-range"); + } field2index[iarg] = add_custom(name,0); break; - // custom per-atom floating point array = d2_ID - - case ArgInfo::DARRAY: - return iarg; - - // custom per-atom integer array = i2_ID - - case ArgInfo::IARRAY: - return iarg; - // no match default: @@ -1915,55 +1884,16 @@ int DumpCustom::modify_param(int narg, char **arg) else if (strcmp(arg[1],"tqy") == 0) thresh_array[nthresh] = TQY; else if (strcmp(arg[1],"tqz") == 0) thresh_array[nthresh] = TQZ; - // custom per-atom array = i2_ID or d2_ID, must include bracketed index - // OLDSTYLE code - remove this after extend ArgInfo for i2/d2 arrays - - 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][3]); - - 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"); - - 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,which); - delete [] suffix; - // compute or fix or variable or custom vector/array - // NEWSTYLE code - add ArgInfo returns for IVEC, DVEC, IARRAY, DARRAY // must grow field2index and argindex arrays, since access is beyond nfield - } else { + else { memory->grow(field2index,nfield+nthresh+1,"dump:field2index"); memory->grow(argindex,nfield+nthresh+1,"dump:argindex"); - int n,tmp; + int n,flag,cols; ArgInfo argi(arg[1],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE - |ArgInfo::DVEC|ArgInfo::IVEC); + |ArgInfo::DNAME|ArgInfo::INAME); argindex[nfield+nthresh] = argi.get_index1(); auto name = argi.get_name(); @@ -2026,39 +1956,55 @@ int DumpCustom::modify_param(int narg, char **arg) field2index[nfield+nthresh] = add_variable(name); break; - // custom per atom floating point value = d_ID + // custom per atom floating point vector or array - case ArgInfo::DVEC: - thresh_array[nthresh] = DVEC; - tmp = -1; - n = atom->find_custom(name,tmp); - if ((n < 0) || (tmp != 1)) - error->all(FLERR,"Could not find dump modify custom atom floating point property ID: {}",name); - - field2index[nfield+nthresh] = add_custom(name,1); - break; - - // custom per atom integer value = i_ID - - case ArgInfo::IVEC: - thresh_array[nthresh] = IVEC; - tmp = -1; - n = atom->find_custom(name,tmp); - if ((n < 0) || (tmp != 0)) - error->all(FLERR,"Could not find dump modify custom atom integer property ID: {}",name); + case ArgInfo::DNAME: + n = atom->find_custom(name,flag,cols); + if (n < 0) + error->all(FLERR,"Could not find custom per-atom property ID: {}", name); + if (argindex[nfield+nthresh] == 0) { + if (flag || cols) + error->all(FLERR, + "Property double vector for dump custom does not exist"); + thresh_array[nthresh] = DVEC; + } else { + if (flag || !cols) + error->all(FLERR, + "Property double array for dump custom does not exist"); + if (argindex[nfield+nthresh] > atom->dcols[n]) + error->all(FLERR, + "Dump custom property array is accessed out-of-range"); + thresh_array[nthresh] = DARRAY; + } + field2index[nfield+nthresh] = add_custom(name,0); break; - // custom per-atom floating point array = d2_ID + // custom per atom integer vector or array + + case ArgInfo::INAME: + n = atom->find_custom(name,flag,cols); - case ArgInfo::DARRAY: - return iarg; + if (n < 0) + error->all(FLERR,"Could not find custom per-atom property ID: {}", name); + if (argindex[nfield+nthresh] == 0) { + if (flag || cols) + error->all(FLERR, + "Property integer vector for dump custom does not exist"); + thresh_array[nthresh] = IVEC; + } else { + if (flag || !cols) + error->all(FLERR, + "Property integer array for dump custom does not exist"); + if (argindex[nfield+nthresh] > atom->icols[n]) + error->all(FLERR, + "Dump custom property array is accessed out-of-range"); + thresh_array[nthresh] = IARRAY; + } - // custom per-atom integer array = i2_ID - - case ArgInfo::IARRAY: - return iarg; + field2index[nfield+nthresh] = add_custom(name,0); + break; // no match @@ -2069,7 +2015,7 @@ int DumpCustom::modify_param(int narg, char **arg) } // set operation type of threshold - + if (strcmp(arg[2],"<") == 0) thresh_op[nthresh] = LT; else if (strcmp(arg[2],"<=") == 0) thresh_op[nthresh] = LE; else if (strcmp(arg[2],">") == 0) thresh_op[nthresh] = GT; @@ -2078,11 +2024,11 @@ int DumpCustom::modify_param(int narg, char **arg) else if (strcmp(arg[2],"!=") == 0) thresh_op[nthresh] = NEQ; else if (strcmp(arg[2],"|^") == 0) thresh_op[nthresh] = XOR; else error->all(FLERR,"Invalid dump_modify thresh operator"); - + // set threshold value as number or special LAST keyword // create FixStore to hold LAST values, should work with restart // id = dump-ID + nthreshlast + DUMP_STORE, fix group = dump group - + if (strcmp(arg[3],"LAST") != 0) { thresh_value[nthresh] = utils::numeric(FLERR,arg[3],false,lmp); thresh_last[nthresh] = -1; @@ -2092,17 +2038,17 @@ int DumpCustom::modify_param(int narg, char **arg) thresh_fixID = (char **) memory->srealloc(thresh_fixID,(nthreshlast+1)*sizeof(char *),"dump:thresh_fixID"); memory->grow(thresh_first,(nthreshlast+1),"dump:thresh_first"); - + std::string threshid = fmt::format("{}{}_DUMP_STORE",id,nthreshlast); thresh_fixID[nthreshlast] = utils::strdup(threshid); threshid += fmt::format(" {} STORE peratom 1 1", group->names[igroup]); thresh_fix[nthreshlast] = (FixStore *) modify->add_fix(threshid); - + thresh_last[nthreshlast] = nthreshlast; thresh_first[nthreshlast] = 1; nthreshlast++; } - + nthresh++; return 4; } diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index a45b4768be..47c7475524 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -93,21 +93,21 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (utils::strmatch(arg[iarg],"^i_")) { style[nvalue] = IVEC; - int tmp; - index[nvalue] = atom->find_custom(&arg[iarg][2],tmp); + int flag,cols; + index[nvalue] = atom->find_custom(&arg[iarg][2],flag,cols); if (index[nvalue] >= 0) error->all(FLERR,"Fix property/atom vector name already exists"); - index[nvalue] = atom->add_custom(&arg[iarg][2],0); + index[nvalue] = atom->add_custom(&arg[iarg][2],0,0); nvalue++; - iarg++ + iarg++; } else if (utils::strmatch(arg[iarg],"^d_")) { style[nvalue] = DVEC; - int tmp; - index[nvalue] = atom->find_custom(&arg[iarg][2],tmp); + int flag,ncols; + index[nvalue] = atom->find_custom(&arg[iarg][2],flag,ncols); if (index[nvalue] >= 0) error->all(FLERR,"Fix property/atom vector name already exists"); - index[nvalue] = atom->add_custom(&arg[iarg][2],1); + index[nvalue] = atom->add_custom(&arg[iarg][2],1,0); nvalue++; iarg++; @@ -121,8 +121,8 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : 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); + int flag,ncols; + index[nvalue] = atom->find_custom(&arg[iarg][3],flag,ncols); if (index[nvalue] >= 0) error->all(FLERR,"Fix property/atom array name already exists"); cols[nvalue] = utils::inumeric(FLERR,arg[iarg+1],true,lmp); @@ -418,8 +418,10 @@ void FixPropertyAtom::write_data_section_keyword(int /*mth*/, FILE *fp) if (style[i] == MOLECULE) fputs(" mol",fp); else if (style[i] == CHARGE) fputs(" q",fp); else if (style[i] == RMASS) fputs(" rmass",fp); - else if (style[i] == INTEGER) fprintf(fp," i_%s", atom->iname[index[i]]); - else if (style[i] == DOUBLE) fprintf(fp, " d_%s", atom->dname[index[i]]); + else if (style[i] == IVEC) fprintf(fp," i_%s", atom->ivname[index[i]]); + else if (style[i] == DVEC) fprintf(fp, " d_%s", atom->dvname[index[i]]); + else if (style[i] == IARRAY) fprintf(fp, " i_%s", atom->ianame[index[i]]); + else if (style[i] == DARRAY) fprintf(fp, " d_%s", atom->daname[index[i]]); } fputs("\n\n",fp); } diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index df082f92f6..0d54d2727e 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -222,33 +222,6 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : "Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqz; - // custom per-atom array - // OLDSTYLE code - - } else if (strncmp(arg[iarg],"i2_",3) == 0 || - strncmp(arg[iarg],"d2_",3) == 0) { - 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]; - strcpy(suffix,&arg[iarg][3]); - - char *ptr = strchr(suffix,'['); - if (!ptr) 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'; - - n = strlen(suffix) + 1; - ids[nvalues] = new char[n]; - strcpy(ids[nvalues],suffix); - nvalues++; - delete [] suffix; - // compute or fix or variable or custom per-atom vector or array // NEWSTYLE code @@ -293,16 +266,16 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : if (modify->compute[icompute]->peratom_flag == 0) error->all(FLERR,"Fix store/state compute " "does not calculate per-atom values"); - if (argindex[m] == 0 && + if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) error->all(FLERR,"Fix store/state compute does not " "calculate a per-atom vector"); - if (argindex[m] && modify->compute[icompute]->size_peratom_cols == 0) + if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) error->all(FLERR, "Fix store/state compute does not " "calculate a per-atom array"); - if (argindex[m] && - argindex[m] > modify->compute[icompute]->size_peratom_cols) + if (argindex[i] && + argindex[i] > modify->compute[icompute]->size_peratom_cols) error->all(FLERR, "Fix store/state compute array is accessed out-of-range"); @@ -314,13 +287,13 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : if (modify->fix[ifix]->peratom_flag == 0) error->all(FLERR, "Fix store/state fix does not calculate per-atom values"); - if (argindex[m] == 0 && modify->fix[ifix]->size_peratom_cols != 0) + if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) error->all(FLERR, "Fix store/state fix does not calculate a per-atom vector"); - if (argindex[m] && modify->fix[ifix]->size_peratom_cols == 0) + if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) error->all(FLERR, "Fix store/state fix does not calculate a per-atom array"); - if (argindex[m] && argindex[m] > modify->fix[ifix]->size_peratom_cols) + if (argindex[i] && argindex[i] > 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) @@ -334,33 +307,41 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : if (input->variable->atomstyle(ivariable) == 0) error->all(FLERR,"Fix store/state variable is not atom-style variable"); - } else if (which[i] == ArgInfo::INAME) { - int icustom,iflag,cols; - icustom = atom->find_custom(ids[i],iflag,cols); - if ((icustom < 0) || iflag ||,cols) - error->all(FLERR, - "Custom integer vector for fix store/state does not exist"); - } else if (which[i] == ArgInfo::DNAME) { - int icustom,iflag,cols; - icustom = atom->find_custom(ids[i],iflag,cols); - if ((icustom < 0) || iflag ||,cols) - error->all(FLERR, - "Custom floating point vector for fix store/state does not exist"); + int icustom,iflag,icol; + icustom = atom->find_custom(ids[i],iflag,icol); + if (icustom < 0) + error->all(FLERR,"Custom vector/array for fix store/state does not exist"); + if (argindex[i] == 0) { + if (!iflag || icol) + error->all(FLERR, + "Custom double vector for fix store/state does not exist"); + } else { + if (!iflag || !icol) + error->all(FLERR, + "Custom double array for fix store/state does not exist"); + if (argindex[i] > atom->dcols[icustom]) + error->all(FLERR, + "Fix store/state custom array is accessed out-of-range"); + } - } else if (which[i] == ArgInfo::IARRAY) { - int icustom,flag,cols; - icustom = atom->find_custom(ids[i],flag,cols); - if ((icustom < 0) || flag || !cols) - error->all(FLERR, - "Custom integer array for fix store/state does not exist"); - - } else if (which[m] == Arginfo::DARRAY) { - int icustom,flag,cols; - icustom = atom->find_custom(ids[i],flag,cols); - if ((icustom < 0) || !flag || !cols) - error->all(FLERR, - "Custom floating point array for fix store/state does not exist"); + } else if (which[i] == ArgInfo::INAME) { + int icustom,iflag,icol; + icustom = atom->find_custom(ids[i],iflag,icol); + if (icustom < 0) + error->all(FLERR,"Custom vector/array for fix store/state does not exist"); + if (argindex[i] == 0) { + if (iflag || icol) + error->all(FLERR, + "Custom integer vector for fix store/state does not exist"); + } else { + if (iflag || !icol) + error->all(FLERR, + "Custom integer array for fix store/state does not exist"); + if (argindex[i] > atom->icols[icustom]) + error->all(FLERR, + "Fix store/state custom array is accessed out-of-range"); + } } } @@ -450,36 +431,13 @@ void FixStoreState::init() error->all(FLERR,"Variable name for fix store/state does not exist"); value2index[m] = ivariable; - } else if (which[m] == ArgInfo::IVEC) { + } else if (which[m] == ArgInfo::INAME || which[m] == ArgInfo::DNAME) { int icustom,iflag,cols; icustom = atom->find_custom(ids[m],iflag,cols); - if ((icustom < 0) || iflag || cols) - error->all(FLERR, - "Custom integer vector for fix store/state does not exist"); + if (icustom < 0) + error->all(FLERR,"Custom vector/array for fix store/state does not exist"); value2index[m] = icustom; - - } else if (which[m] == ArgInfo::DVEC) { - int icustom,iflag,cols; - icustom = atom->find_custom(ids[m],iflag,cols); - if ((icustom < 0) || iflag || cols) - error->all(FLERR, - "Custom floating point vector for fix store/state does not exist"); - value2index[m] = icustom; - - } else if (which[m] == ArgInfo::IARRAY) { - int icustom,iflag,cols; - icustom = atom->find_custom(ids[m],iflag,cols); - if ((icustom < 0) || iflag || !cols) - error->all(FLERR, - "Custom integer array for fix store/state does not exist"); - value2index[m] = icustom; - - } else if (which[m] == ArgInfo::DARRAY) { - int icustom,iflag,cols; - icustom = atom->find_custom(ids[m],iflag,cols); - if ((icustom < 0) || iflag || !cols) - error->all(FLERR, - "Custom floating point array for fix store/state does not exist"); value2index[m] = icustom; + } } } @@ -566,32 +524,35 @@ void FixStoreState::end_of_step() // evaluate atom-style variable - } else if (which[m] == VARIABLE) { + } else if (which[m] == ArgInfo::VARIABLE) { input->variable->compute_atom(n,igroup,&values[0][m],nvalues,0); - // access custom atom property fields + // access custom atom vector/array fields - } else if (which[m] == ArgInfo::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] == ArgInfo::DNAME) { + if (j == 0) { + double *dvector = atom->dvector[n]; + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) values[i][m] = dvector[i]; + } else { + 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]; + } - } else if (which[m] == ArgInfo::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] == ArgInfo::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] == ArgInfo::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]; + } else if (which[m] == ArgInfo::INAME) { + if (j == 0) { + int *ivector = atom->ivector[n]; + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) values[i][m] = ivector[i]; + } else { + 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]; + } } } } diff --git a/src/library.cpp b/src/library.cpp index d0f5b2b9fb..b6cdd02e9f 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -3127,7 +3127,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d // compute - if (vptr==nullptr && utils::strmatch(name,"^c_")) + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3156,7 +3156,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d else vptr = (void *) lmp->modify->compute[fcid]->array_atom; } - // custom fix property/atom vector or array + // custom per-atom vector or array // OLDSTYLE code if ((vptr==nullptr) && diff --git a/src/set.cpp b/src/set.cpp index c5021120c1..1aa9a479e6 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -576,9 +576,9 @@ void Set::command(int narg, char **arg) if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - int flag; - index_custom = atom->find_custom(&arg[iarg][2],flag); - if (index_custom < 0 || flag != 0) + int flag,cols; + index_custom = atom->find_custom(&arg[iarg][2],flag,cols); + if (index_custom < 0 || flag || cols) error->all(FLERR,"Set command integer vector does not exist"); set(IVEC); iarg += 2; @@ -587,9 +587,9 @@ void Set::command(int narg, char **arg) if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); - int flag; - index_custom = atom->find_custom(&arg[iarg][2],flag); - if (index_custom < 0 || flag != 1) + int flag,cols; + index_custom = atom->find_custom(&arg[iarg][2],flag,cols); + if (index_custom < 0 || flag || cols) error->all(FLERR,"Set command floating point vector does not exist"); set(DVEC); iarg += 2; diff --git a/src/utils.cpp b/src/utils.cpp index 8da2efd03d..fd3170859b 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -609,13 +609,12 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod // only match custom array reference with a '*' wildcard // number range in the first pair of square brackets - // OLDSTYLE code if (strncmp(arg[iarg],"i2_",3) == 0 || strncmp(arg[iarg],"d2_",3) == 0) { - ptr1 = strchr(arg[iarg],'['); + char *ptr1 = strchr(arg[iarg],'['); if (ptr1) { - ptr2 = strchr(ptr1,']'); + char *ptr2 = strchr(ptr1,']'); if (ptr2) { *ptr2 = '\0'; if (strchr(ptr1,'*')) { From c57da0661df76c58177d1b981cc57dc78e36976f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 12:49:16 -0400 Subject: [PATCH 12/36] update package name --- doc/src/compute_property_atom.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/compute_property_atom.rst b/doc/src/compute_property_atom.rst index 60e8c5f167..c4657ce82c 100644 --- a/doc/src/compute_property_atom.rst +++ b/doc/src/compute_property_atom.rst @@ -92,8 +92,8 @@ Syntax .. parsed-literal:: - USER-MESONT package per-atom properties: - buckling = buckling flag used in mesoscopic simulation of nanotubes + MESONT package per-atom properties: + buckling = buckling flag used in mesoscopic simulation of nanotubes Examples """""""" From c6819e30cf82e1214feaacb3a5b82dbe6cb46dd2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 12:58:39 -0400 Subject: [PATCH 13/36] simplify --- src/KOKKOS/pair_table_rx_kokkos.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 6603d8d88b..b7b9560bc1 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -1054,14 +1054,10 @@ void PairTableRXKokkos::coeff(int narg, char **arg) if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); + site2 = utils::strdup(arg[5]); - n = strlen(arg[5]) + 1; - site2 = new char[n]; - strcpy(site2,arg[5]); - - for (ispecies = 0; ispecies < nspecies; ispecies++) { + for (ispecies = 0; ispecies < nspecies; ispecies++) if (strcmp(site2,&atom->dvname[ispecies][0]) == 0) break; - } if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) error->all(FLERR,"Site2 name not recognized in pair coefficients"); From c50abed92b6db7041fcb404d19b157e1c8f6df92 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 12:59:31 -0400 Subject: [PATCH 14/36] recover compilation --- src/REACTION/fix_bond_react.cpp | 4 +-- src/fix_property_atom.cpp | 2 +- unittest/formats/test_atom_styles.cpp | 39 +++++++++++++++++---------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index e6828b24ab..0c309b9ead 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -2625,8 +2625,8 @@ void FixBondReact::unlimit_bond() // let's now unlimit in terms of i_limit_tags // we just run through all nlocal, looking for > limit_duration // then we return i_limit_tag to 0 (which removes from dynamic group) - int flag,cols - int index1 = atom->find_custom("limit_tags",flag,cols); + int flag, cols; + int index1 = atom->find_custom("limit_tags",flag,cols); int *i_limit_tags = atom->ivector[index1]; int *i_statted_tags; diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 47c7475524..0ca8a75632 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -250,7 +250,7 @@ void FixPropertyAtom::init() void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint id_offset) { - int j,k,m,iword,ncol,nv; + int j,k,m,ncol; tagint itag; char *next; diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index d416074b81..b091360170 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -11,6 +11,7 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "../testing/core.h" #include "atom.h" #include "atom_vec_body.h" #include "atom_vec_ellipsoid.h" @@ -24,7 +25,6 @@ #include "utils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "../testing/core.h" #include #include @@ -48,7 +48,7 @@ using LAMMPS_NS::utils::split_words; -static void create_molecule_files(const std::string & h2o_filename, const std::string & co2_filename) +static void create_molecule_files(const std::string &h2o_filename, const std::string &co2_filename) { // create molecule files const char h2o_file[] = "# Water molecule. SPC/E model.\n\n3 atoms\n2 bonds\n1 angles\n\n" @@ -95,11 +95,10 @@ using ::testing::Eq; class AtomStyleTest : public LAMMPSTest { protected: - static void SetUpTestSuite() { - create_molecule_files("h2o.mol", "co2.mol"); - } + static void SetUpTestSuite() { create_molecule_files("h2o.mol", "co2.mol"); } - static void TearDownTestSuite() { + static void TearDownTestSuite() + { remove("h2o.mol"); remove("co2.mol"); } @@ -237,8 +236,10 @@ struct AtomState { bool has_dihedral = false; bool has_improper = false; - bool has_iname = false; - bool has_dname = false; + bool has_ivname = false; + bool has_dvname = false; + bool has_ianame = false; + bool has_daname = false; bool has_mass = false; bool has_mass_setflag = false; @@ -444,8 +445,10 @@ void ASSERT_ATOM_STATE_EQ(Atom *atom, const AtomState &expected) ASSERT_EQ(atom->nivector, expected.nivector); ASSERT_EQ(atom->ndvector, expected.ndvector); - ASSERT_ARRAY_ALLOCATED(atom->iname, expected.has_iname); - ASSERT_ARRAY_ALLOCATED(atom->dname, expected.has_dname); + ASSERT_ARRAY_ALLOCATED(atom->ivname, expected.has_ivname); + ASSERT_ARRAY_ALLOCATED(atom->dvname, expected.has_dvname); + ASSERT_ARRAY_ALLOCATED(atom->ianame, expected.has_ianame); + ASSERT_ARRAY_ALLOCATED(atom->daname, expected.has_daname); ASSERT_ARRAY_ALLOCATED(atom->mass, expected.has_mass); ASSERT_ARRAY_ALLOCATED(atom->mass_setflag, expected.has_mass_setflag); @@ -4555,7 +4558,8 @@ TEST_F(AtomStyleTest, property_atom) { BEGIN_HIDE_OUTPUT(); command("atom_modify map array"); - command("fix Properties all property/atom i_one d_two mol d_three q rmass ghost yes"); + command("fix Properties all property/atom " + "i_one d_two mol d_three q rmass i2_four 2 d2_five 3 ghost yes"); END_HIDE_OUTPUT(); AtomState expected; @@ -4570,8 +4574,10 @@ TEST_F(AtomStyleTest, property_atom) expected.has_x = true; expected.has_v = true; expected.has_f = true; - expected.has_iname = true; - expected.has_dname = true; + expected.has_ivname = true; + expected.has_dvname = true; + expected.has_ianame = true; + expected.has_daname = true; expected.has_extra_grow = true; expected.has_extra_restart = true; expected.has_extra_border = true; @@ -4614,7 +4620,12 @@ TEST_F(AtomStyleTest, property_atom) command("set atom 2 d_three -1.0"); command("set atom 3 d_three 0.5"); command("set atom 4 d_three 2.0"); - + command("set atom * d2_five[1] -5.9"); + command("set atom * d2_five[2] 1.1e-2"); + command("set atom * d2_five[3] .1"); + command("set atom 1*2 i2_four[1] -2"); + command("set atom 3*4 i2_four[1] -1"); + command("set atom * i2_four[2] 2"); END_HIDE_OUTPUT(); expected.natoms = 4; expected.nlocal = 4; From 300fee043745a890f976aedcd98364e018b75768 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 12:59:56 -0400 Subject: [PATCH 15/36] add some more checks for typical string matches for references to fixes and alike --- unittest/utils/test_utils.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 08922e648f..44cd865a21 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -478,6 +478,17 @@ TEST(Utils, strmatch_opt_char) { ASSERT_TRUE(utils::strmatch("rigid", "^r?igid")); ASSERT_TRUE(utils::strmatch("igid", "^r?igid")); + ASSERT_TRUE(utils::strmatch("c_name","^[cfvid]2?_name")); + ASSERT_TRUE(utils::strmatch("f_name","^[cfvid]2?_name")); + ASSERT_TRUE(utils::strmatch("v_name","^[cfvid]2?_name")); + ASSERT_TRUE(utils::strmatch("i_name","^[cfvid]2?_name")); + ASSERT_TRUE(utils::strmatch("d_name","^[cfvid]2?_name")); + ASSERT_TRUE(utils::strmatch("i2_name","^[cfvid]2?_name")); + ASSERT_TRUE(utils::strmatch("d2_name","^[cfvid]2?_name")); + ASSERT_FALSE(utils::strmatch("d2name","^[cfvid]2?_name")); + ASSERT_FALSE(utils::strmatch("i1_name","^[cfvid]2?_name")); + ASSERT_FALSE(utils::strmatch("V_name","^[cfvid]2?_name")); + ASSERT_FALSE(utils::strmatch("x_name","^[cfvid]2?_name")); } TEST(Utils, strmatch_dot) From f9b32f0eef356e28bc7b19edc36e7834ad54d78c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 13:00:32 -0400 Subject: [PATCH 16/36] use ArgInfo class to process references to custom vectors and arrays --- src/set.cpp | 112 +++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/src/set.cpp b/src/set.cpp index 1aa9a479e6..2a36874c8b 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -14,6 +14,7 @@ #include "set.h" +#include "arg_info.h" #include "atom.h" #include "atom_vec.h" #include "atom_vec_body.h" @@ -570,69 +571,64 @@ void Set::command(int narg, char **arg) set(DPDTHETA); iarg += 2; - // custom per-atom vector + } else { - } else if (utils::strmatch(arg[iarg],"^i_")) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); - if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); - else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - int flag,cols; - index_custom = atom->find_custom(&arg[iarg][2],flag,cols); - if (index_custom < 0 || flag || cols) - error->all(FLERR,"Set command integer vector does not exist"); - set(IVEC); - iarg += 2; - - } else if (utils::strmatch(arg[iarg],"^d_")) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); - if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); - else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); - int flag,cols; - index_custom = atom->find_custom(&arg[iarg][2],flag,cols); - if (index_custom < 0 || flag || cols) - error->all(FLERR,"Set command floating point vector does not exist"); - set(DVEC); - iarg += 2; - - // custom per-atom array, must include bracketed index - // OLDSTYLE code - - } 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 = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); - - 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"); + // set custom per-atom vector or array or error out int flag,cols; - index_custom = atom->find_custom(suffix,flag,cols); - delete [] suffix; + ArgInfo argi(arg[iarg],ArgInfo::DNAME|ArgInfo::INAME); + const char *pname = argi.get_name(); + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + index_custom = atom->find_custom(argi.get_name(),flag,cols); + if (index_custom < 0) error->all(FLERR,"Custom property {} does not exist",pname); - 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"); + switch (argi.get_type()) { - if (!which) set(IARRAY); - else set(DARRAY); + case ArgInfo::INAME: + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + if (flag != 0) error->all(FLERR,"Custom property {} is not integer",pname); + + if (argi.get_dim() == 0) { + if (cols > 0) + error->all(FLERR,"Set command custom integer property {} is not a vector",pname); + set(IVEC); + } else if (argi.get_dim() == 1) { + if (cols == 0) + error->all(FLERR,"Set command custom integer property {} is not an array",pname); + icol_custom = argi.get_index1(); + if (icol_custom <= 0 || icol_custom > cols) + error->all(FLERR,"Set command per-atom custom integer array {} is accessed " + "out-of-range",pname); + set(IARRAY); + } else error->all(FLERR,"Illegal set command"); + break; + + case ArgInfo::DNAME: + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (flag != 1) error->all(FLERR,"Custom property {} is not floating-point",argi.get_name()); + + if (argi.get_dim() == 0) { + if (cols > 0) + error->all(FLERR,"Set command custom floating-point property is not a vector"); + set(DVEC); + } else if (argi.get_dim() == 1) { + if (cols == 0) + error->all(FLERR,"Set command custom floating-point property is not an array"); + icol_custom = argi.get_index1(); + if (icol_custom <= 0 || icol_custom > cols) + error->all(FLERR,"Set command per-atom custom integer array is accessed out-of-range"); + set(DARRAY); + } else error->all(FLERR,"Illegal set command"); + break; + + default: + error->all(FLERR,"Illegal set command"); + break; + } iarg += 2; - - } else error->all(FLERR,"Illegal set command"); + } // statistics // for CC option, include species index @@ -1007,7 +1003,7 @@ void Set::set(int keyword) (((imageint) (zbox + IMGMAX) & IMGMASK) << IMG2BITS); } - // set value for custom vector or array + // set value for custom property vector or array else if (keyword == IVEC) { atom->ivector[index_custom][i] = ivalue; From 4fed16fe8b526434d19c69691beaea865e5440cc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 13:00:40 -0400 Subject: [PATCH 17/36] pretty --- src/fix_store_state.cpp | 49 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index 0d54d2727e..1f302b4ca3 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -142,88 +142,71 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_muz; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_mu; } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_radius; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_diameter; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_angmomz; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); + error->all(FLERR,"Fix store/state for atom property that isn't allocated"); pack_choice[nvalues++] = &FixStoreState::pack_tqz; // compute or fix or variable or custom per-atom vector or array - // NEWSTYLE code } else { ArgInfo argi(arg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE From e08c4abb4b3bfa5534b40d03ea0e97376be8f56e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 13:06:00 -0400 Subject: [PATCH 18/36] whitespace fixes --- doc/src/compute_property_atom.rst | 2 +- src/KOKKOS/atom_kokkos.cpp | 12 +++---- src/VTK/dump_vtk.cpp | 6 ++-- src/atom.cpp | 24 +++++++------- src/compute_property_atom.cpp | 14 ++++---- src/compute_property_atom.h | 2 +- src/dump_custom.cpp | 20 ++++++------ src/fix_group.cpp | 8 ++--- src/fix_property_atom.cpp | 22 ++++++------- src/fix_store_state.cpp | 6 ++-- src/library.cpp | 54 +++++++++++++++---------------- src/set.cpp | 4 +-- src/utils.cpp | 6 ++-- 13 files changed, 90 insertions(+), 90 deletions(-) diff --git a/doc/src/compute_property_atom.rst b/doc/src/compute_property_atom.rst index c4657ce82c..fee859d96e 100644 --- a/doc/src/compute_property_atom.rst +++ b/doc/src/compute_property_atom.rst @@ -136,7 +136,7 @@ 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 ` command, are as follows. diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 3304d638ce..f40b9c324a 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -272,7 +272,7 @@ int AtomKokkos::add_custom(const char *name, int flag, int cols) ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *), "atom:ivector"); memory->create(ivector[index],nmax,"atom:ivector"); - + } else if (flag == 1 && cols == 0) { index = ndvector; ndvector++; @@ -299,10 +299,10 @@ int AtomKokkos::add_custom(const char *name, int flag, int cols) 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++; @@ -318,7 +318,7 @@ int AtomKokkos::add_custom(const char *name, int flag, int cols) dcols = (int *) memory->srealloc(dcols,ndarray*sizeof(int),"atom:dcols"); dcols[index] = cols; } - + return index; } @@ -335,7 +335,7 @@ void AtomKokkos::remove_custom(int index, int flag, int cols) ivector[index] = NULL; delete [] ivname[index]; ivname[index] = NULL; - + } else if (flag == 1 && cols == 0) { dvector[index] = NULL; delete [] dvname[index]; @@ -346,7 +346,7 @@ void AtomKokkos::remove_custom(int index, int flag, int cols) iarray[index] = NULL; delete [] ianame[index]; ianame[index] = NULL; - + } else if (flag == 1 && cols) { memory->destroy(darray[index]); darray[index] = NULL; diff --git a/src/VTK/dump_vtk.cpp b/src/VTK/dump_vtk.cpp index 75092ff204..f94a6957fb 100644 --- a/src/VTK/dump_vtk.cpp +++ b/src/VTK/dump_vtk.cpp @@ -757,7 +757,7 @@ int DumpVTK::count() i = ATTRIBUTES + nfield + ithresh; iwhich = atom->find_custom(id_custom[field2index[i]],flag,cols); int *ivector = atom->ivector[iwhich]; - for (i = 0; i < nlocal; i++) + for (i = 0; i < nlocal; i++) dchoose[i] = ivector[i]; ptr = dchoose; nstride = 1; @@ -775,7 +775,7 @@ int DumpVTK::count() iwhich = atom->find_custom(id_custom[field2index[i]],flag,cols); int **iarray = atom->iarray[iwhich]; int icol = argindex[i] - 1; - for (i = 0; i < nlocal; i++) + for (i = 0; i < nlocal; i++) dchoose[i] = iarray[i][icol]; ptr = dchoose; nstride = 1; @@ -1827,7 +1827,7 @@ int DumpVTK::parse_fields(int narg, char **arg) field2index[ATTRIBUTES+i] = add_variable(argi.get_name()); name[ATTRIBUTES+i] = arg[iarg]; break; - + // custom per-atom integer vector = i_ID case ArgInfo::INAME: diff --git a/src/atom.cpp b/src/atom.cpp index 760aba5845..c1cb9e011b 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2481,7 +2481,7 @@ int Atom::add_custom(const char *name, int flag, int cols) ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *), "atom:ivector"); memory->create(ivector[index],nmax,"atom:ivector"); - + } else if (flag == 1 && cols == 0) { index = ndvector; ndvector++; @@ -2501,10 +2501,10 @@ int Atom::add_custom(const char *name, int flag, int cols) 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++; @@ -2518,7 +2518,7 @@ int Atom::add_custom(const char *name, int flag, int cols) dcols = (int *) memory->srealloc(dcols,ndarray*sizeof(int),"atom:dcols"); dcols[index] = cols; } - + return index; } @@ -2542,7 +2542,7 @@ void Atom::remove_custom(int index, int flag, int cols) ivector[index] = NULL; delete [] ivname[index]; ivname[index] = NULL; - + } else if (flag == 1 && cols == 0) { memory->destroy(dvector[index]); dvector[index] = NULL; @@ -2554,7 +2554,7 @@ void Atom::remove_custom(int index, int flag, int cols) iarray[index] = NULL; delete [] ianame[index]; ianame[index] = NULL; - + } else if (flag == 1 && cols) { memory->destroy(darray[index]); darray[index] = NULL; @@ -2762,7 +2762,7 @@ void *Atom::extract(const char *name) if (strcmp(name, "damage") == 0) return (void *) damage; // DPD-REACT pakage - + if (strcmp(name,"dpdTheta") == 0) return (void *) dpdTheta; // DPD-MESO package @@ -2790,15 +2790,15 @@ void *Atom::extract(const char *name) 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]; @@ -2906,14 +2906,14 @@ int Atom::extract_datatype(const char *name) // custom vectors and arrays // OLDSTYLE code - + 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); diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index a7eb4bf144..e8e1293e28 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -147,8 +147,8 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyAtom::pack_mu; // pack magnetic variables - - } else if (strcmp(arg[iarg],"spx") == 0) { + + } else if (strcmp(arg[iarg],"spx") == 0) { if (!atom->sp_flag) error->all(FLERR,"Compute property/atom for " "atom property that isn't allocated"); @@ -185,7 +185,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : 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 " @@ -193,7 +193,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : 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 " @@ -401,11 +401,11 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : // custom per-atom arrays, must include bracketed index // OLDSTYLE code - } else if (strstr(arg[iarg],"i2_") == arg[iarg] || + } 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]); @@ -418,7 +418,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : 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; diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h index 19f8b73451..d8b1cae449 100644 --- a/src/compute_property_atom.h +++ b/src/compute_property_atom.h @@ -109,7 +109,7 @@ 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); diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 68a2ab4a57..3aac7a3e79 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -1046,7 +1046,7 @@ int DumpCustom::count() 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]]; @@ -1977,12 +1977,12 @@ int DumpCustom::modify_param(int narg, char **arg) "Dump custom property array is accessed out-of-range"); thresh_array[nthresh] = DARRAY; } - + field2index[nfield+nthresh] = add_custom(name,0); break; // custom per atom integer vector or array - + case ArgInfo::INAME: n = atom->find_custom(name,flag,cols); @@ -2015,7 +2015,7 @@ int DumpCustom::modify_param(int narg, char **arg) } // set operation type of threshold - + if (strcmp(arg[2],"<") == 0) thresh_op[nthresh] = LT; else if (strcmp(arg[2],"<=") == 0) thresh_op[nthresh] = LE; else if (strcmp(arg[2],">") == 0) thresh_op[nthresh] = GT; @@ -2024,11 +2024,11 @@ int DumpCustom::modify_param(int narg, char **arg) else if (strcmp(arg[2],"!=") == 0) thresh_op[nthresh] = NEQ; else if (strcmp(arg[2],"|^") == 0) thresh_op[nthresh] = XOR; else error->all(FLERR,"Invalid dump_modify thresh operator"); - + // set threshold value as number or special LAST keyword // create FixStore to hold LAST values, should work with restart // id = dump-ID + nthreshlast + DUMP_STORE, fix group = dump group - + if (strcmp(arg[3],"LAST") != 0) { thresh_value[nthresh] = utils::numeric(FLERR,arg[3],false,lmp); thresh_last[nthresh] = -1; @@ -2038,17 +2038,17 @@ int DumpCustom::modify_param(int narg, char **arg) thresh_fixID = (char **) memory->srealloc(thresh_fixID,(nthreshlast+1)*sizeof(char *),"dump:thresh_fixID"); memory->grow(thresh_first,(nthreshlast+1),"dump:thresh_first"); - + std::string threshid = fmt::format("{}{}_DUMP_STORE",id,nthreshlast); thresh_fixID[nthreshlast] = utils::strdup(threshid); threshid += fmt::format(" {} STORE peratom 1 1", group->names[igroup]); thresh_fix[nthreshlast] = (FixStore *) modify->add_fix(threshid); - + thresh_last[nthreshlast] = nthreshlast; thresh_first[nthreshlast] = 1; nthreshlast++; } - + nthresh++; return 4; } @@ -2135,7 +2135,7 @@ void DumpCustom::pack_custom(int n) 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++) { diff --git a/src/fix_group.cpp b/src/fix_group.cpp index 03a046d3bf..c15f2590c5 100644 --- a/src/fix_group.cpp +++ b/src/fix_group.cpp @@ -61,7 +61,7 @@ idregion(nullptr), idvar(nullptr), idprop(nullptr) delete [] idregion; idregion = utils::strdup(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) @@ -70,19 +70,19 @@ idregion(nullptr), idvar(nullptr), idprop(nullptr) delete [] idvar; idvar = utils::strdup(arg[iarg+1]); iarg += 2; - + } else if (strcmp(arg[iarg],"property") == 0) { 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) + if (iprop < 1 || cols) error->all(FLERR,"Custom per-atom vector for group dynamic " "does not exist"); propflag = 1; delete [] idprop; idprop = utils::strdup(arg[iarg+1]); iarg += 2; - + } else if (strcmp(arg[iarg],"every") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal group command"); nevery = utils::inumeric(FLERR,arg[iarg+1],false,lmp); diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 0ca8a75632..7ec30025bc 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -50,7 +50,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : nvalue = 0; values_peratom = 0; - + while (iarg < narg) { if (strcmp(arg[iarg],"mol") == 0) { if (atom->molecule_flag) @@ -114,7 +114,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : // custom atom array // OLDSTYLE code - } else if (strstr(arg[iarg],"i2_") == arg[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; @@ -539,7 +539,7 @@ void FixPropertyAtom::grow_arrays(int nmax) void FixPropertyAtom::copy_arrays(int i, int j, int /*delflag*/) { int k,ncol; - + for (int nv = 0; nv < nvalue; nv++) { if (style[nv] == MOLECULE) atom->molecule[j] = atom->molecule[i]; @@ -697,15 +697,15 @@ int FixPropertyAtom::pack_exchange(int i, double *buf) 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++) + 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++) + for (k = 0; k < ncol; k++) buf[m++] = atom->darray[index[nv]][i][k]; } } - + return m; } @@ -731,15 +731,15 @@ int FixPropertyAtom::unpack_exchange(int nlocal, double *buf) atom->dvector[index[nv]][nlocal] = buf[m++]; else if (style[nv] == IARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) + 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++) + for (k = 0; k < ncol; k++) atom->darray[index[nv]][nlocal][k] = buf[m++]; } } - + return m; } @@ -750,9 +750,9 @@ 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] = values_peratom+1; int m = 1; diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index 1f302b4ca3..1d3d48a06b 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -293,7 +293,7 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : } else if (which[i] == ArgInfo::DNAME) { int icustom,iflag,icol; icustom = atom->find_custom(ids[i],iflag,icol); - if (icustom < 0) + if (icustom < 0) error->all(FLERR,"Custom vector/array for fix store/state does not exist"); if (argindex[i] == 0) { if (!iflag || icol) @@ -311,7 +311,7 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : } else if (which[i] == ArgInfo::INAME) { int icustom,iflag,icol; icustom = atom->find_custom(ids[i],iflag,icol); - if (icustom < 0) + if (icustom < 0) error->all(FLERR,"Custom vector/array for fix store/state does not exist"); if (argindex[i] == 0) { if (iflag || icol) @@ -417,7 +417,7 @@ void FixStoreState::init() } else if (which[m] == ArgInfo::INAME || which[m] == ArgInfo::DNAME) { int icustom,iflag,cols; icustom = atom->find_custom(ids[m],iflag,cols); - if (icustom < 0) + if (icustom < 0) error->all(FLERR,"Custom vector/array for fix store/state does not exist"); value2index[m] = icustom; } diff --git a/src/library.cpp b/src/library.cpp index b6cdd02e9f..1397cf889e 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2834,7 +2834,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) int i,j,offset,fcid,ltype,icol; // error if tags are not defined or not consecutive - + int flag = 0; if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) flag = 1; @@ -2849,7 +2849,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) void *vptr = lmp->atom->extract(name); // fix - + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); @@ -2884,7 +2884,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) } // compute - + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); @@ -2913,7 +2913,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) if (count==1) vptr = (void *) lmp->modify->compute[fcid]->vector_atom; else vptr = (void *) lmp->modify->compute[fcid]->array_atom; } - + // custom fix property/atom vector or array // OLDSTYLE code @@ -2930,7 +2930,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) lmp->error->warning(FLERR,"lammps_gather: unknown property/atom id"); return; } - + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom type"); @@ -2950,7 +2950,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) if (count == 1) { if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; else vptr = (void *) lmp->atom->dvector[fcid]; - } else { + } else { if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; else vptr = (void *) lmp->atom->darray[fcid]; } @@ -2963,11 +2963,11 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) lmp->error->warning(FLERR,"lammps_gather: undefined property name"); return; } - + // copy = Natom length vector of per-atom values // use atom ID to insert each atom's values into copy // MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID - + if (type==0) { int *vector = nullptr; int **array = nullptr; @@ -3078,7 +3078,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d int i,offset,fcid,ltype,icol; // error if tags are not defined or not consecutive - + int flag = 0; if (lmp->atom->tag_enable == 0) flag = 1; if (lmp->atom->natoms > MAXSMALLINT) flag = 1; @@ -3126,7 +3126,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d } // compute - + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); @@ -3162,7 +3162,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if ((vptr==nullptr) && ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { - + if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) fcid = lmp->atom->find_custom(&name[2],ltype,icol); else fcid = lmp->atom->find_custom(&name[3],ltype,icol); @@ -3173,7 +3173,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d "unknown property/atom id"); return; } - + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_concat: " @@ -3221,7 +3221,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if (type == 0) { int *vector = nullptr; int **array = nullptr; - + const int imgunpack = (count == 3) && (strcmp(name,"image") == 0); if ((count == 1) || imgunpack) vector = (int *) vptr; @@ -3345,7 +3345,7 @@ void lammps_gather_subset(void *handle, char *name, tagint id; // error if tags are not defined or not consecutive - + int flag = 0; if (lmp->atom->tag_enable == 0) flag = 1; if (lmp->atom->natoms > MAXSMALLINT) flag = 1; @@ -3358,7 +3358,7 @@ void lammps_gather_subset(void *handle, char *name, void *vptr = lmp->atom->extract(name); // fix - + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); @@ -3391,7 +3391,7 @@ void lammps_gather_subset(void *handle, char *name, } // compute - + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); @@ -3438,7 +3438,7 @@ void lammps_gather_subset(void *handle, char *name, "unknown property/atom id"); return; } - + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_gather_subset: " @@ -3529,7 +3529,7 @@ void lammps_gather_subset(void *handle, char *name, } else { double *vector = nullptr; double **array = nullptr; - + if (count == 1) vector = (double *) vptr; else array = (double **) vptr; @@ -3619,7 +3619,7 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) void *vptr = lmp->atom->extract(name); // fix - + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); @@ -3647,7 +3647,7 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) } // compute - + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); @@ -3679,7 +3679,7 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) // custom fix property/atom vector or array // OLDSTYLE code - + if ((vptr == nullptr) && ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { @@ -3693,7 +3693,7 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) lmp->error->warning(FLERR,"lammps_scatter: unknown property/atom id"); return; } - + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter: mismatch property/atom type"); @@ -3713,7 +3713,7 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) if (count == 1) { if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; else vptr = (void *) lmp->atom->dvector[fcid]; - } else { + } else { if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; else vptr = (void *) lmp->atom->darray[fcid]; } @@ -3843,7 +3843,7 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, void *vptr = lmp->atom->extract(name); // fix - + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); @@ -3903,7 +3903,7 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, // custom fix property/atom vector or array // OLDSTYLE code - + if ((vptr == nullptr) && ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { @@ -3918,7 +3918,7 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, "unknown property/atom id"); return; } - + if (ltype != type) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter_subset: " @@ -3939,7 +3939,7 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, if (count == 1) { if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; else vptr = (void *) lmp->atom->dvector[fcid]; - } else { + } else { if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; else vptr = (void *) lmp->atom->darray[fcid]; } diff --git a/src/set.cpp b/src/set.cpp index 2a36874c8b..2966106345 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -581,7 +581,7 @@ void Set::command(int narg, char **arg) if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); index_custom = atom->find_custom(argi.get_name(),flag,cols); if (index_custom < 0) error->all(FLERR,"Custom property {} does not exist",pname); - + switch (argi.get_type()) { case ArgInfo::INAME: @@ -1025,7 +1025,7 @@ void Set::set(int keyword) } // update bonus data numbers - + if (keyword == SHAPE) { bigint nlocal_bonus = avec_ellipsoid->nlocal_bonus; MPI_Allreduce(&nlocal_bonus,&atom->nellipsoids,1, diff --git a/src/utils.cpp b/src/utils.cpp index fd3170859b..5be2b37c34 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -633,15 +633,15 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod expandflag = 1; } } - + } else if (arg[iarg][0] == 'd') { *ptr1 = '\0'; int flag,cols; int icustom = lmp->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; From 1e37d1ad7ff2a9beb8d9247072b2577d988315b4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 14:34:03 -0400 Subject: [PATCH 19/36] pretty --- src/atom.cpp | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/atom.cpp b/src/atom.cpp index c1cb9e011b..a0f7099319 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2472,47 +2472,39 @@ int Atom::add_custom(const char *name, int flag, int cols) { int index; - if (flag == 0 && cols == 0) { + if ((flag == 0) && (cols == 0)) { index = nivector; nivector++; - ivname = (char **) memory->srealloc(ivname,nivector*sizeof(char *), - "atom:ivname"); + ivname = (char **) memory->srealloc(ivname,nivector*sizeof(char *),"atom:ivname"); ivname[index] = utils::strdup(name); - ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *), - "atom:ivector"); + ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *),"atom:ivector"); memory->create(ivector[index],nmax,"atom:ivector"); - } else if (flag == 1 && cols == 0) { + } else if ((flag == 1) && (cols == 0)) { index = ndvector; ndvector++; - dvname = (char **) memory->srealloc(dvname,ndvector*sizeof(char *), - "atom:dvname"); + dvname = (char **) memory->srealloc(dvname,ndvector*sizeof(char *),"atom:dvname"); dvname[index] = utils::strdup(name); - dvector = (double **) memory->srealloc(dvector,ndvector*sizeof(double *), - "atom:dvector"); + dvector = (double **) memory->srealloc(dvector,ndvector*sizeof(double *),"atom:dvector"); memory->create(dvector[index],nmax,"atom:dvector"); - } else if (flag == 0 && cols) { + } else if ((flag == 0) && (cols > 0)) { index = niarray; niarray++; - ianame = (char **) memory->srealloc(ianame,niarray*sizeof(char *), - "atom:ianame"); + ianame = (char **) memory->srealloc(ianame,niarray*sizeof(char *),"atom:ianame"); ianame[index] = utils::strdup(name); - iarray = (int ***) memory->srealloc(iarray,niarray*sizeof(int **), - "atom:iarray"); + 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) { + } else if ((flag == 1) && (cols > 0)) { index = ndarray; ndarray++; - daname = (char **) memory->srealloc(daname,ndarray*sizeof(char *), - "atom:daname"); + daname = (char **) memory->srealloc(daname,ndarray*sizeof(char *),"atom:daname"); daname[index] = utils::strdup(name); - darray = (double ***) memory->srealloc(darray,ndarray*sizeof(double **), - "atom:darray"); + 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"); From 0a99d338f21b6cebee425a60feae9fc3427ab559 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 14:35:02 -0400 Subject: [PATCH 20/36] update argument parsing --- src/fix_property_atom.cpp | 45 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 7ec30025bc..2d122e9b03 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -112,24 +112,29 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : iarg++; // custom atom array - // OLDSTYLE code - } else if (strstr(arg[iarg],"i2_") == arg[iarg] || - strstr(arg[iarg],"d2_") == arg[iarg]) { + } else if (utils::strmatch(arg[iarg],"^[id]2_")) { 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 flag,ncols; - index[nvalue] = atom->find_custom(&arg[iarg][3],flag,ncols); - if (index[nvalue] >= 0) - 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]; + + int which,flag,ncols; + which = atom->find_custom(&arg[iarg][3],flag,ncols); + if (which >= 0) + error->all(FLERR,"Fix property/atom array name {} already exists", &arg[iarg][3]); + + ncols = utils::inumeric(FLERR,arg[iarg+1],true,lmp); + if (ncols < 1) + error->all(FLERR,"Invalid array columns number {} in fix property/atom", ncols); + + if (arg[iarg][0] == 'i') { + which = 0; + style[nvalue] = IARRAY; + } else { + which = 1; + style[nvalue] = DARRAY; + } + index[nvalue] = atom->add_custom(&arg[iarg][3],which,ncols); + cols[nvalue] = ncols; + values_peratom += ncols; nvalue++; iarg += 2; @@ -386,15 +391,15 @@ void FixPropertyAtom::write_data_section_pack(int /*mth*/, double **buf) 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; + 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; + for (k = 0; k < ncol; k++) + buf[i][icol+k] = darray[i][k]; icol += ncol; } } From de61b3a547fa0267841e0548877339d26359b7a9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 14:35:27 -0400 Subject: [PATCH 21/36] update utils::expand_args --- src/utils.cpp | 79 ++++++++++++++++----------------------------------- 1 file changed, 24 insertions(+), 55 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 5be2b37c34..66d5bf2af2 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -214,7 +214,7 @@ char *utils::fgets_trunc(char *buf, int size, FILE *fp) void utils::sfgets(const char *srcname, int srcline, char *s, int size, FILE *fp, const char *filename, Error *error) { - constexpr int MAXPATHLENBUF=1024; + constexpr int MAXPATHLENBUF = 1024; char *rv = fgets(s, size, fp); if (rv == nullptr) { // something went wrong char buf[MAXPATHLENBUF]; @@ -243,7 +243,7 @@ void utils::sfgets(const char *srcname, int srcline, char *s, int size, FILE *fp void utils::sfread(const char *srcname, int srcline, void *s, size_t size, size_t num, FILE *fp, const char *filename, Error *error) { - constexpr int MAXPATHLENBUF=1024; + constexpr int MAXPATHLENBUF = 1024; size_t rv = fread(s, size, num, fp); if (rv != num) { // something went wrong char buf[MAXPATHLENBUF]; @@ -543,16 +543,21 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod std::string word(arg[iarg]); expandflag = 0; - // only match compute/fix reference with a '*' wildcard + // match compute, fix, or custom property array reference with a '*' wildcard // number range in the first pair of square brackets - if (strmatch(word, "^[cf]_\\w+\\[\\d*\\*\\d*\\]")) { + if (strmatch(word, "^[cf]_\\w+\\[\\d*\\*\\d*\\]") || + strmatch(word, "^[id]2_\\w+\\[\\d*\\*\\d*\\]")) { - // split off the compute/fix ID, the wildcard and trailing text + // split off the compute/fix/property ID, the wildcard and trailing text size_t first = word.find("["); size_t second = word.find("]", first + 1); - id = word.substr(2, first - 2); + if (word[1] == '2') + id = word.substr(3, first - 3); + else + id = word.substr(2, first - 2); + wc = word.substr(first + 1, second - first - 1); tail = word.substr(second + 1); @@ -580,7 +585,7 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod } } - // fix + // fix } else if (word[0] == 'f') { int ifix = lmp->modify->find_fix(id); @@ -609,59 +614,20 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod // only match custom array reference with a '*' wildcard // number range in the first pair of square brackets - // OLDSTYLE code - if (strncmp(arg[iarg],"i2_",3) == 0 || strncmp(arg[iarg],"d2_",3) == 0) { - char *ptr1 = strchr(arg[iarg],'['); - if (ptr1) { - char *ptr2 = strchr(ptr1,']'); - if (ptr2) { - *ptr2 = '\0'; - if (strchr(ptr1,'*')) { + if ((word[0] == 'i') || (word[0] == 'd')) { + int flag, cols; + int icustom = lmp->atom->find_custom(id.c_str(), flag, cols); - if (arg[iarg][0] == 'i') { - *ptr1 = '\0'; - int flag,cols; - int icustom = lmp->atom->find_custom(&arg[iarg][3],flag,cols); - *ptr1 = '['; + if ((icustom >= 0) && (mode == 1) && (cols > 0)) { - // check for custom per-atom integer array + // check for custom per-atom 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 = lmp->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; - } - } - } - } + if (((word[0] == 'i') && (flag == 0)) || ((word[0] == 'i') && (flag == 1))) { + nmax = cols; + expandflag = 1; } } - - // split off the array name ID, the wildcard and trailing text - - if (expandflag) { - size_t first = word.find("["); - size_t second = word.find("]", first + 1); - id = word.substr(2, first - 2); - wc = word.substr(first + 1, second - first - 1); - tail = word.substr(second + 1); - } } // expansion will take place @@ -678,7 +644,10 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod for (int index = nlo; index <= nhi; index++) { // assemble and duplicate expanded string - earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}", word[0], id, index, tail)); + if (word[1] == '2') + earg[newarg] = utils::strdup(fmt::format("{}2_{}[{}]{}", word[0], id, index, tail)); + else + earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}", word[0], id, index, tail)); newarg++; } From cf25a586bd961c396f1e6c24e71b7bf3dbdd89c1 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 18 Aug 2021 13:07:49 -0600 Subject: [PATCH 22/36] debugging merged version --- doc/src/dump.rst | 33 +++++++++++++++++++-------------- src/dump_custom.cpp | 2 ++ src/utils.cpp | 6 +++--- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/doc/src/dump.rst b/doc/src/dump.rst index 1b81e23e28..998498d1d4 100644 --- a/doc/src/dump.rst +++ b/doc/src/dump.rst @@ -569,10 +569,11 @@ Nprocs-1) that currently owns the atom. *Procp1* is the proc ID+1, which can be convenient in place of a *type* attribute (1 to Ntypes) for coloring atoms in a visualization program. *Type* is the atom type (1 to Ntypes). *Element* is typically the chemical name of an -element, which you must assign to each type via the :doc:`dump_modify element ` command. More generally, it can be any -string you wish to associated with an atom type. *Mass* is the atom -mass. *Vx*, *vy*, *vz*, *fx*, *fy*, *fz*, and *q* are components of -atom velocity and force and atomic charge. +element, which you must assign to each type via the :doc:`dump_modify +element ` command. More generally, it can be any string +you wish to associated with an atom type. *Mass* is the atom mass. +*Vx*, *vy*, *vz*, *fx*, *fy*, *fz*, and *q* are components of atom +velocity and force and atomic charge. There are several options for outputting atom coordinates. The *x*, *y*, *z* attributes write atom coordinates "unscaled", in the @@ -646,11 +647,12 @@ above for how I can be specified with a wildcard asterisk to effectively specify multiple values. The *f_ID* and *f_ID[I]* attributes allow vector or array per-atom -quantities calculated by a :doc:`fix ` to be output. The ID in the -attribute should be replaced by the actual ID of the fix that has been -defined previously in the input script. The :doc:`fix ave/atom ` command is one that calculates per-atom -quantities. Since it can time-average per-atom quantities produced by -any :doc:`compute `, :doc:`fix `, or atom-style +quantities calculated by a :doc:`fix ` to be output. The ID in +the attribute should be replaced by the actual ID of the fix that has +been defined previously in the input script. The :doc:`fix ave/atom +` command is one that calculates per-atom quantities. +Since it can time-average per-atom quantities produced by any +:doc:`compute `, :doc:`fix `, or atom-style :doc:`variable `, this allows those time-averaged results to be written to a dump file. @@ -667,10 +669,10 @@ should be replaced by the actual name of the variable that has been defined previously in the input script. Only an atom-style variable can be referenced, since it is the only style that generates per-atom values. Variables of style *atom* can reference individual atom -attributes, per-atom attributes, thermodynamic keywords, or -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. +attributes, per-atom attributes, thermodynamic keywords, or 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 *i_name*, *d_name*, *i2_name*, *d2_name* attributes refer to per-atom integer and floating-point vectors or arrays that have been @@ -678,7 +680,10 @@ added via the :doc:`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]. +the name in brackets: e.g. d2_xyz[I], i2_mySpin[I], where I is in the +range from 1-M, where M is the number of columns in the custom array. +See the discussion above for how I can be specified with a wildcard +asterisk to effectively specify multiple values. See the :doc:`Modify ` page for information on how to add new compute and fix styles to LAMMPS to calculate per-atom quantities diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 68a2ab4a57..e7ad930019 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -1554,6 +1554,8 @@ int DumpCustom::parse_fields(int narg, char **arg) n = atom->find_custom(name,flag,cols); + printf("NAME %s\n",name); + if (n < 0) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[iarg] == 0) { diff --git a/src/utils.cpp b/src/utils.cpp index fd3170859b..d63cd1d1c4 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -693,9 +693,9 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod } } - //printf("NEWARG %d\n",newarg); - //for (int i = 0; i < newarg; i++) - // printf(" arg %d: %s\n",i,earg[i]); + printf("NEWARG %d\n",newarg); + for (int i = 0; i < newarg; i++) + printf(" arg %d: %s\n",i,earg[i]); return newarg; } From 104fa4624ec4cfa4dc9357ce976009d20e670b63 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 18:04:44 -0400 Subject: [PATCH 23/36] correct utils::expand_args() --- src/utils.cpp | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 66d5bf2af2..949d6d7793 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -609,56 +609,54 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod expandflag = 1; } } - } - } - // only match custom array reference with a '*' wildcard - // number range in the first pair of square brackets + // only match custom array reference with a '*' wildcard + // number range in the first pair of square brackets - if ((word[0] == 'i') || (word[0] == 'd')) { - int flag, cols; - int icustom = lmp->atom->find_custom(id.c_str(), flag, cols); + } else if ((word[0] == 'i') || (word[0] == 'd')) { + int flag, cols; + int icustom = lmp->atom->find_custom(id.c_str(), flag, cols); - if ((icustom >= 0) && (mode == 1) && (cols > 0)) { + if ((icustom >= 0) && (mode == 1) && (cols > 0)) { - // check for custom per-atom array + // check for custom per-atom array - if (((word[0] == 'i') && (flag == 0)) || ((word[0] == 'i') && (flag == 1))) { - nmax = cols; - expandflag = 1; + if (((word[0] == 'i') && (flag == 0)) || ((word[0] == 'd') && (flag == 1))) { + nmax = cols; + expandflag = 1; + } } } - } - // expansion will take place + // expansion will take place - if (expandflag) { + if (expandflag) { - // expand wild card string to nlo/nhi numbers - utils::bounds(file, line, wc, 1, nmax, nlo, nhi, lmp->error); + // expand wild card string to nlo/nhi numbers + utils::bounds(file, line, wc, 1, nmax, nlo, nhi, lmp->error); - if (newarg + nhi - nlo + 1 > maxarg) { - maxarg += nhi - nlo + 1; - earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); - } + if (newarg + nhi - nlo + 1 > maxarg) { + maxarg += nhi - nlo + 1; + earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); + } - for (int index = nlo; index <= nhi; index++) { - // assemble and duplicate expanded string - if (word[1] == '2') - earg[newarg] = utils::strdup(fmt::format("{}2_{}[{}]{}", word[0], id, index, tail)); - else - earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}", word[0], id, index, tail)); + for (int index = nlo; index <= nhi; index++) { + // assemble and duplicate expanded string + if (word[1] == '2') + earg[newarg] = utils::strdup(fmt::format("{}2_{}[{}]{}", word[0], id, index, tail)); + else + earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}", word[0], id, index, tail)); + newarg++; + } + } else { + // no expansion: duplicate original string + if (newarg == maxarg) { + maxarg++; + earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); + } + earg[newarg] = utils::strdup(word); newarg++; } - - } else { - // no expansion: duplicate original string - if (newarg == maxarg) { - maxarg++; - earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); - } - earg[newarg] = utils::strdup(word); - newarg++; } } From f6874af7e5cd21b2958bba3219a26e69334765fe Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 18:05:36 -0400 Subject: [PATCH 24/36] pretty --- src/VTK/dump_vtk.cpp | 4 +- src/compute_property_atom.cpp | 141 ++++++++++++---------------------- src/modify.cpp | 15 ++-- 3 files changed, 54 insertions(+), 106 deletions(-) diff --git a/src/VTK/dump_vtk.cpp b/src/VTK/dump_vtk.cpp index f94a6957fb..f323ce820f 100644 --- a/src/VTK/dump_vtk.cpp +++ b/src/VTK/dump_vtk.cpp @@ -785,8 +785,8 @@ int DumpVTK::count() i = ATTRIBUTES + nfield + ithresh; iwhich = atom->find_custom(id_custom[field2index[i]],flag,cols) double **darray = atom->darray[iwhich]; - ptr = &darray[0][argindex[i]-1]; - nstride = atom->dcols[iwhich]; + ptr = &darray[0][argindex[i]-1]; + nstride = atom->dcols[iwhich]; } // unselect atoms that don't meet threshold criterion diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index e8e1293e28..190168db4b 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -122,262 +122,215 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_muz; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_mu; // 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"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_spx; } else if (strcmp(arg[iarg],"spy") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_spy; } else if (strcmp(arg[iarg],"spz") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_spz; } else if (strcmp(arg[iarg],"sp") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_sp; } else if (strcmp(arg[iarg],"fmx") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_fmx; } else if (strcmp(arg[iarg],"fmy") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_fmy; } else if (strcmp(arg[iarg],"fmz") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_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"); + 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 " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_radius; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_diameter; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_angmomz; } else if (strcmp(arg[iarg],"shapex") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapex; } else if (strcmp(arg[iarg],"shapey") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapey; } else if (strcmp(arg[iarg],"shapez") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapez; } else if (strcmp(arg[iarg],"quatw") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); avec_body = (AtomVecBody *) atom->style_match("body"); if (!avec_ellipsoid && !avec_body) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatw; } else if (strcmp(arg[iarg],"quati") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); avec_body = (AtomVecBody *) atom->style_match("body"); if (!avec_ellipsoid && !avec_body) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quati; } else if (strcmp(arg[iarg],"quatj") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); avec_body = (AtomVecBody *) atom->style_match("body"); if (!avec_ellipsoid && !avec_body) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatj; } else if (strcmp(arg[iarg],"quatk") == 0) { avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); avec_body = (AtomVecBody *) atom->style_match("body"); if (!avec_ellipsoid && !avec_body) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatk; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_tqz; } else if (strcmp(arg[iarg],"end1x") == 0) { avec_line = (AtomVecLine *) atom->style_match("line"); - if (!avec_line) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_end1x; } else if (strcmp(arg[iarg],"end1y") == 0) { avec_line = (AtomVecLine *) atom->style_match("line"); - if (!avec_line) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_end1y; } else if (strcmp(arg[iarg],"end1z") == 0) { avec_line = (AtomVecLine *) atom->style_match("line"); - if (!avec_line) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_end1z; } else if (strcmp(arg[iarg],"end2x") == 0) { avec_line = (AtomVecLine *) atom->style_match("line"); - if (!avec_line) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_end2x; } else if (strcmp(arg[iarg],"end2y") == 0) { avec_line = (AtomVecLine *) atom->style_match("line"); - if (!avec_line) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_end2y; } else if (strcmp(arg[iarg],"end2z") == 0) { avec_line = (AtomVecLine *) atom->style_match("line"); - if (!avec_line) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_end2z; } else if (strcmp(arg[iarg],"corner1x") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner1x; } else if (strcmp(arg[iarg],"corner1y") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner1y; } else if (strcmp(arg[iarg],"corner1z") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner1z; } else if (strcmp(arg[iarg],"corner2x") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + 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 " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner2y; } else if (strcmp(arg[iarg],"corner2z") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner2z; } else if (strcmp(arg[iarg],"corner3x") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner3x; } else if (strcmp(arg[iarg],"corner3y") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_corner3y; } else if (strcmp(arg[iarg],"corner3z") == 0) { avec_tri = (AtomVecTri *) atom->style_match("tri"); - if (!avec_tri) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for 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"); + error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_nbonds; // custom per-atom vector diff --git a/src/modify.cpp b/src/modify.cpp index 995b3b82ac..eff6ea8337 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -223,16 +223,11 @@ void Modify::init() list_init_energy_global(n_energy_global,list_energy_global); list_init_energy_atom(n_energy_atom,list_energy_atom); - list_init(INITIAL_INTEGRATE_RESPA, - n_initial_integrate_respa,list_initial_integrate_respa); - list_init(POST_INTEGRATE_RESPA, - n_post_integrate_respa,list_post_integrate_respa); - list_init(POST_FORCE_RESPA, - n_post_force_respa,list_post_force_respa); - list_init(PRE_FORCE_RESPA, - n_pre_force_respa,list_pre_force_respa); - list_init(FINAL_INTEGRATE_RESPA, - n_final_integrate_respa,list_final_integrate_respa); + list_init(INITIAL_INTEGRATE_RESPA,n_initial_integrate_respa,list_initial_integrate_respa); + list_init(POST_INTEGRATE_RESPA,n_post_integrate_respa,list_post_integrate_respa); + list_init(POST_FORCE_RESPA,n_post_force_respa,list_post_force_respa); + list_init(PRE_FORCE_RESPA,n_pre_force_respa,list_pre_force_respa); + list_init(FINAL_INTEGRATE_RESPA,n_final_integrate_respa,list_final_integrate_respa); list_init(MIN_PRE_EXCHANGE,n_min_pre_exchange,list_min_pre_exchange); list_init(MIN_PRE_NEIGHBOR,n_min_pre_neighbor,list_min_pre_neighbor); From b19a211d701685390d33e4603f9f06dd674d91ee Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 18:06:21 -0400 Subject: [PATCH 25/36] update code --- src/atom.cpp | 14 +--- src/compute_property_atom.cpp | 84 ++++++++++--------- src/library.cpp | 148 +++++++++++++--------------------- 3 files changed, 101 insertions(+), 145 deletions(-) diff --git a/src/atom.cpp b/src/atom.cpp index a0f7099319..ab044b6c47 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2774,13 +2774,10 @@ void *Atom::extract(const char *name) // -------------------------------------------------------------------- // custom vectors and arrays - // OLDSTYLE code - if (strstr(name,"i_") == name || strstr(name,"d_") == name || - strstr(name,"i2_") == name || strstr(name,"d2_") == name) { - int which = 0; + if (utils::strmatch(name,"^[id]2?_")) { + int which = 0, array = 0; if (name[0] == 'd') which = 1; - int array = 0; if (name[1] == '2') array = 1; int index,flag,cols; @@ -2897,13 +2894,10 @@ int Atom::extract_datatype(const char *name) // -------------------------------------------------------------------- // custom vectors and arrays - // OLDSTYLE code - if (strstr(name,"i_") == name || strstr(name,"d_") == name || - strstr(name,"i2_") == name || strstr(name,"d2_") == name) { - int which = 0; + if (utils::strmatch(name,"^[id]2?_")) { + int which = 0, array = 0; if (name[0] == 'd') which = 1; - int array = 0; if (name[1] == '2') array = 1; int index,flag,cols; diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 190168db4b..d4cec70fe4 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -14,6 +14,7 @@ #include "compute_property_atom.h" +#include "arg_info.h" #include "atom.h" #include "atom_vec.h" #include "atom_vec_body.h" @@ -333,55 +334,52 @@ 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_nbonds; - // custom per-atom vector + // custom per-atom vector or array - } else if (utils::strmatch(arg[iarg],"^i_")) { + } else if (utils::strmatch(arg[iarg],"^[id]2?_")) { 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 integer " - "vector does not exist"); - pack_choice[i] = &ComputePropertyAtom::pack_iname; + ArgInfo argi(arg[iarg], ArgInfo::INAME| ArgInfo::DNAME); + const char *pname = argi.get_name(); - } else if (utils::strmatch(arg[iarg],"^d_")) { - 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 floating point " - "vector does not exist"); - pack_choice[i] = &ComputePropertyAtom::pack_dname; + index[i] = atom->find_custom(pname,flag,cols); + if (index[i] < 0) + error->all(FLERR,"Compute property/atom property {} does not exist", pname); - // custom per-atom arrays, must include bracketed index - // OLDSTYLE code + // handle vectors + if ((cols == 0) && (arg[iarg][1] == '_')) { + if (argi.get_dim() != 0) + error->all(FLERR,"Compute property/atom custom vector {} is incorrectly indexed",pname); - } else if (strstr(arg[iarg],"i2_") == arg[iarg] || - strstr(arg[iarg],"d2_") == arg[iarg]) { - int which = 0; - if (arg[iarg][0] == 'd') which = 1; + if (arg[iarg][0] == 'i') { + if (argi.get_type() == ArgInfo::INAME) + pack_choice[i] = &ComputePropertyAtom::pack_iname; + else + error->all(FLERR,"Compute property/atom integer vector {} does not exist",pname); + } else if (arg[iarg][0] == 'd') { + if (argi.get_type() == ArgInfo::DNAME) + pack_choice[i] = &ComputePropertyAtom::pack_dname; + else + error->all(FLERR,"Compute property/atom floating-point vector {} does not exist",pname); + } + } + // handle arrays + else if ((cols > 0) && (arg[iarg][1] == '2')) { + if (argi.get_dim() != 1) + error->all(FLERR,"Compute property/atom custom array {} is not indexed",pname); + colindex[i] = argi.get_index1(); - 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; + if (arg[iarg][0] == 'i') { + if (argi.get_type() == ArgInfo::INAME) + pack_choice[i] = &ComputePropertyAtom::pack_i2name; + else + error->all(FLERR,"Compute property/atom integer array {} does not exist",pname); + } else if (arg[iarg][0] == 'd') { + if (argi.get_type() == ArgInfo::DNAME) + pack_choice[i] = &ComputePropertyAtom::pack_d2name; + else + error->all(FLERR,"Compute property/atom floating-point array {} does not exist",pname); + } + } else error->all(FLERR,"Inconsistent request for custom property {}", pname); // anything else must be recognized by atom style diff --git a/src/library.cpp b/src/library.cpp index 1397cf889e..db609351f7 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2829,7 +2829,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) { #if defined(LAMMPS_BIGBIG) lmp->error->all(FLERR,"Library function lammps_gather" - " not compatible with -DLAMMPS_BIGBIG"); + " not compatible with -DLAMMPS_BIGBIG"); #else int i,j,offset,fcid,ltype,icol; @@ -2915,14 +2915,10 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) } // custom fix property/atom vector or array - // OLDSTYLE code - if ((vptr == nullptr) && - ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || - (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { - if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) - fcid = lmp->atom->find_custom(&name[2],ltype,icol); + if (utils::strmatch(name,"^[id]_")) fcid = lmp->atom->find_custom(&name[2],ltype,icol); else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { @@ -2948,11 +2944,11 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) } if (count == 1) { - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; } else { - if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; - else vptr = (void *) lmp->atom->darray[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; } } @@ -2960,7 +2956,7 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data) if (vptr == nullptr) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather: undefined property name"); + lmp->error->warning(FLERR,"lammps_gather: undefined property name"); return; } @@ -3104,20 +3100,17 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if (lmp->modify->fix[fcid]->peratom_flag == 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat:" - " fix does not return peratom data"); + lmp->error->warning(FLERR,"lammps_gather_concat: fix does not return peratom data"); return; } if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat:" - " count != values peratom for fix"); + lmp->error->warning(FLERR,"lammps_gather_concat: count != values peratom for fix"); return; } if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { if (lmp->comm->me == 0) - lmp->error->all(FLERR,"lammps_gather_concat:" - " fix not computed at compatible time"); + lmp->error->all(FLERR,"lammps_gather_concat: fix not computed at compatible time"); return; } @@ -3138,14 +3131,12 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if (lmp->modify->compute[fcid]->peratom_flag == 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat:" - " compute does not return peratom data"); + lmp->error->warning(FLERR,"lammps_gather_concat: compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat:" - " count != values peratom for compute"); + lmp->error->warning(FLERR,"lammps_gather_concat: count != values peratom for compute"); return; } @@ -3157,48 +3148,40 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d } // custom per-atom vector or array - // OLDSTYLE code - if ((vptr==nullptr) && - ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || - (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + if ((vptr==nullptr) && utils::strmatch(name,"^[id]2?_")) { - if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) - fcid = lmp->atom->find_custom(&name[2],ltype,icol); + if (utils::strmatch(name,"^[id]_")) fcid = lmp->atom->find_custom(&name[2],ltype,icol); else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: " - "unknown property/atom id"); + lmp->error->warning(FLERR,"lammps_gather_concat: unknown property/atom id"); return; } if (ltype != type) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: " - "mismatch property/atom type"); + lmp->error->warning(FLERR,"lammps_gather_concat: mismatch property/atom type"); return; } if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: " - "mismatch property/atom count"); + lmp->error->warning(FLERR,"lammps_gather_concat: mismatch property/atom count"); return; } if (count > 1 && icol != count) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: " - "mismatch property/atom count"); + lmp->error->warning(FLERR,"lammps_gather_concat: mismatch property/atom count"); return; } if (count == 1) { - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; } else { - if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; - else vptr = (void *) lmp->atom->darray[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; } } @@ -3206,7 +3189,7 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d if (vptr == nullptr) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: undefined property name"); + lmp->error->warning(FLERR,"lammps_gather_concat: undefined property name"); return; } @@ -3375,14 +3358,12 @@ void lammps_gather_subset(void *handle, char *name, return; } if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_gather_subset:" - " count != values peratom for fix"); + lmp->error->warning(FLERR,"lammps_gather_subset: count != values peratom for fix"); return; } if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { if (lmp->comm->me == 0) - lmp->error->all(FLERR,"lammps_gather_subset:" - " fix not computed at compatible time"); + lmp->error->all(FLERR,"lammps_gather_subset: fix not computed at compatible time"); return; } @@ -3403,14 +3384,12 @@ void lammps_gather_subset(void *handle, char *name, if (lmp->modify->compute[fcid]->peratom_flag == 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset:" - " compute does not return peratom data"); + lmp->error->warning(FLERR,"lammps_gather_subset: compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset:" - " count != values peratom for compute"); + lmp->error->warning(FLERR,"lammps_gather_subset: count != values peratom for compute"); return; } @@ -3422,48 +3401,41 @@ void lammps_gather_subset(void *handle, char *name, } // custom fix property/atom vector or array - // OLDSTYLE code - if ((vptr == nullptr) && - ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || - (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { - if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) - fcid = lmp->atom->find_custom(&name[2],ltype,icol); + if (utils::strmatch(name,"^[id]_")) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: " - "unknown property/atom id"); + lmp->error->warning(FLERR,"lammps_gather_subset: unknown property/atom id"); return; } if (ltype != type) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: " - "mismatch property/atom type"); + lmp->error->warning(FLERR,"lammps_gather_subset: mismatch property/atom type"); return; } if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: " - "mismatch property/atom count"); + lmp->error->warning(FLERR,"lammps_gather_subset: mismatch property/atom count"); return; } if (count > 1 && icol != count) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: " - "mismatch property/atom count"); + lmp->error->warning(FLERR,"lammps_gather_subset: mismatch property/atom count"); return; } if (count == 1) { - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; } else { - if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; - else vptr = (void *) lmp->atom->darray[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; } } @@ -3471,7 +3443,7 @@ void lammps_gather_subset(void *handle, char *name, if (vptr == nullptr) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: undefined property name"); + lmp->error->warning(FLERR,"lammps_gather_subset: undefined property name"); return; } @@ -3678,14 +3650,11 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) } // custom fix property/atom vector or array - // OLDSTYLE code - if ((vptr == nullptr) && - ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || - (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { - if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) - fcid = lmp->atom->find_custom(&name[2],ltype,icol); + if (utils::strmatch(name,"^[id]_")) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { @@ -3711,11 +3680,11 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data) } if (count == 1) { - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; } else { - if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; - else vptr = (void *) lmp->atom->darray[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; } } @@ -3902,27 +3871,22 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, } // custom fix property/atom vector or array - // OLDSTYLE code - if ((vptr == nullptr) && - ((strstr(name,"d_") == name) || (strstr(name,"i_") == name) || - (strstr(name,"d2_") == name) || (strstr(name,"i2_") == name))) { + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { - if ((strstr(name,"d_") == name) || (strstr(name,"i_") == name)) - fcid = lmp->atom->find_custom(&name[2],ltype,icol); + if (utils::strmatch(name,"^[id]_")) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); else fcid = lmp->atom->find_custom(&name[3],ltype,icol); if (fcid < 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_scatter_subset: " - "unknown property/atom id"); + lmp->error->warning(FLERR,"lammps_scatter_subset: unknown property/atom id"); return; } if (ltype != type) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_scatter_subset: " - "mismatch property/atom type"); + lmp->error->warning(FLERR,"lammps_scatter_subset: mismatch property/atom type"); return; } if (count == 1 && icol != 0) { @@ -3937,11 +3901,11 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, } if (count == 1) { - if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; - else vptr = (void *) lmp->atom->dvector[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; + else vptr = (void *) lmp->atom->dvector[fcid]; } else { - if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; - else vptr = (void *) lmp->atom->darray[fcid]; + if (ltype==0) vptr = (void *) lmp->atom->iarray[fcid]; + else vptr = (void *) lmp->atom->darray[fcid]; } } From 546c9a109ebdf7ec280bea8985e03faede042107 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 20:25:49 -0400 Subject: [PATCH 26/36] fix uninitialized data bug --- src/fix_property_atom.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 2d122e9b03..0744aca7b2 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -93,11 +93,12 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (utils::strmatch(arg[iarg],"^i_")) { style[nvalue] = IVEC; - int flag,cols; - index[nvalue] = atom->find_custom(&arg[iarg][2],flag,cols); + int flag,ncols; + index[nvalue] = atom->find_custom(&arg[iarg][2],flag,ncols); if (index[nvalue] >= 0) error->all(FLERR,"Fix property/atom vector name already exists"); index[nvalue] = atom->add_custom(&arg[iarg][2],0,0); + cols[nvalue] = 0; nvalue++; iarg++; @@ -108,6 +109,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : if (index[nvalue] >= 0) error->all(FLERR,"Fix property/atom vector name already exists"); index[nvalue] = atom->add_custom(&arg[iarg][2],1,0); + cols[nvalue] = 0; nvalue++; iarg++; From d9f3745effafa22f633aa9a383b84a9f4f226af1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 20:26:01 -0400 Subject: [PATCH 27/36] pretty --- src/dump_custom.cpp | 9 +++------ src/fix_property_atom.cpp | 6 ++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 3aac7a3e79..3f70d242b1 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -1532,15 +1532,12 @@ int DumpCustom::parse_fields(int narg, char **arg) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[iarg] == 0) { if (!flag || cols) - error->all(FLERR, - "Property double vector for dump custom does not exist"); + error->all(FLERR,"Property double vector for dump custom does not exist"); } else { if (!flag || !cols) - error->all(FLERR, - "Property double array for dump custom does not exist"); + error->all(FLERR,"Property double array for dump custom does not exist"); if (argindex[iarg] > atom->dcols[n]) - error->all(FLERR, - "Dump custom property array is accessed out-of-range"); + error->all(FLERR,"Dump custom property array is accessed out-of-range"); } field2index[iarg] = add_custom(name,1); diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 0744aca7b2..761f8264d3 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -66,8 +66,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : iarg++; } else if (strcmp(arg[iarg],"q") == 0) { if (atom->q_flag) - error->all(FLERR,"Fix property/atom q when atom_style " - "already has charge attribute"); + error->all(FLERR,"Fix property/atom q when atom_style already has charge attribute"); if (q_flag) error->all(FLERR,"Fix property/atom cannot specify q twice"); style[nvalue] = CHARGE; @@ -78,8 +77,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : iarg++; } else if (strcmp(arg[iarg],"rmass") == 0) { if (atom->rmass_flag) - error->all(FLERR,"Fix property/atom rmass when atom_style " - "already has rmass attribute"); + error->all(FLERR,"Fix property/atom rmass when atom_style already has rmass attribute"); if (rmass_flag) error->all(FLERR,"Fix property/atom cannot specify rmass twice"); style[nvalue] = RMASS; From 04b0f98a5f040598034b1a87ab5cf1a3e7e38e66 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 20:26:51 -0400 Subject: [PATCH 28/36] fix logic bug in utils::expand_args() --- src/utils.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 949d6d7793..528908807c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -627,36 +627,32 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod } } } + } - // expansion will take place + // expansion will take place - if (expandflag) { + if (expandflag) { - // expand wild card string to nlo/nhi numbers - utils::bounds(file, line, wc, 1, nmax, nlo, nhi, lmp->error); + // expand wild card string to nlo/nhi numbers + utils::bounds(file, line, wc, 1, nmax, nlo, nhi, lmp->error); - if (newarg + nhi - nlo + 1 > maxarg) { - maxarg += nhi - nlo + 1; - earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); - } + if (newarg + nhi - nlo + 1 > maxarg) { + maxarg += nhi - nlo + 1; + earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); + } - for (int index = nlo; index <= nhi; index++) { - // assemble and duplicate expanded string - if (word[1] == '2') - earg[newarg] = utils::strdup(fmt::format("{}2_{}[{}]{}", word[0], id, index, tail)); - else - earg[newarg] = utils::strdup(fmt::format("{}_{}[{}]{}", word[0], id, index, tail)); - newarg++; - } - } else { - // no expansion: duplicate original string - if (newarg == maxarg) { - maxarg++; - earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); - } - earg[newarg] = utils::strdup(word); + for (int index = nlo; index <= nhi; index++) { + earg[newarg] = utils::strdup(fmt::format("{}2_{}[{}]{}", word[0], id, index, tail)); newarg++; } + } else { + // no expansion: duplicate original string + if (newarg == maxarg) { + maxarg++; + earg = (char **) lmp->memory->srealloc(earg, maxarg * sizeof(char *), "input:earg"); + } + earg[newarg] = utils::strdup(word); + newarg++; } } From b942c4d122e18331416b11c98a2a3264fb1de819 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 22:31:46 -0400 Subject: [PATCH 29/36] fix data corruption bug affecting write_data --- src/fix_property_atom.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 761f8264d3..0f86d8abc3 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -97,6 +97,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR,"Fix property/atom vector name already exists"); index[nvalue] = atom->add_custom(&arg[iarg][2],0,0); cols[nvalue] = 0; + values_peratom++; nvalue++; iarg++; @@ -108,6 +109,7 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR,"Fix property/atom vector name already exists"); index[nvalue] = atom->add_custom(&arg[iarg][2],1,0); cols[nvalue] = 0; + values_peratom++; nvalue++; iarg++; From c53875421b31e35e7753eb3fe643c9528e3ccd76 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 22:50:42 -0400 Subject: [PATCH 30/36] fix read_data bug --- src/fix_property_atom.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 0f86d8abc3..1e583a4ec9 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -254,8 +254,7 @@ void FixPropertyAtom::init() id_offset is applied to first atomID field if multiple data files are read ------------------------------------------------------------------------- */ -void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, - tagint id_offset) +void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint id_offset) { int j,k,m,ncol; tagint itag; @@ -280,14 +279,13 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, try { ValueTokenizer values(buf); - if ((int)values.count() != nvalue+1) - error->all(FLERR,"Incorrect format in {} section " - "of data file: {}",keyword,buf); + if ((int)values.count() != values_peratom+1) + error->all(FLERR,"Incorrect format in {} section of data file: {}" + " expected {} and got {}",keyword,buf,values_peratom+1,values.count()); itag = values.next_tagint() + id_offset; if (itag <= 0 || itag > map_tag_max) - error->all(FLERR,"Invalid atom ID {} in {} section of " - "data file",itag, keyword); + error->all(FLERR,"Invalid atom ID {} in {} section of data file",itag, keyword); // assign words in line to per-atom vectors @@ -303,7 +301,6 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, atom->ivector[index[j]][m] = values.next_int(); } else if (style[j] == DVEC) { atom->dvector[index[j]][m] = values.next_double(); - // NOTE: Axel please check these lines of array code } else if (style[j] == IARRAY) { ncol = cols[j]; for (k = 0; k < ncol; k++) @@ -316,8 +313,7 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, } } } catch (TokenizerException &e) { - error->all(FLERR,"Invalid format in {} section of data " - "file '{}': {}",keyword, buf,e.what()); + error->all(FLERR,"Invalid format in {} section of data file '{}': {}",keyword, buf,e.what()); } buf = next + 1; } From 5c46c6d3a6c5c046c85dbe6b4f1092d20526e5b4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 18 Aug 2021 22:51:09 -0400 Subject: [PATCH 31/36] update unit test for per-atom arrays and vectors --- unittest/formats/test_atom_styles.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index b091360170..71c1ed882f 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -4648,7 +4648,8 @@ TEST_F(AtomStyleTest, property_atom) command("pair_style zero 4.0"); command("units real"); command("atom_modify map array"); - command("fix props all property/atom i_one d_two mol d_three q rmass ghost yes"); + command("fix props all property/atom i_one d_two mol d_three q rmass " + "i2_four 2 d2_five 3 ghost yes"); command("read_data test_atom_styles.data fix props NULL Properties"); command("pair_coeff * *"); END_HIDE_OUTPUT(); @@ -4737,7 +4738,8 @@ TEST_F(AtomStyleTest, property_atom) command("clear"); ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic")); command("read_restart test_atom_styles.restart"); - command("fix props all property/atom i_one d_two mol d_three q rmass ghost yes"); + command("fix props all property/atom i_one d_two mol d_three q rmass " + "i2_four 2 d2_five 3 ghost yes"); END_HIDE_OUTPUT(); expected.natoms = 2; expected.nlocal = 2; @@ -4749,7 +4751,11 @@ TEST_F(AtomStyleTest, property_atom) expected.has_mass_setflag = true; expected.has_sametag = true; expected.has_extra = true; - expected.nextra_store = 7; + expected.has_ivname = true; + expected.has_dvname = true; + expected.has_ianame = true; + expected.has_daname = true; + expected.nextra_store = 12; ASSERT_ATOM_STATE_EQ(lmp->atom, expected); ASSERT_NE(lmp->atom->avec, nullptr); From 9470a0eeb669bf308a7d694f71df5a3ff3547ee8 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 19 Aug 2021 11:34:25 -0600 Subject: [PATCH 32/36] clarified doc pages for fix property/atom and read_data --- doc/src/fix_property_atom.rst | 18 +++++++++++------- doc/src/read_data.rst | 22 +++++++++++----------- src/dump_custom.cpp | 2 -- src/read_data.cpp | 33 ++++++++++++++++----------------- src/utils.cpp | 6 +++--- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/doc/src/fix_property_atom.rst b/doc/src/fix_property_atom.rst index c7bf3f8c37..b6f6560770 100644 --- a/doc/src/fix_property_atom.rst +++ b/doc/src/fix_property_atom.rst @@ -180,7 +180,9 @@ 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. +property on each line. Note that the order of values on each line +corresponds to the order of custom names in the fix property/atom +command. 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 @@ -301,12 +303,14 @@ uninterrupted fashion. .. warning:: - When reading data from a restart file, this fix command has to be specified - **exactly** the same way as before. LAMMPS will only check whether a - fix is of the same style and has the same fix ID and in case of a match - will then try to initialize the fix with the data stored in the binary - restart file. If the fix property/atom command does not match exactly, - data can be corrupted or LAMMPS may crash. + When reading data from a restart file, this fix command has to be + specified **exactly** the same was in the input script that created + the restart file. LAMMPS will only check whether a fix is of the + same style and has the same fix ID and in case of a match will then + try to initialize the fix with the data stored in the binary + restart file. If the names and associated date types in the new + fix property/atom command do not match the old one exactly, data + can be corrupted or LAMMPS may crash. None of the :doc:`fix_modify ` options are relevant to this fix. No global or per-atom quantities are stored by this fix for diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 18cc24ffff..5b5c951688 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -66,8 +66,8 @@ simulation. The file can be ASCII text or a gzipped text file (detected by a .gz suffix). This is one of 3 ways to specify initial atom coordinates; see the :doc:`read_restart ` and :doc:`create_atoms ` commands for alternative methods. -Also see the explanation of the :doc:`-restart command-line switch ` which can convert a restart file to a data -file. +Also see the explanation of the :doc:`-restart command-line switch +` which can convert a restart file to a data file. This command can be used multiple times to add new atoms and their properties to an existing system by using the *add*, *offset*, and @@ -246,22 +246,22 @@ appear in any order, with a few exceptions as noted below. The keyword *fix* can be used one or more times. Each usage specifies a fix that will be used to process a specific portion of the data -file. Any header line containing *header-string* and any section with -a name containing *section-string* will be passed to the specified +file. Any header line containing *header-string* and any section that +is an exact match to *section-string* will be passed to the specified fix. See the :doc:`fix property/atom ` command for -an example of a fix that operates in this manner. The page for -the fix defines the syntax of the header line(s) and section(s) that -it reads from the data file. Note that the *header-string* can be +an example of a fix that operates in this manner. The doc page for +the fix defines the syntax of the header line(s) and section that it +reads from the data file. Note that the *header-string* can be specified as NULL, in which case no header lines are passed to the -fix. This means that it can infer the length of its Section from +fix. This means the fix can infer the length of its Section from standard header settings, such as the number of atoms. The formatting of individual lines in the data file (indentation, spacing between words and numbers) is not important except that header and section keywords (e.g. atoms, xlo xhi, Masses, Bond Coeffs) must -be capitalized as shown and can't have extra white-space between their -words - e.g. two spaces or a tab between the 2 words in "xlo xhi" or -the 2 words in "Bond Coeffs", is not valid. +be capitalized as shown and cannot have extra white-space between +their words - e.g. two spaces or a tab between the 2 words in "xlo +xhi" or the 2 words in "Bond Coeffs", is not valid. ---------- diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 3acaf6535e..3f70d242b1 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -1551,8 +1551,6 @@ int DumpCustom::parse_fields(int narg, char **arg) n = atom->find_custom(name,flag,cols); - printf("NAME %s\n",name); - if (n < 0) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[iarg] == 0) { diff --git a/src/read_data.cpp b/src/read_data.cpp index 12ad6c3b8c..c33c65f676 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -509,21 +509,6 @@ void ReadData::command(int narg, char **arg) while (strlen(keyword)) { - // if special fix matches, it processes section - - if (nfix) { - int i; - for (i = 0; i < nfix; i++) - if (strcmp(keyword,fix_section[i]) == 0) { - if (firstpass) fix(fix_index[i],keyword); - else skip_lines(modify->fix[fix_index[i]]-> - read_data_skip_lines(keyword)); - parse_keyword(0); - break; - } - if (i < nfix) continue; - } - if (strcmp(keyword,"Atoms") == 0) { atomflag = 1; if (firstpass) { @@ -728,8 +713,22 @@ void ReadData::command(int narg, char **arg) if (firstpass) impropercoeffs(1); else skip_lines(nimpropertypes); - } else error->all(FLERR,"Unknown identifier in data file: {}", - keyword); + // if specified fix matches, it processes section + + } else if (nfix) { + int i; + for (i = 0; i < nfix; i++) + if (strcmp(keyword,fix_section[i]) == 0) { + if (firstpass) fix(fix_index[i],keyword); + else skip_lines(modify->fix[fix_index[i]]-> + read_data_skip_lines(keyword)); + parse_keyword(0); + break; + } + if (i == nfix) + error->all(FLERR,"Unknown identifier in data file: {}",keyword); + + } else error->all(FLERR,"Unknown identifier in data file: {}",keyword); parse_keyword(0); } diff --git a/src/utils.cpp b/src/utils.cpp index 7a7a03946e..528908807c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -656,9 +656,9 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod } } - printf("NEWARG %d\n",newarg); - for (int i = 0; i < newarg; i++) - printf(" arg %d: %s\n",i,earg[i]); + //printf("NEWARG %d\n",newarg); + //for (int i = 0; i < newarg; i++) + // printf(" arg %d: %s\n",i,earg[i]); return newarg; } From 7d0c052425bed1e84bec7df2a8ffb50a07d49915 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 19 Aug 2021 14:00:37 -0600 Subject: [PATCH 33/36] Fix deallocation with Kokkos --- src/atom.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/atom.cpp b/src/atom.cpp index ab044b6c47..1476a9ae2f 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -309,7 +309,8 @@ Atom::~Atom() } for (int i = 0; i < ndvector; i++) { delete [] dvname[i]; - memory->destroy(dvector[i]); + if (dvector) + memory->destroy(dvector[i]); } for (int i = 0; i < niarray; i++) { delete [] ianame[i]; From 845cebaab1d4fcbbbd7c1970428b0ba098f59f36 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 19 Aug 2021 14:02:57 -0600 Subject: [PATCH 34/36] Add comment --- src/atom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom.cpp b/src/atom.cpp index 1476a9ae2f..4135298673 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -309,7 +309,7 @@ Atom::~Atom() } for (int i = 0; i < ndvector; i++) { delete [] dvname[i]; - if (dvector) + if (dvector) // (needed for Kokkos) memory->destroy(dvector[i]); } for (int i = 0; i < niarray; i++) { From bc6e805c990ebf6ace86b1de14d47b65a785146d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 19 Aug 2021 16:53:03 -0400 Subject: [PATCH 35/36] fix doc formatting issues --- doc/src/Developer_utils.rst | 2 +- doc/src/dump.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/Developer_utils.rst b/doc/src/Developer_utils.rst index 60eded42e0..e419520edd 100644 --- a/doc/src/Developer_utils.rst +++ b/doc/src/Developer_utils.rst @@ -336,7 +336,7 @@ repetitive tasks. The :cpp:class:`LAMMPS_NS::ArgInfo` class provides an abstraction for parsing references to compute or fix styles, variables or custom integer or double properties handled by :doc:`fix property/atom `. -These would start with a "c\_", "f\_", "v\_", "d\_", "d2\_", "i\_", or "i2_" +These would start with a "c\_", "f\_", "v\_", "d\_", "d2\_", "i\_", or "i2\_" followed by the ID or name of than instance and may be postfixed with one or two array indices "[]" with numbers > 0. diff --git a/doc/src/dump.rst b/doc/src/dump.rst index 998498d1d4..c2509e6654 100644 --- a/doc/src/dump.rst +++ b/doc/src/dump.rst @@ -81,7 +81,7 @@ Syntax radius, diameter, omegax, omegay, omegaz, angmomx, angmomy, angmomz, tqx, tqy, tqz, c_ID, c_ID[I], f_ID, f_ID[I], v_name, - i_name, d_name, i2_name[I], d2_name[I] + i_name, d_name, i2_name[I], d2_name[I] .. parsed-literal:: From f7c8b0c88b1ca9051bb4cf284ee26498462c863b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 19 Aug 2021 17:00:46 -0400 Subject: [PATCH 36/36] address spellcheck issues --- doc/src/fix_property_atom.rst | 8 ++++---- doc/utils/sphinx-config/false_positives.txt | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/src/fix_property_atom.rst b/doc/src/fix_property_atom.rst index b6f6560770..cc92c18655 100644 --- a/doc/src/fix_property_atom.rst +++ b/doc/src/fix_property_atom.rst @@ -61,7 +61,7 @@ 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 ciykd be useful to define "molecules" to use as rigid +keywords. This could be useful to define "molecules" to use as rigid bodies with the :doc:`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 @@ -150,7 +150,7 @@ Per-atom properties that are defined by the :doc:`atom style ` are initialized when atoms are created, e.g. by the :doc:`read_data ` or :doc:`create_atoms ` commands. The per-atom properties defined by this fix are not. So -you need to initialize them explicitly. One way to do thisis +you need to initialize them explicitly. One way to do this is :doc:`read_data ` command, using its *fix* keyword and passing it the fix-ID of this fix. @@ -178,7 +178,7 @@ would allow a data file to have a section like this: 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* +array was specified in the fix property/atom command then the *N* values for that array must be specified consecutively for that property on each line. Note that the order of values on each line corresponds to the order of custom names in the fix property/atom @@ -222,7 +222,7 @@ values. This means that the values can be used accessed by fixes like :doc:`compute reduce `, or used in :doc:`atom-style variables `. -For example, these commands will output both the instantanous and +For example, these commands will output both the instantaneous and time-averaged values of two new properties to a custom dump file: .. code-block:: LAMMPS diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index c866a9409b..6b40fcde71 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -531,6 +531,7 @@ covalently covariance cpp cpu +cradius createatoms createAtoms CreateIDs @@ -1598,6 +1599,7 @@ Kosovan Koster Kosztin Kp +kradius Kraker Kraus Kremer @@ -1993,6 +1995,7 @@ Mj mK mkdir mkv +mlength mliap mliappy mlparks @@ -2049,6 +2052,7 @@ mpiio mpirun mplayer mps +mradius Mrovec Mryglod mscg @@ -2107,6 +2111,7 @@ myIndex mylammps MyPool mysocket +mySpin myTemp myVec na @@ -2317,6 +2322,7 @@ nsub Nswap Nt Ntable +nt ntheta nthreads ntimestep