diff --git a/cmake/Modules/Packages/KOKKOS.cmake b/cmake/Modules/Packages/KOKKOS.cmake index aea766b79c..a1cf680266 100644 --- a/cmake/Modules/Packages/KOKKOS.cmake +++ b/cmake/Modules/Packages/KOKKOS.cmake @@ -74,7 +74,7 @@ else() target_link_libraries(lammps PRIVATE kokkos) target_link_libraries(lmp PRIVATE kokkos) endif() -target_compile_definitions(lammps PRIVATE -DLMP_KOKKOS) +target_compile_definitions(lammps PUBLIC $) set(KOKKOS_PKG_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/KOKKOS) set(KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/kokkos.cpp @@ -127,4 +127,4 @@ endif() get_property(KOKKOS_PKG_SOURCES GLOBAL PROPERTY KOKKOS_PKG_SOURCES) target_sources(lammps PRIVATE ${KOKKOS_PKG_SOURCES}) -target_include_directories(lammps PRIVATE ${KOKKOS_PKG_SOURCES_DIR}) +target_include_directories(lammps PUBLIC $) diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 184fb25300..7cf4e7635b 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -75,6 +75,7 @@ OPT. * :doc:`coul/debye (gko) ` * :doc:`coul/diel (o) ` * :doc:`coul/dsf (gko) ` + * :doc:`coul/exclude ` * :doc:`coul/long (gko) ` * :doc:`coul/long/cs (g) ` * :doc:`coul/long/dielectric ` 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/balance.rst b/doc/src/balance.rst index 94ea27f49e..5063a502bb 100644 --- a/doc/src/balance.rst +++ b/doc/src/balance.rst @@ -477,12 +477,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 333f31d013..fee859d96e 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 + 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 1917d2db95..c2509e6654 100644 --- a/doc/src/dump.rst +++ b/doc/src/dump.rst @@ -80,7 +80,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:: @@ -110,8 +111,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* or *local/gz* or *local/zstd* args = list of local attributes @@ -474,16 +477,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 @@ -521,8 +523,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 @@ -566,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 @@ -643,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. @@ -664,14 +669,21 @@ 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 *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[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/doc/src/fix_bond_swap.rst b/doc/src/fix_bond_swap.rst index 71bb122c90..dbbaceb61f 100644 --- a/doc/src/fix_bond_swap.rst +++ b/doc/src/fix_bond_swap.rst @@ -27,21 +27,26 @@ Examples Description """"""""""" -In a simulation of polymer chains, this command attempts to swap bonds -between two different chains, effectively grafting the end of one -chain onto another chain and vice versa. This is done via Monte Carlo -rules using the Boltzmann acceptance criterion. The purpose is to -equilibrate the polymer chain conformations more rapidly than dynamics -alone would do it, by enabling instantaneous large conformational -changes in a dense polymer melt. The polymer chains should thus more -rapidly converge to the proper end-to-end distances and radii of -gyration. It is designed for use with systems of -:doc:`FENE ` or :doc:`harmonic ` bead-spring -polymer chains where each polymer is a linear chain of monomers, but -LAMMPS does not enforce this requirement, i.e. any -:doc:`bond_style ` can be used. +In a simulation of polymer chains this command attempts to swap a pair +of bonds, as illustrated below. This is done via Monte Carlo rules +using the Boltzmann acceptance criterion, typically with the goal of +equilibrating the polymer system more quickly. This fix is designed +for use with idealized bead-spring polymer chains where each polymer +is a linear chain of monomers, but LAMMPS does not check that is the +case for your system. -A schematic of the kinds of bond swaps that can occur is shown here: +Here are two use cases for this fix. + +The first use case is for swapping bonds on two different chains, +effectively grafting the end of one chain onto the other chain and +vice versa. The purpose is to equilibrate the polymer chain +conformations more rapidly than dynamics alone would do it, by +enabling instantaneous large conformational changes in a dense polymer +melt. The polymer chains should thus more rapidly converge to the +proper end-to-end distances and radii of gyration. + +A schematic of the kinds of bond swaps that can occur in this use case +is shown here: .. image:: JPG/bondswap.jpg :align: center @@ -53,38 +58,76 @@ attempt to delete the A1-A2 and B1-B2 bonds and replace them with A1-B2 and B1-A2 bonds. If the swap is energetically favorable, the two chains on the right are the result and each polymer chain has undergone a dramatic conformational change. This reference, -:ref:`(Sides) ` provides more details on how the algorithm works and -its application: +:ref:`(Sides) ` provides more details on the algorithm's +effectiveness for this use case. -The bond swapping operation is invoked every *Nevery* timesteps. If -any bond is swapped, a re-build of the neighbor lists is triggered, -since a swap alters the list of which neighbors are considered for -pairwise interaction. At each invocation, each processor considers a -random specified *fraction* of its atoms as potential swapping -monomers for this timestep. Choosing a small *fraction* value can -reduce the likelihood of a reverse swap occurring soon after an -initial swap. +The second use case is a collection of polymer chains with some +fraction of their sites identified as "sticker" sites. Initially each +polymer chain is isolated from the others in a topological sense, and +there is an intra-chain bond between every pair of sticker sites on +the same chain. Over time, bonds swap so that inter-moleculer sticker +bonds are created. This models a vitrification-style process whereby +the polymer chains all become interconnected. For this use case, if +angles are defined they should not include bonds between sticker +sites. -For each monomer A1, its neighbors are examined to find a possible B1 -monomer. Both A1 and B1 must be in the fix group, their separation -must be less than the specified *cutoff*, and the molecule IDs of A1 -and B1 must be the same (see below). If a suitable partner is found, -the energy change due to swapping the 2 bonds is computed. This -includes changes in pairwise, bond, and angle energies due to the -altered connectivity of the 2 chains. Dihedral and improper -interactions are not allowed to be defined when this fix is used. +---------- + +The bond swapping operation is invoked once every *Nevery* timesteps. +If any bond in the entire system is swapped, a re-build of the +neighbor lists is triggered, since a swap alters the list of which +neighbors are considered for pairwise interaction. At each +invocation, each processor considers a random specified *fraction* of +its atoms as potential swapping monomers for this timestep. Choosing +a small *fraction* value can reduce the likelihood of a reverse swap +occurring soon after an initial swap. + +For each monomer A1, its neighbors are looped over as B1 monomers. +For each A1,B1 an additional double loop of bond partners A2 of A1, +and bond partners B2 of B1 a is performed. For each pair of A1-A2 and +B1-B2 bonds to be eligible for swapping, the following 4 criteria must +be met: + +(1) All 4 monomers must be in the fix group. + +(2) All 4 monomers must be owned by the processor (not ghost atoms). +This insures that another processor does not attempt to swap bonds +involving the same atoms on the same timestep. Note that this also +means that bond pairs which straddle processor boundaries are not +eligible for swapping on this step. + +(3) The distances between 4 pairs of atoms -- (A1,A2), (B1,B2), +(A1,B2), (B1,A2) -- must all be less thann the specified *cutoff*\ . + +(4) The molecule IDs of A1 and B1 must be the same (see below). + +If an eligible B1 partner is found, the energy change due to swapping +the 2 bonds is computed. This includes changes in pairwise, bond, and +angle energies due to the altered connectivity of the 2 chains. +Dihedral and improper interactions are not allowed to be defined when +this fix is used. If the energy decreases due to the swap operation, the bond swap is accepted. If the energy increases it is accepted with probability exp(-delta/kT) where delta is the increase in energy, k is the Boltzmann constant, and T is the current temperature of the system. -Whether the swap is accepted or rejected, no other swaps are attempted -by this processor on this timestep. -The criterion for matching molecule IDs is how bond swaps performed by -this fix conserve chain length. To use this features you must setup -the molecule IDs for your polymer chains in a certain way, typically -in the data file, read by the :doc:`read_data ` command. +.. note:: + + IMPORTANT: Whether the swap is accepted or rejected, no other swaps + are attempted by this processor on this timestep. No other + eliglble 4-tuples of atoms are considered. This means that each + processor will perform either a single swap or none on timesteps + this fix is invoked. + +---------- + +The criterion for matching molecule IDs is how the first use case +described above can be simulated while conserving chain lengths. This +is done by setting up the molecule IDs for the polymer chains in a +specific way, typically in the data file, read by the :doc:`read_data +` command. + Consider a system of 6-mer chains. You have 2 choices. If the molecule IDs for monomers on each chain are set to 1,2,3,4,5,6 then swaps will conserve chain length. For a particular monomer there will @@ -113,6 +156,9 @@ ends of a chain swap with each other. running dynamics, but can affect calculation of some diagnostic quantities or the printing of unwrapped coordinates to a dump file. +For the second use case described above, the molecule IDs for all +sticker sites should be the same. + ---------- This fix computes a temperature each time it is invoked for use by the @@ -129,27 +175,28 @@ appended and the group for the new compute is "all", so that the temperature of the entire system is used. Note that this is NOT the compute used by thermodynamic output (see -the :doc:`thermo_style ` command) with ID = *thermo_temp*. -This means you can change the attributes of this fix's temperature -(e.g. its degrees-of-freedom) via the -:doc:`compute_modify ` command or print this temperature -during thermodynamic output via the :doc:`thermo_style custom ` command using the appropriate compute-ID. -It also means that changing attributes of *thermo_temp* will have no -effect on this fix. +the :doc:`thermo_style ` command) with ID = +*thermo_temp*. This means you can change the attributes of this fix's +temperature (e.g. its degrees-of-freedom) via the :doc:`compute_modify +` command or print this temperature during +thermodynamic output via the :doc:`thermo_style custom ` +command using the appropriate compute-ID. It also means that changing +attributes of *thermo_temp* will have no effect on this fix. ---------- Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" -No information about this fix is written to :doc:`binary restart files `. Because the state of the random number generator -is not saved in restart files, this means you cannot do "exact" -restarts with this fix, where the simulation continues on the same as -if no restart had taken place. However, in a statistical sense, a -restarted simulation should produce the same behavior. Also note that -each processor generates possible swaps independently of other -processors. Thus if you repeat the same simulation on a different number -of processors, the specific swaps performed will be different. +No information about this fix is written to :doc:`binary restart files +`. Because the state of the random number generator is not +saved in restart files, this means you cannot do "exact" restarts with +this fix, where the simulation continues on the same as if no restart +had taken place. However, in a statistical sense, a restarted +simulation should produce the same behavior. Also note that each +processor generates possible swaps independently of other processors. +Thus if you repeat the same simulation on a different number of +processors, the specific swaps performed will be different. The :doc:`fix_modify ` *temp* option is supported by this fix. You can use it to assign a :doc:`compute ` you have @@ -157,16 +204,18 @@ defined to this fix which will be used to compute the temperature for the Boltzmann criterion. This fix computes two statistical quantities as a global 2-vector of -output, which can be accessed by various :doc:`output commands `. The first component of the vector is the -cumulative number of swaps performed by all processors. The second -component of the vector is the cumulative number of swaps attempted -(whether accepted or rejected). Note that a swap "attempt" only -occurs when swap partners meeting the criteria described above are -found on a particular timestep. The vector values calculated by this -fix are "intensive". +output, which can be accessed by various :doc:`output commands +`. The first component of the vector is the cumulative +number of swaps performed by all processors. The second component of +the vector is the cumulative number of swaps attempted (whether +accepted or rejected). Note that a swap "attempt" only occurs when +swap partners meeting the criteria described above are found on a +particular timestep. The vector values calculated by this fix are +"intensive". 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/fix_property_atom.rst b/doc/src/fix_property_atom.rst index 8ac19af25d..cc92c18655 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 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 +` 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 ` @@ -108,43 +118,39 @@ new properties are also defined for the ghost atoms. .. admonition:: Properties on ghost atoms :class: 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. .. admonition:: Limitations on ghost atom properties :class: 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. + 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. -.. note:: - - If this fix is defined **after** the simulation box is created, - a 'run 0' command may be needed to properly initialize the storage - created by this fix. - -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 this is :doc:`read_data ` command, using its *fix* keyword and passing it the fix-ID of this fix. @@ -169,15 +175,24 @@ 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 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 +command. -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 @@ -187,53 +202,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 instantaneous 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 @@ -241,22 +262,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 @@ -276,24 +297,27 @@ 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 uninterrupted -fashion. +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, the 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 +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 """""""""""" @@ -302,9 +326,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_rigid.rst b/doc/src/fix_rigid.rst index 5b367a48a4..1f722aff7b 100644 --- a/doc/src/fix_rigid.rst +++ b/doc/src/fix_rigid.rst @@ -73,7 +73,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 @@ -296,15 +296,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/doc/src/fix_store_state.rst b/doc/src/fix_store_state.rst index 829a25b517..b47b6900aa 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,15 +108,16 @@ 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. .. 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 @@ -130,7 +134,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 aedf1d39bc..e72eeb7c19 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/pair_coul.rst b/doc/src/pair_coul.rst index 990458887d..4e0793467b 100644 --- a/doc/src/pair_coul.rst +++ b/doc/src/pair_coul.rst @@ -10,6 +10,7 @@ .. index:: pair_style coul/dsf/gpu .. index:: pair_style coul/dsf/kk .. index:: pair_style coul/dsf/omp +.. index:: pair_style coul/exclude .. index:: pair_style coul/cut/global .. index:: pair_style coul/cut/global/omp .. index:: pair_style coul/long @@ -42,6 +43,9 @@ pair_style coul/dsf command Accelerator Variants: *coul/dsf/gpu*, *coul/dsf/kk*, *coul/dsf/omp* +pair_style coul/exclude command +=============================== + pair_style coul/cut/global command ================================== @@ -83,6 +87,7 @@ Syntax pair_style coul/cut cutoff pair_style coul/debye kappa cutoff pair_style coul/dsf alpha cutoff + pair_style coul/exclude cutoff pair_style coul/cut/global cutoff pair_style coul/long cutoff pair_style coul/wolf alpha cutoff @@ -110,6 +115,9 @@ Examples pair_style coul/dsf 0.05 10.0 pair_coeff * * + pair_style hybrid/overlay coul/exclude 10.0 ... + pair_coeff * * coul/exclude + pair_style coul/long 10.0 pair_coeff * * @@ -257,6 +265,19 @@ as style *coul/cut* except that it allows only a single global cutoff and thus makes it compatible for use in combination with long-range coulomb styles in :doc:`hybrid pair styles `. +Pair style *coul/exclude* computes Coulombic interactions like *coul/cut* +but **only** applies them to excluded pairs using a scaling factor +of :math:`\gamma - 1.0` with :math:`\gamma` being the factor assigned +to that excluded pair via the :doc:`special_bonds coul ` +setting. With this it is possible to treat Coulomb interactions for +molecular systems with :doc:`kspace style scafacos `, +which always computes the *full* Coulomb interactions without exclusions. +Pair style *coul/exclude* will then *subtract* the excluded interactions +accordingly. So to achieve the same forces as with ``pair_style lj/cut/coul/long 12.0`` +with ``kspace_style pppm 1.0e-6``, one would use +``pair_style hybrid/overlay lj/cut 12.0 coul/exclude 12.0`` with +``kspace_style scafacos p3m 1.0e-6``. + Styles *coul/long* and *coul/msm* compute the same Coulombic interactions as style *coul/cut* except that an additional damping factor is applied so it can be used in conjunction with the diff --git a/doc/src/pair_style.rst b/doc/src/pair_style.rst index 7677cd9535..1cf033ddba 100644 --- a/doc/src/pair_style.rst +++ b/doc/src/pair_style.rst @@ -139,6 +139,7 @@ accelerated styles exist. * :doc:`coul/debye ` - cutoff Coulomb potential with Debye screening * :doc:`coul/diel ` - Coulomb potential with dielectric permittivity * :doc:`coul/dsf ` - Coulomb with damped-shifted-force model +* :doc:`coul/exclude ` - subtract Coulomb potential for excluded pairs * :doc:`coul/long ` - long-range Coulomb potential * :doc:`coul/long/cs ` - long-range Coulomb potential and core/shell * :doc:`coul/long/dielectric ` - diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index e0cd38416e..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. ---------- @@ -636,12 +636,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 @@ -664,8 +666,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) @@ -676,10 +680,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/doc/src/set.rst b/doc/src/set.rst index e61c288a74..1ca8168317 100644 --- a/doc/src/set.rst +++ b/doc/src/set.rst @@ -13,16 +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 *vx* or *vy* or *vz* - or *charge* or *dipole* or *dipole/random* or *spin* or *spin/random* - or *quat* *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:: @@ -123,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 """""""" @@ -141,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 """"""""""" @@ -482,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/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 diff --git a/examples/PACKAGES/interlayer/kolmogorov_crespi_full/CC.KC-full b/examples/PACKAGES/interlayer/kolmogorov_crespi_full/CC.KC-full deleted file mode 120000 index 6b829c2157..0000000000 --- a/examples/PACKAGES/interlayer/kolmogorov_crespi_full/CC.KC-full +++ /dev/null @@ -1 +0,0 @@ -../../../../potentials/CC.KC-full \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/kolmogorov_crespi_full/CH.KC b/examples/PACKAGES/interlayer/kolmogorov_crespi_full/CH.KC deleted file mode 120000 index 74f7f340e5..0000000000 --- a/examples/PACKAGES/interlayer/kolmogorov_crespi_full/CH.KC +++ /dev/null @@ -1 +0,0 @@ -../../../../potentials/CH.KC \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/lebedeva/lebedeva00.plot b/examples/PACKAGES/interlayer/lebedeva/lebedeva00.plot index a598c3e6b1..f401dc5677 100644 --- a/examples/PACKAGES/interlayer/lebedeva/lebedeva00.plot +++ b/examples/PACKAGES/interlayer/lebedeva/lebedeva00.plot @@ -28,7 +28,7 @@ set yrange [-0.002:0.001] #set yrange [*:*] plot \ - "LamppsResult.dat" u 2:5 t "Leb LAMMPS",\ + "LammpsResult.dat" u 2:5 t "Leb LAMMPS",\ "PerlResult.dat" u 1:($4*0.001/2.) w l t "Leb Perl" exit diff --git a/potentials/BNCH-old.ILP b/potentials/BNCH-old.ILP index 2830172a86..2f98de2261 100644 --- a/potentials/BNCH-old.ILP +++ b/potentials/BNCH-old.ILP @@ -1,6 +1,6 @@ +# DATE: 2020-01-16 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: J. Chem.Theory Comput. 2016, 12, 2896-905 and J. Phys. Chem. C 2017, 121, 22826-22835 # Interlayer Potential (ILP) for bilayer graphene/graphene, graphene/hBN and hBN/hBN junctions # The parameters below are fitted against the HSE + MBD DFT reference data from 3.1 A to 15 A. -# Cite J. Chem.Theory Comput. 2016, 12, 2896-905 and J. Phys. Chem. C 2017, 121, 22826-22835. # beta alpha delta epsilon C d sR reff C6 S rcut C C 3.22 9.200 1.20 0.010 0.800 15.0 0.704 3.586 522.915 43.363442016573508 2.0 diff --git a/potentials/BNCH.ILP b/potentials/BNCH.ILP index eb15c35e0b..3c097d91bf 100644 --- a/potentials/BNCH.ILP +++ b/potentials/BNCH.ILP @@ -1,6 +1,6 @@ +# DATE: 2020-01-16 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Ouyang, Mandelli, Urbakh, Hod, Nano Letters 18, 6009-6016 (2018). # Interlayer Potential (ILP) for bilayer graphene/graphene, graphene/hBN and hBN/hBN junctions # The parameters below are fitted against the HSE + MBD DFT reference data from 2.5 A to 15 A. -# Cite as W. Ouyang, D. Mandelli, M. Urbakh and O. Hod, Nano Letters 18, 6009-6016 (2018). # # ----------------- Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ # beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut diff --git a/potentials/BNC_MBD_bulk.ILP b/potentials/BNC_MBD_bulk.ILP index 9093f01447..381cb0359a 100644 --- a/potentials/BNC_MBD_bulk.ILP +++ b/potentials/BNC_MBD_bulk.ILP @@ -1,6 +1,6 @@ +# DATE: 2020-01-16 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: W. Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020) # Interlayer Potential (ILP) for graphite, bulk-hBN and their heterojunctions # The parameters below are fitted against the HSE + MBD DFT reference data from 2 A to 10 A. -# Cite as W. Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020). # # ------------------------------ Repulsion Potential --------------------++++++++++++++ Vdw Potential ++++++++++++++++************ # MBD-HSE beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut diff --git a/potentials/BNC_TS_bulk.ILP b/potentials/BNC_TS_bulk.ILP index 13de8b25fc..b0bf3cd800 100644 --- a/potentials/BNC_TS_bulk.ILP +++ b/potentials/BNC_TS_bulk.ILP @@ -1,6 +1,6 @@ +# DATE: 2020-01-16 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: W. Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020) # Interlayer Potential (ILP) for graphite, bulk-hBN and their heterojunctions # The parameters below are fitted against the HSE + TS DFT reference data from 2 A to 10 A. -# Cite as W. Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020). # # ------------------------------ Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ # TS-HSE beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut diff --git a/potentials/C.drip b/potentials/C.drip index 435efe40a9..afde83a786 100644 --- a/potentials/C.drip +++ b/potentials/C.drip @@ -1,15 +1,11 @@ -# DATE: 2019-04-19 CONTRIBUTOR: Mingjian Wen, wenxx151@umn.edu +# DATE: 2019-04-19 UNITS: metal CONTRIBUTOR: Mingjian Wen, wenxx151@umn.edu CITATION: Wen, Carr, Fang, Kaxiras, Tadmor, Phys. Rev. B, 98, 235404 (2018). # # Parameters of the Dihedral-angle-corrected registry-dependent interlayer (DRIP) # potential for multilayer graphene structures. -# -# Cite as M. Wen, S. Carr, S. Fang, E. Kaxiras, and E. B. Tadmor, Phys. Rev. B, 98, 235404 (2018). - # C0 C2 C4 C delta lambda A z0 B eta rho_cut r_cut normal_cut C C 1.1598e-02 1.2981e-02 3.2515e-02 7.8151e-03 8.3679e-01 2.7158 2.2216e-02 3.34 7.6799e-03 1.1432 1.562 12.0 3.7 - # C0, C2, C4, C, A, and B in [eV] # delta, z0, eta, rho_cut, r_cut, and normal_cut in [Angstrom] # lambda in [1/Angstrom] diff --git a/potentials/CC.KC b/potentials/CC.KC index 6559eb4120..5e0bc0d89d 100644 --- a/potentials/CC.KC +++ b/potentials/CC.KC @@ -1,8 +1,5 @@ -# Kolmogorov-Crespi Potential +# DATE: 2017-02-28 UNITS: metal CONTRIBUTOR: Jaap Kroes jaapkroes@gmail.com CITATION: Kolmogorov, Crespi, Physical Review B 71, 235415 (2005) +# Kolmogorov-Crespi Potential for pair style kolmogorov/crespi/z # -# Cite as A.N. Kolmogorov & V. H. Crespi, -# Registry-dependent interlayer potential for graphitic systems -# Physical Review B 71, 235415 (2005) -# # z0 C0 C2 C4 C delta lambda A S C C 3.34 15.71 12.29 4.933 3.030 0.578 3.629 10.238 1.0 diff --git a/potentials/CC.KC-full b/potentials/CC.KC-full index a3bf302fe0..fee2f6a5ef 100644 --- a/potentials/CC.KC-full +++ b/potentials/CC.KC-full @@ -1,8 +1,5 @@ +# DATE: 2018-03-23 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Kolmogorov, Crespi, Physical Review B 71, 235415 (2005) # Kolmogorov-Crespi Potential # -# Cite as A.N. Kolmogorov & V. H. Crespi, -# Registry-dependent interlayer potential for graphitic systems -# Physical Review B 71, 235415 (2005) -# # z0 C0 C2 C4 C delta lambda A S rcut C C 3.34 15.71 12.29 4.933 3.030 0.578 3.629 10.238 1.0 2.0 diff --git a/potentials/CC.Lebedeva b/potentials/CC.Lebedeva index 930f7b4328..bc2db03f6b 100644 --- a/potentials/CC.Lebedeva +++ b/potentials/CC.Lebedeva @@ -1,14 +1,12 @@ -# Lebedeva Potential. Original values from Lebedeva. May be played with ;) +# DATE: 2018-11-28 UNITS: metal CONTRIBUTOR: Zbigniew Koziol softquake@gmail.com CITATION: Z. Koziol et al.: https://arxiv.org/abs/1803.05162 # -# Cite as: Irina V. Lebedeva, Andrey A. Knizhnik, Andrey M. Popov, Yurii E. Lozovik, Boris V. Potapkin, -# Modeling of graphene-based NEMS -# Physica E 44 (6), 949 (2012) -# https://doi.org/10.1016/j.physe.2011.07.018 -# -# Parameters must be in this order as here, otherwise their values may be changed. +# Lebedeva Potential. https://doi.org/10.1016/j.physe.2011.07.018 + +# Parameters must be in this order as here, otherwise their values may be changed. # The last one, S, is convenient for scaling the potential amplitude. S is a multiplication factor for A, B, C -# A B C z0 alpha D1 D2 lambda1 lambda2 S +# A B C z0 alpha D1 D2 lambda1 lambda2 S # These are values according to Levedeva et al -#C C 10.510 11.6523.34 35.883 3.34 4.16 -0.86232 0.10049 0.48703 0.46445 1.0 +#C C 10.510 11.6523.34 35.883 3.34 4.16 -0.86232 0.10049 0.48703 0.46445 1.0 +# # These are values by Z. Koziol et al.: https://arxiv.org/abs/1803.05162 -C C 14.558 21.204 1.8 3.198 4.16 -0.862 0.10049 0.6 0.4 1.0 +C C 14.558 21.204 1.8 3.198 4.16 -0.862 0.10049 0.6 0.4 1.0 diff --git a/potentials/CH.KC b/potentials/CH.KC index 029f682f34..0ec32b8dff 100644 --- a/potentials/CH.KC +++ b/potentials/CH.KC @@ -1,7 +1,6 @@ -# Refined parameters for Kolmogorov-Crespi Potential without taper function +# DATE: 2018-09-12 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Ouyang, Mandelli, Urbakh, Hod, Nano Letters 18, 6009-6016 (2018). +# Refined parameters for Kolmogorov-Crespi Potential without taper function for pair style kolmogorov/crespi/full # -# Cite as W. Ouyang, D. Mandelli, M. Urbakh and O. Hod, Nano Letters 18, 6009-6016 (2018). -# # z0 C0 C2 C4 C delta lambda A S rcut C C 3.328819 21.847167 12.060173 4.711099 6.678908e-4 0.7718101 3.143921 12.660270 1.0 2.0 C H 3.156492 37.400478 8.3910462e-3 55.06177 5.176215e-5 0.4437309 2.508847 11.479055 1.0 1.5 diff --git a/potentials/CH_taper.KC b/potentials/CH_taper.KC index 0f08b2e6dd..e7f4b566c8 100644 --- a/potentials/CH_taper.KC +++ b/potentials/CH_taper.KC @@ -1,10 +1,9 @@ -# Refined parameters for Kolmogorov-Crespi Potential with taper function +# DATE: 2018-09-12 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: W. Ouyang, D. Mandelli, M. Urbakh and O. Hod, Nano Letters 18, 6009-6016 (2018). +# Refined parameters for Kolmogorov-Crespi Potential with taper function for pair style kolmogorov/crespi/full # -# Cite as W. Ouyang, D. Mandelli, M. Urbakh and O. Hod, Nano Letters 18, 6009-6016 (2018). -# # z0 C0 C2 C4 C delta lambda A S rcut -C C 3.416084 20.021583 10.9055107 4.2756354 1.0010836E-2 0.8447122 2.9360584 14.3132588 1.0 2.0 -C H 2.849054 72.557245 1.0164169E-2 65.923312 8.7962504E-5 0.3349237 3.0402632 14.7533201 1.0 1.5 -H H 2.187478 3.915802E-5 5.0896431E-5 3.6657827 1.5373722446 0.9633581 0.4249989 1.570737E-4 1.0 1.2 -H C 2.849054 72.557245 1.0164169E-2 65.923312 8.7962504E-5 0.3349237 3.0402632 14.7533201 1.0 2.2 +C C 3.416084 20.021583 10.9055107 4.2756354 1.0010836E-2 0.8447122 2.9360584 14.3132588 1.0 2.0 +C H 2.849054 72.557245 1.0164169E-2 65.923312 8.7962504E-5 0.3349237 3.0402632 14.7533201 1.0 1.5 +H H 2.187478 3.915802E-5 5.0896431E-5 3.6657827 1.5373722446 0.9633581 0.4249989 1.570737E-4 1.0 1.2 +H C 2.849054 72.557245 1.0164169E-2 65.923312 8.7962504E-5 0.3349237 3.0402632 14.7533201 1.0 2.2 diff --git a/src/DPD-REACT/fix_eos_table_rx.cpp b/src/DPD-REACT/fix_eos_table_rx.cpp index 7df5a3d7ce..b39e029c3e 100644 --- a/src/DPD-REACT/fix_eos_table_rx.cpp +++ b/src/DPD-REACT/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/DPD-REACT/fix_rx.cpp b/src/DPD-REACT/fix_rx.cpp index e50e145853..91eb3f54df 100644 --- a/src/DPD-REACT/fix_rx.cpp +++ b/src/DPD-REACT/fix_rx.cpp @@ -374,7 +374,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) { @@ -434,7 +434,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); @@ -446,7 +446,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) @@ -560,7 +560,7 @@ void FixRX::initSparse() else sprintf(digit,"%4.1f ", sparseKinetics_nu[i][kk]); rstr += digit; - rstr += atom->dname[k]; + rstr += atom->dvname[k]; } } @@ -576,7 +576,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) @@ -914,7 +914,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; @@ -1293,7 +1293,8 @@ void FixRX::odeDiagnostics(void) // 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 ); + int cols; + int rx_weight_index = atom->find_custom( "rx_weight", /*0:int, 1:float*/ type_flag, cols ); // Compute the average # of neighbors. double averageNumNeighbors = 0; diff --git a/src/DPD-REACT/pair_exp6_rx.cpp b/src/DPD-REACT/pair_exp6_rx.cpp index 8240cb88b7..1d242de90b 100644 --- a/src/DPD-REACT/pair_exp6_rx.cpp +++ b/src/DPD-REACT/pair_exp6_rx.cpp @@ -599,7 +599,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"); @@ -607,7 +607,7 @@ void PairExp6rx::coeff(int narg, char **arg) site2 = utils::strdup(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"); @@ -620,7 +620,7 @@ void PairExp6rx::coeff(int narg, char **arg) else { 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"); @@ -633,7 +633,7 @@ void PairExp6rx::coeff(int narg, char **arg) else { 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"); @@ -779,7 +779,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 @@ -797,7 +797,7 @@ void PairExp6rx::read_file(char *file) params[nparams].ispecies = ispecies; - params[nparams].name = utils::strdup(&atom->dname[ispecies][0]); + params[nparams].name = utils::strdup(&atom->dvname[ispecies][0]); params[nparams].potential = utils::strdup(words[1]); if (strcmp(params[nparams].potential,"exp6") == 0) { params[nparams].alpha = utils::numeric(FLERR,words[2],false,lmp); diff --git a/src/DPD-REACT/pair_multi_lucy_rx.cpp b/src/DPD-REACT/pair_multi_lucy_rx.cpp index 4c7cfe65e5..c386abded4 100644 --- a/src/DPD-REACT/pair_multi_lucy_rx.cpp +++ b/src/DPD-REACT/pair_multi_lucy_rx.cpp @@ -436,7 +436,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; } @@ -450,7 +450,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; } diff --git a/src/DPD-REACT/pair_table_rx.cpp b/src/DPD-REACT/pair_table_rx.cpp index d47b8a7173..fedc5fa879 100644 --- a/src/DPD-REACT/pair_table_rx.cpp +++ b/src/DPD-REACT/pair_table_rx.cpp @@ -330,7 +330,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"); @@ -338,7 +338,7 @@ void PairTableRX::coeff(int narg, char **arg) site2 = utils::strdup(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"); @@ -405,7 +405,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; } @@ -420,7 +420,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; } diff --git a/src/EXTRA-PAIR/pair_coul_exclude.cpp b/src/EXTRA-PAIR/pair_coul_exclude.cpp new file mode 100644 index 0000000000..404fc9c784 --- /dev/null +++ b/src/EXTRA-PAIR/pair_coul_exclude.cpp @@ -0,0 +1,307 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "pair_coul_exclude.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" +#include "neighbor.h" + +#include +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairCoulExclude::PairCoulExclude(LAMMPS *lmp) : Pair(lmp) { + writedata = 1; +} + +/* ---------------------------------------------------------------------- */ + +PairCoulExclude::~PairCoulExclude() +{ + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulExclude::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair; + double rsq,r2inv,rinv,forcecoul,factor_coul; + int *ilist,*jlist,*numneigh,**firstneigh; + + ecoul = 0.0; + ev_init(eflag,vflag); + + double **x = atom->x; + double **f = atom->f; + double *q = atom->q; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + int newton_pair = force->newton_pair; + double qqrd2e = force->qqrd2e; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + + // skip over all non-excluded pairs and subtract excluded coulomb + + if (sbmask(j) == 0) continue; + factor_coul = special_coul[sbmask(j)] - 1.0; + + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + forcecoul = qqrd2e * qtmp*q[j]*rinv; + fpair = factor_coul*forcecoul * r2inv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (eflag) + ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv; + + if (evflag) ev_tally(i,j,nlocal,newton_pair,0.0,ecoul,fpair,delx,dely,delz); + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairCoulExclude::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + memory->create(cutsq,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairCoulExclude::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = utils::numeric(FLERR,arg[0],false,lmp); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairCoulExclude::coeff(int narg, char **arg) +{ + if (narg != 2) + error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error); + utils::bounds(FLERR,arg[1],1,atom->ntypes,jlo,jhi,error); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairCoulExclude::init_style() +{ + if (!atom->q_flag) + error->all(FLERR,"Pair style coul/exclude requires atom attribute q"); + + neighbor->request(this,instance_me); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairCoulExclude::init_one(int i, int j) +{ + return cut_global; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairCoulExclude::write_restart(FILE *fp) +{ + write_restart_settings(fp); + + int i,j; + for (i = 1; i <= atom->ntypes; i++) { + for (j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j],sizeof(int),1,fp); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairCoulExclude::read_restart(FILE *fp) +{ + read_restart_settings(fp); + allocate(); + + int i,j; + int me = comm->me; + for (i = 1; i <= atom->ntypes; i++) { + for (j = i; j <= atom->ntypes; j++) { + if (me == 0) { + utils::sfread(FLERR,&setflag[i][j],sizeof(int),1,fp,nullptr,error); + } + MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairCoulExclude::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); + fwrite(&offset_flag,sizeof(int),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairCoulExclude::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + utils::sfread(FLERR,&cut_global,sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR,&offset_flag,sizeof(int),1,fp,nullptr,error); + utils::sfread(FLERR,&mix_flag,sizeof(int),1,fp,nullptr,error); + } + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&offset_flag,1,MPI_INT,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void PairCoulExclude::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + fprintf(fp,"%d\n",i); +} + +/* ---------------------------------------------------------------------- + proc 0 writes all pairs to data file +------------------------------------------------------------------------- */ + +void PairCoulExclude::write_data_all(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) + fprintf(fp,"%d %d\n",i,j); +} + +/* ---------------------------------------------------------------------- */ + +double PairCoulExclude::single(int i, int j, int /*itype*/, int /*jtype*/, + double rsq, double factor_coul, double /*factor_lj*/, + double &fforce) +{ + double r2inv,rinv,forcecoul,phicoul; + + factor_coul -= 1.0; // we want to subtract the excluded coulomb + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + forcecoul = force->qqrd2e * atom->q[i]*atom->q[j]*rinv; + fforce = factor_coul*forcecoul * r2inv; + + phicoul = force->qqrd2e * atom->q[i]*atom->q[j]*rinv; + return factor_coul*phicoul; +} + +/* ---------------------------------------------------------------------- */ + +void *PairCoulExclude::extract(const char *str, int &dim) +{ + dim = 0; + if (strcmp(str,"cut_coul") == 0) return (void *) &cut_global; + return nullptr; +} diff --git a/src/EXTRA-PAIR/pair_coul_exclude.h b/src/EXTRA-PAIR/pair_coul_exclude.h new file mode 100644 index 0000000000..38cd30cbb7 --- /dev/null +++ b/src/EXTRA-PAIR/pair_coul_exclude.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(coul/exclude,PairCoulExclude); +// clang-format on +#else + +#ifndef LMP_PAIR_COUL_EXCLUDE_H +#define LMP_PAIR_COUL_EXCLUDE_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairCoulExclude : public Pair { + public: + PairCoulExclude(class LAMMPS *); + virtual ~PairCoulExclude(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + virtual void write_data(FILE *); + virtual void write_data_all(FILE *); + virtual double single(int, int, int, int, double, double, double, double &); + virtual void *extract(const char *, int &); + + protected: + double cut_global; + + virtual void allocate(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair style coul/cut requires atom attribute q + +The atom style defined does not have these attributes. + +*/ diff --git a/src/INTERLAYER/interlayer_taper.h b/src/INTERLAYER/interlayer_taper.h new file mode 100644 index 0000000000..a496daca5d --- /dev/null +++ b/src/INTERLAYER/interlayer_taper.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +// Common definition of taper function and its derivative for interlayer potentials + +#ifndef LMP_INTERLAYER_TAPER_H +#define LMP_INTERLAYER_TAPER_H + +namespace LAMMPS_NS { +namespace InterLayer { + + static constexpr double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; + + /* ----Calculate the long-range cutoff term */ + static inline double calc_Tap(double r_ij, double Rcut) + { + double Tap, r; + + r = r_ij / Rcut; + if (r >= 1.0) { + Tap = 0.0; + } else { + Tap = Tap_coeff[7] * r + Tap_coeff[6]; + Tap = Tap * r + Tap_coeff[5]; + Tap = Tap * r + Tap_coeff[4]; + Tap = Tap * r + Tap_coeff[3]; + Tap = Tap * r + Tap_coeff[2]; + Tap = Tap * r + Tap_coeff[1]; + Tap = Tap * r + Tap_coeff[0]; + } + + return (Tap); + } + + /* ----Calculate the derivatives of long-range cutoff term */ + static inline double calc_dTap(double r_ij, double Rcut) + { + double dTap, r; + + r = r_ij / Rcut; + if (r >= 1.0) { + dTap = 0.0; + } else { + dTap = 7.0 * Tap_coeff[7] * r + 6.0 * Tap_coeff[6]; + dTap = dTap * r + 5.0 * Tap_coeff[5]; + dTap = dTap * r + 4.0 * Tap_coeff[4]; + dTap = dTap * r + 3.0 * Tap_coeff[3]; + dTap = dTap * r + 2.0 * Tap_coeff[2]; + dTap = dTap * r + Tap_coeff[1]; + dTap = dTap / Rcut; + } + + return (dTap); + } +} // namespace InterLayer +} // namespace LAMMPS_NS +#endif diff --git a/src/INTERLAYER/pair_coul_shield.cpp b/src/INTERLAYER/pair_coul_shield.cpp index dbb12abf2e..da2a2cf2fd 100644 --- a/src/INTERLAYER/pair_coul_shield.cpp +++ b/src/INTERLAYER/pair_coul_shield.cpp @@ -24,6 +24,7 @@ #include "comm.h" #include "error.h" #include "force.h" +#include "interlayer_taper.h" #include "math_special.h" #include "memory.h" #include "neigh_list.h" @@ -32,6 +33,7 @@ #include using namespace LAMMPS_NS; +using namespace InterLayer; /* ---------------------------------------------------------------------- */ @@ -257,7 +259,7 @@ double PairCoulShield::init_one(int i, int j) r3 = r * r * r; rarg = 1.0 / sigmae[i][j]; th = r3 + MathSpecial::cube(rarg); - epsr = 1.0 / pow(th, 1.0/3.0); + epsr = 1.0 / pow(th, 1.0 / 3.0); offset[i][j] = qqrd2e * q[i] * q[j] * epsr; } else offset[i][j] = 0.0; @@ -362,7 +364,7 @@ double PairCoulShield::single(int i, int j, int itype, int jtype, double rsq, do r3 = rsq * r; rarg = 1.0 / sigmae[itype][jtype]; th = r3 + MathSpecial::cube(rarg); - epsr = 1.0 / pow(th, 1.0/3.0); + epsr = 1.0 / pow(th, 1.0 / 3.0); depsdr = epsr * epsr; depsdr *= depsdr; Vc = qqrd2e * q[i] * q[j] * epsr; diff --git a/src/INTERLAYER/pair_coul_shield.h b/src/INTERLAYER/pair_coul_shield.h index 4413732577..10ace5ebd2 100644 --- a/src/INTERLAYER/pair_coul_shield.h +++ b/src/INTERLAYER/pair_coul_shield.h @@ -46,51 +46,9 @@ class PairCoulShield : public Pair { double cut_global; double **cut; double **sigmae, **offset; - //double a_eps, b_eps, eps_s; int tap_flag; void allocate(); - - /* ----Calculate the long-range cutoff term */ - inline double calc_Tap(double r_ij, double Rcut) - { - double Tap, r; - //int Tap_coeff[8] = {1,0,0,0,-35,84,-70,20}; - double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; - - r = r_ij / Rcut; - Tap = 0.0; - - Tap = Tap_coeff[7] * r + Tap_coeff[6]; - Tap = Tap * r + Tap_coeff[5]; - Tap = Tap * r + Tap_coeff[4]; - Tap = Tap * r + Tap_coeff[3]; - Tap = Tap * r + Tap_coeff[2]; - Tap = Tap * r + Tap_coeff[1]; - Tap = Tap * r + Tap_coeff[0]; - - return (Tap); - } - - /* ----Calculate the derivatives of long-range cutoff term */ - inline double calc_dTap(double r_ij, double Rcut) - { - double dTap, r; - double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; - - r = r_ij / Rcut; - dTap = 0.0; - - dTap = 7.0 * Tap_coeff[7] * r + 6.0 * Tap_coeff[6]; - dTap = dTap * r + 5.0 * Tap_coeff[5]; - dTap = dTap * r + 4.0 * Tap_coeff[4]; - dTap = dTap * r + 3.0 * Tap_coeff[3]; - dTap = dTap * r + 2.0 * Tap_coeff[2]; - dTap = dTap * r + Tap_coeff[1]; - dTap = dTap / Rcut; - - return (dTap); - } }; } // namespace LAMMPS_NS diff --git a/src/INTERLAYER/pair_drip.cpp b/src/INTERLAYER/pair_drip.cpp index 71281623ac..e9d32bdb8b 100644 --- a/src/INTERLAYER/pair_drip.cpp +++ b/src/INTERLAYER/pair_drip.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -31,6 +30,8 @@ #include "neigh_list.h" #include "neigh_request.h" #include "neighbor.h" +#include "potential_file_reader.h" +#include "tokenizer.h" #include #include @@ -41,6 +42,17 @@ using namespace LAMMPS_NS; #define DELTA 4 #define HALF 0.5 +// inline functions +static inline double dot(double const *x, double const *y) +{ + return x[0] * y[0] + x[1] * y[1] + x[2] * y[2]; +} + +static inline void mat_dot_vec(PairDRIP::V3 const *X, double const *y, double *const z) +{ + for (int k = 0; k < 3; k++) { z[k] = X[k][0] * y[0] + X[k][1] * y[1] + X[k][2] * y[2]; } +} + /* ---------------------------------------------------------------------- */ PairDRIP::PairDRIP(LAMMPS *lmp) : Pair(lmp) @@ -49,6 +61,7 @@ PairDRIP::PairDRIP(LAMMPS *lmp) : Pair(lmp) restartinfo = 0; manybody_flag = 1; centroidstressflag = CENTROID_NOTAVAIL; + unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); params = nullptr; nearest3neigh = nullptr; @@ -75,13 +88,11 @@ PairDRIP::~PairDRIP() void PairDRIP::init_style() { - if (force->newton_pair == 0) - error->all(FLERR,"Pair style drip requires newton pair on"); - if (!atom->molecule_flag) - error->all(FLERR,"Pair style drip requires atom attribute molecule"); + if (force->newton_pair == 0) error->all(FLERR, "Pair style drip requires newton pair on"); + if (!atom->molecule_flag) error->all(FLERR, "Pair style drip requires atom attribute molecule"); // need a full neighbor list, including neighbors of ghosts - int irequest = neighbor->request(this,instance_me); + int irequest = neighbor->request(this, instance_me); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->ghost = 1; @@ -94,11 +105,11 @@ void PairDRIP::init_style() void PairDRIP::allocate() { allocated = 1; - int n = atom->ntypes; + int n = atom->ntypes + 1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - map = new int[n+1]; + memory->create(setflag, n, n, "pair:setflag"); + memory->create(cutsq, n, n, "pair:cutsq"); + map = new int[n]; } /* ---------------------------------------------------------------------- @@ -107,9 +118,9 @@ void PairDRIP::allocate() void PairDRIP::settings(int narg, char ** /* arg */) { - if (narg != 0) error->all(FLERR,"Illegal pair_style command"); - if (!utils::strmatch(force->pair_style,"^hybrid/overlay")) - error->all(FLERR,"Pair style drip must be used as sub-style with hybrid/overlay"); + if (narg != 0) error->all(FLERR, "Illegal pair_style command"); + if (!utils::strmatch(force->pair_style, "^hybrid/overlay")) + error->all(FLERR, "Pair style drip must be used as sub-style with hybrid/overlay"); } /* ---------------------------------------------------------------------- @@ -120,28 +131,25 @@ void PairDRIP::coeff(int narg, char **arg) { if (!allocated) allocate(); - map_element2type(narg-3,arg+3); + map_element2type(narg - 3, arg + 3); read_file(arg[2]); } - /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairDRIP::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + if (setflag[i][j] == 0) error->all(FLERR, "All pair coeffs are not set"); int itype = map[i]; int jtype = map[j]; int iparam_ij = elem2param[itype][jtype]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; // max cutoff is the main cutoff plus the normal cutoff such that - double cutmax = p.rcut + p.ncut; - - return cutmax; + return p.rcut + p.ncut; } /* ---------------------------------------------------------------------- @@ -150,154 +158,130 @@ double PairDRIP::init_one(int i, int j) void PairDRIP::read_file(char *filename) { - int params_per_line = 15; - char **words = new char*[params_per_line+1]; memory->sfree(params); - int nparams = 0; - int maxparam = 0; + params = nullptr; + nparams = maxparam = 0; // open file on proc 0 - FILE *fp; if (comm->me == 0) { - fp = utils::open_potential(filename,lmp,nullptr); - if (fp == nullptr) - error->one(FLERR,"Cannot open DRIP potential file {}: {}",filename,utils::getsyserror()); - } + PotentialFileReader reader(lmp, filename, "drip", unit_convert_flag); + char *line; - // read each line out of file, skipping blank lines or leading '#' - // store line of params if all 3 element tags are in element list + // transparently convert units for supported conversions - int i,j,n,m,nwords,ielement,jelement; - char line[MAXLINE],*ptr; - int eof = 0; + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, unit_convert); - while (1) { - if (comm->me == 0) { - ptr = fgets(line,MAXLINE,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; - } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + while ((line = reader.next_line(NPARAMS_PER_LINE))) { - // strip comment, skip line if blank + try { + ValueTokenizer values(line); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); - if (nwords == 0) continue; + std::string iname = values.next_string(); + std::string jname = values.next_string(); - // concatenate additional lines until have params_per_line words + // ielement,jelement = 1st args + // if both args are in element list, then parse this line + // else skip to next entry in file + int ielement, jelement; - while (nwords < params_per_line) { - n = strlen(line); - if (comm->me == 0) { - ptr = fgets(&line[n],MAXLINE-n,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; + for (ielement = 0; ielement < nelements; ielement++) + if (iname == elements[ielement]) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (jname == elements[jelement]) break; + if (jelement == nelements) continue; + + // expand storage, if needed + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); + + // make certain all addional allocated storage is initialized + // to avoid false positives when checking with valgrind + + memset(params + nparams, 0, DELTA * sizeof(Param)); + } + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].C0 = values.next_double(); + params[nparams].C2 = values.next_double(); + params[nparams].C4 = values.next_double(); + params[nparams].C = values.next_double(); + params[nparams].delta = values.next_double(); + params[nparams].lambda = values.next_double(); + params[nparams].A = values.next_double(); + params[nparams].z0 = values.next_double(); + params[nparams].B = values.next_double(); + params[nparams].eta = values.next_double(); + params[nparams].rhocut = values.next_double(); + params[nparams].rcut = values.next_double(); + params[nparams].ncut = values.next_double(); + + } catch (TokenizerException &e) { + error->one(FLERR, e.what()); } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); + + if (unit_convert) { + params[nparams].C0 *= conversion_factor; + params[nparams].C2 *= conversion_factor; + params[nparams].C4 *= conversion_factor; + params[nparams].C *= conversion_factor; + params[nparams].A *= conversion_factor; + params[nparams].B *= conversion_factor; + } + + // convenient precomputations + params[nparams].rhocutsq = params[nparams].rhocut * params[nparams].rhocut; + params[nparams].rcutsq = params[nparams].rcut * params[nparams].rcut; + params[nparams].ncutsq = params[nparams].ncut * params[nparams].ncut; + + nparams++; } - if (nwords != params_per_line) - error->all(FLERR,"Insufficient format in DRIP potential file"); + MPI_Bcast(&nparams, 1, MPI_INT, 0, world); + MPI_Bcast(&maxparam, 1, MPI_INT, 0, world); - // words = ptrs to all words in line - - nwords = 0; - words[nwords++] = strtok(line," \t\n\r\f"); - while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; - - // ielement,jelement = 1st args - // if these 2 args are in element list, then parse this line - // else skip to next line (continue) - - for (ielement = 0; ielement < nelements; ielement++) - if (strcmp(words[0],elements[ielement]) == 0) break; - if (ielement == nelements) continue; - for (jelement = 0; jelement < nelements; jelement++) - if (strcmp(words[1],elements[jelement]) == 0) break; - if (jelement == nelements) continue; - - // load up parameter settings and error check their values - - if (nparams == maxparam) { - maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), - "pair:params"); - - // make certain all addional allocated storage is initialized - // to avoid false positives when checking with valgrind - - memset(params + nparams, 0, DELTA*sizeof(Param)); + if (comm->me != 0) { + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); } - params[nparams].ielement = ielement; - params[nparams].jelement = jelement; - params[nparams].C0 = atof(words[2]); - params[nparams].C2 = atof(words[3]); - params[nparams].C4 = atof(words[4]); - params[nparams].C = atof(words[5]); - params[nparams].delta = atof(words[6]); - params[nparams].lambda = atof(words[7]); - params[nparams].A = atof(words[8]); - params[nparams].z0 = atof(words[9]); - params[nparams].B = atof(words[10]); - params[nparams].eta = atof(words[11]); - params[nparams].rhocut = atof(words[12]); - params[nparams].rcut = atof(words[13]); - params[nparams].ncut = atof(words[14]); - - // convenient precomputations - params[nparams].rhocutsq = params[nparams].rhocut * params[nparams].rhocut; - params[nparams].rcutsq = params[nparams].rcut * params[nparams].rcut; - params[nparams].ncutsq = params[nparams].ncut * params[nparams].ncut; - - nparams++; + MPI_Bcast(params, maxparam * sizeof(Param), MPI_BYTE, 0, world); } memory->destroy(elem2param); - memory->create(elem2param,nelements,nelements,"pair:elem2param"); - for (i = 0; i < nelements; i++) { - for (j = 0; j < nelements; j++) { - n = -1; - for (m = 0; m < nparams; m++) { + memory->create(elem2param, nelements, nelements, "pair:elem2param"); + for (int i = 0; i < nelements; i++) { + for (int j = 0; j < nelements; j++) { + int n = -1; + for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR, "Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR, "Potential file is missing an entry"); elem2param[i][j] = n; } } - delete [] words; } /* ---------------------------------------------------------------------- */ void PairDRIP::compute(int eflag, int vflag) { - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,rsq; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, rsq; + int *ilist, *jlist, *numneigh, **firstneigh; - double ni[DIM]; - double dni_dri[DIM][DIM], dni_drnb1[DIM][DIM]; - double dni_drnb2[DIM][DIM], dni_drnb3[DIM][DIM]; + double ni[3]; + double dni_dri[3][3], dni_drnb1[3][3]; + double dni_drnb2[3][3], dni_drnb3[3][3]; - ev_init(eflag,vflag); + ev_init(eflag, vflag); double **x = atom->x; double **f = atom->f; @@ -314,9 +298,7 @@ void PairDRIP::compute(int eflag, int vflag) for (ii = 0; ii < inum; ii++) { i = ilist[ii]; - if (nearest3neigh[i][0] == -1) { - continue; - } + if (nearest3neigh[i][0] == -1) { continue; } xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; @@ -325,68 +307,64 @@ void PairDRIP::compute(int eflag, int vflag) jnum = numneigh[i]; // normal and its derivatives w.r.t. atom i and its 3 nearest neighbors - calc_normal(i, ni, dni_dri,dni_drnb1, dni_drnb2, dni_drnb3); + calc_normal(i, ni, dni_dri, dni_drnb1, dni_drnb2, dni_drnb3); - double fi[DIM] = {0., 0., 0.}; + double fi[3] = {0., 0., 0.}; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; - if (nearest3neigh[j][0] == -1) { - continue; - } + if (nearest3neigh[j][0] == -1) { continue; } jtype = map[type[j]]; delx = x[j][0] - xtmp; dely = x[j][1] - ytmp; delz = x[j][2] - ztmp; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; int iparam_ij = elem2param[itype][jtype]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; double rcutsq = p.rcutsq; // only include the interaction between different layers if (rsq < rcutsq && atom->molecule[i] != atom->molecule[j]) { - double fj[DIM] = {0., 0., 0.}; - double rvec[DIM] = {delx, dely, delz}; + double fj[3] = {0., 0., 0.}; + double rvec[3] = {delx, dely, delz}; double phi_attr = calc_attractive(p, rsq, rvec, fi, fj); - double phi_repul = calc_repulsive(i, j, p, rsq, rvec, - ni, dni_dri, dni_drnb1, dni_drnb2, dni_drnb3, fi, fj); + double phi_repul = calc_repulsive(i, j, p, rsq, rvec, ni, dni_dri, dni_drnb1, dni_drnb2, + dni_drnb3, fi, fj); - if (eflag) evdwl = HALF * (phi_repul + phi_attr); - else evdwl = 0.0; - if (evflag) ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,0,0,0,0); + if (eflag) + evdwl = HALF * (phi_repul + phi_attr); + else + evdwl = 0.0; + if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, 0, 0, 0, 0); f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2]; if (vflag_either) v_tally2_newton(j, fj, x[j]); - } - } //loop over jj + } //loop over jj f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2]; if (vflag_either) v_tally2_newton(i, fi, x[i]); - } // loop over ii - - -if (vflag_fdotr) - virial_fdotr_compute(); + } // loop over ii + if (vflag_fdotr) virial_fdotr_compute(); } /* ---------------------------------------------------------------------- Attractive part, i.e. the r^(-6) part ------------------------------------------------------------------------- */ -double PairDRIP::calc_attractive(Param& p, double const rsq, double const *rvec, - double *const fi, double *const fj) +double PairDRIP::calc_attractive(Param &p, double const rsq, double const *rvec, double *const fi, + double *const fj) { double const z0 = p.z0; double const A = p.A; @@ -416,10 +394,10 @@ double PairDRIP::calc_attractive(Param& p, double const rsq, double const *rvec, Repulsive part that depends on transverse distance and dihedral angle ------------------------------------------------------------------------- */ -double PairDRIP::calc_repulsive(int const i, int const j, Param& p, - double const rsq, double const *rvec, double const *ni, - V3 const *dni_dri, V3 const *dni_drnb1, V3 const *dni_drnb2, - V3 const *dni_drnb3, double *const fi, double *const fj) +double PairDRIP::calc_repulsive(int const i, int const j, Param &p, double const rsq, + double const *rvec, double const *ni, V3 const *dni_dri, + V3 const *dni_drnb1, V3 const *dni_drnb2, V3 const *dni_drnb3, + double *const fi, double *const fj) { double **f = atom->f; double **x = atom->x; @@ -441,12 +419,12 @@ double PairDRIP::calc_repulsive(int const i, int const j, Param& p, int nbj2 = nearest3neigh[j][1]; int nbj3 = nearest3neigh[j][2]; - double fnbi1[DIM]; - double fnbi2[DIM]; - double fnbi3[DIM]; - double fnbj1[DIM]; - double fnbj2[DIM]; - double fnbj3[DIM]; + double fnbi1[3]; + double fnbi2[3]; + double fnbi3[3]; + double fnbj1[3]; + double fnbj2[3]; + double fnbj3[3]; V3 dgij_dri; V3 dgij_drj; V3 dgij_drk1; @@ -464,8 +442,8 @@ double PairDRIP::calc_repulsive(int const i, int const j, Param& p, double r = sqrt(rsq); // derivative of rhosq w.r.t. atoms i j and the nearests 3 neighs of i - get_drhosqij(rvec, ni, dni_dri, dni_drnb1, dni_drnb2, dni_drnb3, drhosqij_dri, - drhosqij_drj, drhosqij_drnb1, drhosqij_drnb2, drhosqij_drnb3); + get_drhosqij(rvec, ni, dni_dri, dni_drnb1, dni_drnb2, dni_drnb3, drhosqij_dri, drhosqij_drj, + drhosqij_drnb1, drhosqij_drnb2, drhosqij_drnb3); // transverse decay function f(rho) and its derivative w.r.t. rhosq double rhosqij; @@ -474,8 +452,8 @@ double PairDRIP::calc_repulsive(int const i, int const j, Param& p, // dihedral angle function and its derivateives double dgij_drhosq; - double gij = dihedral(i, j, p, rhosqij, dgij_drhosq, dgij_dri, dgij_drj, - dgij_drk1, dgij_drk2, dgij_drk3, dgij_drl1, dgij_drl2, dgij_drl3); + double gij = dihedral(i, j, p, rhosqij, dgij_drhosq, dgij_dri, dgij_drj, dgij_drk1, dgij_drk2, + dgij_drk3, dgij_drl1, dgij_drl2, dgij_drl3); double V2 = C + tdij + gij; @@ -490,7 +468,7 @@ double PairDRIP::calc_repulsive(int const i, int const j, Param& p, // total energy double phi = tp * V1 * V2; - for (int k = 0; k < DIM; k++) { + for (int k = 0; k < 3; k++) { // forces due to derivatives of tap and V1 double tmp = HALF * (dtp * V1 + tp * dV1) * V2 * rvec[k] / r; fi[k] += tmp; @@ -499,19 +477,19 @@ double PairDRIP::calc_repulsive(int const i, int const j, Param& p, // contributions from transverse decay part tdij and the dihedral part gij // derivative of V2 contribute to atoms i, j - fi[k] -= HALF*tp*V1*((dtdij+dgij_drhosq)*drhosqij_dri[k]+dgij_dri[k]); - fj[k] -= HALF*tp*V1*((dtdij+dgij_drhosq)*drhosqij_drj[k]+dgij_drj[k]); + fi[k] -= HALF * tp * V1 * ((dtdij + dgij_drhosq) * drhosqij_dri[k] + dgij_dri[k]); + fj[k] -= HALF * tp * V1 * ((dtdij + dgij_drhosq) * drhosqij_drj[k] + dgij_drj[k]); // derivative of V2 contribute to nearest 3 neighs of atom i - fnbi1[k] = -HALF*tp*V1*((dtdij+dgij_drhosq)*drhosqij_drnb1[k]+dgij_drk1[k]); - fnbi2[k] = -HALF*tp*V1*((dtdij+dgij_drhosq)*drhosqij_drnb2[k]+dgij_drk2[k]); - fnbi3[k] = -HALF*tp*V1*((dtdij+dgij_drhosq)*drhosqij_drnb3[k]+dgij_drk3[k]); + fnbi1[k] = -HALF * tp * V1 * ((dtdij + dgij_drhosq) * drhosqij_drnb1[k] + dgij_drk1[k]); + fnbi2[k] = -HALF * tp * V1 * ((dtdij + dgij_drhosq) * drhosqij_drnb2[k] + dgij_drk2[k]); + fnbi3[k] = -HALF * tp * V1 * ((dtdij + dgij_drhosq) * drhosqij_drnb3[k] + dgij_drk3[k]); // derivative of V2 contribute to nearest 3 neighs of atom j fnbj1[k] = -HALF * tp * V1 * dgij_drl1[k]; fnbj2[k] = -HALF * tp * V1 * dgij_drl2[k]; fnbj3[k] = -HALF * tp * V1 * dgij_drl3[k]; } - for (int k = 0; k < DIM; k++) { + for (int k = 0; k < 3; k++) { f[nbi1][k] += fnbi1[k]; f[nbi2][k] += fnbi2[k]; f[nbi3][k] += fnbi3[k]; @@ -543,7 +521,6 @@ void PairDRIP::find_nearest3neigh() double **x = atom->x; int *type = atom->type; - allnum = list->inum + list->gnum; inum = list->inum; ilist = list->ilist; @@ -559,7 +536,7 @@ void PairDRIP::find_nearest3neigh() // If "NULL" used in pair_coeff, i could be larger than allnum if (i >= size) { - size = i+1; + size = i + 1; memory->grow(nearest3neigh, size, 3, "pair:nearest3neigh"); } @@ -600,26 +577,24 @@ void PairDRIP::find_nearest3neigh() nb3_rsq = nb2_rsq; nb2_rsq = nb1_rsq; nb1_rsq = rsq; - } - else if (rsq < nb2_rsq) { + } else if (rsq < nb2_rsq) { nb3 = nb2; nb2 = j; nb3_rsq = nb2_rsq; nb2_rsq = rsq; - } - else if (rsq < nb3_rsq) { + } else if (rsq < nb3_rsq) { nb3 = j; nb3_rsq = rsq; } - } - } // loop over jj + } // loop over jj // store neighbors to be used later to compute normal if (nb3_rsq >= 1.0e10) { - if (ione(FLERR, "No enough neighbors to construct normal. Check the " - "configuration to see whether atoms fly away."); + if (i < inum) { + error->one(FLERR, + "No enough neighbors to construct normal. Check the " + "configuration to see whether atoms fly away."); } else { // This only happens for ghost atoms that are near the boundary of the // domain (i.e. r > r_cut + n_cut). These ghost atoms will not be @@ -630,30 +605,26 @@ void PairDRIP::find_nearest3neigh() nearest3neigh[i][1] = -1; nearest3neigh[i][2] = -1; } - } - else{ + } else { nearest3neigh[i][0] = nb1; nearest3neigh[i][1] = nb2; nearest3neigh[i][2] = nb3; } - } // loop over ii - + } // loop over ii } /* ---------------------------------------------------------------------- */ -void PairDRIP::calc_normal(int const i, double *const normal, - V3 *const dn_dri, V3 *const dn_drk1, V3 *const dn_drk2, V3 *const dn_drk3) +void PairDRIP::calc_normal(int const i, double *const normal, V3 *const dn_dri, V3 *const dn_drk1, + V3 *const dn_drk2, V3 *const dn_drk3) { int k1 = nearest3neigh[i][0]; int k2 = nearest3neigh[i][1]; int k3 = nearest3neigh[i][2]; // normal does not depend on i, setting to zero - for (int j = 0; j < DIM; j++) { - for (int k = 0; k < DIM; k++) { - dn_dri[j][k] = 0.0; - } + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 3; k++) { dn_dri[j][k] = 0.0; } } // get normal and derives of normal w.r.t to its 3 nearest neighbors @@ -663,18 +634,18 @@ void PairDRIP::calc_normal(int const i, double *const normal, /* ---------------------------------------------------------------------- */ -void PairDRIP::get_drhosqij(double const *rij, double const *ni, - V3 const *dni_dri, V3 const *dni_drn1, V3 const *dni_drn2, - V3 const *dni_drn3, double *const drhosq_dri, double *const drhosq_drj, - double *const drhosq_drn1, double *const drhosq_drn2, - double *const drhosq_drn3) +void PairDRIP::get_drhosqij(double const *rij, double const *ni, V3 const *dni_dri, + V3 const *dni_drn1, V3 const *dni_drn2, V3 const *dni_drn3, + double *const drhosq_dri, double *const drhosq_drj, + double *const drhosq_drn1, double *const drhosq_drn2, + double *const drhosq_drn3) { int k; double ni_dot_rij = 0; - double dni_dri_dot_rij[DIM]; - double dni_drn1_dot_rij[DIM]; - double dni_drn2_dot_rij[DIM]; - double dni_drn3_dot_rij[DIM]; + double dni_dri_dot_rij[3]; + double dni_drn1_dot_rij[3]; + double dni_drn2_dot_rij[3]; + double dni_drn3_dot_rij[3]; ni_dot_rij = dot(ni, rij); mat_dot_vec(dni_dri, rij, dni_dri_dot_rij); @@ -682,8 +653,8 @@ void PairDRIP::get_drhosqij(double const *rij, double const *ni, mat_dot_vec(dni_drn2, rij, dni_drn2_dot_rij); mat_dot_vec(dni_drn3, rij, dni_drn3_dot_rij); - for (k = 0; k < DIM; k++) { - drhosq_dri[k] = -2*rij[k] - 2 * ni_dot_rij * (-ni[k] + dni_dri_dot_rij[k]); + for (k = 0; k < 3; k++) { + drhosq_dri[k] = -2 * rij[k] - 2 * ni_dot_rij * (-ni[k] + dni_dri_dot_rij[k]); drhosq_drj[k] = 2 * rij[k] - 2 * ni_dot_rij * ni[k]; drhosq_drn1[k] = -2 * ni_dot_rij * dni_drn1_dot_rij[k]; drhosq_drn2[k] = -2 * ni_dot_rij * dni_drn2_dot_rij[k]; @@ -695,18 +666,15 @@ void PairDRIP::get_drhosqij(double const *rij, double const *ni, derivartive of transverse decay function f(rho) w.r.t. rho ------------------------------------------------------------------------- */ -double PairDRIP::td(double C0, double C2, double C4, double delta, - double const *const rvec, double r, const double *const n, - double& rho_sq, double& dtd) +double PairDRIP::td(double C0, double C2, double C4, double delta, double const *const rvec, + double r, const double *const n, double &rho_sq, double &dtd) { double n_dot_r = dot(n, rvec); rho_sq = r * r - n_dot_r * n_dot_r; // in case n is [0, 0, 1] and rho_sq is negative due to numerical error - if (rho_sq < 0) { - rho_sq = 0; - } + if (rho_sq < 0) { rho_sq = 0; } double del_sq = delta * delta; double rod_sq = rho_sq / del_sq; @@ -720,11 +688,10 @@ double PairDRIP::td(double C0, double C2, double C4, double delta, derivartive of dihedral angle func gij w.r.t rho, and atom positions ------------------------------------------------------------------------- */ -double PairDRIP::dihedral(const int i, const int j, Param& p, - double const rhosq, double& d_drhosq, - double *const d_dri, double *const d_drj, - double *const d_drk1, double *const d_drk2, double *const d_drk3, - double *const d_drl1, double *const d_drl2, double *const d_drl3) +double PairDRIP::dihedral(const int i, const int j, Param &p, double const rhosq, double &d_drhosq, + double *const d_dri, double *const d_drj, double *const d_drk1, + double *const d_drk2, double *const d_drk3, double *const d_drl1, + double *const d_drl2, double *const d_drl3) { double **x = atom->x; @@ -734,16 +701,15 @@ double PairDRIP::dihedral(const int i, const int j, Param& p, double cut_rhosq = p.rhocutsq; // local vars - double cos_kl[3][3]; // cos_omega_k1ijl1, cos_omega_k1ijl2 ... - double d_dcos_kl[3][3]; // deriv of dihedral w.r.t to cos_omega_kijl - double dcos_kl[3][3][4][DIM]; // 4 indicates k, i, j, l. e.g. dcoskl[0][1][0] - // means dcos_omega_k1ijl2 / drk - + double cos_kl[3][3]; // cos_omega_k1ijl1, cos_omega_k1ijl2 ... + double d_dcos_kl[3][3]; // deriv of dihedral w.r.t to cos_omega_kijl + double dcos_kl[3][3][4][3]; // 4 indicates k, i, j, l. e.g. dcoskl[0][1][0] + // means dcos_omega_k1ijl2 / drk // if larger than cutoff of rho, return 0 if (rhosq >= cut_rhosq) { d_drhosq = 0; - for (int dim = 0; dim < DIM; dim++) { + for (int dim = 0; dim < 3; dim++) { d_dri[dim] = 0; d_drj[dim] = 0; d_drk1[dim] = 0; @@ -767,9 +733,8 @@ double PairDRIP::dihedral(const int i, const int j, Param& p, // cos_omega_kijl and the derivatives w.r.t coordinates for (int m = 0; m < 3; m++) { for (int n = 0; n < 3; n++) { - cos_kl[m][n] = deriv_cos_omega(x[k[m]], x[i], x[j], x[l[n]], - dcos_kl[m][n][0], dcos_kl[m][n][1], - dcos_kl[m][n][2], dcos_kl[m][n][3]); + cos_kl[m][n] = deriv_cos_omega(x[k[m]], x[i], x[j], x[l[n]], dcos_kl[m][n][0], + dcos_kl[m][n][1], dcos_kl[m][n][2], dcos_kl[m][n][3]); } } @@ -800,7 +765,7 @@ double PairDRIP::dihedral(const int i, const int j, Param& p, d_dcos_kl[2][2] = -D0 * epart3 * eta * cos_kl[2][0] * cos_kl[2][1]; // initialization to be zero and later add values - for (int dim = 0; dim < DIM; dim++) { + for (int dim = 0; dim < 3; dim++) { d_drk1[dim] = 0.; d_drk2[dim] = 0.; d_drk3[dim] = 0.; @@ -835,21 +800,20 @@ double PairDRIP::dihedral(const int i, const int j, Param& p, compute cos(omega_kijl) and the derivateives ------------------------------------------------------------------------- */ -double PairDRIP::deriv_cos_omega(double const *rk, double const *ri, - double const *rj, double const *rl, double *const dcos_drk, - double *const dcos_dri, double *const dcos_drj, double *const dcos_drl) +double PairDRIP::deriv_cos_omega(double const *rk, double const *ri, double const *rj, + double const *rl, double *const dcos_drk, double *const dcos_dri, + double *const dcos_drj, double *const dcos_drl) { - double ejik[DIM]; - double eijl[DIM]; - double tmp1[DIM]; - double tmp2[DIM]; - double dejik_dri[DIM][DIM]; - double dejik_drj[DIM][DIM]; - double dejik_drk[DIM][DIM]; - double deijl_dri[DIM][DIM]; - double deijl_drj[DIM][DIM]; - double deijl_drl[DIM][DIM]; - + double ejik[3]; + double eijl[3]; + double tmp1[3]; + double tmp2[3]; + double dejik_dri[3][3]; + double dejik_drj[3][3]; + double dejik_drk[3][3]; + double deijl_dri[3][3]; + double deijl_drj[3][3]; + double deijl_drl[3][3]; // ejik and derivatives // Note the returned dejik_dri ... are actually the transpose @@ -857,9 +821,9 @@ double PairDRIP::deriv_cos_omega(double const *rk, double const *ri, // flip sign // deriv_cross computes rij cross rik, here we need rji cross rik - for (int m = 0; m < DIM; m++) { + for (int m = 0; m < 3; m++) { ejik[m] = -ejik[m]; - for (int n = 0; n < DIM; n++) { + for (int n = 0; n < 3; n++) { dejik_dri[m][n] = -dejik_dri[m][n]; dejik_drj[m][n] = -dejik_drj[m][n]; dejik_drk[m][n] = -dejik_drk[m][n]; @@ -869,9 +833,9 @@ double PairDRIP::deriv_cos_omega(double const *rk, double const *ri, // eijl and derivatives deriv_cross(rj, ri, rl, eijl, deijl_drj, deijl_dri, deijl_drl); // flip sign - for (int m = 0; m < DIM; m++) { + for (int m = 0; m < 3; m++) { eijl[m] = -eijl[m]; - for (int n = 0; n < DIM; n++) { + for (int n = 0; n < 3; n++) { deijl_drj[m][n] = -deijl_drj[m][n]; deijl_dri[m][n] = -deijl_dri[m][n]; deijl_drl[m][n] = -deijl_drl[m][n]; @@ -883,15 +847,11 @@ double PairDRIP::deriv_cos_omega(double const *rk, double const *ri, // dcos_dri mat_dot_vec(dejik_dri, eijl, tmp1); mat_dot_vec(deijl_dri, ejik, tmp2); - for (int m = 0; m < DIM; m++) { - dcos_dri[m] = tmp1[m] + tmp2[m]; - } + for (int m = 0; m < 3; m++) { dcos_dri[m] = tmp1[m] + tmp2[m]; } // dcos_drj mat_dot_vec(dejik_drj, eijl, tmp1); mat_dot_vec(deijl_drj, ejik, tmp2); - for (int m = 0; m < DIM; m++) { - dcos_drj[m] = tmp1[m] + tmp2[m]; - } + for (int m = 0; m < 3; m++) { dcos_drj[m] = tmp1[m] + tmp2[m]; } // dcos drl mat_dot_vec(deijl_drl, ejik, dcos_drl); @@ -903,7 +863,7 @@ double PairDRIP::deriv_cos_omega(double const *rk, double const *ri, /* ---------------------------------------------------------------------- */ -double PairDRIP::tap(double r, double cutoff, double& dtap) +double PairDRIP::tap(double r, double cutoff, double &dtap) { double t; double r_min = 0; @@ -911,13 +871,12 @@ double PairDRIP::tap(double r, double cutoff, double& dtap) if (r <= r_min) { t = 1; dtap = 0; - } - else { + } else { double roc = (r - r_min) / (cutoff - r_min); double roc_sq = roc * roc; - t = roc_sq*roc_sq*(-35.0 + 84.0 * roc + roc_sq * (-70.0 + 20.0 * roc)) + 1; - dtap = roc_sq * roc / (cutoff - r_min) - * (-140.0 + 420.0 * roc + roc_sq * (-420.0 + 140.0 * roc)); + t = roc_sq * roc_sq * (-35.0 + 84.0 * roc + roc_sq * (-70.0 + 20.0 * roc)) + 1; + dtap = + roc_sq * roc / (cutoff - r_min) * (-140.0 + 420.0 * roc + roc_sq * (-420.0 + 140.0 * roc)); } return t; @@ -925,7 +884,7 @@ double PairDRIP::tap(double r, double cutoff, double& dtap) /* ---------------------------------------------------------------------- */ -double PairDRIP::tap_rho(double rhosq, double cut_rhosq, double& drhosq) +double PairDRIP::tap_rho(double rhosq, double cut_rhosq, double &drhosq) { double roc_sq; double roc; @@ -933,10 +892,10 @@ double PairDRIP::tap_rho(double rhosq, double cut_rhosq, double& drhosq) roc_sq = rhosq / cut_rhosq; roc = sqrt(roc_sq); - t = roc_sq*roc_sq*(-35.0 + 84.0 * roc + roc_sq * (-70.0 + 20.0 * roc)) + 1; + t = roc_sq * roc_sq * (-35.0 + 84.0 * roc + roc_sq * (-70.0 + 20.0 * roc)) + 1; // Note this dtap/drho_sq not dtap/drho - drhosq = roc_sq/cut_rhosq*(-70.0 + 210.0*roc + roc_sq*(-210.0 + 70.0*roc)); + drhosq = roc_sq / cut_rhosq * (-70.0 + 210.0 * roc + roc_sq * (-210.0 + 70.0 * roc)); return t; } @@ -948,13 +907,13 @@ double PairDRIP::tap_rho(double rhosq, double cut_rhosq, double& drhosq) transpose. ------------------------------------------------------------------------- */ -void PairDRIP::deriv_cross(double const *rk, double const *rl, - double const *rm, double *const cross, - V3 *const dcross_drk, V3 *const dcross_drl, V3 *const dcross_drm) +void PairDRIP::deriv_cross(double const *rk, double const *rl, double const *rm, + double *const cross, V3 *const dcross_drk, V3 *const dcross_drl, + V3 *const dcross_drm) { - double x[DIM]; - double y[DIM]; - double p[DIM]; + double x[3]; + double y[3]; + double p[3]; double q; double q_cubic; double d_invq_d_x0; @@ -966,9 +925,8 @@ void PairDRIP::deriv_cross(double const *rk, double const *rl, int i, j; - // get x = rkl and y = rkm - for (i = 0; i < DIM; i++) { + for (i = 0; i < 3; i++) { x[i] = rl[i] - rk[i]; y[i] = rm[i] - rk[i]; } @@ -1022,9 +980,7 @@ void PairDRIP::deriv_cross(double const *rk, double const *rl, dcross_drm[2][2] = p[2] * d_invq_d_y2; // dcross/drk transposed - for (i = 0; i < DIM; i++) { - for (j = 0; j < DIM; j++) { - dcross_drk[i][j] = -(dcross_drl[i][j] + dcross_drm[i][j]); - } + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { dcross_drk[i][j] = -(dcross_drl[i][j] + dcross_drm[i][j]); } } } diff --git a/src/INTERLAYER/pair_drip.h b/src/INTERLAYER/pair_drip.h index bd719e0b57..eb854b585b 100644 --- a/src/INTERLAYER/pair_drip.h +++ b/src/INTERLAYER/pair_drip.h @@ -33,9 +33,6 @@ PairStyle(drip, PairDRIP); namespace LAMMPS_NS { -#define DIM 3 -typedef double V3[3]; - class PairDRIP : public Pair { public: PairDRIP(class LAMMPS *); @@ -47,6 +44,9 @@ class PairDRIP : public Pair { double init_one(int, int); void init_style(); + static constexpr int NPARAMS_PER_LINE = 15; + typedef double V3[3]; + protected: struct Param { int ielement, jelement; @@ -90,17 +90,6 @@ class PairDRIP : public Pair { void deriv_cross(double const *, double const *, double const *, double *const, V3 *const, V3 *const, V3 *const); - - // inline functions - inline double dot(double const *x, double const *y) const - { - return x[0] * y[0] + x[1] * y[1] + x[2] * y[2]; - } - - inline void mat_dot_vec(V3 const *X, double const *y, double *const z) const - { - for (int k = 0; k < 3; k++) { z[k] = X[k][0] * y[0] + X[k][1] * y[1] + X[k][2] * y[2]; } - } }; } // namespace LAMMPS_NS diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index 3a35c281c1..43070c5156 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -28,30 +27,34 @@ #include "comm.h" #include "error.h" #include "force.h" +#include "interlayer_taper.h" #include "memory.h" #include "my_page.h" #include "neigh_list.h" #include "neigh_request.h" #include "neighbor.h" +#include "potential_file_reader.h" +#include "tokenizer.h" #include #include using namespace LAMMPS_NS; +using namespace InterLayer; #define MAXLINE 1024 #define DELTA 4 #define PGDELTA 1 static const char cite_ilp[] = - "@Article{Ouyang2018\n" - " author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod},\n" - " title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials},\n" - " journal = {Nano Letters},\n" - " volume = 18,\n" - " pages = {6009}\n" - " year = 2018,\n" - "}\n\n"; + "@Article{Ouyang2018\n" + " author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod},\n" + " title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials},\n" + " journal = {Nano Letters},\n" + " volume = 18,\n" + " pages = {6009}\n" + " year = 2018,\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ @@ -59,6 +62,9 @@ PairILPGrapheneHBN::PairILPGrapheneHBN(LAMMPS *lmp) : Pair(lmp) { restartinfo = 0; one_coeff = 1; + manybody_flag = 1; + centroidstressflag = CENTROID_NOTAVAIL; + unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); if (lmp->citeme) lmp->citeme->add(cite_ilp); @@ -82,7 +88,8 @@ PairILPGrapheneHBN::PairILPGrapheneHBN(LAMMPS *lmp) : Pair(lmp) // always compute energy offset offset_flag = 1; - // turn on the taper function + + // turn on the taper function by default tap_flag = 1; } @@ -92,8 +99,8 @@ PairILPGrapheneHBN::~PairILPGrapheneHBN() { memory->destroy(ILP_numneigh); memory->sfree(ILP_firstneigh); - delete [] ipage; - delete [] pvector; + delete[] ipage; + delete[] pvector; memory->destroy(normal); memory->destroy(dnormal); memory->destroy(dnormdri); @@ -101,12 +108,12 @@ PairILPGrapheneHBN::~PairILPGrapheneHBN() if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); memory->destroy(offset); } memory->destroy(elem2param); memory->destroy(cutILPsq); + memory->sfree(params); } /* ---------------------------------------------------------------------- @@ -116,17 +123,15 @@ PairILPGrapheneHBN::~PairILPGrapheneHBN() void PairILPGrapheneHBN::allocate() { allocated = 1; - int n = atom->ntypes; + int n = atom->ntypes + 1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; + memory->create(setflag, n, n, "pair:setflag"); + for (int i = 1; i < n; i++) + for (int j = i; j < n; j++) setflag[i][j] = 0; - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(offset,n+1,n+1,"pair:offset"); - map = new int[atom->ntypes+1]; + memory->create(cutsq, n, n, "pair:cutsq"); + memory->create(offset, n, n, "pair:offset"); + map = new int[n]; } /* ---------------------------------------------------------------------- @@ -135,21 +140,12 @@ void PairILPGrapheneHBN::allocate() void PairILPGrapheneHBN::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); - if (strcmp(force->pair_style,"hybrid/overlay")!=0) - error->all(FLERR,"ERROR: requires hybrid/overlay pair_style"); + if (narg < 1 || narg > 2) error->all(FLERR, "Illegal pair_style command"); + if (strcmp(force->pair_style, "hybrid/overlay") != 0) + error->all(FLERR, "ERROR: requires hybrid/overlay pair_style"); - cut_global = utils::numeric(FLERR,arg[0],false,lmp); - if (narg == 2) tap_flag = utils::numeric(FLERR,arg[1],false,lmp); - - // reset cutoffs that have been explicitly set - - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; - } + cut_global = utils::numeric(FLERR, arg[0], false, lmp); + if (narg == 2) tap_flag = utils::numeric(FLERR, arg[1], false, lmp); } /* ---------------------------------------------------------------------- @@ -160,29 +156,29 @@ void PairILPGrapheneHBN::coeff(int narg, char **arg) { if (!allocated) allocate(); - map_element2type(narg-3,arg+3); + map_element2type(narg - 3, arg + 3); read_file(arg[2]); } - /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairILPGrapheneHBN::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - if (!offset_flag) - error->all(FLERR,"Must use 'pair_modify shift yes' with this pair style"); + if (setflag[i][j] == 0) error->all(FLERR, "All pair coeffs are not set"); + if (!offset_flag) error->all(FLERR, "Must use 'pair_modify shift yes' with this pair style"); - if (offset_flag && (cut[i][j] > 0.0)) { + if (offset_flag && (cut_global > 0.0)) { int iparam_ij = elem2param[map[i]][map[j]]; - Param& p = params[iparam_ij]; - offset[i][j] = -p.C6*pow(1.0/cut[i][j],6)/(1.0 + exp(-p.d*(cut[i][j]/p.seff - 1.0))); - } else offset[i][j] = 0.0; + Param &p = params[iparam_ij]; + offset[i][j] = + -p.C6 * pow(1.0 / cut_global, 6) / (1.0 + exp(-p.d * (cut_global / p.seff - 1.0))); + } else + offset[i][j] = 0.0; offset[j][i] = offset[i][j]; - return cut[i][j]; + return cut_global; } /* ---------------------------------------------------------------------- @@ -191,147 +187,119 @@ double PairILPGrapheneHBN::init_one(int i, int j) void PairILPGrapheneHBN::read_file(char *filename) { - int params_per_line = 13; - char **words = new char*[params_per_line+1]; memory->sfree(params); params = nullptr; nparams = maxparam = 0; // open file on proc 0 - FILE *fp; if (comm->me == 0) { - fp = utils::open_potential(filename,lmp,nullptr); - if (fp == nullptr) - error->one(FLERR,"Cannot open ILP potential file {}: {}",filename,utils::getsyserror()); - } + PotentialFileReader reader(lmp, filename, "ilp/graphene/hbn", unit_convert_flag); + char *line; - // read each line out of file, skipping blank lines or leading '#' - // store line of params if all 3 element tags are in element list + // transparently convert units for supported conversions - int i,j,n,m,nwords,ielement,jelement; - char line[MAXLINE],*ptr; - int eof = 0; + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, unit_convert); - while (1) { - if (comm->me == 0) { - ptr = fgets(line,MAXLINE,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; - } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + while ((line = reader.next_line(NPARAMS_PER_LINE))) { - // strip comment, skip line if blank + try { + ValueTokenizer values(line); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); - if (nwords == 0) continue; + std::string iname = values.next_string(); + std::string jname = values.next_string(); - // concatenate additional lines until have params_per_line words + // ielement,jelement = 1st args + // if both args are in element list, then parse this line + // else skip to next entry in file + int ielement, jelement; - while (nwords < params_per_line) { - n = strlen(line); - if (comm->me == 0) { - ptr = fgets(&line[n],MAXLINE-n,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; + for (ielement = 0; ielement < nelements; ielement++) + if (iname == elements[ielement]) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (jname == elements[jelement]) break; + if (jelement == nelements) continue; + + // expand storage, if needed + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); + + // make certain all addional allocated storage is initialized + // to avoid false positives when checking with valgrind + + memset(params + nparams, 0, DELTA * sizeof(Param)); + } + + // load up parameter settings and error check their values + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].z0 = values.next_double(); + params[nparams].alpha = values.next_double(); + params[nparams].delta = values.next_double(); + params[nparams].epsilon = values.next_double(); + params[nparams].C = values.next_double(); + params[nparams].d = values.next_double(); + params[nparams].sR = values.next_double(); + params[nparams].reff = values.next_double(); + params[nparams].C6 = values.next_double(); + // S provides a convenient scaling of all energies + params[nparams].S = values.next_double(); + params[nparams].rcut = values.next_double(); + + } catch (TokenizerException &e) { + error->one(FLERR, e.what()); } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); + + // energies in meV further scaled by S + // S = 43.3634 meV = 1 kcal/mol + + double meV = 1e-3 * params[nparams].S; + if (unit_convert) meV *= conversion_factor; + + params[nparams].C *= meV; + params[nparams].C6 *= meV; + params[nparams].epsilon *= meV; + + // precompute some quantities + params[nparams].delta2inv = pow(params[nparams].delta, -2.0); + params[nparams].lambda = params[nparams].alpha / params[nparams].z0; + params[nparams].seff = params[nparams].sR * params[nparams].reff; + + nparams++; } - if (nwords != params_per_line) - error->all(FLERR,"Insufficient format in ILP potential file"); + MPI_Bcast(&nparams, 1, MPI_INT, 0, world); + MPI_Bcast(&maxparam, 1, MPI_INT, 0, world); - // words = ptrs to all words in line - - nwords = 0; - words[nwords++] = strtok(line," \t\n\r\f"); - while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; - - // ielement,jelement = 1st args - // if these 2 args are in element list, then parse this line - // else skip to next line (continue) - - for (ielement = 0; ielement < nelements; ielement++) - if (strcmp(words[0],elements[ielement]) == 0) break; - if (ielement == nelements) continue; - for (jelement = 0; jelement < nelements; jelement++) - if (strcmp(words[1],elements[jelement]) == 0) break; - if (jelement == nelements) continue; - - // load up parameter settings and error check their values - - if (nparams == maxparam) { - maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), - "pair:params"); - - // make certain all addional allocated storage is initialized - // to avoid false positives when checking with valgrind - - memset(params + nparams, 0, DELTA*sizeof(Param)); + if (comm->me != 0) { + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); } - params[nparams].ielement = ielement; - params[nparams].jelement = jelement; - params[nparams].z0 = atof(words[2]); - params[nparams].alpha = atof(words[3]); - params[nparams].delta = atof(words[4]); - params[nparams].epsilon = atof(words[5]); - params[nparams].C = atof(words[6]); - params[nparams].d = atof(words[7]); - params[nparams].sR = atof(words[8]); - params[nparams].reff = atof(words[9]); - params[nparams].C6 = atof(words[10]); - // S provides a convenient scaling of all energies - params[nparams].S = atof(words[11]); - params[nparams].rcut = atof(words[12]); - - // energies in meV further scaled by S - // S = 43.3634 meV = 1 kcal/mol - double meV = 1e-3*params[nparams].S; - params[nparams].C *= meV; - params[nparams].C6 *= meV; - params[nparams].epsilon *= meV; - - // precompute some quantities - params[nparams].delta2inv = pow(params[nparams].delta,-2.0); - params[nparams].lambda = params[nparams].alpha/params[nparams].z0; - params[nparams].seff = params[nparams].sR * params[nparams].reff; - - nparams++; + MPI_Bcast(params, maxparam * sizeof(Param), MPI_BYTE, 0, world); } memory->destroy(elem2param); memory->destroy(cutILPsq); - memory->create(elem2param,nelements,nelements,"pair:elem2param"); - memory->create(cutILPsq,nelements,nelements,"pair:cutILPsq"); - for (i = 0; i < nelements; i++) { - for (j = 0; j < nelements; j++) { - n = -1; - for (m = 0; m < nparams; m++) { + memory->create(elem2param, nelements, nelements, "pair:elem2param"); + memory->create(cutILPsq, nelements, nelements, "pair:cutILPsq"); + for (int i = 0; i < nelements; i++) { + for (int j = 0; j < nelements; j++) { + int n = -1; + for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR, "ILP Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR, "Potential file is missing an entry"); elem2param[i][j] = n; - cutILPsq[i][j] = params[n].rcut*params[n].rcut; + cutILPsq[i][j] = params[n].rcut * params[n].rcut; } } - delete [] words; } /* ---------------------------------------------------------------------- @@ -341,13 +309,13 @@ void PairILPGrapheneHBN::read_file(char *filename) void PairILPGrapheneHBN::init_style() { if (force->newton_pair == 0) - error->all(FLERR,"Pair style ilp/graphene/hbn requires newton pair on"); + error->all(FLERR, "Pair style ilp/graphene/hbn requires newton pair on"); if (!atom->molecule_flag) - error->all(FLERR,"Pair style ilp/graphene/hbn requires atom attribute molecule"); + error->all(FLERR, "Pair style ilp/graphene/hbn requires atom attribute molecule"); // need a full neighbor list, including neighbors of ghosts - int irequest = neighbor->request(this,instance_me); + int irequest = neighbor->request(this, instance_me); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->ghost = 1; @@ -361,21 +329,20 @@ void PairILPGrapheneHBN::init_style() if (oneatom != neighbor->oneatom) create = 1; if (create) { - delete [] ipage; + delete[] ipage; pgsize = neighbor->pgsize; oneatom = neighbor->oneatom; - int nmypage= comm->nthreads; + int nmypage = comm->nthreads; ipage = new MyPage[nmypage]; - for (int i = 0; i < nmypage; i++) - ipage[i].init(oneatom,pgsize,PGDELTA); + for (int i = 0; i < nmypage; i++) ipage[i].init(oneatom, pgsize, PGDELTA); } } /* ---------------------------------------------------------------------- */ void PairILPGrapheneHBN::compute(int eflag, int vflag) { - ev_init(eflag,vflag); + ev_init(eflag, vflag); pvector[0] = pvector[1] = 0.0; // Build full neighbor list @@ -383,9 +350,9 @@ void PairILPGrapheneHBN::compute(int eflag, int vflag) // Calculate the normals and its derivatives calc_normal(); // Calculate the van der Waals force and energy - calc_FvdW(eflag,vflag); + calc_FvdW(eflag, vflag); // Calculate the repulsive force and energy - calc_FRep(eflag,vflag); + calc_FRep(eflag, vflag); if (vflag_fdotr) virial_fdotr_compute(); } @@ -396,11 +363,11 @@ void PairILPGrapheneHBN::compute(int eflag, int vflag) void PairILPGrapheneHBN::calc_FvdW(int eflag, int /* vflag */) { - int i,j,ii,jj,inum,jnum,itype,jtype; - tagint itag,jtag; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; - double rsq,r,Rcut,r2inv,r6inv,r8inv,Tap,dTap,Vilp,TSvdw,TSvdw2inv,fsum; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itype, jtype; + tagint itag, jtag; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair; + double rsq, r, Rcut, r2inv, r6inv, r8inv, Tap, dTap, Vilp, TSvdw, TSvdw2inv, fsum; + int *ilist, *jlist, *numneigh, **firstneigh; evdwl = 0.0; double **x = atom->x; @@ -434,9 +401,9 @@ void PairILPGrapheneHBN::calc_FvdW(int eflag, int /* vflag */) // two-body interactions from full neighbor list, skip half of them if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; + if ((itag + jtag) % 2 == 0) continue; } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; + if ((itag + jtag) % 2 == 1) continue; } else { if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; @@ -446,43 +413,46 @@ void PairILPGrapheneHBN::calc_FvdW(int eflag, int /* vflag */) delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; // only include the interaction between different layers if (rsq < cutsq[itype][jtype] && atom->molecule[i] != atom->molecule[j]) { int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - r8inv = r6inv*r2inv; + r2inv = 1.0 / rsq; + r6inv = r2inv * r2inv * r2inv; + r8inv = r6inv * r2inv; // turn on/off taper function if (tap_flag) { Rcut = sqrt(cutsq[itype][jtype]); - Tap = calc_Tap(r,Rcut); - dTap = calc_dTap(r,Rcut); - } else {Tap = 1.0; dTap = 0.0;} + Tap = calc_Tap(r, Rcut); + dTap = calc_dTap(r, Rcut); + } else { + Tap = 1.0; + dTap = 0.0; + } - TSvdw = 1.0 + exp(-p.d*(r/p.seff - 1.0)); - TSvdw2inv = pow(TSvdw,-2.0); - Vilp = -p.C6*r6inv/TSvdw; + TSvdw = 1.0 + exp(-p.d * (r / p.seff - 1.0)); + TSvdw2inv = pow(TSvdw, -2.0); + Vilp = -p.C6 * r6inv / TSvdw; // derivatives - fpair = -6.0*p.C6*r8inv/TSvdw + p.C6*p.d/p.seff*(TSvdw-1.0)*TSvdw2inv*r8inv*r; - fsum = fpair*Tap - Vilp*dTap/r; + fpair = -6.0 * p.C6 * r8inv / TSvdw + + p.C6 * p.d / p.seff * (TSvdw - 1.0) * TSvdw2inv * r8inv * r; + fsum = fpair * Tap - Vilp * dTap / r; - f[i][0] += fsum*delx; - f[i][1] += fsum*dely; - f[i][2] += fsum*delz; - f[j][0] -= fsum*delx; - f[j][1] -= fsum*dely; - f[j][2] -= fsum*delz; + f[i][0] += fsum * delx; + f[i][1] += fsum * dely; + f[i][2] += fsum * delz; + f[j][0] -= fsum * delx; + f[j][1] -= fsum * dely; + f[j][2] -= fsum * delz; - if (eflag) pvector[0] += evdwl = Vilp*Tap; - if (evflag) ev_tally(i,j,nlocal,newton_pair, - evdwl,0.0,fsum,delx,dely,delz); + if (eflag) pvector[0] += evdwl = Vilp * Tap; + if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, fsum, delx, dely, delz); } } } @@ -494,12 +464,12 @@ void PairILPGrapheneHBN::calc_FvdW(int eflag, int /* vflag */) void PairILPGrapheneHBN::calc_FRep(int eflag, int /* vflag */) { - int i,j,ii,jj,inum,jnum,itype,jtype,k,kk; - double prodnorm1,fkcx,fkcy,fkcz; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,fpair1; - double rsq,r,Rcut,rhosq1,exp0,exp1,Tap,dTap,Vilp; - double frho1,Erep,fsum,rdsq1; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itype, jtype, k, kk; + double prodnorm1, fkcx, fkcy, fkcz; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair, fpair1; + double rsq, r, Rcut, rhosq1, exp0, exp1, Tap, dTap, Vilp; + double frho1, Erep, fsum, rdsq1; + int *ilist, *jlist, *numneigh, **firstneigh; int *ILP_neighs_i; evdwl = 0.0; @@ -539,57 +509,63 @@ void PairILPGrapheneHBN::calc_FRep(int eflag, int /* vflag */) delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; // only include the interaction between different layers if (rsq < cutsq[itype][jtype] && atom->molecule[i] != atom->molecule[j]) { int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); // turn on/off taper function if (tap_flag) { Rcut = sqrt(cutsq[itype][jtype]); - Tap = calc_Tap(r,Rcut); - dTap = calc_dTap(r,Rcut); - } else {Tap = 1.0; dTap = 0.0;} + Tap = calc_Tap(r, Rcut); + dTap = calc_dTap(r, Rcut); + } else { + Tap = 1.0; + dTap = 0.0; + } // Calculate the transverse distance - prodnorm1 = normal[i][0]*delx + normal[i][1]*dely + normal[i][2]*delz; - rhosq1 = rsq - prodnorm1*prodnorm1; // rho_ij - rdsq1 = rhosq1*p.delta2inv; // (rho_ij/delta)^2 + prodnorm1 = normal[i][0] * delx + normal[i][1] * dely + normal[i][2] * delz; + rhosq1 = rsq - prodnorm1 * prodnorm1; // rho_ij + rdsq1 = rhosq1 * p.delta2inv; // (rho_ij/delta)^2 // store exponents - exp0 = exp(-p.lambda*(r-p.z0)); + exp0 = exp(-p.lambda * (r - p.z0)); exp1 = exp(-rdsq1); - frho1 = exp1*p.C; - Erep = 0.5*p.epsilon + frho1; - Vilp = exp0*Erep; + frho1 = exp1 * p.C; + Erep = 0.5 * p.epsilon + frho1; + Vilp = exp0 * Erep; // derivatives - fpair = p.lambda*exp0/r*Erep; - fpair1 = 2.0*exp0*frho1*p.delta2inv; + fpair = p.lambda * exp0 / r * Erep; + fpair1 = 2.0 * exp0 * frho1 * p.delta2inv; fsum = fpair + fpair1; // derivatives of the product of rij and ni, the result is a vector - dprodnorm1[0] = dnormdri[0][0][i]*delx + dnormdri[1][0][i]*dely + dnormdri[2][0][i]*delz; - dprodnorm1[1] = dnormdri[0][1][i]*delx + dnormdri[1][1][i]*dely + dnormdri[2][1][i]*delz; - dprodnorm1[2] = dnormdri[0][2][i]*delx + dnormdri[1][2][i]*dely + dnormdri[2][2][i]*delz; - fp1[0] = prodnorm1*normal[i][0]*fpair1; - fp1[1] = prodnorm1*normal[i][1]*fpair1; - fp1[2] = prodnorm1*normal[i][2]*fpair1; - fprod1[0] = prodnorm1*dprodnorm1[0]*fpair1; - fprod1[1] = prodnorm1*dprodnorm1[1]*fpair1; - fprod1[2] = prodnorm1*dprodnorm1[2]*fpair1; + dprodnorm1[0] = + dnormdri[0][0][i] * delx + dnormdri[1][0][i] * dely + dnormdri[2][0][i] * delz; + dprodnorm1[1] = + dnormdri[0][1][i] * delx + dnormdri[1][1][i] * dely + dnormdri[2][1][i] * delz; + dprodnorm1[2] = + dnormdri[0][2][i] * delx + dnormdri[1][2][i] * dely + dnormdri[2][2][i] * delz; + fp1[0] = prodnorm1 * normal[i][0] * fpair1; + fp1[1] = prodnorm1 * normal[i][1] * fpair1; + fp1[2] = prodnorm1 * normal[i][2] * fpair1; + fprod1[0] = prodnorm1 * dprodnorm1[0] * fpair1; + fprod1[1] = prodnorm1 * dprodnorm1[1] * fpair1; + fprod1[2] = prodnorm1 * dprodnorm1[2] * fpair1; - fkcx = (delx*fsum - fp1[0])*Tap - Vilp*dTap*delx/r; - fkcy = (dely*fsum - fp1[1])*Tap - Vilp*dTap*dely/r; - fkcz = (delz*fsum - fp1[2])*Tap - Vilp*dTap*delz/r; + fkcx = (delx * fsum - fp1[0]) * Tap - Vilp * dTap * delx / r; + fkcy = (dely * fsum - fp1[1]) * Tap - Vilp * dTap * dely / r; + fkcz = (delz * fsum - fp1[2]) * Tap - Vilp * dTap * delz / r; - f[i][0] += fkcx - fprod1[0]*Tap; - f[i][1] += fkcy - fprod1[1]*Tap; - f[i][2] += fkcz - fprod1[2]*Tap; + f[i][0] += fkcx - fprod1[0] * Tap; + f[i][1] += fkcy - fprod1[1] * Tap; + f[i][2] += fkcz - fprod1[2] * Tap; f[j][0] -= fkcx; f[j][1] -= fkcy; f[j][2] -= fkcz; @@ -600,26 +576,32 @@ void PairILPGrapheneHBN::calc_FRep(int eflag, int /* vflag */) k = ILP_neighs_i[kk]; if (k == i) continue; // derivatives of the product of rij and ni respect to rk, k=0,1,2, where atom k is the neighbors of atom i - dprodnorm1[0] = dnormal[0][0][kk][i]*delx + dnormal[1][0][kk][i]*dely + dnormal[2][0][kk][i]*delz; - dprodnorm1[1] = dnormal[0][1][kk][i]*delx + dnormal[1][1][kk][i]*dely + dnormal[2][1][kk][i]*delz; - dprodnorm1[2] = dnormal[0][2][kk][i]*delx + dnormal[1][2][kk][i]*dely + dnormal[2][2][kk][i]*delz; - fk[0] = (-prodnorm1*dprodnorm1[0]*fpair1)*Tap; - fk[1] = (-prodnorm1*dprodnorm1[1]*fpair1)*Tap; - fk[2] = (-prodnorm1*dprodnorm1[2]*fpair1)*Tap; + dprodnorm1[0] = dnormal[0][0][kk][i] * delx + dnormal[1][0][kk][i] * dely + + dnormal[2][0][kk][i] * delz; + dprodnorm1[1] = dnormal[0][1][kk][i] * delx + dnormal[1][1][kk][i] * dely + + dnormal[2][1][kk][i] * delz; + dprodnorm1[2] = dnormal[0][2][kk][i] * delx + dnormal[1][2][kk][i] * dely + + dnormal[2][2][kk][i] * delz; + fk[0] = (-prodnorm1 * dprodnorm1[0] * fpair1) * Tap; + fk[1] = (-prodnorm1 * dprodnorm1[1] * fpair1) * Tap; + fk[2] = (-prodnorm1 * dprodnorm1[2] * fpair1) * Tap; f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2]; delkj[0] = x[k][0] - x[j][0]; delkj[1] = x[k][1] - x[j][1]; delkj[2] = x[k][2] - x[j][2]; - if (evflag) ev_tally_xyz(k,j,nlocal,newton_pair,0.0,0.0,fk[0],fk[1],fk[2],delkj[0],delkj[1],delkj[2]); + if (evflag) + ev_tally_xyz(k, j, nlocal, newton_pair, 0.0, 0.0, fk[0], fk[1], fk[2], delkj[0], + delkj[1], delkj[2]); } - if (eflag) pvector[1] += evdwl = Tap*Vilp; - if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,evdwl,0.0,fkcx,fkcy,fkcz,delx,dely,delz); + if (eflag) pvector[1] += evdwl = Tap * Vilp; + if (evflag) + ev_tally_xyz(i, j, nlocal, newton_pair, evdwl, 0.0, fkcx, fkcy, fkcz, delx, dely, delz); } - } // loop over jj - } // loop over ii + } // loop over jj + } // loop over ii } /* ---------------------------------------------------------------------- @@ -628,9 +610,9 @@ void PairILPGrapheneHBN::calc_FRep(int eflag, int /* vflag */) void PairILPGrapheneHBN::ILP_neigh() { - int i,j,ii,jj,n,allnum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, n, allnum, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int *ilist, *jlist, *numneigh, **firstneigh; int *neighptr; double **x = atom->x; @@ -640,8 +622,9 @@ void PairILPGrapheneHBN::ILP_neigh() maxlocal = atom->nmax; memory->destroy(ILP_numneigh); memory->sfree(ILP_firstneigh); - memory->create(ILP_numneigh,maxlocal,"ILPGrapheneHBN:numneigh"); - ILP_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *),"ILPGrapheneHBN:firstneigh"); + memory->create(ILP_numneigh, maxlocal, "ILPGrapheneHBN:numneigh"); + ILP_firstneigh = + (int **) memory->smalloc(maxlocal * sizeof(int *), "ILPGrapheneHBN:firstneigh"); } allnum = list->inum + list->gnum; @@ -674,20 +657,21 @@ void PairILPGrapheneHBN::ILP_neigh() delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq != 0 && rsq < cutILPsq[itype][jtype] && atom->molecule[i] == atom->molecule[j]) { neighptr[n++] = j; } - } // loop over jj + } // loop over jj ILP_firstneigh[i] = neighptr; ILP_numneigh[i] = n; - if (n > 3) error->one(FLERR,"There are too many neighbors for some atoms, please check your configuration"); + if (n > 3) + error->one(FLERR, + "There are too many neighbors for some atoms, please check your configuration"); ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } } @@ -696,12 +680,12 @@ void PairILPGrapheneHBN::ILP_neigh() ------------------------------------------------------------------------- */ void PairILPGrapheneHBN::calc_normal() { - int i,j,ii,jj,inum,jnum; - int cont,id,ip,m; - double nn,xtp,ytp,ztp,delx,dely,delz,nn2; - int *ilist,*jlist; - double pv12[3],pv31[3],pv23[3],n1[3],dni[3],dnn[3][3],vet[3][3],dpvdri[3][3]; - double dn1[3][3][3],dpv12[3][3][3],dpv23[3][3][3],dpv31[3][3][3]; + int i, j, ii, jj, inum, jnum; + int cont, id, ip, m; + double nn, xtp, ytp, ztp, delx, dely, delz, nn2; + int *ilist, *jlist; + double pv12[3], pv31[3], pv23[3], n1[3], dni[3], dnn[3][3], vet[3][3], dpvdri[3][3]; + double dn1[3][3][3], dpv12[3][3][3], dpv23[3][3][3], dpv31[3][3][3]; double **x = atom->x; @@ -712,9 +696,9 @@ void PairILPGrapheneHBN::calc_normal() memory->destroy(dnormal); memory->destroy(dnormdri); nmax = atom->nmax; - memory->create(normal,nmax,3,"ILPGrapheneHBN:normal"); - memory->create(dnormdri,3,3,nmax,"ILPGrapheneHBN:dnormdri"); - memory->create(dnormal,3,3,3,nmax,"ILPGrapheneHBN:dnormal"); + memory->create(normal, nmax, 3, "ILPGrapheneHBN:normal"); + memory->create(dnormdri, 3, 3, nmax, "ILPGrapheneHBN:dnormdri"); + memory->create(dnormal, 3, 3, 3, nmax, "ILPGrapheneHBN:dnormal"); } inum = list->inum; @@ -773,85 +757,78 @@ void PairILPGrapheneHBN::calc_normal() for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { dnormdri[id][ip][i] = 0.0; - for (m = 0; m < 3; m++) { - dnormal[id][ip][m][i] = 0.0; - } + for (m = 0; m < 3; m++) { dnormal[id][ip][m][i] = 0.0; } } } - } - else if (cont == 2) { - pv12[0] = vet[0][1]*vet[1][2] - vet[1][1]*vet[0][2]; - pv12[1] = vet[0][2]*vet[1][0] - vet[1][2]*vet[0][0]; - pv12[2] = vet[0][0]*vet[1][1] - vet[1][0]*vet[0][1]; + } else if (cont == 2) { + pv12[0] = vet[0][1] * vet[1][2] - vet[1][1] * vet[0][2]; + pv12[1] = vet[0][2] * vet[1][0] - vet[1][2] * vet[0][0]; + pv12[2] = vet[0][0] * vet[1][1] - vet[1][0] * vet[0][1]; // derivatives of pv12[0] to ri dpvdri[0][0] = 0.0; - dpvdri[0][1] = vet[0][2]-vet[1][2]; - dpvdri[0][2] = vet[1][1]-vet[0][1]; + dpvdri[0][1] = vet[0][2] - vet[1][2]; + dpvdri[0][2] = vet[1][1] - vet[0][1]; // derivatives of pv12[1] to ri - dpvdri[1][0] = vet[1][2]-vet[0][2]; + dpvdri[1][0] = vet[1][2] - vet[0][2]; dpvdri[1][1] = 0.0; - dpvdri[1][2] = vet[0][0]-vet[1][0]; + dpvdri[1][2] = vet[0][0] - vet[1][0]; // derivatives of pv12[2] to ri - dpvdri[2][0] = vet[0][1]-vet[1][1]; - dpvdri[2][1] = vet[1][0]-vet[0][0]; + dpvdri[2][0] = vet[0][1] - vet[1][1]; + dpvdri[2][1] = vet[1][0] - vet[0][0]; dpvdri[2][2] = 0.0; - dpv12[0][0][0] = 0.0; - dpv12[0][1][0] = vet[1][2]; + dpv12[0][0][0] = 0.0; + dpv12[0][1][0] = vet[1][2]; dpv12[0][2][0] = -vet[1][1]; dpv12[1][0][0] = -vet[1][2]; - dpv12[1][1][0] = 0.0; - dpv12[1][2][0] = vet[1][0]; - dpv12[2][0][0] = vet[1][1]; + dpv12[1][1][0] = 0.0; + dpv12[1][2][0] = vet[1][0]; + dpv12[2][0][0] = vet[1][1]; dpv12[2][1][0] = -vet[1][0]; - dpv12[2][2][0] = 0.0; + dpv12[2][2][0] = 0.0; // derivatives respect to the second neighbor, atom l - dpv12[0][0][1] = 0.0; + dpv12[0][0][1] = 0.0; dpv12[0][1][1] = -vet[0][2]; - dpv12[0][2][1] = vet[0][1]; - dpv12[1][0][1] = vet[0][2]; - dpv12[1][1][1] = 0.0; + dpv12[0][2][1] = vet[0][1]; + dpv12[1][0][1] = vet[0][2]; + dpv12[1][1][1] = 0.0; dpv12[1][2][1] = -vet[0][0]; dpv12[2][0][1] = -vet[0][1]; - dpv12[2][1][1] = vet[0][0]; - dpv12[2][2][1] = 0.0; + dpv12[2][1][1] = vet[0][0]; + dpv12[2][2][1] = 0.0; // derivatives respect to the third neighbor, atom n // derivatives of pv12 to rn is zero for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv12[id][ip][2] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv12[id][ip][2] = 0.0; } } n1[0] = pv12[0]; n1[1] = pv12[1]; n1[2] = pv12[2]; // the magnitude of the normal vector - nn2 = n1[0]*n1[0] + n1[1]*n1[1] + n1[2]*n1[2]; + nn2 = n1[0] * n1[0] + n1[1] * n1[1] + n1[2] * n1[2]; nn = sqrt(nn2); - if (nn == 0) error->one(FLERR,"The magnitude of the normal vector is zero"); + if (nn == 0) error->one(FLERR, "The magnitude of the normal vector is zero"); // the unit normal vector - normal[i][0] = n1[0]/nn; - normal[i][1] = n1[1]/nn; - normal[i][2] = n1[2]/nn; + normal[i][0] = n1[0] / nn; + normal[i][1] = n1[1] / nn; + normal[i][2] = n1[2] / nn; // derivatives of nn, dnn:3x1 vector - dni[0] = (n1[0]*dpvdri[0][0] + n1[1]*dpvdri[1][0] + n1[2]*dpvdri[2][0])/nn; - dni[1] = (n1[0]*dpvdri[0][1] + n1[1]*dpvdri[1][1] + n1[2]*dpvdri[2][1])/nn; - dni[2] = (n1[0]*dpvdri[0][2] + n1[1]*dpvdri[1][2] + n1[2]*dpvdri[2][2])/nn; + dni[0] = (n1[0] * dpvdri[0][0] + n1[1] * dpvdri[1][0] + n1[2] * dpvdri[2][0]) / nn; + dni[1] = (n1[0] * dpvdri[0][1] + n1[1] * dpvdri[1][1] + n1[2] * dpvdri[2][1]) / nn; + dni[2] = (n1[0] * dpvdri[0][2] + n1[1] * dpvdri[1][2] + n1[2] * dpvdri[2][2]) / nn; // derivatives of unit vector ni respect to ri, the result is 3x3 matrix for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - dnormdri[id][ip][i] = dpvdri[id][ip]/nn - n1[id]*dni[ip]/nn2; + dnormdri[id][ip][i] = dpvdri[id][ip] / nn - n1[id] * dni[ip] / nn2; } } // derivatives of non-normalized normal vector, dn1:3x3x3 array for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - for (m = 0; m < 3; m++) { - dn1[id][ip][m] = dpv12[id][ip][m]; - } + for (m = 0; m < 3; m++) { dn1[id][ip][m] = dpv12[id][ip][m]; } } } // derivatives of nn, dnn:3x3 vector @@ -859,7 +836,7 @@ void PairILPGrapheneHBN::calc_normal() // r[id][m]: the id's component of atom m for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { - dnn[id][m] = (n1[0]*dn1[0][id][m] + n1[1]*dn1[1][id][m] + n1[2]*dn1[2][id][m])/nn; + dnn[id][m] = (n1[0] * dn1[0][id][m] + n1[1] * dn1[1][id][m] + n1[2] * dn1[2][id][m]) / nn; } } // dnormal[id][ip][m][i]: the derivative of normal[id] respect to r[ip][m], id,ip=0,1,2 @@ -867,131 +844,123 @@ void PairILPGrapheneHBN::calc_normal() for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - dnormal[id][ip][m][i] = dn1[id][ip][m]/nn - n1[id]*dnn[ip][m]/nn2; + dnormal[id][ip][m][i] = dn1[id][ip][m] / nn - n1[id] * dnn[ip][m] / nn2; } } } } -//############################################################################################## + //############################################################################################## else if (cont == 3) { - pv12[0] = vet[0][1]*vet[1][2] - vet[1][1]*vet[0][2]; - pv12[1] = vet[0][2]*vet[1][0] - vet[1][2]*vet[0][0]; - pv12[2] = vet[0][0]*vet[1][1] - vet[1][0]*vet[0][1]; + pv12[0] = vet[0][1] * vet[1][2] - vet[1][1] * vet[0][2]; + pv12[1] = vet[0][2] * vet[1][0] - vet[1][2] * vet[0][0]; + pv12[2] = vet[0][0] * vet[1][1] - vet[1][0] * vet[0][1]; // derivatives respect to the first neighbor, atom k - dpv12[0][0][0] = 0.0; - dpv12[0][1][0] = vet[1][2]; + dpv12[0][0][0] = 0.0; + dpv12[0][1][0] = vet[1][2]; dpv12[0][2][0] = -vet[1][1]; dpv12[1][0][0] = -vet[1][2]; - dpv12[1][1][0] = 0.0; - dpv12[1][2][0] = vet[1][0]; - dpv12[2][0][0] = vet[1][1]; + dpv12[1][1][0] = 0.0; + dpv12[1][2][0] = vet[1][0]; + dpv12[2][0][0] = vet[1][1]; dpv12[2][1][0] = -vet[1][0]; - dpv12[2][2][0] = 0.0; + dpv12[2][2][0] = 0.0; // derivatives respect to the second neighbor, atom l - dpv12[0][0][1] = 0.0; + dpv12[0][0][1] = 0.0; dpv12[0][1][1] = -vet[0][2]; - dpv12[0][2][1] = vet[0][1]; - dpv12[1][0][1] = vet[0][2]; - dpv12[1][1][1] = 0.0; + dpv12[0][2][1] = vet[0][1]; + dpv12[1][0][1] = vet[0][2]; + dpv12[1][1][1] = 0.0; dpv12[1][2][1] = -vet[0][0]; dpv12[2][0][1] = -vet[0][1]; - dpv12[2][1][1] = vet[0][0]; - dpv12[2][2][1] = 0.0; + dpv12[2][1][1] = vet[0][0]; + dpv12[2][2][1] = 0.0; // derivatives respect to the third neighbor, atom n for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv12[id][ip][2] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv12[id][ip][2] = 0.0; } } - pv31[0] = vet[2][1]*vet[0][2] - vet[0][1]*vet[2][2]; - pv31[1] = vet[2][2]*vet[0][0] - vet[0][2]*vet[2][0]; - pv31[2] = vet[2][0]*vet[0][1] - vet[0][0]*vet[2][1]; + pv31[0] = vet[2][1] * vet[0][2] - vet[0][1] * vet[2][2]; + pv31[1] = vet[2][2] * vet[0][0] - vet[0][2] * vet[2][0]; + pv31[2] = vet[2][0] * vet[0][1] - vet[0][0] * vet[2][1]; // derivatives respect to the first neighbor, atom k - dpv31[0][0][0] = 0.0; + dpv31[0][0][0] = 0.0; dpv31[0][1][0] = -vet[2][2]; - dpv31[0][2][0] = vet[2][1]; - dpv31[1][0][0] = vet[2][2]; - dpv31[1][1][0] = 0.0; + dpv31[0][2][0] = vet[2][1]; + dpv31[1][0][0] = vet[2][2]; + dpv31[1][1][0] = 0.0; dpv31[1][2][0] = -vet[2][0]; dpv31[2][0][0] = -vet[2][1]; - dpv31[2][1][0] = vet[2][0]; - dpv31[2][2][0] = 0.0; + dpv31[2][1][0] = vet[2][0]; + dpv31[2][2][0] = 0.0; // derivatives respect to the third neighbor, atom n - dpv31[0][0][2] = 0.0; - dpv31[0][1][2] = vet[0][2]; + dpv31[0][0][2] = 0.0; + dpv31[0][1][2] = vet[0][2]; dpv31[0][2][2] = -vet[0][1]; dpv31[1][0][2] = -vet[0][2]; - dpv31[1][1][2] = 0.0; - dpv31[1][2][2] = vet[0][0]; - dpv31[2][0][2] = vet[0][1]; + dpv31[1][1][2] = 0.0; + dpv31[1][2][2] = vet[0][0]; + dpv31[2][0][2] = vet[0][1]; dpv31[2][1][2] = -vet[0][0]; - dpv31[2][2][2] = 0.0; + dpv31[2][2][2] = 0.0; // derivatives respect to the second neighbor, atom l for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv31[id][ip][1] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv31[id][ip][1] = 0.0; } } - pv23[0] = vet[1][1]*vet[2][2] - vet[2][1]*vet[1][2]; - pv23[1] = vet[1][2]*vet[2][0] - vet[2][2]*vet[1][0]; - pv23[2] = vet[1][0]*vet[2][1] - vet[2][0]*vet[1][1]; + pv23[0] = vet[1][1] * vet[2][2] - vet[2][1] * vet[1][2]; + pv23[1] = vet[1][2] * vet[2][0] - vet[2][2] * vet[1][0]; + pv23[2] = vet[1][0] * vet[2][1] - vet[2][0] * vet[1][1]; // derivatives respect to the second neighbor, atom k for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv23[id][ip][0] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv23[id][ip][0] = 0.0; } } // derivatives respect to the second neighbor, atom l - dpv23[0][0][1] = 0.0; - dpv23[0][1][1] = vet[2][2]; + dpv23[0][0][1] = 0.0; + dpv23[0][1][1] = vet[2][2]; dpv23[0][2][1] = -vet[2][1]; dpv23[1][0][1] = -vet[2][2]; - dpv23[1][1][1] = 0.0; - dpv23[1][2][1] = vet[2][0]; - dpv23[2][0][1] = vet[2][1]; + dpv23[1][1][1] = 0.0; + dpv23[1][2][1] = vet[2][0]; + dpv23[2][0][1] = vet[2][1]; dpv23[2][1][1] = -vet[2][0]; - dpv23[2][2][1] = 0.0; + dpv23[2][2][1] = 0.0; // derivatives respect to the third neighbor, atom n - dpv23[0][0][2] = 0.0; + dpv23[0][0][2] = 0.0; dpv23[0][1][2] = -vet[1][2]; - dpv23[0][2][2] = vet[1][1]; - dpv23[1][0][2] = vet[1][2]; - dpv23[1][1][2] = 0.0; + dpv23[0][2][2] = vet[1][1]; + dpv23[1][0][2] = vet[1][2]; + dpv23[1][1][2] = 0.0; dpv23[1][2][2] = -vet[1][0]; dpv23[2][0][2] = -vet[1][1]; - dpv23[2][1][2] = vet[1][0]; - dpv23[2][2][2] = 0.0; + dpv23[2][1][2] = vet[1][0]; + dpv23[2][2][2] = 0.0; -//############################################################################################ + //############################################################################################ // average the normal vectors by using the 3 neighboring planes - n1[0] = (pv12[0] + pv31[0] + pv23[0])/cont; - n1[1] = (pv12[1] + pv31[1] + pv23[1])/cont; - n1[2] = (pv12[2] + pv31[2] + pv23[2])/cont; + n1[0] = (pv12[0] + pv31[0] + pv23[0]) / cont; + n1[1] = (pv12[1] + pv31[1] + pv23[1]) / cont; + n1[2] = (pv12[2] + pv31[2] + pv23[2]) / cont; // the magnitude of the normal vector - nn2 = n1[0]*n1[0] + n1[1]*n1[1] + n1[2]*n1[2]; + nn2 = n1[0] * n1[0] + n1[1] * n1[1] + n1[2] * n1[2]; nn = sqrt(nn2); - if (nn == 0) error->one(FLERR,"The magnitude of the normal vector is zero"); + if (nn == 0) error->one(FLERR, "The magnitude of the normal vector is zero"); // the unit normal vector - normal[i][0] = n1[0]/nn; - normal[i][1] = n1[1]/nn; - normal[i][2] = n1[2]/nn; + normal[i][0] = n1[0] / nn; + normal[i][1] = n1[1] / nn; + normal[i][2] = n1[2] / nn; // for the central atoms, dnormdri is always zero for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dnormdri[id][ip][i] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dnormdri[id][ip][i] = 0.0; } } // derivatives of non-normalized normal vector, dn1:3x3x3 array for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { for (m = 0; m < 3; m++) { - dn1[id][ip][m] = (dpv12[id][ip][m] + dpv23[id][ip][m] + dpv31[id][ip][m])/cont; + dn1[id][ip][m] = (dpv12[id][ip][m] + dpv23[id][ip][m] + dpv31[id][ip][m]) / cont; } } } @@ -1000,7 +969,7 @@ void PairILPGrapheneHBN::calc_normal() // r[id][m]: the id's component of atom m for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { - dnn[id][m] = (n1[0]*dn1[0][id][m] + n1[1]*dn1[1][id][m] + n1[2]*dn1[2][id][m])/nn; + dnn[id][m] = (n1[0] * dn1[0][id][m] + n1[1] * dn1[1][id][m] + n1[2] * dn1[2][id][m]) / nn; } } // dnormal[id][ip][m][i]: the derivative of normal[id] respect to r[ip][m], id,ip=0,1,2 @@ -1008,50 +977,51 @@ void PairILPGrapheneHBN::calc_normal() for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - dnormal[id][ip][m][i] = dn1[id][ip][m]/nn - n1[id]*dnn[ip][m]/nn2; + dnormal[id][ip][m][i] = dn1[id][ip][m] / nn - n1[id] * dnn[ip][m] / nn2; } } } - } - else { - error->one(FLERR,"There are too many neighbors for calculating normals"); + } else { + error->one(FLERR, "There are too many neighbors for calculating normals"); } -//############################################################################################## + //############################################################################################## } } /* ---------------------------------------------------------------------- */ double PairILPGrapheneHBN::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, - double /*factor_coul*/, double factor_lj, - double &fforce) + double /*factor_coul*/, double factor_lj, double &fforce) { - double r,r2inv,r6inv,r8inv,forcelj,philj,fpair; - double Tap,dTap,Vilp,TSvdw,TSvdw2inv; + double r, r2inv, r6inv, r8inv, forcelj, philj, fpair; + double Tap, dTap, Vilp, TSvdw, TSvdw2inv; int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); // turn on/off taper function if (tap_flag) { - Tap = calc_Tap(r,sqrt(cutsq[itype][jtype])); - dTap = calc_dTap(r,sqrt(cutsq[itype][jtype])); - } else {Tap = 1.0; dTap = 0.0;} + Tap = calc_Tap(r, sqrt(cutsq[itype][jtype])); + dTap = calc_dTap(r, sqrt(cutsq[itype][jtype])); + } else { + Tap = 1.0; + dTap = 0.0; + } - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - r8inv = r2inv*r6inv; + r2inv = 1.0 / rsq; + r6inv = r2inv * r2inv * r2inv; + r8inv = r2inv * r6inv; - TSvdw = 1.0 + exp(-p.d*(r/p.seff - 1.0)); - TSvdw2inv = pow(TSvdw,-2.0); - Vilp = -p.C6*r6inv/TSvdw; + TSvdw = 1.0 + exp(-p.d * (r / p.seff - 1.0)); + TSvdw2inv = pow(TSvdw, -2.0); + Vilp = -p.C6 * r6inv / TSvdw; // derivatives - fpair = -6.0*p.C6*r8inv/TSvdw + p.d/p.seff*p.C6*(TSvdw - 1.0)*r6inv*TSvdw2inv/r; + fpair = -6.0 * p.C6 * r8inv / TSvdw + p.d / p.seff * p.C6 * (TSvdw - 1.0) * r6inv * TSvdw2inv / r; forcelj = fpair; - fforce = factor_lj*(forcelj*Tap - Vilp*dTap/r); + fforce = factor_lj * (forcelj * Tap - Vilp * dTap / r); - philj = Vilp*Tap; - return factor_lj*philj; + philj = Vilp * Tap; + return factor_lj * philj; } diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.h b/src/INTERLAYER/pair_ilp_graphene_hbn.h index 952d6edb9b..c89ef47a21 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.h +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.h @@ -40,6 +40,8 @@ class PairILPGrapheneHBN : public Pair { void calc_FvdW(int, int); double single(int, int, int, int, double, double, double, double &); + static constexpr int NPARAMS_PER_LINE = 13; + protected: int me; int maxlocal; // size of numneigh, firstneigh arrays @@ -60,7 +62,6 @@ class PairILPGrapheneHBN : public Pair { double cut_global; double cut_normal; - double **cut; double **cutILPsq; // mapping the cutoff from element pairs to parameters double **offset; double **normal; @@ -69,48 +70,6 @@ class PairILPGrapheneHBN : public Pair { void read_file(char *); void allocate(); - - /* ----Calculate the long-range cutoff term */ - inline double calc_Tap(double r_ij, double Rcut) - { - double Tap, r; - double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; - - r = r_ij / Rcut; - if (r >= 1.0) { - Tap = 0.0; - } else { - Tap = Tap_coeff[7] * r + Tap_coeff[6]; - Tap = Tap * r + Tap_coeff[5]; - Tap = Tap * r + Tap_coeff[4]; - Tap = Tap * r + Tap_coeff[3]; - Tap = Tap * r + Tap_coeff[2]; - Tap = Tap * r + Tap_coeff[1]; - Tap = Tap * r + Tap_coeff[0]; - } - return (Tap); - } - - /* ----Calculate the derivatives of long-range cutoff term */ - inline double calc_dTap(double r_ij, double Rcut) - { - double dTap, r; - double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; - - r = r_ij / Rcut; - if (r >= 1.0) { - dTap = 0.0; - } else { - dTap = 7.0 * Tap_coeff[7] * r + 6.0 * Tap_coeff[6]; - dTap = dTap * r + 5.0 * Tap_coeff[5]; - dTap = dTap * r + 4.0 * Tap_coeff[4]; - dTap = dTap * r + 3.0 * Tap_coeff[3]; - dTap = dTap * r + 2.0 * Tap_coeff[2]; - dTap = dTap * r + Tap_coeff[1]; - dTap = dTap / Rcut; - } - return (dTap); - } }; } // namespace LAMMPS_NS diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp index bd5050401e..e8db858218 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp +++ b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -28,30 +27,34 @@ #include "comm.h" #include "error.h" #include "force.h" +#include "interlayer_taper.h" #include "memory.h" #include "my_page.h" #include "neigh_list.h" #include "neigh_request.h" #include "neighbor.h" +#include "potential_file_reader.h" +#include "tokenizer.h" #include #include using namespace LAMMPS_NS; +using namespace InterLayer; #define MAXLINE 1024 #define DELTA 4 #define PGDELTA 1 static const char cite_kc[] = - "@Article{Ouyang2018\n" - " author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod},\n" - " title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials},\n" - " journal = {Nano Letters},\n" - " volume = 18,\n" - " pages = {6009}\n" - " year = 2018,\n" - "}\n\n"; + "@Article{Ouyang2018\n" + " author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod},\n" + " title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials},\n" + " journal = {Nano Letters},\n" + " volume = 18,\n" + " pages = {6009}\n" + " year = 2018,\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ @@ -59,6 +62,9 @@ PairKolmogorovCrespiFull::PairKolmogorovCrespiFull(LAMMPS *lmp) : Pair(lmp) { restartinfo = 0; one_coeff = 1; + manybody_flag = 1; + centroidstressflag = CENTROID_NOTAVAIL; + unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); if (lmp->citeme) lmp->citeme->add(cite_kc); @@ -83,7 +89,7 @@ PairKolmogorovCrespiFull::PairKolmogorovCrespiFull(LAMMPS *lmp) : Pair(lmp) // always compute energy offset offset_flag = 1; - // turn on the taper function + // turn off the taper function by default tap_flag = 0; } @@ -93,8 +99,8 @@ PairKolmogorovCrespiFull::~PairKolmogorovCrespiFull() { memory->destroy(KC_numneigh); memory->sfree(KC_firstneigh); - delete [] ipage; - delete [] pvector; + delete[] ipage; + delete[] pvector; memory->destroy(normal); memory->destroy(dnormal); memory->destroy(dnormdri); @@ -102,7 +108,6 @@ PairKolmogorovCrespiFull::~PairKolmogorovCrespiFull() if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); memory->destroy(offset); } @@ -118,17 +123,15 @@ PairKolmogorovCrespiFull::~PairKolmogorovCrespiFull() void PairKolmogorovCrespiFull::allocate() { allocated = 1; - int n = atom->ntypes; + int n = atom->ntypes + 1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; + memory->create(setflag, n, n, "pair:setflag"); + for (int i = 1; i < n; i++) + for (int j = i; j < n; j++) setflag[i][j] = 0; - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(offset,n+1,n+1,"pair:offset"); - map = new int[atom->ntypes+1]; + memory->create(cutsq, n, n, "pair:cutsq"); + memory->create(offset, n, n, "pair:offset"); + map = new int[n]; } /* ---------------------------------------------------------------------- @@ -137,21 +140,12 @@ void PairKolmogorovCrespiFull::allocate() void PairKolmogorovCrespiFull::settings(int narg, char **arg) { - if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command"); - if (strcmp(force->pair_style,"hybrid/overlay")!=0) - error->all(FLERR,"ERROR: requires hybrid/overlay pair_style"); + if (narg < 1 || narg > 2) error->all(FLERR, "Illegal pair_style command"); + if (strcmp(force->pair_style, "hybrid/overlay") != 0) + error->all(FLERR, "ERROR: requires hybrid/overlay pair_style"); - cut_global = utils::numeric(FLERR,arg[0],false,lmp); - if (narg == 2) tap_flag = utils::numeric(FLERR,arg[1],false,lmp); - - // reset cutoffs that have been explicitly set - - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; - } + cut_global = utils::numeric(FLERR, arg[0], false, lmp); + if (narg == 2) tap_flag = utils::numeric(FLERR, arg[1], false, lmp); } /* ---------------------------------------------------------------------- @@ -161,29 +155,28 @@ void PairKolmogorovCrespiFull::settings(int narg, char **arg) void PairKolmogorovCrespiFull::coeff(int narg, char **arg) { if (!allocated) allocate(); - map_element2type(narg-3,arg+3); + map_element2type(narg - 3, arg + 3); read_file(arg[2]); } - /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairKolmogorovCrespiFull::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - if (!offset_flag) - error->all(FLERR,"Must use 'pair_modify shift yes' with this pair style"); + if (setflag[i][j] == 0) error->all(FLERR, "All pair coeffs are not set"); + if (!offset_flag) error->all(FLERR, "Must use 'pair_modify shift yes' with this pair style"); - if (offset_flag && (cut[i][j] > 0.0)) { + if (offset_flag && (cut_global > 0.0)) { int iparam_ij = elem2param[map[i]][map[j]]; - Param& p = params[iparam_ij]; - offset[i][j] = -p.A*pow(p.z0/cut[i][j],6); - } else offset[i][j] = 0.0; + Param &p = params[iparam_ij]; + offset[i][j] = -p.A * pow(p.z0 / cut_global, 6); + } else + offset[i][j] = 0.0; offset[j][i] = offset[i][j]; - return cut[i][j]; + return cut_global; } /* ---------------------------------------------------------------------- @@ -192,147 +185,119 @@ double PairKolmogorovCrespiFull::init_one(int i, int j) void PairKolmogorovCrespiFull::read_file(char *filename) { - int params_per_line = 12; - char **words = new char*[params_per_line+1]; memory->sfree(params); params = nullptr; nparams = maxparam = 0; // open file on proc 0 - FILE *fp; if (comm->me == 0) { - fp = utils::open_potential(filename,lmp,nullptr); - if (fp == nullptr) - error->one(FLERR,"Cannot open KC potential file {}: {}",filename,utils::getsyserror()); - } + PotentialFileReader reader(lmp, filename, "kolmogorov/crespi/full", unit_convert_flag); + char *line; - // read each line out of file, skipping blank lines or leading '#' - // store line of params if all 3 element tags are in element list + // transparently convert units for supported conversions - int i,j,n,m,nwords,ielement,jelement; - char line[MAXLINE],*ptr; - int eof = 0; + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, unit_convert); - while (1) { - if (comm->me == 0) { - ptr = fgets(line,MAXLINE,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; - } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + while ((line = reader.next_line(NPARAMS_PER_LINE))) { - // strip comment, skip line if blank + try { + ValueTokenizer values(line); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); - if (nwords == 0) continue; + std::string iname = values.next_string(); + std::string jname = values.next_string(); - // concatenate additional lines until have params_per_line words + // ielement,jelement = 1st args + // if both args are in element list, then parse this line + // else skip to next entry in file + int ielement, jelement; - while (nwords < params_per_line) { - n = strlen(line); - if (comm->me == 0) { - ptr = fgets(&line[n],MAXLINE-n,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; + for (ielement = 0; ielement < nelements; ielement++) + if (iname == elements[ielement]) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (jname == elements[jelement]) break; + if (jelement == nelements) continue; + + // expand storage, if needed + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); + + // make certain all addional allocated storage is initialized + // to avoid false positives when checking with valgrind + + memset(params + nparams, 0, DELTA * sizeof(Param)); + } + + // load up parameter settings and error check their values + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].z0 = values.next_double(); + params[nparams].C0 = values.next_double(); + params[nparams].C2 = values.next_double(); + params[nparams].C4 = values.next_double(); + params[nparams].C = values.next_double(); + params[nparams].delta = values.next_double(); + params[nparams].lambda = values.next_double(); + params[nparams].A = values.next_double(); + // S provides a convenient scaling of all energies + params[nparams].S = values.next_double(); + params[nparams].rcut = values.next_double(); + + } catch (TokenizerException &e) { + error->one(FLERR, e.what()); } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); + + // energies in meV further scaled by S + + double meV = 1.0e-3 * params[nparams].S; + if (unit_convert) meV *= conversion_factor; + + params[nparams].C *= meV; + params[nparams].A *= meV; + params[nparams].C0 *= meV; + params[nparams].C2 *= meV; + params[nparams].C4 *= meV; + + // precompute some quantities + params[nparams].delta2inv = pow(params[nparams].delta, -2); + params[nparams].z06 = pow(params[nparams].z0, 6); + + nparams++; } - if (nwords != params_per_line) - error->all(FLERR,"Insufficient format in KC potential file"); + MPI_Bcast(&nparams, 1, MPI_INT, 0, world); + MPI_Bcast(&maxparam, 1, MPI_INT, 0, world); - // words = ptrs to all words in line - - nwords = 0; - words[nwords++] = strtok(line," \t\n\r\f"); - while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; - - // ielement,jelement = 1st args - // if these 2 args are in element list, then parse this line - // else skip to next line (continue) - - for (ielement = 0; ielement < nelements; ielement++) - if (strcmp(words[0],elements[ielement]) == 0) break; - if (ielement == nelements) continue; - for (jelement = 0; jelement < nelements; jelement++) - if (strcmp(words[1],elements[jelement]) == 0) break; - if (jelement == nelements) continue; - - // load up parameter settings and error check their values - - if (nparams == maxparam) { - maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), - "pair:params"); - - // make certain all addional allocated storage is initialized - // to avoid false positives when checking with valgrind - - memset(params + nparams, 0, DELTA*sizeof(Param)); + if (comm->me != 0) { + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); } - params[nparams].ielement = ielement; - params[nparams].jelement = jelement; - params[nparams].z0 = atof(words[2]); - params[nparams].C0 = atof(words[3]); - params[nparams].C2 = atof(words[4]); - params[nparams].C4 = atof(words[5]); - params[nparams].C = atof(words[6]); - params[nparams].delta = atof(words[7]); - params[nparams].lambda = atof(words[8]); - params[nparams].A = atof(words[9]); - // S provides a convenient scaling of all energies - params[nparams].S = atof(words[10]); - params[nparams].rcut = atof(words[11]); - - // energies in meV further scaled by S - double meV = 1.0e-3*params[nparams].S; - params[nparams].C *= meV; - params[nparams].A *= meV; - params[nparams].C0 *= meV; - params[nparams].C2 *= meV; - params[nparams].C4 *= meV; - - // precompute some quantities - params[nparams].delta2inv = pow(params[nparams].delta,-2); - params[nparams].z06 = pow(params[nparams].z0,6); - - nparams++; - //if(nparams >= pow(atom->ntypes,3)) break; + MPI_Bcast(params, maxparam * sizeof(Param), MPI_BYTE, 0, world); } + memory->destroy(elem2param); memory->destroy(cutKCsq); - memory->create(elem2param,nelements,nelements,"pair:elem2param"); - memory->create(cutKCsq,nelements,nelements,"pair:cutKCsq"); - for (i = 0; i < nelements; i++) { - for (j = 0; j < nelements; j++) { - n = -1; - for (m = 0; m < nparams; m++) { + memory->create(elem2param, nelements, nelements, "pair:elem2param"); + memory->create(cutKCsq, nelements, nelements, "pair:cutKCsq"); + for (int i = 0; i < nelements; i++) { + for (int j = 0; j < nelements; j++) { + int n = -1; + for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR, "KC Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR, "Potential file is missing an entry"); elem2param[i][j] = n; - cutKCsq[i][j] = params[n].rcut*params[n].rcut; + cutKCsq[i][j] = params[n].rcut * params[n].rcut; } } - delete [] words; } /* ---------------------------------------------------------------------- @@ -342,13 +307,13 @@ void PairKolmogorovCrespiFull::read_file(char *filename) void PairKolmogorovCrespiFull::init_style() { if (force->newton_pair == 0) - error->all(FLERR,"Pair style kolmolgorov/crespi/full requires newton pair on"); + error->all(FLERR, "Pair style kolmolgorov/crespi/full requires newton pair on"); if (!atom->molecule_flag) - error->all(FLERR,"Pair style kolmolgorov/crespi/full requires atom attribute molecule"); + error->all(FLERR, "Pair style kolmolgorov/crespi/full requires atom attribute molecule"); // need a full neighbor list, including neighbors of ghosts - int irequest = neighbor->request(this,instance_me); + int irequest = neighbor->request(this, instance_me); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->ghost = 1; @@ -362,14 +327,13 @@ void PairKolmogorovCrespiFull::init_style() if (oneatom != neighbor->oneatom) create = 1; if (create) { - delete [] ipage; + delete[] ipage; pgsize = neighbor->pgsize; oneatom = neighbor->oneatom; - int nmypage= comm->nthreads; + int nmypage = comm->nthreads; ipage = new MyPage[nmypage]; - for (int i = 0; i < nmypage; i++) - ipage[i].init(oneatom,pgsize,PGDELTA); + for (int i = 0; i < nmypage; i++) ipage[i].init(oneatom, pgsize, PGDELTA); } } @@ -377,7 +341,7 @@ void PairKolmogorovCrespiFull::init_style() void PairKolmogorovCrespiFull::compute(int eflag, int vflag) { - ev_init(eflag,vflag); + ev_init(eflag, vflag); pvector[0] = pvector[1] = 0.0; // Build full neighbor list @@ -385,9 +349,9 @@ void PairKolmogorovCrespiFull::compute(int eflag, int vflag) // Calculate the normals and its derivatives calc_normal(); // Calculate the van der Waals force and energy - calc_FvdW(eflag,vflag); + calc_FvdW(eflag, vflag); // Calculate the repulsive force and energy - calc_FRep(eflag,vflag); + calc_FRep(eflag, vflag); if (vflag_fdotr) virial_fdotr_compute(); } @@ -398,11 +362,11 @@ void PairKolmogorovCrespiFull::compute(int eflag, int vflag) void PairKolmogorovCrespiFull::calc_FvdW(int eflag, int /* vflag */) { - int i,j,ii,jj,inum,jnum,itype,jtype; - tagint itag,jtag; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; - double rsq,r,Rcut,r2inv,r6inv,r8inv,Tap,dTap,Vkc,fsum; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itype, jtype; + tagint itag, jtag; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair; + double rsq, r, Rcut, r2inv, r6inv, r8inv, Tap, dTap, Vkc, fsum; + int *ilist, *jlist, *numneigh, **firstneigh; evdwl = 0.0; double **x = atom->x; @@ -436,9 +400,9 @@ void PairKolmogorovCrespiFull::calc_FvdW(int eflag, int /* vflag */) // two-body interactions from full neighbor list, skip half of them if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; + if ((itag + jtag) % 2 == 0) continue; } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; + if ((itag + jtag) % 2 == 1) continue; } else { if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; @@ -448,41 +412,43 @@ void PairKolmogorovCrespiFull::calc_FvdW(int eflag, int /* vflag */) delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; // only include the interaction between different layers if (rsq < cutsq[itype][jtype] && atom->molecule[i] != atom->molecule[j]) { int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - r8inv = r6inv*r2inv; + r2inv = 1.0 / rsq; + r6inv = r2inv * r2inv * r2inv; + r8inv = r6inv * r2inv; // turn on/off taper function if (tap_flag) { Rcut = sqrt(cutsq[itype][jtype]); - Tap = calc_Tap(r,Rcut); - dTap = calc_dTap(r,Rcut); - } else {Tap = 1.0; dTap = 0.0;} + Tap = calc_Tap(r, Rcut); + dTap = calc_dTap(r, Rcut); + } else { + Tap = 1.0; + dTap = 0.0; + } - Vkc = -p.A*p.z06*r6inv; + Vkc = -p.A * p.z06 * r6inv; // derivatives - fpair = -6.0*p.A*p.z06*r8inv; - fsum = fpair*Tap - Vkc*dTap/r; + fpair = -6.0 * p.A * p.z06 * r8inv; + fsum = fpair * Tap - Vkc * dTap / r; - f[i][0] += fsum*delx; - f[i][1] += fsum*dely; - f[i][2] += fsum*delz; - f[j][0] -= fsum*delx; - f[j][1] -= fsum*dely; - f[j][2] -= fsum*delz; + f[i][0] += fsum * delx; + f[i][1] += fsum * dely; + f[i][2] += fsum * delz; + f[j][0] -= fsum * delx; + f[j][1] -= fsum * dely; + f[j][2] -= fsum * delz; - if (eflag) pvector[0] += evdwl = Vkc*Tap; - if (evflag) ev_tally(i,j,nlocal,newton_pair, - evdwl,0.0,fsum,delx,dely,delz); + if (eflag) pvector[0] += evdwl = Vkc * Tap; + if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, fsum, delx, dely, delz); } } } @@ -494,12 +460,12 @@ void PairKolmogorovCrespiFull::calc_FvdW(int eflag, int /* vflag */) void PairKolmogorovCrespiFull::calc_FRep(int eflag, int /* vflag */) { - int i,j,ii,jj,inum,jnum,itype,jtype,k,kk; - double prodnorm1,fkcx,fkcy,fkcz; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,fpair1; - double rsq,r,rhosq1,exp0,exp1,Tap,dTap,Vkc; - double frho_ij,sumC1,sumC11,sumCff,fsum,rho_ij; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itype, jtype, k, kk; + double prodnorm1, fkcx, fkcy, fkcz; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair, fpair1; + double rsq, r, rhosq1, exp0, exp1, Tap, dTap, Vkc; + double frho_ij, sumC1, sumC11, sumCff, fsum, rho_ij; + int *ilist, *jlist, *numneigh, **firstneigh; int *KC_neighs_i; evdwl = 0.0; @@ -539,58 +505,64 @@ void PairKolmogorovCrespiFull::calc_FRep(int eflag, int /* vflag */) delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; // only include the interaction between different layers if (rsq < cutsq[itype][jtype] && atom->molecule[i] != atom->molecule[j]) { int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); // turn on/off taper function if (tap_flag) { - Tap = calc_Tap(r,sqrt(cutsq[itype][jtype])); - dTap = calc_dTap(r,sqrt(cutsq[itype][jtype])); - } else {Tap = 1.0; dTap = 0.0;} + Tap = calc_Tap(r, sqrt(cutsq[itype][jtype])); + dTap = calc_dTap(r, sqrt(cutsq[itype][jtype])); + } else { + Tap = 1.0; + dTap = 0.0; + } // Calculate the transverse distance - prodnorm1 = normal[i][0]*delx + normal[i][1]*dely + normal[i][2]*delz; - rhosq1 = rsq - prodnorm1*prodnorm1; // rho_ij - rho_ij = rhosq1*p.delta2inv; // (rho_ij/delta)^2 + prodnorm1 = normal[i][0] * delx + normal[i][1] * dely + normal[i][2] * delz; + rhosq1 = rsq - prodnorm1 * prodnorm1; // rho_ij + rho_ij = rhosq1 * p.delta2inv; // (rho_ij/delta)^2 // store exponents - exp0 = exp(-p.lambda*(r-p.z0)); + exp0 = exp(-p.lambda * (r - p.z0)); exp1 = exp(-rho_ij); - sumC1 = p.C0 + p.C2*rho_ij + p.C4*rho_ij*rho_ij; - sumC11 = (p.C2 + 2.0*p.C4*rho_ij)*p.delta2inv; - frho_ij = exp1*sumC1; - sumCff = 0.5*p.C + frho_ij; - Vkc = exp0*sumCff; + sumC1 = p.C0 + p.C2 * rho_ij + p.C4 * rho_ij * rho_ij; + sumC11 = (p.C2 + 2.0 * p.C4 * rho_ij) * p.delta2inv; + frho_ij = exp1 * sumC1; + sumCff = 0.5 * p.C + frho_ij; + Vkc = exp0 * sumCff; // derivatives - fpair = p.lambda*exp0/r*sumCff; - fpair1 = 2.0*exp0*exp1*(p.delta2inv*sumC1 - sumC11); + fpair = p.lambda * exp0 / r * sumCff; + fpair1 = 2.0 * exp0 * exp1 * (p.delta2inv * sumC1 - sumC11); fsum = fpair + fpair1; // derivatives of the product of rij and ni, the result is a vector - dprodnorm1[0] = dnormdri[0][0][i]*delx + dnormdri[1][0][i]*dely + dnormdri[2][0][i]*delz; - dprodnorm1[1] = dnormdri[0][1][i]*delx + dnormdri[1][1][i]*dely + dnormdri[2][1][i]*delz; - dprodnorm1[2] = dnormdri[0][2][i]*delx + dnormdri[1][2][i]*dely + dnormdri[2][2][i]*delz; - fp1[0] = prodnorm1*normal[i][0]*fpair1; - fp1[1] = prodnorm1*normal[i][1]*fpair1; - fp1[2] = prodnorm1*normal[i][2]*fpair1; - fprod1[0] = prodnorm1*dprodnorm1[0]*fpair1; - fprod1[1] = prodnorm1*dprodnorm1[1]*fpair1; - fprod1[2] = prodnorm1*dprodnorm1[2]*fpair1; - fkcx = (delx*fsum - fp1[0])*Tap - Vkc*dTap*delx/r; - fkcy = (dely*fsum - fp1[1])*Tap - Vkc*dTap*dely/r; - fkcz = (delz*fsum - fp1[2])*Tap - Vkc*dTap*delz/r; + dprodnorm1[0] = + dnormdri[0][0][i] * delx + dnormdri[1][0][i] * dely + dnormdri[2][0][i] * delz; + dprodnorm1[1] = + dnormdri[0][1][i] * delx + dnormdri[1][1][i] * dely + dnormdri[2][1][i] * delz; + dprodnorm1[2] = + dnormdri[0][2][i] * delx + dnormdri[1][2][i] * dely + dnormdri[2][2][i] * delz; + fp1[0] = prodnorm1 * normal[i][0] * fpair1; + fp1[1] = prodnorm1 * normal[i][1] * fpair1; + fp1[2] = prodnorm1 * normal[i][2] * fpair1; + fprod1[0] = prodnorm1 * dprodnorm1[0] * fpair1; + fprod1[1] = prodnorm1 * dprodnorm1[1] * fpair1; + fprod1[2] = prodnorm1 * dprodnorm1[2] * fpair1; + fkcx = (delx * fsum - fp1[0]) * Tap - Vkc * dTap * delx / r; + fkcy = (dely * fsum - fp1[1]) * Tap - Vkc * dTap * dely / r; + fkcz = (delz * fsum - fp1[2]) * Tap - Vkc * dTap * delz / r; - f[i][0] += fkcx - fprod1[0]*Tap; - f[i][1] += fkcy - fprod1[1]*Tap; - f[i][2] += fkcz - fprod1[2]*Tap; + f[i][0] += fkcx - fprod1[0] * Tap; + f[i][1] += fkcy - fprod1[1] * Tap; + f[i][2] += fkcz - fprod1[2] * Tap; f[j][0] -= fkcx; f[j][1] -= fkcy; f[j][2] -= fkcz; @@ -601,29 +573,37 @@ void PairKolmogorovCrespiFull::calc_FRep(int eflag, int /* vflag */) k = KC_neighs_i[kk]; if (k == i) continue; // derivatives of the product of rij and ni respect to rk, k=0,1,2, where atom k is the neighbors of atom i - dprodnorm1[0] = dnormal[0][0][kk][i]*delx + dnormal[1][0][kk][i]*dely + dnormal[2][0][kk][i]*delz; - dprodnorm1[1] = dnormal[0][1][kk][i]*delx + dnormal[1][1][kk][i]*dely + dnormal[2][1][kk][i]*delz; - dprodnorm1[2] = dnormal[0][2][kk][i]*delx + dnormal[1][2][kk][i]*dely + dnormal[2][2][kk][i]*delz; - fk[0] = (-prodnorm1*dprodnorm1[0]*fpair1)*Tap; - fk[1] = (-prodnorm1*dprodnorm1[1]*fpair1)*Tap; - fk[2] = (-prodnorm1*dprodnorm1[2]*fpair1)*Tap; + dprodnorm1[0] = dnormal[0][0][kk][i] * delx + dnormal[1][0][kk][i] * dely + + dnormal[2][0][kk][i] * delz; + dprodnorm1[1] = dnormal[0][1][kk][i] * delx + dnormal[1][1][kk][i] * dely + + dnormal[2][1][kk][i] * delz; + dprodnorm1[2] = dnormal[0][2][kk][i] * delx + dnormal[1][2][kk][i] * dely + + dnormal[2][2][kk][i] * delz; + fk[0] = (-prodnorm1 * dprodnorm1[0] * fpair1) * Tap; + fk[1] = (-prodnorm1 * dprodnorm1[1] * fpair1) * Tap; + fk[2] = (-prodnorm1 * dprodnorm1[2] * fpair1) * Tap; f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2]; delkj[0] = x[k][0] - x[j][0]; delkj[1] = x[k][1] - x[j][1]; delkj[2] = x[k][2] - x[j][2]; - if (evflag) ev_tally_xyz(k,j,nlocal,newton_pair,0.0,0.0,fk[0],fk[1],fk[2],delkj[0],delkj[1],delkj[2]); + if (evflag) + ev_tally_xyz(k, j, nlocal, newton_pair, 0.0, 0.0, fk[0], fk[1], fk[2], delkj[0], + delkj[1], delkj[2]); } if (eflag) { - if (tap_flag) pvector[1] += evdwl = Tap*Vkc; - else pvector[1] += evdwl = Vkc - offset[itype][jtype]; + if (tap_flag) + pvector[1] += evdwl = Tap * Vkc; + else + pvector[1] += evdwl = Vkc - offset[itype][jtype]; } - if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,evdwl,0.0,fkcx,fkcy,fkcz,delx,dely,delz); + if (evflag) + ev_tally_xyz(i, j, nlocal, newton_pair, evdwl, 0.0, fkcx, fkcy, fkcz, delx, dely, delz); } - } // loop over jj - } // loop over ii + } // loop over jj + } // loop over ii } /* ---------------------------------------------------------------------- @@ -632,9 +612,9 @@ void PairKolmogorovCrespiFull::calc_FRep(int eflag, int /* vflag */) void PairKolmogorovCrespiFull::KC_neigh() { - int i,j,ii,jj,n,allnum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, n, allnum, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + int *ilist, *jlist, *numneigh, **firstneigh; int *neighptr; double **x = atom->x; @@ -644,9 +624,9 @@ void PairKolmogorovCrespiFull::KC_neigh() maxlocal = atom->nmax; memory->destroy(KC_numneigh); memory->sfree(KC_firstneigh); - memory->create(KC_numneigh,maxlocal,"KolmogorovCrespiFull:numneigh"); - KC_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *), - "KolmogorovCrespiFull:firstneigh"); + memory->create(KC_numneigh, maxlocal, "KolmogorovCrespiFull:numneigh"); + KC_firstneigh = + (int **) memory->smalloc(maxlocal * sizeof(int *), "KolmogorovCrespiFull:firstneigh"); } allnum = list->inum + list->gnum; @@ -679,7 +659,7 @@ void PairKolmogorovCrespiFull::KC_neigh() delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; if (rsq != 0 && rsq < cutKCsq[itype][jtype] && atom->molecule[i] == atom->molecule[j]) { neighptr[n++] = j; @@ -688,11 +668,12 @@ void PairKolmogorovCrespiFull::KC_neigh() KC_firstneigh[i] = neighptr; KC_numneigh[i] = n; - if (n > 3) error->one(FLERR,"There are too many neighbors for some atoms, please check your configuration"); + if (n > 3) + error->one(FLERR, + "There are too many neighbors for some atoms, please check your configuration"); ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (ipage->status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one"); } } @@ -701,12 +682,12 @@ void PairKolmogorovCrespiFull::KC_neigh() ------------------------------------------------------------------------- */ void PairKolmogorovCrespiFull::calc_normal() { - int i,j,ii,jj,inum,jnum; - int cont,id,ip,m; - double nn,xtp,ytp,ztp,delx,dely,delz,nn2; - int *ilist,*jlist; - double pv12[3],pv31[3],pv23[3],n1[3],dni[3],dnn[3][3],vet[3][3],dpvdri[3][3]; - double dn1[3][3][3],dpv12[3][3][3],dpv23[3][3][3],dpv31[3][3][3]; + int i, j, ii, jj, inum, jnum; + int cont, id, ip, m; + double nn, xtp, ytp, ztp, delx, dely, delz, nn2; + int *ilist, *jlist; + double pv12[3], pv31[3], pv23[3], n1[3], dni[3], dnn[3][3], vet[3][3], dpvdri[3][3]; + double dn1[3][3][3], dpv12[3][3][3], dpv23[3][3][3], dpv31[3][3][3]; double **x = atom->x; @@ -717,9 +698,9 @@ void PairKolmogorovCrespiFull::calc_normal() memory->destroy(dnormal); memory->destroy(dnormdri); nmax = atom->nmax; - memory->create(normal,nmax,3,"KolmogorovCrespiFull:normal"); - memory->create(dnormdri,3,3,nmax,"KolmogorovCrespiFull:dnormdri"); - memory->create(dnormal,3,3,3,nmax,"KolmogorovCrespiFull:dnormal"); + memory->create(normal, nmax, 3, "KolmogorovCrespiFull:normal"); + memory->create(dnormdri, 3, 3, nmax, "KolmogorovCrespiFull:dnormdri"); + memory->create(dnormal, 3, 3, 3, nmax, "KolmogorovCrespiFull:dnormal"); } inum = list->inum; @@ -779,84 +760,77 @@ void PairKolmogorovCrespiFull::calc_normal() for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { dnormdri[id][ip][i] = 0.0; - for (m = 0; m < 3; m++) { - dnormal[id][ip][m][i] = 0.0; - } + for (m = 0; m < 3; m++) { dnormal[id][ip][m][i] = 0.0; } } } - } - else if (cont == 2) { + } else if (cont == 2) { // for the atoms at the edge who has only two neighbor atoms - pv12[0] = vet[0][1]*vet[1][2] - vet[1][1]*vet[0][2]; - pv12[1] = vet[0][2]*vet[1][0] - vet[1][2]*vet[0][0]; - pv12[2] = vet[0][0]*vet[1][1] - vet[1][0]*vet[0][1]; + pv12[0] = vet[0][1] * vet[1][2] - vet[1][1] * vet[0][2]; + pv12[1] = vet[0][2] * vet[1][0] - vet[1][2] * vet[0][0]; + pv12[2] = vet[0][0] * vet[1][1] - vet[1][0] * vet[0][1]; dpvdri[0][0] = 0.0; - dpvdri[0][1] = vet[0][2]-vet[1][2]; - dpvdri[0][2] = vet[1][1]-vet[0][1]; - dpvdri[1][0] = vet[1][2]-vet[0][2]; + dpvdri[0][1] = vet[0][2] - vet[1][2]; + dpvdri[0][2] = vet[1][1] - vet[0][1]; + dpvdri[1][0] = vet[1][2] - vet[0][2]; dpvdri[1][1] = 0.0; - dpvdri[1][2] = vet[0][0]-vet[1][0]; - dpvdri[2][0] = vet[0][1]-vet[1][1]; - dpvdri[2][1] = vet[1][0]-vet[0][0]; + dpvdri[1][2] = vet[0][0] - vet[1][0]; + dpvdri[2][0] = vet[0][1] - vet[1][1]; + dpvdri[2][1] = vet[1][0] - vet[0][0]; dpvdri[2][2] = 0.0; // derivatives respect to the first neighbor, atom k - dpv12[0][0][0] = 0.0; - dpv12[0][1][0] = vet[1][2]; + dpv12[0][0][0] = 0.0; + dpv12[0][1][0] = vet[1][2]; dpv12[0][2][0] = -vet[1][1]; dpv12[1][0][0] = -vet[1][2]; - dpv12[1][1][0] = 0.0; - dpv12[1][2][0] = vet[1][0]; - dpv12[2][0][0] = vet[1][1]; + dpv12[1][1][0] = 0.0; + dpv12[1][2][0] = vet[1][0]; + dpv12[2][0][0] = vet[1][1]; dpv12[2][1][0] = -vet[1][0]; - dpv12[2][2][0] = 0.0; + dpv12[2][2][0] = 0.0; // derivatives respect to the second neighbor, atom l - dpv12[0][0][1] = 0.0; + dpv12[0][0][1] = 0.0; dpv12[0][1][1] = -vet[0][2]; - dpv12[0][2][1] = vet[0][1]; - dpv12[1][0][1] = vet[0][2]; - dpv12[1][1][1] = 0.0; + dpv12[0][2][1] = vet[0][1]; + dpv12[1][0][1] = vet[0][2]; + dpv12[1][1][1] = 0.0; dpv12[1][2][1] = -vet[0][0]; dpv12[2][0][1] = -vet[0][1]; - dpv12[2][1][1] = vet[0][0]; - dpv12[2][2][1] = 0.0; + dpv12[2][1][1] = vet[0][0]; + dpv12[2][2][1] = 0.0; // derivatives respect to the third neighbor, atom n for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv12[id][ip][2] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv12[id][ip][2] = 0.0; } } n1[0] = pv12[0]; n1[1] = pv12[1]; n1[2] = pv12[2]; // the magnitude of the normal vector - nn2 = n1[0]*n1[0] + n1[1]*n1[1] + n1[2]*n1[2]; + nn2 = n1[0] * n1[0] + n1[1] * n1[1] + n1[2] * n1[2]; nn = sqrt(nn2); - if (nn == 0) error->one(FLERR,"The magnitude of the normal vector is zero"); + if (nn == 0) error->one(FLERR, "The magnitude of the normal vector is zero"); // the unit normal vector - normal[i][0] = n1[0]/nn; - normal[i][1] = n1[1]/nn; - normal[i][2] = n1[2]/nn; + normal[i][0] = n1[0] / nn; + normal[i][1] = n1[1] / nn; + normal[i][2] = n1[2] / nn; // derivatives of nn, dnn:3x1 vector - dni[0] = (n1[0]*dpvdri[0][0] + n1[1]*dpvdri[1][0] + n1[2]*dpvdri[2][0])/nn; - dni[1] = (n1[0]*dpvdri[0][1] + n1[1]*dpvdri[1][1] + n1[2]*dpvdri[2][1])/nn; - dni[2] = (n1[0]*dpvdri[0][2] + n1[1]*dpvdri[1][2] + n1[2]*dpvdri[2][2])/nn; + dni[0] = (n1[0] * dpvdri[0][0] + n1[1] * dpvdri[1][0] + n1[2] * dpvdri[2][0]) / nn; + dni[1] = (n1[0] * dpvdri[0][1] + n1[1] * dpvdri[1][1] + n1[2] * dpvdri[2][1]) / nn; + dni[2] = (n1[0] * dpvdri[0][2] + n1[1] * dpvdri[1][2] + n1[2] * dpvdri[2][2]) / nn; // derivatives of unit vector ni respect to ri, the result is 3x3 matrix for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - dnormdri[id][ip][i] = dpvdri[id][ip]/nn - n1[id]*dni[ip]/nn2; + dnormdri[id][ip][i] = dpvdri[id][ip] / nn - n1[id] * dni[ip] / nn2; } } // derivatives of non-normalized normal vector, dn1:3x3x3 array for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - for (m = 0; m < 3; m++) { - dn1[id][ip][m] = dpv12[id][ip][m]; - } + for (m = 0; m < 3; m++) { dn1[id][ip][m] = dpv12[id][ip][m]; } } } // derivatives of nn, dnn:3x3 vector @@ -864,7 +838,7 @@ void PairKolmogorovCrespiFull::calc_normal() // r[id][m]: the id's component of atom m for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { - dnn[id][m] = (n1[0]*dn1[0][id][m] + n1[1]*dn1[1][id][m] + n1[2]*dn1[2][id][m])/nn; + dnn[id][m] = (n1[0] * dn1[0][id][m] + n1[1] * dn1[1][id][m] + n1[2] * dn1[2][id][m]) / nn; } } // dnormal[id][ip][m][i]: the derivative of normal[id] respect to r[ip][m], id,ip=0,1,2 @@ -872,135 +846,127 @@ void PairKolmogorovCrespiFull::calc_normal() for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - dnormal[id][ip][m][i] = dn1[id][ip][m]/nn - n1[id]*dnn[ip][m]/nn2; + dnormal[id][ip][m][i] = dn1[id][ip][m] / nn - n1[id] * dnn[ip][m] / nn2; } } } } -//############################################################################################## + //############################################################################################## else if (cont == 3) { // for the atoms at the edge who has only two neighbor atoms - pv12[0] = vet[0][1]*vet[1][2] - vet[1][1]*vet[0][2]; - pv12[1] = vet[0][2]*vet[1][0] - vet[1][2]*vet[0][0]; - pv12[2] = vet[0][0]*vet[1][1] - vet[1][0]*vet[0][1]; + pv12[0] = vet[0][1] * vet[1][2] - vet[1][1] * vet[0][2]; + pv12[1] = vet[0][2] * vet[1][0] - vet[1][2] * vet[0][0]; + pv12[2] = vet[0][0] * vet[1][1] - vet[1][0] * vet[0][1]; // derivatives respect to the first neighbor, atom k - dpv12[0][0][0] = 0.0; - dpv12[0][1][0] = vet[1][2]; + dpv12[0][0][0] = 0.0; + dpv12[0][1][0] = vet[1][2]; dpv12[0][2][0] = -vet[1][1]; dpv12[1][0][0] = -vet[1][2]; - dpv12[1][1][0] = 0.0; - dpv12[1][2][0] = vet[1][0]; - dpv12[2][0][0] = vet[1][1]; + dpv12[1][1][0] = 0.0; + dpv12[1][2][0] = vet[1][0]; + dpv12[2][0][0] = vet[1][1]; dpv12[2][1][0] = -vet[1][0]; - dpv12[2][2][0] = 0.0; + dpv12[2][2][0] = 0.0; // derivatives respect to the second neighbor, atom l - dpv12[0][0][1] = 0.0; + dpv12[0][0][1] = 0.0; dpv12[0][1][1] = -vet[0][2]; - dpv12[0][2][1] = vet[0][1]; - dpv12[1][0][1] = vet[0][2]; - dpv12[1][1][1] = 0.0; + dpv12[0][2][1] = vet[0][1]; + dpv12[1][0][1] = vet[0][2]; + dpv12[1][1][1] = 0.0; dpv12[1][2][1] = -vet[0][0]; dpv12[2][0][1] = -vet[0][1]; - dpv12[2][1][1] = vet[0][0]; - dpv12[2][2][1] = 0.0; + dpv12[2][1][1] = vet[0][0]; + dpv12[2][2][1] = 0.0; // derivatives respect to the third neighbor, atom n for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv12[id][ip][2] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv12[id][ip][2] = 0.0; } } - pv31[0] = vet[2][1]*vet[0][2] - vet[0][1]*vet[2][2]; - pv31[1] = vet[2][2]*vet[0][0] - vet[0][2]*vet[2][0]; - pv31[2] = vet[2][0]*vet[0][1] - vet[0][0]*vet[2][1]; + pv31[0] = vet[2][1] * vet[0][2] - vet[0][1] * vet[2][2]; + pv31[1] = vet[2][2] * vet[0][0] - vet[0][2] * vet[2][0]; + pv31[2] = vet[2][0] * vet[0][1] - vet[0][0] * vet[2][1]; // derivatives respect to the first neighbor, atom k - dpv31[0][0][0] = 0.0; + dpv31[0][0][0] = 0.0; dpv31[0][1][0] = -vet[2][2]; - dpv31[0][2][0] = vet[2][1]; - dpv31[1][0][0] = vet[2][2]; - dpv31[1][1][0] = 0.0; + dpv31[0][2][0] = vet[2][1]; + dpv31[1][0][0] = vet[2][2]; + dpv31[1][1][0] = 0.0; dpv31[1][2][0] = -vet[2][0]; dpv31[2][0][0] = -vet[2][1]; - dpv31[2][1][0] = vet[2][0]; - dpv31[2][2][0] = 0.0; + dpv31[2][1][0] = vet[2][0]; + dpv31[2][2][0] = 0.0; // derivatives respect to the third neighbor, atom n - dpv31[0][0][2] = 0.0; - dpv31[0][1][2] = vet[0][2]; + dpv31[0][0][2] = 0.0; + dpv31[0][1][2] = vet[0][2]; dpv31[0][2][2] = -vet[0][1]; // derivatives of pv13[1] to rn dpv31[1][0][2] = -vet[0][2]; - dpv31[1][1][2] = 0.0; - dpv31[1][2][2] = vet[0][0]; + dpv31[1][1][2] = 0.0; + dpv31[1][2][2] = vet[0][0]; // derivatives of pv13[2] to rn - dpv31[2][0][2] = vet[0][1]; + dpv31[2][0][2] = vet[0][1]; dpv31[2][1][2] = -vet[0][0]; - dpv31[2][2][2] = 0.0; + dpv31[2][2][2] = 0.0; // derivatives respect to the second neighbor, atom l for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv31[id][ip][1] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv31[id][ip][1] = 0.0; } } - pv23[0] = vet[1][1]*vet[2][2] - vet[2][1]*vet[1][2]; - pv23[1] = vet[1][2]*vet[2][0] - vet[2][2]*vet[1][0]; - pv23[2] = vet[1][0]*vet[2][1] - vet[2][0]*vet[1][1]; + pv23[0] = vet[1][1] * vet[2][2] - vet[2][1] * vet[1][2]; + pv23[1] = vet[1][2] * vet[2][0] - vet[2][2] * vet[1][0]; + pv23[2] = vet[1][0] * vet[2][1] - vet[2][0] * vet[1][1]; // derivatives respect to the second neighbor, atom k for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dpv23[id][ip][0] = 0.0; - } + for (ip = 0; ip < 3; ip++) { dpv23[id][ip][0] = 0.0; } } // derivatives respect to the second neighbor, atom l - dpv23[0][0][1] = 0.0; - dpv23[0][1][1] = vet[2][2]; + dpv23[0][0][1] = 0.0; + dpv23[0][1][1] = vet[2][2]; dpv23[0][2][1] = -vet[2][1]; dpv23[1][0][1] = -vet[2][2]; - dpv23[1][1][1] = 0.0; - dpv23[1][2][1] = vet[2][0]; - dpv23[2][0][1] = vet[2][1]; + dpv23[1][1][1] = 0.0; + dpv23[1][2][1] = vet[2][0]; + dpv23[2][0][1] = vet[2][1]; dpv23[2][1][1] = -vet[2][0]; - dpv23[2][2][1] = 0.0; + dpv23[2][2][1] = 0.0; // derivatives respect to the third neighbor, atom n - dpv23[0][0][2] = 0.0; + dpv23[0][0][2] = 0.0; dpv23[0][1][2] = -vet[1][2]; - dpv23[0][2][2] = vet[1][1]; - dpv23[1][0][2] = vet[1][2]; - dpv23[1][1][2] = 0.0; + dpv23[0][2][2] = vet[1][1]; + dpv23[1][0][2] = vet[1][2]; + dpv23[1][1][2] = 0.0; dpv23[1][2][2] = -vet[1][0]; dpv23[2][0][2] = -vet[1][1]; - dpv23[2][1][2] = vet[1][0]; - dpv23[2][2][2] = 0.0; + dpv23[2][1][2] = vet[1][0]; + dpv23[2][2][2] = 0.0; -//############################################################################################ + //############################################################################################ // average the normal vectors by using the 3 neighboring planes - n1[0] = (pv12[0] + pv31[0] + pv23[0])/cont; - n1[1] = (pv12[1] + pv31[1] + pv23[1])/cont; - n1[2] = (pv12[2] + pv31[2] + pv23[2])/cont; + n1[0] = (pv12[0] + pv31[0] + pv23[0]) / cont; + n1[1] = (pv12[1] + pv31[1] + pv23[1]) / cont; + n1[2] = (pv12[2] + pv31[2] + pv23[2]) / cont; // the magnitude of the normal vector - nn2 = n1[0]*n1[0] + n1[1]*n1[1] + n1[2]*n1[2]; + nn2 = n1[0] * n1[0] + n1[1] * n1[1] + n1[2] * n1[2]; nn = sqrt(nn2); - if (nn == 0) error->one(FLERR,"The magnitude of the normal vector is zero"); + if (nn == 0) error->one(FLERR, "The magnitude of the normal vector is zero"); // the unit normal vector - normal[i][0] = n1[0]/nn; - normal[i][1] = n1[1]/nn; - normal[i][2] = n1[2]/nn; + normal[i][0] = n1[0] / nn; + normal[i][1] = n1[1] / nn; + normal[i][2] = n1[2] / nn; // for the central atoms, dnormdri is always zero for (id = 0; id < 3; id++) { - for (ip = 0; ip < 3; ip++) { - dnormdri[id][ip][i] = 0.0; - } - } // end of derivatives of normals respect to atom i + for (ip = 0; ip < 3; ip++) { dnormdri[id][ip][i] = 0.0; } + } // end of derivatives of normals respect to atom i // derivatives of non-normalized normal vector, dn1:3x3x3 array for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { for (m = 0; m < 3; m++) { - dn1[id][ip][m] = (dpv12[id][ip][m] + dpv23[id][ip][m] + dpv31[id][ip][m])/cont; + dn1[id][ip][m] = (dpv12[id][ip][m] + dpv23[id][ip][m] + dpv31[id][ip][m]) / cont; } } } @@ -1009,7 +975,7 @@ void PairKolmogorovCrespiFull::calc_normal() // r[id][m]: the id's component of atom m for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { - dnn[id][m] = (n1[0]*dn1[0][id][m] + n1[1]*dn1[1][id][m] + n1[2]*dn1[2][id][m])/nn; + dnn[id][m] = (n1[0] * dn1[0][id][m] + n1[1] * dn1[1][id][m] + n1[2] * dn1[2][id][m]) / nn; } } // dnormal[id][ip][m][i]: the derivative of normal[id] respect to r[ip][m], id,ip=0,1,2 @@ -1017,49 +983,52 @@ void PairKolmogorovCrespiFull::calc_normal() for (m = 0; m < 3; m++) { for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - dnormal[id][ip][m][i] = dn1[id][ip][m]/nn - n1[id]*dnn[ip][m]/nn2; + dnormal[id][ip][m][i] = dn1[id][ip][m] / nn - n1[id] * dnn[ip][m] / nn2; } } } - } - else { - error->one(FLERR,"There are too many neighbors for calculating normals"); + } else { + error->one(FLERR, "There are too many neighbors for calculating normals"); } -//############################################################################################## + //############################################################################################## } } /* ---------------------------------------------------------------------- */ double PairKolmogorovCrespiFull::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, - double /*factor_coul*/, double factor_lj, - double &fforce) + double /*factor_coul*/, double factor_lj, double &fforce) { - double r,r2inv,r6inv,r8inv,forcelj,philj; - double Tap,dTap,Vkc,fpair; + double r, r2inv, r6inv, r8inv, forcelj, philj; + double Tap, dTap, Vkc, fpair; int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); // turn on/off taper function if (tap_flag) { - Tap = calc_Tap(r,sqrt(cutsq[itype][jtype])); - dTap = calc_dTap(r,sqrt(cutsq[itype][jtype])); - } else {Tap = 1.0; dTap = 0.0;} + Tap = calc_Tap(r, sqrt(cutsq[itype][jtype])); + dTap = calc_dTap(r, sqrt(cutsq[itype][jtype])); + } else { + Tap = 1.0; + dTap = 0.0; + } - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - r8inv = r2inv*r6inv; + r2inv = 1.0 / rsq; + r6inv = r2inv * r2inv * r2inv; + r8inv = r2inv * r6inv; - Vkc = -p.A*p.z06*r6inv; + Vkc = -p.A * p.z06 * r6inv; // derivatives - fpair = -6.0*p.A*p.z06*r8inv; + fpair = -6.0 * p.A * p.z06 * r8inv; forcelj = fpair; - fforce = factor_lj*(forcelj*Tap - Vkc*dTap/r); + fforce = factor_lj * (forcelj * Tap - Vkc * dTap / r); - if (tap_flag) philj = Vkc*Tap; - else philj = Vkc - offset[itype][jtype]; - return factor_lj*philj; + if (tap_flag) + philj = Vkc * Tap; + else + philj = Vkc - offset[itype][jtype]; + return factor_lj * philj; } diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_full.h b/src/INTERLAYER/pair_kolmogorov_crespi_full.h index a87e8374ad..b7264a0883 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_full.h +++ b/src/INTERLAYER/pair_kolmogorov_crespi_full.h @@ -17,8 +17,8 @@ PairStyle(kolmogorov/crespi/full,PairKolmogorovCrespiFull); // clang-format on #else -#ifndef LMP_PAIR_KolmogorovCrespi_FULL_H -#define LMP_PAIR_KolmogorovCrespi_FULL_H +#ifndef LMP_PAIR_KOLMOGOROV_CRESPI_FULL_H +#define LMP_PAIR_KOLMOGOROV_CRESPI_FULL_H #include "pair.h" @@ -40,8 +40,9 @@ class PairKolmogorovCrespiFull : public Pair { void calc_FvdW(int, int); double single(int, int, int, int, double, double, double, double &); + static constexpr int NPARAMS_PER_LINE = 12; + protected: - int me; int maxlocal; // size of numneigh, firstneigh arrays int pgsize; // size of neighbor page int oneatom; // max # of neighbors for one atom @@ -60,7 +61,6 @@ class PairKolmogorovCrespiFull : public Pair { double cut_global; double cut_normal; - double **cut; double **cutKCsq; double **offset; double **normal; @@ -69,50 +69,6 @@ class PairKolmogorovCrespiFull : public Pair { void read_file(char *); void allocate(); - - /* ----Calculate the long-range cutoff term */ - inline double calc_Tap(double r_ij, double Rcut) - { - double Tap, r; - double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; - - r = r_ij / Rcut; - if (r >= 1.0) { - Tap = 0.0; - } else { - Tap = Tap_coeff[7] * r + Tap_coeff[6]; - Tap = Tap * r + Tap_coeff[5]; - Tap = Tap * r + Tap_coeff[4]; - Tap = Tap * r + Tap_coeff[3]; - Tap = Tap * r + Tap_coeff[2]; - Tap = Tap * r + Tap_coeff[1]; - Tap = Tap * r + Tap_coeff[0]; - } - - return (Tap); - } - - /* ----Calculate the derivatives of long-range cutoff term */ - inline double calc_dTap(double r_ij, double Rcut) - { - double dTap, r; - double Tap_coeff[8] = {1.0, 0.0, 0.0, 0.0, -35.0, 84.0, -70.0, 20.0}; - - r = r_ij / Rcut; - if (r >= 1.0) { - dTap = 0.0; - } else { - dTap = 7.0 * Tap_coeff[7] * r + 6.0 * Tap_coeff[6]; - dTap = dTap * r + 5.0 * Tap_coeff[5]; - dTap = dTap * r + 4.0 * Tap_coeff[4]; - dTap = dTap * r + 3.0 * Tap_coeff[3]; - dTap = dTap * r + 2.0 * Tap_coeff[2]; - dTap = dTap * r + Tap_coeff[1]; - dTap = dTap / Rcut; - } - - return (dTap); - } }; } // namespace LAMMPS_NS diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp b/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp index 481e9f6604..70672ac670 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp +++ b/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -30,6 +29,8 @@ #include "force.h" #include "memory.h" #include "neigh_list.h" +#include "potential_file_reader.h" +#include "tokenizer.h" #include #include @@ -45,14 +46,15 @@ PairKolmogorovCrespiZ::PairKolmogorovCrespiZ(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; restartinfo = 0; + manybody_flag = 1; + centroidstressflag = CENTROID_NOTAVAIL; + unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); // initialize element to parameter maps nelements = 0; elements = nullptr; nparams = maxparam = 0; params = nullptr; - elem2param = nullptr; - map = nullptr; // always compute energy offset offset_flag = 1; @@ -65,7 +67,6 @@ PairKolmogorovCrespiZ::~PairKolmogorovCrespiZ() if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); memory->destroy(offset); } @@ -77,14 +78,14 @@ PairKolmogorovCrespiZ::~PairKolmogorovCrespiZ() void PairKolmogorovCrespiZ::compute(int eflag, int vflag) { - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair, fpair1; - double rsq,r,rhosq,exp1,exp2,r6,r8; - double frho,sumC,sumC2,sumCff,fsum,rdsq; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair, fpair1; + double rsq, r, rhosq, exp1, exp2, r6, r8; + double frho, sumC, sumC2, sumCff, fsum, rdsq; + int *ilist, *jlist, *numneigh, **firstneigh; evdwl = 0.0; - ev_init(eflag,vflag); + ev_init(eflag, vflag); double **x = atom->x; double **f = atom->f; @@ -115,52 +116,49 @@ void PairKolmogorovCrespiZ::compute(int eflag, int vflag) dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; // rho^2 = r^2 - (n,r) = r^2 - z^2 - rhosq = delx*delx + dely*dely; - rsq = rhosq + delz*delz; + rhosq = delx * delx + dely * dely; + rsq = rhosq + delz * delz; if (rsq < cutsq[itype][jtype]) { int iparam_ij = elem2param[map[itype]][map[jtype]]; - Param& p = params[iparam_ij]; + Param &p = params[iparam_ij]; r = sqrt(rsq); - r6 = rsq*rsq*rsq; - r8 = r6*rsq; - rdsq = rhosq*p.delta2inv; // (rho/delta)^2 + r6 = rsq * rsq * rsq; + r8 = r6 * rsq; + rdsq = rhosq * p.delta2inv; // (rho/delta)^2 // store exponents - exp1 = exp(-p.lambda*(r-p.z0)); + exp1 = exp(-p.lambda * (r - p.z0)); exp2 = exp(-rdsq); // note that f(rho_ij) equals f(rho_ji) as normals are all along z - sumC = p.C0+p.C2*rdsq+p.C4*rdsq*rdsq; - sumC2 = (2*p.C2+4*p.C4*rdsq)*p.delta2inv; - frho = exp2*sumC; - sumCff = p.C + 2*frho; + sumC = p.C0 + p.C2 * rdsq + p.C4 * rdsq * rdsq; + sumC2 = (2 * p.C2 + 4 * p.C4 * rdsq) * p.delta2inv; + frho = exp2 * sumC; + sumCff = p.C + 2 * frho; // derivatives - fpair = -6.0*p.A*p.z06/r8+p.lambda*exp1/r*sumCff; - fpair1 = exp1*exp2*(4.0*p.delta2inv*sumC-2.0*sumC2); + fpair = -6.0 * p.A * p.z06 / r8 + p.lambda * exp1 / r * sumCff; + fpair1 = exp1 * exp2 * (4.0 * p.delta2inv * sumC - 2.0 * sumC2); fsum = fpair + fpair1; - f[i][0] += delx*fsum; - f[i][1] += dely*fsum; + f[i][0] += delx * fsum; + f[i][1] += dely * fsum; // fi_z does not contain contributions from df/dr // because rho_ij does not depend on z_i or z_j - f[i][2] += delz*fpair; + f[i][2] += delz * fpair; if (newton_pair || j < nlocal) { - f[j][0] -= delx*fsum; - f[j][1] -= dely*fsum; - f[j][2] -= delz*fpair; + f[j][0] -= delx * fsum; + f[j][1] -= dely * fsum; + f[j][2] -= delz * fpair; } - if (eflag) { - evdwl = -p.A*p.z06/r6+ exp1*sumCff - offset[itype][jtype]; - } + if (eflag) { evdwl = -p.A * p.z06 / r6 + exp1 * sumCff - offset[itype][jtype]; } if (evflag) { - ev_tally_xyz(i,j,nlocal,newton_pair,evdwl,0, - fsum,fsum,fpair,delx,dely,delz); + ev_tally_xyz(i, j, nlocal, newton_pair, evdwl, 0, fsum, fsum, fpair, delx, dely, delz); } } } @@ -176,17 +174,15 @@ void PairKolmogorovCrespiZ::compute(int eflag, int vflag) void PairKolmogorovCrespiZ::allocate() { allocated = 1; - int n = atom->ntypes; + int n = atom->ntypes + 1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; + memory->create(setflag, n, n, "pair:setflag"); + for (int i = 1; i < n; i++) + for (int j = i; j < n; j++) setflag[i][j] = 0; - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(offset,n+1,n+1,"pair:offset"); - map = new int[atom->ntypes+1]; + memory->create(cutsq, n, n, "pair:cutsq"); + memory->create(offset, n, n, "pair:offset"); + map = new int[n]; } /* ---------------------------------------------------------------------- @@ -195,20 +191,11 @@ void PairKolmogorovCrespiZ::allocate() void PairKolmogorovCrespiZ::settings(int narg, char **arg) { - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); - if (strcmp(force->pair_style,"hybrid/overlay")!=0) - error->all(FLERR,"ERROR: requires hybrid/overlay pair_style"); + if (narg != 1) error->all(FLERR, "Illegal pair_style command"); + if (strcmp(force->pair_style, "hybrid/overlay") != 0) + error->all(FLERR, "ERROR: requires hybrid/overlay pair_style"); - cut_global = utils::numeric(FLERR,arg[0],false,lmp); - - // reset cutoffs that have been explicitly set - - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; - } + cut_global = utils::numeric(FLERR, arg[0], false, lmp); } /* ---------------------------------------------------------------------- @@ -219,48 +206,46 @@ void PairKolmogorovCrespiZ::coeff(int narg, char **arg) { if (!allocated) allocate(); - int ilo,ihi,jlo,jhi; - utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error); - utils::bounds(FLERR,arg[1],1,atom->ntypes,jlo,jhi,error); + int ilo, ihi, jlo, jhi; + utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error); + utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error); - map_element2type(narg-3,arg+3,false); + map_element2type(narg - 3, arg + 3, false); read_file(arg[2]); // set setflag only for i,j pairs where both are mapped to elements int count = 0; for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - if ((map[i] >=0) && (map[j] >= 0)) { - cut[i][j] = cut_global; + for (int j = MAX(jlo, i); j <= jhi; j++) { + if ((map[i] >= 0) && (map[j] >= 0)) { setflag[i][j] = 1; count++; } } } - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients"); } - /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairKolmogorovCrespiZ::init_one(int i, int j) { - if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - if (!offset_flag) - error->all(FLERR,"Must use 'pair_modify shift yes' with this pair style"); + if (setflag[i][j] == 0) error->all(FLERR, "All pair coeffs are not set"); + if (!offset_flag) error->all(FLERR, "Must use 'pair_modify shift yes' with this pair style"); - if (offset_flag && (cut[i][j] > 0.0)) { + if (offset_flag && (cut_global > 0.0)) { int iparam_ij = elem2param[map[i]][map[j]]; - Param& p = params[iparam_ij]; - offset[i][j] = -p.A*pow(p.z0/cut[i][j],6); - } else offset[i][j] = 0.0; + Param &p = params[iparam_ij]; + offset[i][j] = -p.A * pow(p.z0 / cut_global, 6); + } else + offset[i][j] = 0.0; offset[j][i] = offset[i][j]; - return cut[i][j]; + return cut_global; } /* ---------------------------------------------------------------------- @@ -269,143 +254,117 @@ double PairKolmogorovCrespiZ::init_one(int i, int j) void PairKolmogorovCrespiZ::read_file(char *filename) { - int params_per_line = 11; - char **words = new char*[params_per_line+1]; memory->sfree(params); params = nullptr; nparams = maxparam = 0; // open file on proc 0 - FILE *fp; if (comm->me == 0) { - fp = utils::open_potential(filename,lmp,nullptr); - if (fp == nullptr) - error->one(FLERR,"Cannot open KC potential file {}: {}",filename, utils::getsyserror()); - } + PotentialFileReader reader(lmp, filename, "kolmogorov/crespi/z", unit_convert_flag); + char *line; - // read each line out of file, skipping blank lines or leading '#' - // store line of params if all 3 element tags are in element list + // transparently convert units for supported conversions - int i,j,n,m,nwords,ielement,jelement; - char line[MAXLINE],*ptr; - int eof = 0; + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, unit_convert); - while (1) { - if (comm->me == 0) { - ptr = fgets(line,MAXLINE,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; - } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + while ((line = reader.next_line(NPARAMS_PER_LINE))) { - // strip comment, skip line if blank + try { + ValueTokenizer values(line); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); - if (nwords == 0) continue; + std::string iname = values.next_string(); + std::string jname = values.next_string(); - // concatenate additional lines until have params_per_line words + // ielement,jelement = 1st args + // if both args are in element list, then parse this line + // else skip to next entry in file + int ielement, jelement; - while (nwords < params_per_line) { - n = strlen(line); - if (comm->me == 0) { - ptr = fgets(&line[n],MAXLINE-n,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; + for (ielement = 0; ielement < nelements; ielement++) + if (iname == elements[ielement]) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (jname == elements[jelement]) break; + if (jelement == nelements) continue; + + // expand storage, if needed + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); + + // make certain all addional allocated storage is initialized + // to avoid false positives when checking with valgrind + + memset(params + nparams, 0, DELTA * sizeof(Param)); + } + + // load up parameter settings and error check their values + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].z0 = values.next_double(); + params[nparams].C0 = values.next_double(); + params[nparams].C2 = values.next_double(); + params[nparams].C4 = values.next_double(); + params[nparams].C = values.next_double(); + params[nparams].delta = values.next_double(); + params[nparams].lambda = values.next_double(); + params[nparams].A = values.next_double(); + // S provides a convenient scaling of all energies + params[nparams].S = values.next_double(); + + } catch (TokenizerException &e) { + error->one(FLERR, e.what()); } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); + + // energies in meV further scaled by S + // S = 43.3634 meV = 1 kcal/mol + + double meV = 1e-3 * params[nparams].S; + if (unit_convert) meV *= conversion_factor; + + params[nparams].C *= meV; + params[nparams].A *= meV; + params[nparams].C0 *= meV; + params[nparams].C2 *= meV; + params[nparams].C4 *= meV; + + // precompute some quantities + params[nparams].delta2inv = pow(params[nparams].delta, -2); + params[nparams].z06 = pow(params[nparams].z0, 6); + + nparams++; + if (nparams >= pow(atom->ntypes, 3)) break; } - if (nwords != params_per_line) - error->all(FLERR,"Insufficient format in KC potential file"); + MPI_Bcast(&nparams, 1, MPI_INT, 0, world); + MPI_Bcast(&maxparam, 1, MPI_INT, 0, world); - // words = ptrs to all words in line - - nwords = 0; - words[nwords++] = strtok(line," \t\n\r\f"); - while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; - - // ielement,jelement = 1st args - // if these 2 args are in element list, then parse this line - // else skip to next line (continue) - - for (ielement = 0; ielement < nelements; ielement++) - if (strcmp(words[0],elements[ielement]) == 0) break; - if (ielement == nelements) continue; - for (jelement = 0; jelement < nelements; jelement++) - if (strcmp(words[1],elements[jelement]) == 0) break; - if (jelement == nelements) continue; - - // load up parameter settings and error check their values - - if (nparams == maxparam) { - maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), - "pair:params"); - - // make certain all addional allocated storage is initialized - // to avoid false positives when checking with valgrind - - memset(params + nparams, 0, DELTA*sizeof(Param)); + if (comm->me != 0) { + params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params"); } - params[nparams].ielement = ielement; - params[nparams].jelement = jelement; - params[nparams].z0 = atof(words[2]); - params[nparams].C0 = atof(words[3]); - params[nparams].C2 = atof(words[4]); - params[nparams].C4 = atof(words[5]); - params[nparams].C = atof(words[6]); - params[nparams].delta = atof(words[7]); - params[nparams].lambda = atof(words[8]); - params[nparams].A = atof(words[9]); - // S provides a convenient scaling of all energies - params[nparams].S = atof(words[10]); - - // energies in meV further scaled by S - double meV = 1.0e-3*params[nparams].S; - params[nparams].C *= meV; - params[nparams].A *= meV; - params[nparams].C0 *= meV; - params[nparams].C2 *= meV; - params[nparams].C4 *= meV; - - // precompute some quantities - params[nparams].delta2inv = pow(params[nparams].delta,-2); - params[nparams].z06 = pow(params[nparams].z0,6); - - nparams++; - if (nparams >= pow(atom->ntypes,3)) break; + MPI_Bcast(params, maxparam * sizeof(Param), MPI_BYTE, 0, world); } + memory->destroy(elem2param); - memory->create(elem2param,nelements,nelements,"pair:elem2param"); - for (i = 0; i < nelements; i++) { - for (j = 0; j < nelements; j++) { - n = -1; - for (m = 0; m < nparams; m++) { + memory->create(elem2param, nelements, nelements, "pair:elem2param"); + for (int i = 0; i < nelements; i++) { + for (int j = 0; j < nelements; j++) { + int n = -1; + for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR, "Potential file has duplicate entry"); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR, "Potential file is missing an entry"); elem2param[i][j] = n; } } - delete [] words; } /* ---------------------------------------------------------------------- */ diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_z.h b/src/INTERLAYER/pair_kolmogorov_crespi_z.h index 9db07b59f7..fc07dcb96e 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_z.h +++ b/src/INTERLAYER/pair_kolmogorov_crespi_z.h @@ -34,9 +34,9 @@ class PairKolmogorovCrespiZ : public Pair { void coeff(int, char **); double init_one(int, int); - protected: - int me; + static constexpr int NPARAMS_PER_LINE = 11; + protected: struct Param { double z0, C0, C2, C4, C, delta, lambda, A, S; double delta2inv, z06; @@ -45,7 +45,6 @@ class PairKolmogorovCrespiZ : public Pair { Param *params; // parameter set for I-J interactions double cut_global; - double **cut; double **offset; void read_file(char *); void allocate(); diff --git a/src/INTERLAYER/pair_lebedeva_z.cpp b/src/INTERLAYER/pair_lebedeva_z.cpp index 13a7797534..d78c4bfbbc 100644 --- a/src/INTERLAYER/pair_lebedeva_z.cpp +++ b/src/INTERLAYER/pair_lebedeva_z.cpp @@ -31,6 +31,8 @@ #include "force.h" #include "memory.h" #include "neigh_list.h" +#include "potential_file_reader.h" +#include "tokenizer.h" #include #include @@ -46,6 +48,9 @@ PairLebedevaZ::PairLebedevaZ(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; restartinfo = 0; + manybody_flag = 1; + centroidstressflag = CENTROID_NOTAVAIL; + unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); // initialize element to parameter maps params = nullptr; @@ -61,7 +66,6 @@ PairLebedevaZ::~PairLebedevaZ() if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); memory->destroy(offset); } @@ -167,17 +171,16 @@ void PairLebedevaZ::compute(int eflag, int vflag) void PairLebedevaZ::allocate() { allocated = 1; - int n = atom->ntypes; + int n = atom->ntypes+1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) + memory->create(setflag,n,n,"pair:setflag"); + for (int i = 1; i < n; i++) + for (int j = i; j < n; j++) setflag[i][j] = 0; - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(offset,n+1,n+1,"pair:offset"); - map = new int[atom->ntypes+1]; + memory->create(cutsq,n,n,"pair:cutsq"); + memory->create(offset,n,n,"pair:offset"); + map = new int[n]; } /* ---------------------------------------------------------------------- @@ -191,15 +194,6 @@ void PairLebedevaZ::settings(int narg, char **arg) error->all(FLERR,"Pair style lebedeva/z requires using hybrid/overlay"); cut_global = utils::numeric(FLERR,arg[0],false,lmp); - - // reset cutoffs that have been explicitly set - - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; - } } /* ---------------------------------------------------------------------- @@ -223,7 +217,6 @@ void PairLebedevaZ::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { if ((map[i] >= 0) && (map[j] >= 0)) { - cut[i][j] = cut_global; setflag[i][j] = 1; count++; } @@ -233,7 +226,6 @@ void PairLebedevaZ::coeff(int narg, char **arg) if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } - /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -244,14 +236,14 @@ double PairLebedevaZ::init_one(int i, int j) if (!offset_flag) error->all(FLERR,"Must use 'pair_modify shift yes' with this pair style"); - if (offset_flag && (cut[i][j] > 0.0)) { + if (offset_flag && (cut_global > 0.0)) { int iparam_ij = elem2param[map[i]][map[j]]; Param& p = params[iparam_ij]; - offset[i][j] = -p.A*pow(p.z0/cut[i][j],6); + offset[i][j] = -p.A*pow(p.z0/cut_global,6); } else offset[i][j] = 0.0; offset[j][i] = offset[i][j]; - return cut[i][j]; + return cut_global; } /* ---------------------------------------------------------------------- @@ -260,134 +252,107 @@ double PairLebedevaZ::init_one(int i, int j) void PairLebedevaZ::read_file(char *filename) { - int params_per_line = 12; - char **words = new char*[params_per_line+1]; memory->sfree(params); params = nullptr; nparams = maxparam = 0; // open file on proc 0 - FILE *fp; if (comm->me == 0) { - fp = utils::open_potential(filename,lmp,nullptr); - if (fp == nullptr) { - char str[128]; - sprintf(str,"Cannot open Lebedeva potential file %s",filename); - error->one(FLERR,str); - } - } + PotentialFileReader reader(lmp, filename, "lebedeva/z", unit_convert_flag); + char *line; - // read each line out of file, skipping blank lines or leading '#' - // store line of params if all 3 element tags are in element list + // transparently convert units for supported conversions - int i,j,n,m,nwords,ielement,jelement; - char line[MAXLINE],*ptr; - int eof = 0; + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, unit_convert); - while (1) { - if (comm->me == 0) { - ptr = fgets(line,MAXLINE,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; - } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + while ((line = reader.next_line(NPARAMS_PER_LINE))) { - // strip comment, skip line if blank + try { + ValueTokenizer values(line); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); - if (nwords == 0) continue; + std::string iname = values.next_string(); + std::string jname = values.next_string(); - // concatenate additional lines until have params_per_line words + // ielement,jelement = 1st args + // if both args are in element list, then parse this line + // else skip to next entry in file + int ielement, jelement; - while (nwords < params_per_line) { - n = strlen(line); - if (comm->me == 0) { - ptr = fgets(&line[n],MAXLINE-n,fp); - if (ptr == nullptr) { - eof = 1; - fclose(fp); - } else n = strlen(line) + 1; + for (ielement = 0; ielement < nelements; ielement++) + if (iname == elements[ielement]) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (jname == elements[jelement]) break; + if (jelement == nelements) continue; + + // expand storage, if needed + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), "pair:params"); + + // make certain all addional allocated storage is initialized + // to avoid false positives when checking with valgrind + + memset(params + nparams, 0, DELTA*sizeof(Param)); + } + + // load up parameter settings and error check their values + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].A = values.next_double(); + params[nparams].B = values.next_double(); + params[nparams].C = values.next_double(); + params[nparams].z0 = values.next_double(); + params[nparams].alpha = values.next_double(); + params[nparams].D1 = values.next_double(); + params[nparams].D2 = values.next_double(); + params[nparams].lambda1 = values.next_double(); + params[nparams].lambda2 = values.next_double(); + // S provides a convenient scaling of all energies + params[nparams].S = values.next_double(); + + } catch (TokenizerException &e) { + error->one(FLERR, e.what()); } - MPI_Bcast(&eof,1,MPI_INT,0,world); - if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); + + // energies in meV further scaled by S + // S = 43.3634 meV = 1 kcal/mol + + double meV = 1e-3*params[nparams].S; + if (unit_convert) meV *= conversion_factor; + + params[nparams].A *= meV; + params[nparams].B *= meV; + params[nparams].C *= meV; + + // precompute some quantities. That speeds up later process + params[nparams].z02 = pow(params[nparams].z0,2); + params[nparams].z06 = pow(params[nparams].z0,6); + + nparams++; + if (nparams >= pow(atom->ntypes,3)) break; } - if (nwords != params_per_line) - error->all(FLERR,"Insufficient format in Lebedeva potential file"); + MPI_Bcast(&nparams, 1, MPI_INT, 0, world); + MPI_Bcast(&maxparam, 1, MPI_INT, 0, world); - // words = ptrs to all words in line - - nwords = 0; - words[nwords++] = strtok(line," \t\n\r\f"); - while ((words[nwords++] = strtok(nullptr," \t\n\r\f"))) continue; - - // ielement,jelement = 1st args - // if these 2 args are in element list, then parse this line - // else skip to next line (continue) - - for (ielement = 0; ielement < nelements; ielement++) - if (strcmp(words[0],elements[ielement]) == 0) break; - if (ielement == nelements) continue; - for (jelement = 0; jelement < nelements; jelement++) - if (strcmp(words[1],elements[jelement]) == 0) break; - if (jelement == nelements) continue; - - // load up parameter settings and error check their values - - if (nparams == maxparam) { - maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), - "pair:params"); - - // make certain all addional allocated storage is initialized - // to avoid false positives when checking with valgrind - - memset(params + nparams, 0, DELTA*sizeof(Param)); + if (comm->me != 0) { + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), "pair:params"); } - params[nparams].ielement = ielement; - params[nparams].jelement = jelement; - params[nparams].A = atof(words[2]); - params[nparams].B = atof(words[3]); - params[nparams].C = atof(words[4]); - params[nparams].z0 = atof(words[5]); - params[nparams].alpha = atof(words[6]); - params[nparams].D1 = atof(words[7]); - params[nparams].D2 = atof(words[8]); - params[nparams].lambda1 = atof(words[9]); - params[nparams].lambda2 = atof(words[10]); - // S provides a convenient scaling of all energies - params[nparams].S = atof(words[11]); - // energies in meV further scaled by S - double meV = 1.0e-3*params[nparams].S; - params[nparams].A *= meV; - params[nparams].B *= meV; - params[nparams].C *= meV; - - // precompute some quantities. That speeds up later process - params[nparams].z02 = pow(params[nparams].z0,2); - params[nparams].z06 = pow(params[nparams].z0,6); - - nparams++; - if (nparams >= pow(atom->ntypes,3)) break; + MPI_Bcast(params, maxparam*sizeof(Param), MPI_BYTE, 0, world); } + memory->destroy(elem2param); memory->create(elem2param,nelements,nelements,"pair:elem2param"); - for (i = 0; i < nelements; i++) { - for (j = 0; j < nelements; j++) { - n = -1; - for (m = 0; m < nparams; m++) { + for (int i = 0; i < nelements; i++) { + for (int j = 0; j < nelements; j++) { + int n = -1; + for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); n = m; @@ -397,7 +362,6 @@ void PairLebedevaZ::read_file(char *filename) elem2param[i][j] = n; } } - delete [] words; } /* ---------------------------------------------------------------------- */ diff --git a/src/INTERLAYER/pair_lebedeva_z.h b/src/INTERLAYER/pair_lebedeva_z.h index afe2ac1b81..9b2fbd56f8 100644 --- a/src/INTERLAYER/pair_lebedeva_z.h +++ b/src/INTERLAYER/pair_lebedeva_z.h @@ -34,9 +34,9 @@ class PairLebedevaZ : public Pair { void coeff(int, char **); double init_one(int, int); - protected: - int me; + static constexpr int NPARAMS_PER_LINE = 12; + protected: struct Param { double z0, A, B, C, alpha, D1, D2, lambda1, lambda2, S; double z02, z06; @@ -45,7 +45,6 @@ class PairLebedevaZ : public Pair { Param *params; // parameter set for I-J interactions double cut_global; - double **cut; double **offset; void read_file(char *); void allocate(); diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 02cd4ea708..f40b9c324a 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -257,25 +257,66 @@ 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"); - iname[index] = utils::strdup(name); - ivector = (int **) memory->srealloc(ivector, nivector * sizeof(int *), "atom:ivector"); - memory->create(ivector[index], nmax, "atom:ivector"); - } else { + ivname = (char **) memory->srealloc(ivname,nivector*sizeof(char *), + "atom:ivname"); + int n = strlen(name) + 1; + 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 if (flag == 1 && cols == 0) { index = ndvector; ndvector++; - dname = (char **) memory->srealloc(dname, ndvector * sizeof(char *), "atom:dname"); - dname[index] = utils::strdup(name); - this->sync(Device, DVECTOR_MASK); - memoryKK->grow_kokkos(k_dvector, dvector, ndvector, nmax, "atom:dvector"); - this->modified(Device, DVECTOR_MASK); + dvname = (char **) memory->srealloc(dvname,ndvector*sizeof(char *), + "atom:dvname"); + int n = strlen(name) + 1; + 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; @@ -283,22 +324,34 @@ int AtomKokkos::add_custom(const char *name, int flag) /* ---------------------------------------------------------------------- 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 6cf91a5ddc..d3d73a6a90 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -111,8 +111,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: diff --git a/src/KOKKOS/domain_kokkos.cpp b/src/KOKKOS/domain_kokkos.cpp index 82e1684de9..6a1decbed6 100644 --- a/src/KOKKOS/domain_kokkos.cpp +++ b/src/KOKKOS/domain_kokkos.cpp @@ -27,14 +27,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -DomainKokkos::DomainKokkos(LAMMPS *lmp) : Domain(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void DomainKokkos::init() -{ +DomainKokkos::DomainKokkos(LAMMPS *lmp) : Domain(lmp) { atomKK = (AtomKokkos *) atom; - Domain::init(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/domain_kokkos.h b/src/KOKKOS/domain_kokkos.h index 591d2ef7b9..50c7542e82 100644 --- a/src/KOKKOS/domain_kokkos.h +++ b/src/KOKKOS/domain_kokkos.h @@ -30,7 +30,6 @@ class DomainKokkos : public Domain { public: DomainKokkos(class LAMMPS *); ~DomainKokkos() {} - void init(); void reset_box(); void pbc(); void remap_all(); diff --git a/src/KOKKOS/fix_deform_kokkos.cpp b/src/KOKKOS/fix_deform_kokkos.cpp index bf7fdfb429..576e34503c 100644 --- a/src/KOKKOS/fix_deform_kokkos.cpp +++ b/src/KOKKOS/fix_deform_kokkos.cpp @@ -38,7 +38,7 @@ using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; -enum{NONE,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE,VARIABLE}; +enum{NONE=0,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE,VARIABLE}; enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE}; /* ---------------------------------------------------------------------- */ @@ -143,7 +143,7 @@ void FixDeformKokkos::end_of_step() // set new box size for VOLUME dims that are linked to other dims // NOTE: still need to set h_rate for these dims - for (int i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) { if (set[i].style != VOLUME) continue; if (set[i].substyle == ONE_FROM_ONE) { @@ -227,7 +227,7 @@ void FixDeformKokkos::end_of_step() // tilt_target can be large positive or large negative value // add/subtract box lengths until tilt_target is closest to current value - int idenom; + int idenom = 0; if (i == 5) idenom = 0; else if (i == 4) idenom = 0; else if (i == 3) idenom = 1; diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 152c4c3a7d..4da3a43243 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -1788,7 +1788,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,8 +1801,9 @@ void PairExp6rxKokkos::read_file(char *file) } params[nparams].ispecies = ispecies; - params[nparams].name = utils::strdup(&atom->dname[ispecies][0]); + params[nparams].name = utils::strdup(&atom->dvname[ispecies][0]); params[nparams].potential = utils::strdup(words[1]); + if (strcmp(params[nparams].potential,"exp6") == 0) { params[nparams].alpha = atof(words[2]); params[nparams].epsilon = atof(words[3]); diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 6cb6f1b96a..b7b9560bc1 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -1048,15 +1048,16 @@ void PairTableRXKokkos::coeff(int narg, char **arg) site1 = utils::strdup(arg[4]); int ispecies; - for (ispecies = 0; ispecies < nspecies; ispecies++) - if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; + for (ispecies = 0; ispecies < nspecies; ispecies++) { + 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"); - site2 = utils::strdup(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"); @@ -1123,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; } @@ -1138,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; } diff --git a/src/KSPACE/msm.cpp b/src/KSPACE/msm.cpp index d7cc35cf19..2259d2f829 100644 --- a/src/KSPACE/msm.cpp +++ b/src/KSPACE/msm.cpp @@ -643,6 +643,7 @@ void MSM::allocate() if (active_flag[n]) { delete gc[n]; int **procneigh = procneigh_levels[n]; + gc[n] = new GridComm(lmp,world_levels[n],2,nx_msm[n],ny_msm[n],nz_msm[n], nxlo_in[n],nxhi_in[n],nylo_in[n],nyhi_in[n], nzlo_in[n],nzhi_in[n], @@ -1194,20 +1195,13 @@ void MSM::set_grid_local() for (int n=0; n (comm->xsplit[comm->myloc[0]] * nx_msm[n]); - nxhi_in[n] = static_cast (comm->xsplit[comm->myloc[0]+1] * nx_msm[n]) - 1; - - nylo_in[n] = static_cast (comm->ysplit[comm->myloc[1]] * ny_msm[n]); - nyhi_in[n] = static_cast (comm->ysplit[comm->myloc[1]+1] * ny_msm[n]) - 1; - - nzlo_in[n] = static_cast (comm->zsplit[comm->myloc[2]] * nz_msm[n]); - nzhi_in[n] = static_cast (comm->zsplit[comm->myloc[2]+1] * nz_msm[n]) - 1; - - // nlower,nupper = stencil size for mapping (interpolating) particles to MSM grid + comm->partition_grid(nx_msm[n],ny_msm[n],nz_msm[n],0.0, + nxlo_in[n],nxhi_in[n],nylo_in[n],nyhi_in[n], + nzlo_in[n],nzhi_in[n]); nlower = -(order-1)/2; nupper = order/2; @@ -1287,49 +1281,38 @@ void MSM::set_grid_local() nzhi_out[n] = nhi + MAX(order,nzhi_direct); // add extra grid points for non-periodic boundary conditions + // skip reset of lo/hi for procs who do not own any grid cells if (domain->nonperiodic) { - if (!domain->xperiodic) { - if (nxlo_in[n] == 0) - nxlo_in[n] = alpha[n]; + if (!domain->xperiodic && nxlo_in[n] <= nxhi_in[n]) { + if (nxlo_in[n] == 0) nxlo_in[n] = alpha[n]; nxlo_out[n] = MAX(nxlo_out[n],alpha[n]); if (n == 0) nxlo_out_all = MAX(nxlo_out_all,alpha[0]); - if (nxhi_in[n] == nx_msm[n] - 1) - nxhi_in[n] = betax[n]; + if (nxhi_in[n] == nx_msm[n] - 1) nxhi_in[n] = betax[n]; nxhi_out[n] = MIN(nxhi_out[n],betax[n]); if (n == 0) nxhi_out_all = MIN(nxhi_out_all,betax[0]); - if (nxhi_in[n] < 0) - nxhi_in[n] = alpha[n] - 1; } - if (!domain->yperiodic) { - if (nylo_in[n] == 0) - nylo_in[n] = alpha[n]; + if (!domain->yperiodic && nylo_in[n] <= nyhi_in[n]) { + if (nylo_in[n] == 0) nylo_in[n] = alpha[n]; nylo_out[n] = MAX(nylo_out[n],alpha[n]); if (n == 0) nylo_out_all = MAX(nylo_out_all,alpha[0]); - if (nyhi_in[n] == ny_msm[n] - 1) - nyhi_in[n] = betay[n]; + if (nyhi_in[n] == ny_msm[n] - 1) nyhi_in[n] = betay[n]; nyhi_out[n] = MIN(nyhi_out[n],betay[n]); if (n == 0) nyhi_out_all = MIN(nyhi_out_all,betay[0]); - if (nyhi_in[n] < 0) - nyhi_in[n] = alpha[n] - 1; } - if (!domain->zperiodic) { - if (nzlo_in[n] == 0) - nzlo_in[n] = alpha[n]; + if (!domain->zperiodic && nzlo_in[n] <= nzhi_in[n]) { + if (nzlo_in[n] == 0) nzlo_in[n] = alpha[n]; nzlo_out[n] = MAX(nzlo_out[n],alpha[n]); if (n == 0) nzlo_out_all = MAX(nzlo_out_all,alpha[0]); - if (nzhi_in[n] == nz_msm[n] - 1) - nzhi_in[n] = betaz[n]; + if (nzhi_in[n] == nz_msm[n] - 1) nzhi_in[n] = betaz[n]; nzhi_out[n] = MIN(nzhi_out[n],betaz[n]); if (n == 0) nzhi_out_all = MIN(nzhi_out_all,betaz[0]); - if (nzhi_in[n] < 0) - nzhi_in[n] = alpha[n] - 1; } } diff --git a/src/KSPACE/pair_coul_long.cpp b/src/KSPACE/pair_coul_long.cpp index 09c820160c..b4b467e6bc 100644 --- a/src/KSPACE/pair_coul_long.cpp +++ b/src/KSPACE/pair_coul_long.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -18,27 +17,27 @@ #include "pair_coul_long.h" -#include -#include #include "atom.h" #include "comm.h" +#include "error.h" #include "force.h" #include "kspace.h" -#include "neighbor.h" -#include "neigh_list.h" #include "memory.h" -#include "error.h" +#include "neigh_list.h" +#include "neighbor.h" +#include +#include using namespace LAMMPS_NS; -#define EWALD_F 1.12837917 -#define EWALD_P 0.3275911 -#define A1 0.254829592 -#define A2 -0.284496736 -#define A3 1.421413741 -#define A4 -1.453152027 -#define A5 1.061405429 +#define EWALD_F 1.12837917 +#define EWALD_P 0.3275911 +#define A1 0.254829592 +#define A2 -0.284496736 +#define A3 1.421413741 +#define A4 -1.453152027 +#define A5 1.061405429 /* ---------------------------------------------------------------------- */ @@ -69,16 +68,16 @@ PairCoulLong::~PairCoulLong() void PairCoulLong::compute(int eflag, int vflag) { - int i,j,ii,jj,inum,jnum,itable,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair; - double fraction,table; - double r,r2inv,forcecoul,factor_coul; - double grij,expm2,prefactor,t,erfc; - int *ilist,*jlist,*numneigh,**firstneigh; + int i, j, ii, jj, inum, jnum, itable, itype, jtype; + double qtmp, xtmp, ytmp, ztmp, delx, dely, delz, ecoul, fpair; + double fraction, table; + double r, r2inv, forcecoul, factor_coul; + double grij, expm2, prefactor, t, erfc; + int *ilist, *jlist, *numneigh, **firstneigh; double rsq; ecoul = 0.0; - ev_init(eflag,vflag); + ev_init(eflag, vflag); double **x = atom->x; double **f = atom->f; @@ -114,58 +113,57 @@ void PairCoulLong::compute(int eflag, int vflag) delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; jtype = type[j]; if (rsq < cut_coulsq) { - r2inv = 1.0/rsq; + r2inv = 1.0 / rsq; if (!ncoultablebits || rsq <= tabinnersq) { r = sqrt(rsq); grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * scale[itype][jtype] * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + expm2 = exp(-grij * grij); + t = 1.0 / (1.0 + EWALD_P * grij); + erfc = t * (A1 + t * (A2 + t * (A3 + t * (A4 + t * A5)))) * expm2; + prefactor = qqrd2e * scale[itype][jtype] * qtmp * q[j] / r; + forcecoul = prefactor * (erfc + EWALD_F * grij * expm2); + if (factor_coul < 1.0) forcecoul -= (1.0 - factor_coul) * prefactor; } else { union_int_float_t rsq_lookup; rsq_lookup.f = rsq; itable = rsq_lookup.i & ncoulmask; itable >>= ncoulshiftbits; fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = scale[itype][jtype] * qtmp*q[j] * table; + table = ftable[itable] + fraction * dftable[itable]; + forcecoul = scale[itype][jtype] * qtmp * q[j] * table; if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = scale[itype][jtype] * qtmp*q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; + table = ctable[itable] + fraction * dctable[itable]; + prefactor = scale[itype][jtype] * qtmp * q[j] * table; + forcecoul -= (1.0 - factor_coul) * prefactor; } } fpair = forcecoul * r2inv; - f[i][0] += delx*fpair; - f[i][1] += dely*fpair; - f[i][2] += delz*fpair; + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; if (newton_pair || j < nlocal) { - f[j][0] -= delx*fpair; - f[j][1] -= dely*fpair; - f[j][2] -= delz*fpair; + f[j][0] -= delx * fpair; + f[j][1] -= dely * fpair; + f[j][2] -= delz * fpair; } if (eflag) { if (!ncoultablebits || rsq <= tabinnersq) - ecoul = prefactor*erfc; + ecoul = prefactor * erfc; else { - table = etable[itable] + fraction*detable[itable]; - ecoul = scale[itype][jtype] * qtmp*q[j] * table; + table = etable[itable] + fraction * detable[itable]; + ecoul = scale[itype][jtype] * qtmp * q[j] * table; } - if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; + if (factor_coul < 1.0) ecoul -= (1.0 - factor_coul) * prefactor; } - if (evflag) ev_tally(i,j,nlocal,newton_pair, - 0.0,ecoul,fpair,delx,dely,delz); + if (evflag) ev_tally(i, j, nlocal, newton_pair, 0.0, ecoul, fpair, delx, dely, delz); } } } @@ -182,14 +180,13 @@ void PairCoulLong::allocate() allocated = 1; int n = atom->ntypes; - memory->create(setflag,n+1,n+1,"pair:setflag"); + memory->create(setflag, n + 1, n + 1, "pair:setflag"); for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; + for (int j = i; j <= n; j++) setflag[i][j] = 0; - memory->create(cutsq,n+1,n+1,"pair:cutsq"); + memory->create(cutsq, n + 1, n + 1, "pair:cutsq"); - memory->create(scale,n+1,n+1,"pair:scale"); + memory->create(scale, n + 1, n + 1, "pair:scale"); } /* ---------------------------------------------------------------------- @@ -198,9 +195,9 @@ void PairCoulLong::allocate() void PairCoulLong::settings(int narg, char **arg) { - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + if (narg != 1) error->all(FLERR, "Illegal pair_style command"); - cut_coul = utils::numeric(FLERR,arg[0],false,lmp); + cut_coul = utils::numeric(FLERR, arg[0], false, lmp); } /* ---------------------------------------------------------------------- @@ -209,23 +206,23 @@ void PairCoulLong::settings(int narg, char **arg) void PairCoulLong::coeff(int narg, char **arg) { - if (narg != 2) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg != 2) error->all(FLERR, "Incorrect args for pair coefficients"); if (!allocated) allocate(); - int ilo,ihi,jlo,jhi; - utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error); - utils::bounds(FLERR,arg[1],1,atom->ntypes,jlo,jhi,error); + int ilo, ihi, jlo, jhi; + utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error); + utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error); int count = 0; for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { + for (int j = MAX(jlo, i); j <= jhi; j++) { scale[i][j] = 1.0; setflag[i][j] = 1; count++; } } - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); + if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -234,22 +231,20 @@ void PairCoulLong::coeff(int narg, char **arg) void PairCoulLong::init_style() { - if (!atom->q_flag) - error->all(FLERR,"Pair style lj/cut/coul/long requires atom attribute q"); + if (!atom->q_flag) error->all(FLERR, "Pair style lj/cut/coul/long requires atom attribute q"); - neighbor->request(this,instance_me); + neighbor->request(this, instance_me); cut_coulsq = cut_coul * cut_coul; // insure use of KSpace long-range solver, set g_ewald - if (force->kspace == nullptr) - error->all(FLERR,"Pair style requires a KSpace style"); + if (force->kspace == nullptr) error->all(FLERR, "Pair style requires a KSpace style"); g_ewald = force->kspace->g_ewald; // setup force tables - if (ncoultablebits) init_tables(cut_coul,nullptr); + if (ncoultablebits) init_tables(cut_coul, nullptr); } /* ---------------------------------------------------------------------- @@ -259,7 +254,7 @@ void PairCoulLong::init_style() double PairCoulLong::init_one(int i, int j) { scale[j][i] = scale[i][j]; - return cut_coul+2.0*qdist; + return cut_coul + 2.0 * qdist; } /* ---------------------------------------------------------------------- @@ -272,9 +267,8 @@ void PairCoulLong::write_restart(FILE *fp) for (int i = 1; i <= atom->ntypes; i++) for (int j = i; j <= atom->ntypes; j++) { - fwrite(&setflag[i][j],sizeof(int),1,fp); - if (setflag[i][j]) - fwrite(&scale[i][j],sizeof(double),1,fp); + fwrite(&setflag[i][j], sizeof(int), 1, fp); + if (setflag[i][j]) fwrite(&scale[i][j], sizeof(double), 1, fp); } } @@ -288,15 +282,15 @@ void PairCoulLong::read_restart(FILE *fp) allocate(); - int i,j; + int i, j; int me = comm->me; for (i = 1; i <= atom->ntypes; i++) for (j = i; j <= atom->ntypes; j++) { - if (me == 0) utils::sfread(FLERR,&setflag[i][j],sizeof(int),1,fp,nullptr,error); - MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + if (me == 0) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error); + MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world); if (setflag[i][j]) { - if (me == 0) utils::sfread(FLERR,&scale[i][j],sizeof(double),1,fp,nullptr,error); - MPI_Bcast(&scale[i][j],1,MPI_DOUBLE,0,world); + if (me == 0) utils::sfread(FLERR, &scale[i][j], sizeof(double), 1, fp, nullptr, error); + MPI_Bcast(&scale[i][j], 1, MPI_DOUBLE, 0, world); } } } @@ -307,11 +301,11 @@ void PairCoulLong::read_restart(FILE *fp) void PairCoulLong::write_restart_settings(FILE *fp) { - fwrite(&cut_coul,sizeof(double),1,fp); - fwrite(&offset_flag,sizeof(int),1,fp); - fwrite(&mix_flag,sizeof(int),1,fp); - fwrite(&ncoultablebits,sizeof(int),1,fp); - fwrite(&tabinner,sizeof(double),1,fp); + fwrite(&cut_coul, sizeof(double), 1, fp); + fwrite(&offset_flag, sizeof(int), 1, fp); + fwrite(&mix_flag, sizeof(int), 1, fp); + fwrite(&ncoultablebits, sizeof(int), 1, fp); + fwrite(&tabinner, sizeof(double), 1, fp); } /* ---------------------------------------------------------------------- @@ -321,63 +315,61 @@ void PairCoulLong::write_restart_settings(FILE *fp) void PairCoulLong::read_restart_settings(FILE *fp) { if (comm->me == 0) { - utils::sfread(FLERR,&cut_coul,sizeof(double),1,fp,nullptr,error); - utils::sfread(FLERR,&offset_flag,sizeof(int),1,fp,nullptr,error); - utils::sfread(FLERR,&mix_flag,sizeof(int),1,fp,nullptr,error); - utils::sfread(FLERR,&ncoultablebits,sizeof(int),1,fp,nullptr,error); - utils::sfread(FLERR,&tabinner,sizeof(double),1,fp,nullptr,error); + utils::sfread(FLERR, &cut_coul, sizeof(double), 1, fp, nullptr, error); + utils::sfread(FLERR, &offset_flag, sizeof(int), 1, fp, nullptr, error); + utils::sfread(FLERR, &mix_flag, sizeof(int), 1, fp, nullptr, error); + utils::sfread(FLERR, &ncoultablebits, sizeof(int), 1, fp, nullptr, error); + utils::sfread(FLERR, &tabinner, sizeof(double), 1, fp, nullptr, error); } - MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); - MPI_Bcast(&ncoultablebits,1,MPI_INT,0,world); - MPI_Bcast(&tabinner,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_coul, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&offset_flag, 1, MPI_INT, 0, world); + MPI_Bcast(&mix_flag, 1, MPI_INT, 0, world); + MPI_Bcast(&ncoultablebits, 1, MPI_INT, 0, world); + MPI_Bcast(&tabinner, 1, MPI_DOUBLE, 0, world); } /* ---------------------------------------------------------------------- */ -double PairCoulLong::single(int i, int j, int /*itype*/, int /*jtype*/, - double rsq, - double factor_coul, double /*factor_lj*/, - double &fforce) +double PairCoulLong::single(int i, int j, int /*itype*/, int /*jtype*/, double rsq, + double factor_coul, double /*factor_lj*/, double &fforce) { - double r2inv,r,grij,expm2,t,erfc,prefactor; - double fraction,table,forcecoul,phicoul; + double r2inv, r, grij, expm2, t, erfc, prefactor; + double fraction, table, forcecoul, phicoul; int itable; - r2inv = 1.0/rsq; + r2inv = 1.0 / rsq; if (!ncoultablebits || rsq <= tabinnersq) { r = sqrt(rsq); grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; + expm2 = exp(-grij * grij); + t = 1.0 / (1.0 + EWALD_P * grij); + erfc = t * (A1 + t * (A2 + t * (A3 + t * (A4 + t * A5)))) * expm2; + prefactor = force->qqrd2e * atom->q[i] * atom->q[j] / r; + forcecoul = prefactor * (erfc + EWALD_F * grij * expm2); + if (factor_coul < 1.0) forcecoul -= (1.0 - factor_coul) * prefactor; } else { union_int_float_t rsq_lookup; rsq_lookup.f = rsq; itable = rsq_lookup.i & ncoulmask; itable >>= ncoulshiftbits; fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = atom->q[i]*atom->q[j] * table; + table = ftable[itable] + fraction * dftable[itable]; + forcecoul = atom->q[i] * atom->q[j] * table; if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = atom->q[i]*atom->q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; + table = ctable[itable] + fraction * dctable[itable]; + prefactor = atom->q[i] * atom->q[j] * table; + forcecoul -= (1.0 - factor_coul) * prefactor; } } fforce = forcecoul * r2inv; if (!ncoultablebits || rsq <= tabinnersq) - phicoul = prefactor*erfc; + phicoul = prefactor * erfc; else { - table = etable[itable] + fraction*detable[itable]; - phicoul = atom->q[i]*atom->q[j] * table; + table = etable[itable] + fraction * detable[itable]; + phicoul = atom->q[i] * atom->q[j] * table; } - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; + if (factor_coul < 1.0) phicoul -= (1.0 - factor_coul) * prefactor; return phicoul; } @@ -386,11 +378,11 @@ double PairCoulLong::single(int i, int j, int /*itype*/, int /*jtype*/, void *PairCoulLong::extract(const char *str, int &dim) { - if (strcmp(str,"cut_coul") == 0) { + if (strcmp(str, "cut_coul") == 0) { dim = 0; return (void *) &cut_coul; } - if (strcmp(str,"scale") == 0) { + if (strcmp(str, "scale") == 0) { dim = 2; return (void *) scale; } diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index b4fc5d87ce..c54a115ab2 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -1320,34 +1320,12 @@ double PPPM::final_accuracy() void PPPM::set_grid_local() { - // global indices of PPPM grid range from 0 to N-1 - // nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of - // global PPPM grid that I own without ghost cells - // for slab PPPM, assign z grid as if it were not extended - // both non-tiled and tiled proc layouts use 0-1 fractional sumdomain info + // partition global grid across procs + // n xyz lo/hi in = lower/upper bounds of global grid this proc owns + // indices range from 0 to N-1 inclusive in each dim - if (comm->layout != Comm::LAYOUT_TILED) { - nxlo_in = static_cast (comm->xsplit[comm->myloc[0]] * nx_pppm); - nxhi_in = static_cast (comm->xsplit[comm->myloc[0]+1] * nx_pppm) - 1; - - nylo_in = static_cast (comm->ysplit[comm->myloc[1]] * ny_pppm); - nyhi_in = static_cast (comm->ysplit[comm->myloc[1]+1] * ny_pppm) - 1; - - nzlo_in = static_cast - (comm->zsplit[comm->myloc[2]] * nz_pppm/slab_volfactor); - nzhi_in = static_cast - (comm->zsplit[comm->myloc[2]+1] * nz_pppm/slab_volfactor) - 1; - - } else { - nxlo_in = static_cast (comm->mysplit[0][0] * nx_pppm); - nxhi_in = static_cast (comm->mysplit[0][1] * nx_pppm) - 1; - - nylo_in = static_cast (comm->mysplit[1][0] * ny_pppm); - nyhi_in = static_cast (comm->mysplit[1][1] * ny_pppm) - 1; - - nzlo_in = static_cast (comm->mysplit[2][0] * nz_pppm/slab_volfactor); - nzhi_in = static_cast (comm->mysplit[2][1] * nz_pppm/slab_volfactor) - 1; - } + comm->partition_grid(nx_pppm,ny_pppm,nz_pppm,slab_volfactor, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in); // nlower,nupper = stencil size for mapping particles to PPPM grid @@ -1367,7 +1345,7 @@ void PPPM::set_grid_local() // effectively nlo_in,nhi_in + ghost cells // nlo,nhi = index of global grid pt to "lower left" of smallest/largest // position a particle in my box can be at - // dist[3] = particle position bound = subbox + skin/2.0 + qdist + // dist[3] = max particle position outside subbox = skin/2.0 + qdist // qdist = offset due to TIP4P fictitious charge // convert to triclinic if necessary // nlo_out,nhi_out = nlo,nhi + stencil size for particle mapping diff --git a/src/KSPACE/pppm_disp.cpp b/src/KSPACE/pppm_disp.cpp index 785ac9c131..530995cae2 100644 --- a/src/KSPACE/pppm_disp.cpp +++ b/src/KSPACE/pppm_disp.cpp @@ -2696,22 +2696,12 @@ void PPPMDisp::set_fft_parameters(int& nx_p, int& ny_p, int& nz_p, int& ng, int& nf, int& nfb, double& sft, double& sftone, int& ord) { - // global indices of PPPM grid range from 0 to N-1 - // nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of - // global PPPM grid that I own without ghost cells - // for slab PPPM, assign z grid as if it were not extended - - nxlo_i = static_cast (comm->xsplit[comm->myloc[0]] * nx_p); - nxhi_i = static_cast (comm->xsplit[comm->myloc[0]+1] * nx_p) - 1; - - nylo_i = static_cast (comm->ysplit[comm->myloc[1]] * ny_p); - nyhi_i = static_cast (comm->ysplit[comm->myloc[1]+1] * ny_p) - 1; - - nzlo_i = static_cast - (comm->zsplit[comm->myloc[2]] * nz_p/slab_volfactor); - nzhi_i = static_cast - (comm->zsplit[comm->myloc[2]+1] * nz_p/slab_volfactor) - 1; + // partition global grid across procs + // n xyz lo/hi i = lower/upper bounds of global grid this proc owns + // indices range from 0 to N-1 inclusive in each dim + comm->partition_grid(nx_p,ny_p,nz_p,slab_volfactor, + nxlo_i,nxhi_i,nylo_i,nyhi_i,nzlo_i,nzhi_i); // nlow,nupp = stencil size for mapping particles to PPPM grid diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index 75ece1dc71..fcdda9ef9e 100644 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -293,7 +293,7 @@ void PairSW::read_file(char *file) if (comm->me == 0) { PotentialFileReader reader(lmp, file, "sw", unit_convert_flag); - char * line; + char *line; // transparently convert units for supported conversions @@ -328,8 +328,7 @@ void PairSW::read_file(char *file) if (nparams == maxparam) { maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), - "pair:params"); + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param),"pair:params"); // make certain all addional allocated storage is initialized // to avoid false positives when checking with valgrind diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp index babaecc2bd..5f7ffcbbe5 100644 --- a/src/MC/fix_bond_swap.cpp +++ b/src/MC/fix_bond_swap.cpp @@ -148,7 +148,8 @@ void FixBondSwap::init() error->all(FLERR,"Pair style does not support fix bond/swap"); if (force->angle == nullptr && atom->nangles > 0 && comm->me == 0) - error->warning(FLERR,"Fix bond/swap will ignore defined angles"); + error->warning(FLERR,"Fix bond/swap will not preserve correct angle " + "topology because no angle_style is defined"); if (force->dihedral || force->improper) error->all(FLERR,"Fix bond/swap cannot use dihedral or improper styles"); @@ -255,12 +256,18 @@ void FixBondSwap::post_integrate() } // examine ntest of my eligible atoms for potential swaps - // atom i is randomly selected via atom list - // look at all j neighbors of atom i - // atom j must be on-processor (j < nlocal) - // atom j must be in fix group - // i and j must be same distance from chain end (mol[i] = mol[j]) - // NOTE: must use extra parens in if test on mask[j] & groupbit + // atom I is randomly selected via atom list + // look at all J neighbors of atom I + // J must be on-processor (J < nlocal) + // I,J must be in fix group + // I,J must have same molecule IDs + // use case 1 (see doc page): + // if user defines mol IDs appropriately for linear chains, + // this will mean they are same distance from (either) chain end + // use case 2 (see doc page): + // if user defines a unique mol ID for desired bond sites (on any chain) + // and defines the fix group as these sites, + // this will mean they are eligible bond sites int ntest = static_cast (fraction * neligible); int accept = 0; @@ -277,23 +284,29 @@ void FixBondSwap::post_integrate() if ((mask[j] & groupbit) == 0) continue; if (molecule[i] != molecule[j]) continue; - // look at all bond partners of atoms i and j - // use num_bond for this, not special list, so also find bondtypes - // inext,jnext = bonded atoms + // loop over all bond partners of atoms I and J + // use num_bond for this, not special list, so also have bondtypes + // inext,jnext = atoms bonded to I,J // inext,jnext must be on-processor (inext,jnext < nlocal) - // inext,jnext must be same dist from chain end (mol[inext] = mol[jnext]) - // since swaps may occur between two ends of a single chain, insure - // the 4 atoms are unique (no duplicates): inext != jnext, inext != j + // inext,jnext must be in fix group + // inext,jnext must have same molecule IDs + // in use cases above ... + // for case 1: this insures chain length is preserved + // for case 2: always satisfied b/c fix group = bond-able atoms + // 4 atoms must be unique (no duplicates): inext != jnext, inext != j + // already know i != inext, j != jnext // all 4 old and new bonds must have length < cutoff for (ibond = 0; ibond < num_bond[i]; ibond++) { inext = atom->map(bond_atom[i][ibond]); if (inext >= nlocal || inext < 0) continue; + if ((mask[inext] & groupbit) == 0) continue; ibondtype = bond_type[i][ibond]; for (jbond = 0; jbond < num_bond[j]; jbond++) { jnext = atom->map(bond_atom[j][jbond]); if (jnext >= nlocal || jnext < 0) continue; + if ((mask[jnext] & groupbit) == 0) continue; jbondtype = bond_type[j][jbond]; if (molecule[inext] != molecule[jnext]) continue; @@ -306,7 +319,7 @@ void FixBondSwap::post_integrate() // if angles are enabled: // find other atoms i,inext,j,jnext are in angles with // and angletypes: i/j angletype, i/j nextangletype - // use num_angle for this, not special list, so also find angletypes + // use num_angle for this, not special list, so also have angletypes // 4 atoms consecutively along 1st chain: iprev,i,inext,ilast // 4 atoms consecutively along 2nd chain: jprev,j,jnext,jlast // prev or last atom can be non-existent at end of chain @@ -428,7 +441,7 @@ void FixBondSwap::post_integrate() done: - // trigger immediate reneighboring if any swaps occurred + // trigger immediate reneighboring if swaps occurred on one or more procs int accept_any; MPI_Allreduce(&accept,&accept_any,1,MPI_INT,MPI_SUM,world); diff --git a/src/ML-RANN/rann_fingerprint_bond.cpp b/src/ML-RANN/rann_fingerprint_bond.cpp index 4b96a4f39d..f5912324cd 100644 --- a/src/ML-RANN/rann_fingerprint_bond.cpp +++ b/src/ML-RANN/rann_fingerprint_bond.cpp @@ -591,8 +591,8 @@ void Fingerprint_bond::do3bodyfeatureset_doubleneighborloop(double * features,do delz = zn[jj]; rsq = delx*delx + dely*dely + delz*delz; if (rsq>rc*rc) { - expr[jj][0]=0; - continue; + expr[jj][0]=0; + continue; } double r1 = (rsq*((double)res)*cutinv2); int m1 = (int)r1; @@ -603,7 +603,7 @@ void Fingerprint_bond::do3bodyfeatureset_doubleneighborloop(double * features,do double *p2 = &expcuttable[(m1+1)*kmax]; double *p3 = &expcuttable[(m1+2)*kmax]; for (kk=0;kkrc*rc) { - expr[jj][0]=0; - continue; + expr[jj][0]=0; + continue; } double r1 = (rsq*((double)res)*cutinv2); int m1 = (int)r1; @@ -647,8 +647,8 @@ void Fingerprint_bondscreened::do3bodyfeatureset_doubleneighborloop(double * fea double *p2 = &expcuttable[(m1+1)*kmax]; double *p3 = &expcuttable[(m1+2)*kmax]; for (kk=0;kk= 0; j = bins[j]) { - if (i == j) continue; + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { + if (i == j) continue; jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } } } diff --git a/src/OPENMP/npair_half_multi_newtoff_omp.cpp b/src/OPENMP/npair_half_multi_newtoff_omp.cpp index 852f87d5b5..d4a63cb9e8 100644 --- a/src/OPENMP/npair_half_multi_newtoff_omp.cpp +++ b/src/OPENMP/npair_half_multi_newtoff_omp.cpp @@ -102,7 +102,7 @@ void NPairHalfMultiNewtoffOmp::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in other bins in stencil including self // only store pair if i < j @@ -114,16 +114,16 @@ void NPairHalfMultiNewtoffOmp::build(NeighList *list) ns = nstencil_multi[icollection][jcollection]; for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { + if (j <= i) continue; jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq <= cutneighsq[itype][jtype]) { diff --git a/src/OPENMP/npair_half_multi_newton_omp.cpp b/src/OPENMP/npair_half_multi_newton_omp.cpp index d78df77bec..9ad740a043 100644 --- a/src/OPENMP/npair_half_multi_newton_omp.cpp +++ b/src/OPENMP/npair_half_multi_newton_omp.cpp @@ -101,7 +101,7 @@ void NPairHalfMultiNewtonOmp::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // if same size: uses half stencil so check central bin if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -117,41 +117,41 @@ void NPairHalfMultiNewtonOmp::build(NeighList *list) // if j is owned atom, store it if j > i // if j is ghost, only store if j coords are "above and to the right" of i - for (j = js; j >= 0; j = bins[j]) { + for (j = js; j >= 0; j = bins[j]) { if ((icollection != jcollection) && (j < i)) continue; - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } } // for all collections, loop over all atoms in other bins in stencil, store every pair @@ -159,38 +159,38 @@ void NPairHalfMultiNewtonOmp::build(NeighList *list) // stencil is half if i same size as j // stencil is full if i smaller than j - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } } ilist[i] = i; diff --git a/src/OPENMP/npair_half_multi_newton_tri_omp.cpp b/src/OPENMP/npair_half_multi_newton_tri_omp.cpp index a453851c4c..71f1605366 100644 --- a/src/OPENMP/npair_half_multi_newton_tri_omp.cpp +++ b/src/OPENMP/npair_half_multi_newton_tri_omp.cpp @@ -102,7 +102,7 @@ void NPairHalfMultiNewtonTriOmp::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in bins in stencil // stencil is empty if i larger than j @@ -113,12 +113,12 @@ void NPairHalfMultiNewtonTriOmp::build(NeighList *list) // (equal zyx and j <= i) // latter excludes self-self interaction but allows superposed atoms - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { // if same size (same collection), use half stencil if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -133,30 +133,30 @@ void NPairHalfMultiNewtonTriOmp::build(NeighList *list) } jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } } ilist[i] = i; diff --git a/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp b/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp index c774d4a0a8..da2d7a7590 100644 --- a/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp @@ -92,7 +92,7 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) // if same collection use own bin if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in other bins in stencil including self // only store pair if i < j @@ -104,27 +104,27 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) ns = nstencil_multi[icollection][jcollection]; for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >=0; j = bins[j]) { - if (j <= i) continue; + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >=0; j = bins[j]) { + if (j <= i) continue; jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } + } } } diff --git a/src/OPENMP/npair_half_size_multi_newton_omp.cpp b/src/OPENMP/npair_half_size_multi_newton_omp.cpp index f9e4c95030..cdc68e1b42 100644 --- a/src/OPENMP/npair_half_size_multi_newton_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_newton_omp.cpp @@ -91,7 +91,7 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) // if same collection use own bin if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // if same size: uses half stencil so check central bin if(cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -107,33 +107,33 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) // if j is owned atom, store it if j > i // if j is ghost, only store if j coords are "above and to the right" of i - for (j = js; j >= 0; j = bins[j]) { + for (j = js; j >= 0; j = bins[j]) { if(icollection != jcollection and j < i) continue; - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } } } @@ -142,31 +142,31 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) // stencil is half if i same size as j // stencil is full if i smaller than j - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } - } - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } + } + } } ilist[i] = i; diff --git a/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp index b9a914078f..d38e52fe18 100644 --- a/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp @@ -92,7 +92,7 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) // if same collection use own bin if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in bins in stencil @@ -104,12 +104,12 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) // (equal zyx and j <= i) // latter excludes self-self interaction but allows superposed atoms - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { // if same size (same collection), use half stencil if(cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -126,21 +126,21 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } - } - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } + } + } } ilist[i] = i; diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index e52347727f..0c309b9ead 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -742,8 +742,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++) @@ -766,8 +766,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; @@ -1051,8 +1051,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; @@ -1144,8 +1144,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 @@ -1434,8 +1434,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) { @@ -2592,17 +2592,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++) { @@ -2625,17 +2625,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]; int unlimitflag = 0; @@ -3586,17 +3586,17 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) // initialize group statuses // why aren't these more global... - 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]; i_limit_tags[n] = update->ntimestep + 1; diff --git a/src/RIGID/fix_rigid.cpp b/src/RIGID/fix_rigid.cpp index f53881c4e7..461574a034 100644 --- a/src/RIGID/fix_rigid.cpp +++ b/src/RIGID/fix_rigid.cpp @@ -129,14 +129,14 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // determine whether atom-style variable or atom property is used if (utils::strmatch(arg[4],"^i_")) { - int is_double=0; - int custom_index = atom->find_custom(arg[4]+2,is_double); + int is_double,cols; + int custom_index = atom->find_custom(arg[4]+2,is_double,cols); 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"); + "integer-valued property/atom 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 9a35d2c73b..4a9a74f225 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -112,15 +112,14 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : // determine whether atom-style variable or atom property is used if (utils::strmatch(arg[4],"^i_")) { - int is_double=0; - int custom_index = atom->find_custom(arg[4]+2,is_double); + int is_double,cols; + int custom_index = atom->find_custom(arg[4]+2,is_double,cols); if (custom_index == -1) error->all(FLERR,"Fix rigid/small custom requires " "previously defined property/atom"); - else if (is_double) + else if (is_double || cols) error->all(FLERR,"Fix rigid/small custom requires " - "integer-valued property/atom"); - + "integer-valued property/atom vector"); int minval = INT_MAX; int *value = atom->ivector[custom_index]; for (i = 0; i < nlocal; i++) diff --git a/src/SCAFACOS/scafacos.cpp b/src/SCAFACOS/scafacos.cpp index 451dd7aca9..5e4981663f 100644 --- a/src/SCAFACOS/scafacos.cpp +++ b/src/SCAFACOS/scafacos.cpp @@ -23,6 +23,7 @@ #include "error.h" #include "force.h" #include "memory.h" +#include "pair_hybrid.h" #include #include @@ -108,10 +109,26 @@ void Scafacos::init() if (domain->triclinic) error->all(FLERR, "Cannot use ScaFaCoS with triclinic domain yet"); if (atom->natoms > INT_MAX && sizeof(int) != 8) - error->all(FLERR, "Scafacos atom count exceeds 2B"); + error->all(FLERR, "ScaFaCoS atom count exceeds 2B"); - if (atom->molecular != Atom::ATOMIC) - error->all(FLERR, "Cannot use Scafacos with molecular charged systems yet"); + if ((atom->molecular != Atom::ATOMIC) && (atom->nbonds + atom->nangles + atom->ndihedrals) > 0) { + int flag = 0; + if ((force->special_coul[1] == 1.0) && (force->special_coul[2] == 1.0) && + (force->special_coul[3] == 1.0)) + ++flag; + + PairHybrid *ph = reinterpret_cast(force->pair_match("^hybrid", 0)); + if (ph) { + for (int isub = 0; isub < ph->nstyles; ++isub) + if (force->pair_match("coul/exclude", 0, isub)) ++flag; + } else { + if (force->pair_match("coul/exclude", 0)) ++flag; + } + if (!flag) + error->all(FLERR, + "Must use pair style coul/exclude or 'special_bonds coul 1.0 1.0 1.0'" + "for molecular charged systems with ScaFaCos"); + } FCSResult result; diff --git a/src/VTK/dump_vtk.cpp b/src/VTK/dump_vtk.cpp index 28fab54482..f323ce820f 100644 --- a/src/VTK/dump_vtk.cpp +++ b/src/VTK/dump_vtk.cpp @@ -752,23 +752,41 @@ int DumpVTK::count() ptr = vbuf[field2index[i]]; nstride = 1; - } else if (thresh_array[ithresh] == DNAME) { - int iwhich,tmp; + } else if (thresh_array[ithresh] == IVEC) { + int iwhich,flag,cols i = ATTRIBUTES + 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 = ATTRIBUTES + nfield + ithresh; - iwhich = atom->find_custom(id_custom[field2index[i]],tmp); - + iwhich = atom->find_custom(id_custom[field2index[i]],flag,cols); 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) { + int iwhich,flag,cols; + i = ATTRIBUTES + nfield + ithresh; + iwhich = atom->find_custom(id_custom[field2index[i]],flag,cols); + ptr = atom->dvector[iwhich]; + nstride = 1; + + } else if (thresh_array[ithresh] == IARRAY) { + int iwhich,flag,cols; + i = ATTRIBUTES + nfield + ithresh; + 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++) + dchoose[i] = iarray[i][icol]; + ptr = dchoose; + nstride = 1; + + } else if (thresh_array[ithresh] == DARRAY) { + int iwhich,flag,cols; + 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]; } // unselect atoms that don't meet threshold criterion @@ -1738,7 +1756,7 @@ int DumpVTK::parse_fields(int narg, char **arg) int n,tmp; ArgInfo argi(arg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE - |ArgInfo::DNAME|ArgInfo::INAME); + |ArgInfo::DVEC|ArgInfo::IVEC); argindex[ATTRIBUTES+i] = argi.get_index1(); switch (argi.get_type()) { @@ -1747,8 +1765,8 @@ int DumpVTK::parse_fields(int narg, char **arg) error->all(FLERR,"Invalid attribute in dump vtk command"); break; - // compute value = c_ID - // if no trailing [], then arg is set to 0, else arg is int between [] + // compute value = c_ID + // if no trailing [], then arg is set to 0, else arg is int between [] case ArgInfo::COMPUTE: pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_compute; @@ -1772,8 +1790,8 @@ int DumpVTK::parse_fields(int narg, char **arg) name[ATTRIBUTES+i] = arg[iarg]; break; - // fix value = f_ID - // if no trailing [], then arg is set to 0, else arg is between [] + // fix value = f_ID + // if no trailing [], then arg is set to 0, else arg is between [] case ArgInfo::FIX: pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_fix; @@ -1795,7 +1813,7 @@ int DumpVTK::parse_fields(int narg, char **arg) name[ATTRIBUTES+i] = arg[iarg]; break; - // variable value = v_name + // variable value = v_name case ArgInfo::VARIABLE: pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_variable; @@ -1810,7 +1828,25 @@ int DumpVTK::parse_fields(int narg, char **arg) name[ATTRIBUTES+i] = arg[iarg]; break; - // custom per-atom floating point value = d_ID + // custom per-atom integer vector = i_ID + + case ArgInfo::INAME: + pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_custom; + vtype[ATTRIBUTES+i] = Dump::INT; + + tmp = -1; + n = atom->find_custom(argi.get_name(),tmp); + if (n < 0) + error->all(FLERR,"Could not find custom per-atom property ID"); + + if (tmp != 0) + error->all(FLERR,"Custom per-atom property ID is not integer"); + + field2index[ATTRIBUTES+i] = add_custom(argi.get_name(),0); + name[ATTRIBUTES+i] = arg[iarg]; + break; + + // custom per-atom floating point vector = d_ID case ArgInfo::DNAME: pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_custom; @@ -1828,23 +1864,16 @@ int DumpVTK::parse_fields(int narg, char **arg) name[ATTRIBUTES+i] = arg[iarg]; break; - // custom per-atom integer value = i_ID + // NEWSTYLE + // custom per-atom integer array = i2_ID - case ArgInfo::INAME: - pack_choice[ATTRIBUTES+i] = &DumpVTK::pack_custom; - vtype[ATTRIBUTES+i] = Dump::INT; + case ArgInfo::IARRAY: + return iarg; - tmp = -1; - n = atom->find_custom(argi.get_name(),tmp); - if (n < 0) - error->all(FLERR,"Could not find custom per-atom property ID"); + // custom per-atom floating point array = d2_ID - if (tmp != 0) - error->all(FLERR,"Custom per-atom property ID is not integer"); - - field2index[ATTRIBUTES+i] = add_custom(argi.get_name(),0); - name[ATTRIBUTES+i] = arg[iarg]; - break; + case ArgInfo::DARRAY: + return iarg; default: return iarg; diff --git a/src/atom.cpp b/src/atom.cpp index 0a629e2fe6..4135298673 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -217,10 +217,13 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) // custom atom arrays - nivector = ndvector = 0; + nivector = ndvector = niarray = ndarray = 0; ivector = nullptr; dvector = nullptr; - iname = dname = nullptr; + iarray = nullptr; + darray = nullptr; + icols = dcols = nullptr; + ivname = dvname = ianame = daname = nullptr; // initialize atom style and array existence flags @@ -301,20 +304,33 @@ 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 != nullptr) { - for (int i = 0; i < ndvector; i++) { - delete [] dname[i]; + for (int i = 0; i < ndvector; i++) { + delete [] dvname[i]; + if (dvector) // (needed for Kokkos) 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 @@ -2400,92 +2416,143 @@ 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 == nullptr) 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; } return -1; } -/** \brief Add a custom per-atom property with the given name and type +/** \brief Add a custom per-atom property with the given name and type and size \verbatim embed:rst -This function will add a custom per-atom property with the name "name" -as either list of int or double to the list of custom properties. This -function is called, e.g. from :doc:`fix property/atom `. +This function will add a custom per-atom property with one or more values +with the name "name" to the list of custom properties. +This function is called, e.g. from :doc:`fix property/atom `. \endverbatim - * \param name Name of the property (w/o a "d_" or "i_" prefix) + * \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix) * \param flag Data type of property: 0 for int, 1 for double - * \return Index of property in the respective list of properties + * \param cols Number of values: 0 for a single value, 1 or more for a vector of values + * \return index of property in the respective list of properties */ -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"); - iname[index] = utils::strdup(name); - ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *), - "atom:ivector"); + 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"); 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"); - dname[index] = utils::strdup(name); - dvector = (double **) memory->srealloc(dvector,ndvector*sizeof(double *), - "atom:dvector"); + 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"); memory->create(dvector[index],nmax,"atom:dvector"); + + } else if ((flag == 0) && (cols > 0)) { + index = niarray; + niarray++; + 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"); + 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 > 0)) { + index = ndarray; + ndarray++; + 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"); + memory->create(darray[index],nmax,cols,"atom:darray"); + + dcols = (int *) memory->srealloc(dcols,ndarray*sizeof(int),"atom:dcols"); + dcols[index] = cols; } return index; } -/*! \brief Remove a custom per-atom property of a given type +/*! \brief Remove a custom per-atom property of a given type and size * \verbatim embed:rst -This will remove a property that was requested e.g. by the +This will remove a property that was requested, e.g. by the :doc:`fix property/atom ` command. It frees the -allocated memory and sets the pointer to ``nullptr`` to the entry in -the list can be reused. The lists of those pointers will never be -compacted or never shrink, so that index to name mappings remain valid. +allocated memory and sets the pointer to ``nullptr`` for the entry in +the list so it can be reused. The lists of these pointers are never +compacted or shrink, so that indices to name mappings remain valid. \endverbatim - * - * \param flag whether the property is integer (=0) or double (=1) - * \param index of that property in the respective list. + * \param index Index of property in the respective list of properties + * \param flag Data type of property: 0 for int, 1 for double + * \param cols Number of values: 0 for a single value, 1 or more for a vector of values */ -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] = nullptr; - delete [] iname[index]; - iname[index] = nullptr; - } else { + ivector[index] = NULL; + delete [] ivname[index]; + ivname[index] = NULL; + + } else if (flag == 1 && cols == 0) { memory->destroy(dvector[index]); - dvector[index] = nullptr; - delete [] dname[index]; - dname[index] = nullptr; + 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; } } @@ -2593,6 +2660,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` @@ -2609,10 +2692,8 @@ void *Atom::extract(const char *name) { // -------------------------------------------------------------------- // 4th customization section: customize by adding new variable name - // please see the following function to set the type of the data - // so that programs can detect it dynamically at run time. + // if new variable is from a package, add package comment - /* NOTE: this array is only of length ntypes+1 */ if (strcmp(name,"mass") == 0) return (void *) mass; if (strcmp(name,"id") == 0) return (void *) tag; @@ -2657,10 +2738,13 @@ void *Atom::extract(const char *name) if (strcmp(name,"vest") == 0) return (void *) vest; // 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; + // MACHDYN package + if (strcmp(name, "contact_radius") == 0) return (void *) contact_radius; if (strcmp(name, "smd_data_9") == 0) return (void *) smd_data_9; if (strcmp(name, "smd_stress") == 0) return (void *) smd_stress; @@ -2670,10 +2754,16 @@ void *Atom::extract(const char *name) return (void *) eff_plastic_strain_rate; if (strcmp(name, "damage") == 0) return (void *) damage; + // DPD-REACT pakage + if (strcmp(name,"dpdTheta") == 0) return (void *) dpdTheta; + + // DPD-MESO package + if (strcmp(name,"edpd_temp") == 0) return (void *) edpd_temp; - // DIELECTRIC + // DIELECTRIC package + if (strcmp(name,"area") == 0) return (void *) area; if (strcmp(name,"ed") == 0) return (void *) ed; if (strcmp(name,"em") == 0) return (void *) em; @@ -2684,10 +2774,30 @@ void *Atom::extract(const char *name) // end of customization section // -------------------------------------------------------------------- + // custom vectors and arrays + + if (utils::strmatch(name,"^[id]2?_")) { + int which = 0, array = 0; + if (name[0] == 'd') which = 1; + 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]; + } + return nullptr; } - /** Provide data type info about internal data of the Atom class * \verbatim embed:rst @@ -2750,10 +2860,13 @@ int Atom::extract_datatype(const char *name) if (strcmp(name,"vest") == 0) return LAMMPS_DOUBLE_2D; // 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; + // MACHDYN 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; @@ -2761,10 +2874,16 @@ 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; + // DPD-REACT package + if (strcmp(name,"dpdTheta") == 0) return LAMMPS_DOUBLE; + + // DPD-MESO package + if (strcmp(name,"edpd_temp") == 0) return LAMMPS_DOUBLE; - // DIELECTRIC + // DIELECTRIC package + if (strcmp(name,"area") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"ed") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"em") == 0) return LAMMPS_DOUBLE; @@ -2775,6 +2894,25 @@ int Atom::extract_datatype(const char *name) // end of customization section // -------------------------------------------------------------------- + // custom vectors and arrays + + if (utils::strmatch(name,"^[id]2?_")) { + int which = 0, array = 0; + if (name[0] == 'd') which = 1; + 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; + } + return -1; } diff --git a/src/atom.h b/src/atom.h index daf2f04f8a..a16f1e2752 100644 --- a/src/atom.h +++ b/src/atom.h @@ -221,12 +221,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 @@ -335,9 +336,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/comm.cpp b/src/comm.cpp index 2dddba11c2..17175f9517 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -832,6 +832,103 @@ int Comm::binary(double value, int n, double *vec) return index; } +/* ---------------------------------------------------------------------- + partition a global regular grid into one brick-shaped sub-grid per proc + if grid point is inside my sub-domain I own it, + this includes sub-domain lo boundary but excludes hi boundary + nx,ny,nz = extent of global grid + indices into the global grid range from 0 to N-1 in each dim + zfactor = 0.0 if the grid exactly covers the simulation box + zfactor > 1.0 if the grid extends beyond the +z boundary by this factor + used by 2d slab-mode PPPM + this effectively maps proc sub-grids to a smaller subset of the grid + nxyz lo/hi = inclusive lo/hi bounds of global grid sub-brick I own + if proc owns no grid cells in a dim, then nlo > nhi + special case: 2 procs share boundary which a grid point is exactly on + 2 equality if tests insure a consistent decision as to which proc owns it +------------------------------------------------------------------------- */ + +void Comm::partition_grid(int nx, int ny, int nz, double zfactor, + int &nxlo, int &nxhi, int &nylo, int &nyhi, + int &nzlo, int &nzhi) +{ + double xfraclo,xfrachi,yfraclo,yfrachi,zfraclo,zfrachi; + + if (layout != LAYOUT_TILED) { + xfraclo = xsplit[myloc[0]]; + xfrachi = xsplit[myloc[0]+1]; + yfraclo = ysplit[myloc[1]]; + yfrachi = ysplit[myloc[1]+1]; + zfraclo = zsplit[myloc[2]]; + zfrachi = zsplit[myloc[2]+1]; + } else { + xfraclo = mysplit[0][0]; + xfrachi = mysplit[0][1]; + yfraclo = mysplit[1][0]; + yfrachi = mysplit[1][1]; + zfraclo = mysplit[2][0]; + zfrachi = mysplit[2][1]; + } + + nxlo = static_cast (xfraclo * nx); + if (1.0*nxlo != xfraclo*nx) nxlo++; + nxhi = static_cast (xfrachi * nx); + if (1.0*nxhi == xfrachi*nx) nxhi--; + + nylo = static_cast (yfraclo * ny); + if (1.0*nylo != yfraclo*ny) nylo++; + nyhi = static_cast (yfrachi * ny); + if (1.0*nyhi == yfrachi*ny) nyhi--; + + if (zfactor == 0.0) { + nzlo = static_cast (zfraclo * nz); + if (1.0*nzlo != zfraclo*nz) nzlo++; + nzhi = static_cast (zfrachi * nz); + if (1.0*nzhi == zfrachi*nz) nzhi--; + } else { + nzlo = static_cast (zfraclo * nz/zfactor); + if (1.0*nzlo != zfraclo*nz) nzlo++; + nzhi = static_cast (zfrachi * nz/zfactor); + if (1.0*nzhi == zfrachi*nz) nzhi--; + } + + // OLD code + // could sometimes map grid points slightly outside a proc to the proc + + /* + if (layout != LAYOUT_TILED) { + nxlo = static_cast (xsplit[myloc[0]] * nx); + nxhi = static_cast (xsplit[myloc[0]+1] * nx) - 1; + + nylo = static_cast (ysplit[myloc[1]] * ny); + nyhi = static_cast (ysplit[myloc[1]+1] * ny) - 1; + + if (zfactor == 0.0) { + nzlo = static_cast (zsplit[myloc[2]] * nz); + nzhi = static_cast (zsplit[myloc[2]+1] * nz) - 1; + } else { + nzlo = static_cast (zsplit[myloc[2]] * nz/zfactor); + nzhi = static_cast (zsplit[myloc[2]+1] * nz/zfactor) - 1; + } + + } else { + nxlo = static_cast (mysplit[0][0] * nx); + nxhi = static_cast (mysplit[0][1] * nx) - 1; + + nylo = static_cast (mysplit[1][0] * ny); + nyhi = static_cast (mysplit[1][1] * ny) - 1; + + if (zfactor == 0.0) { + nzlo = static_cast (mysplit[2][0] * nz); + nzhi = static_cast (mysplit[2][1] * nz) - 1; + } else { + nzlo = static_cast (mysplit[2][0] * nz/zfactor); + nzhi = static_cast (mysplit[2][1] * nz/zfactor) - 1; + } + } + */ +} + /* ---------------------------------------------------------------------- communicate inbuf around full ring of processors with messtag nbytes = size of inbuf = n datums * nper bytes diff --git a/src/comm.h b/src/comm.h index bc5faa49f4..2ab999bab3 100644 --- a/src/comm.h +++ b/src/comm.h @@ -105,6 +105,11 @@ class Comm : protected Pointers { virtual void coord2proc_setup() {} virtual int coord2proc(double *, int &, int &, int &); + // partition a global regular grid by proc sub-domains + + void partition_grid(int, int, int, double, + int &, int &, int &, int &, int &, int &); + // memory usage virtual double memory_usage() = 0; @@ -117,6 +122,7 @@ class Comm : protected Pointers { int statflag = 0); // extract data useful to other classes + virtual void *extract(const char *, int &) { return nullptr; } protected: diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index c9d0353e6c..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" @@ -36,7 +37,7 @@ using namespace LAMMPS_NS; ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), - index(nullptr), pack_choice(nullptr) + index(nullptr), colindex(nullptr), pack_choice(nullptr) { if (narg < 4) error->all(FLERR,"Illegal compute property/atom command"); @@ -50,6 +51,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++) { @@ -121,277 +123,271 @@ 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; - } 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"); + 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"); + 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; - } else if (utils::strmatch(arg[iarg],"^i_")) { - 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"); - pack_choice[i] = &ComputePropertyAtom::pack_iname; - } else if (utils::strmatch(arg[iarg],"^d_")) { - 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"); - pack_choice[i] = &ComputePropertyAtom::pack_dname; - } + // custom per-atom vector or array - 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 + } else if (utils::strmatch(arg[iarg],"^[id]2?_")) { + int flag,cols; + ArgInfo argi(arg[iarg], ArgInfo::INAME| ArgInfo::DNAME); + const char *pname = argi.get_name(); + + index[i] = atom->find_custom(pname,flag,cols); + if (index[i] < 0) + error->all(FLERR,"Compute property/atom property {} does not exist", pname); + + // 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); + + 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(); + + 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 } 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; } } @@ -404,6 +400,7 @@ ComputePropertyAtom::~ComputePropertyAtom() { delete [] pack_choice; delete [] index; + delete [] colindex; memory->destroy(vector_atom); memory->destroy(array_atom); } @@ -416,6 +413,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 } /* ---------------------------------------------------------------------- */ @@ -1783,21 +1783,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; @@ -1843,7 +1828,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 929bc6ede0..d8b1cae449 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,15 @@ class ComputePropertyAtom : public Compute { void pack_fmy(int); void pack_fmz(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 +109,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 +126,15 @@ 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); }; } // namespace LAMMPS_NS diff --git a/src/domain.cpp b/src/domain.cpp index 5f780d523c..7df82fbfb3 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -175,7 +175,7 @@ void Domain::init() deform_flag = deform_vremap = deform_groupbit = 0; for (int i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"deform") == 0) { + if (utils::strmatch(modify->fix[i]->style,"^deform")) { deform_flag = 1; if (((FixDeform *) modify->fix[i])->remapflag == Domain::V_REMAP) { deform_vremap = 1; diff --git a/src/domain.h b/src/domain.h index 2a812218f1..711bab0fb2 100644 --- a/src/domain.h +++ b/src/domain.h @@ -42,38 +42,46 @@ class Domain : protected Pointers { int tiltsmall; // 1 if limit tilt, else 0 // orthogonal box + double xprd, yprd, zprd; // global box dimensions double xprd_half, yprd_half, zprd_half; // half dimensions double prd[3]; // array form of dimensions double prd_half[3]; // array form of half dimensions // triclinic box - // xprd,xprd_half,prd,prd_half = - // same as if untilted + // xyzprd,xyzprd_half and prd,prd_half = same as if untilted + double prd_lamda[3]; // lamda box = (1,1,1) double prd_half_lamda[3]; // lamda half box = (0.5,0.5,0.5) - double boxlo[3], boxhi[3]; // orthogonal box global bounds + // orthogonal box global bounds + + double boxlo[3], boxhi[3]; // triclinic box // boxlo/hi = same as if untilted + double boxlo_lamda[3], boxhi_lamda[3]; // lamda box = (0,1) double boxlo_bound[3], boxhi_bound[3]; // bounding box of tilted domain double corners[8][3]; // 8 corner points // orthogonal box & triclinic box + double minxlo, minxhi; // minimum size of global box double minylo, minyhi; // when shrink-wrapping double minzlo, minzhi; // tri only possible for non-skew dims // orthogonal box + double sublo[3], subhi[3]; // sub-box bounds on this proc // triclinic box // sublo/hi = undefined + double sublo_lamda[3], subhi_lamda[3]; // bounds of subbox in lamda // triclinic box + double xy, xz, yz; // 3 tilt factors double h[6], h_inv[6]; // shape matrix in Voigt ordering // Voigt = xx,yy,zz,yz,xz,xy diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 6bb7653e3b..3f70d242b1 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -28,8 +28,8 @@ #include "region.h" #include "update.h" #include "variable.h" - -#include +#include "fmt/format.h" +#include "utils.h" using namespace LAMMPS_NS; @@ -44,7 +44,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 ONEFIELD 32 @@ -55,12 +55,15 @@ enum{LT,LE,GT,GE,EQ,NEQ,XOR}; DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg), idregion(nullptr), thresh_array(nullptr), thresh_op(nullptr), thresh_value(nullptr), - thresh_last(nullptr), thresh_fix(nullptr), thresh_fixID(nullptr), thresh_first(nullptr), + thresh_last(nullptr), thresh_fix(nullptr), + thresh_fixID(nullptr), thresh_first(nullptr), earg(nullptr), vtype(nullptr), vformat(nullptr), columns(nullptr), choose(nullptr), - dchoose(nullptr), clist(nullptr), field2index(nullptr), argindex(nullptr), id_compute(nullptr), - compute(nullptr), id_fix(nullptr), fix(nullptr), id_variable(nullptr), variable(nullptr), - vbuf(nullptr), id_custom(nullptr), flag_custom(nullptr), typenames(nullptr), - pack_choice(nullptr) + dchoose(nullptr), clist(nullptr), field2index(nullptr), + argindex(nullptr), id_compute(nullptr), + compute(nullptr), id_fix(nullptr), fix(nullptr), + id_variable(nullptr), variable(nullptr), + vbuf(nullptr), id_custom(nullptr), custom(nullptr), custom_flag(nullptr), + typenames(nullptr), pack_choice(nullptr) { if (narg == 5) error->all(FLERR,"No dump custom arguments specified"); @@ -118,7 +121,8 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : ncustom = 0; id_custom = nullptr; - flag_custom = nullptr; + custom = nullptr; + custom_flag = nullptr; // process attributes // ioptional = start of additional optional args in expanded args @@ -234,7 +238,8 @@ DumpCustom::~DumpCustom() for (int i = 0; i < ncustom; i++) delete[] id_custom[i]; memory->sfree(id_custom); - memory->sfree(flag_custom); + delete [] custom; + delete [] custom_flag; memory->destroy(choose); memory->destroy(dchoose); @@ -314,7 +319,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 for (i = 0; i < ncompute; i++) { @@ -338,10 +343,16 @@ void DumpCustom::init_style() variable[i] = ivariable; } - for (i = 0; i < ncustom; i++) { - int icustom = atom->find_custom(id_custom[i],flag_custom[i]); + int icustom,flag,cols; + for (int i = 0; i < ncustom; i++) { + 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 @@ -1021,23 +1032,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 @@ -1240,7 +1265,6 @@ int DumpCustom::parse_fields(int narg, char **arg) // customize by adding to if statement for (int iarg = 0; iarg < narg; iarg++) { - if (strcmp(arg[iarg],"id") == 0) { pack_choice[iarg] = &DumpCustom::pack_id; if (sizeof(tagint) == sizeof(smallint)) vtype[iarg] = Dump::INT; @@ -1423,9 +1447,10 @@ int DumpCustom::parse_fields(int narg, char **arg) pack_choice[iarg] = &DumpCustom::pack_tqz; vtype[iarg] = Dump::DOUBLE; - } else { + // compute or fix or variable or custom vector/array - int n,tmp; + } else { + int n,flag,cols; ArgInfo argi(arg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE |ArgInfo::DNAME|ArgInfo::INAME); argindex[iarg] = argi.get_index1(); @@ -1437,8 +1462,8 @@ int DumpCustom::parse_fields(int narg, char **arg) error->all(FLERR,"Invalid attribute in dump custom command"); break; - // compute value = c_ID - // if no trailing [], then arg is set to 0, else arg is int between [] + // compute value = c_ID + // if no trailing [], then arg is set to 0, else arg is int between [] case ArgInfo::COMPUTE: pack_choice[iarg] = &DumpCustom::pack_compute; @@ -1459,8 +1484,8 @@ int DumpCustom::parse_fields(int narg, char **arg) field2index[iarg] = add_compute(name); break; - // fix value = f_ID - // if no trailing [], then arg is set to 0, else arg is between [] + // fix value = f_ID + // if no trailing [], then arg is set to 0, else arg is between [] case ArgInfo::FIX: pack_choice[iarg] = &DumpCustom::pack_fix; @@ -1481,7 +1506,7 @@ int DumpCustom::parse_fields(int narg, char **arg) field2index[iarg] = add_fix(name); break; - // variable value = v_name + // variable value = v_name case ArgInfo::VARIABLE: pack_choice[iarg] = &DumpCustom::pack_variable; @@ -1495,40 +1520,57 @@ int DumpCustom::parse_fields(int narg, char **arg) field2index[iarg] = add_variable(name); break; - // custom per-atom floating point value = d_ID + // custom per-atom floating point vector or array 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 value = i_ID + // custom per-atom integer vector or array 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; + // no match + default: return iarg; } @@ -1613,7 +1655,7 @@ int DumpCustom::add_variable(const 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 ------------------------------------------------------------------------- */ @@ -1621,19 +1663,21 @@ int DumpCustom::add_custom(const char *id, int flag) { 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]; id_custom[ncustom] = utils::strdup(id); - flag_custom[ncustom] = flag; - + custom_flag[ncustom] = flag; ncustom++; + return ncustom-1; } @@ -1717,7 +1761,7 @@ int DumpCustom::modify_param(int narg, char **arg) ArgInfo argi(arg[1],ArgInfo::COMPUTE); if ((argi.get_type() != ArgInfo::COMPUTE) || (argi.get_dim() != 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; refresh = argi.copy_name(); @@ -1837,14 +1881,14 @@ 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; + // compute or fix or variable or custom vector/array + // must grow field2index and argindex arrays, since access is beyond nfield + else { - - // must grow field2index and argindex arrays, since access is beyond nfield - 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::DNAME|ArgInfo::INAME); argindex[nfield+nthresh] = argi.get_index1(); @@ -1856,8 +1900,8 @@ int DumpCustom::modify_param(int narg, char **arg) error->all(FLERR,"Invalid attribute in dump modify command"); break; - // compute value = c_ID - // if no trailing [], then arg is set to 0, else arg is between [] + // compute value = c_ID + // if no trailing [], then arg is set to 0, else arg is between [] case ArgInfo::COMPUTE: thresh_array[nthresh] = COMPUTE; @@ -1877,8 +1921,8 @@ int DumpCustom::modify_param(int narg, char **arg) field2index[nfield+nthresh] = add_compute(name); break; - // fix value = f_ID - // if no trailing [], then arg is set to 0, else arg is between [] + // fix value = f_ID + // if no trailing [], then arg is set to 0, else arg is between [] case ArgInfo::FIX: thresh_array[nthresh] = FIX; @@ -1897,8 +1941,7 @@ int DumpCustom::modify_param(int narg, char **arg) field2index[nfield+nthresh] = add_fix(name); break; - // variable value = v_ID - // must grow field2index and argindex arrays, since access is beyond nfield + // variable value = v_ID case ArgInfo::VARIABLE: thresh_array[nthresh] = VARIABLE; @@ -1910,30 +1953,58 @@ 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::DNAME: - thresh_array[nthresh] = DNAME; - 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); + n = atom->find_custom(name,flag,cols); - field2index[nfield+nthresh] = add_custom(name,1); - break; - - // custom per atom integer value = i_ID - - case ArgInfo::INAME: - thresh_array[nthresh] = INAME; - 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); + 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 integer vector or array + + case ArgInfo::INAME: + 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 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; + } + + field2index[nfield+nthresh] = add_custom(name,0); + break; + + // no match + default: error->all(FLERR,"Invalid dump_modify thresh attribute: {}",name); break; @@ -2058,27 +2129,36 @@ void DumpCustom::pack_variable(int n) void DumpCustom::pack_custom(int n) { + int flag = custom_flag[field2index[n]]; + int iwhich = custom[field2index[n]]; + int index = argindex[n]; - int index = field2index[n]; - - if (flag_custom[index] == 0) { // integer - int iwhich,tmp; - iwhich = atom->find_custom(id_custom[index],tmp); - + 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 1bf1dc46b6..4077a9374b 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 - char **id_compute; // their IDs - class Compute **compute; // list of ptrs to the Compute objects + int ncompute; // # of Computes accessed by dump + char **id_compute; // their IDs + class Compute **compute; // list of ptrs to the Computes - int nfix; // # of Fix objects used by dump - char **id_fix; // their IDs - class Fix **fix; // list of ptrs to the Fix objects + int nfix; // # of Fixes used by dump + char **id_fix; // their IDs + 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 - double **vbuf; // local storage for variable evaluation + int nvariable; // # of Variables used by dump + char **id_variable; // their names + int *variable; // list of Variable indices in Variable class + double **vbuf; // local storage for variable evaluation - int ncustom; // # of custom atom properties - char **id_custom; // their names - int *flag_custom; // their data type + int ncustom; // # of Custom atom properties used by dump + char **id_custom; // their names + 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 + int ntypes; // # of atom types + char **typenames; // array of element names for each type // private methods diff --git a/src/fix_group.cpp b/src/fix_group.cpp index a66aab982e..562384fb40 100644 --- a/src/fix_group.cpp +++ b/src/fix_group.cpp @@ -61,6 +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) @@ -69,14 +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"); - 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 < 0 || 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); @@ -118,7 +124,7 @@ void FixGroup::init() if (utils::strmatch(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); @@ -136,9 +142,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 @@ -215,11 +222,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 @@ -239,8 +245,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 ff25ce4135..b94cb1ee21 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 4d22faf83b..1e583a4ec9 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -25,7 +25,7 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{MOLECULE,CHARGE,RMASS,INTEGER,DOUBLE}; +enum{MOLECULE,CHARGE,RMASS,IVEC,DVEC,IARRAY,DARRAY}; /* ---------------------------------------------------------------------- */ @@ -41,6 +41,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; @@ -48,6 +49,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) @@ -56,45 +59,90 @@ 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 " - "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; + 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 " - "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; + cols[nvalue] = 0; atom->rmass_flag = rmass_flag = 1; + values_peratom++; nvalue++; - } else if (utils::strmatch(arg[iarg],"^i_")) { - style[nvalue] = INTEGER; - int tmp; - index[nvalue] = atom->find_custom(&arg[iarg][2],tmp); - if (index[nvalue] >= 0) - error->all(FLERR,"Fix property/atom vector name already exists"); - index[nvalue] = atom->add_custom(&arg[iarg][2],0); - nvalue++; - } else if (utils::strmatch(arg[iarg],"^d_")) { - style[nvalue] = DOUBLE; - int tmp; - index[nvalue] = atom->find_custom(&arg[iarg][2],tmp); - if (index[nvalue] >= 0) - error->all(FLERR,"Fix property/atom vector name already exists"); - index[nvalue] = atom->add_custom(&arg[iarg][2],1); - nvalue++; - } else break; + iarg++; - iarg++; + // custom atom vector + + } else if (utils::strmatch(arg[iarg],"^i_")) { + style[nvalue] = IVEC; + 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; + values_peratom++; + nvalue++; + iarg++; + + } else if (utils::strmatch(arg[iarg],"^d_")) { + style[nvalue] = DVEC; + 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,0); + cols[nvalue] = 0; + values_peratom++; + nvalue++; + iarg++; + + // custom atom array + + } else if (utils::strmatch(arg[iarg],"^[id]2_")) { + if (iarg+2 > narg) error->all(FLERR,"Illegal fix property/atom command"); + + 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; + + // no match + + } else break; } // optional args @@ -110,7 +158,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 @@ -133,8 +181,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(Atom::GROW); atom->add_callback(Atom::RESTART); if (border) atom->add_callback(Atom::BORDER); @@ -153,27 +200,32 @@ FixPropertyAtom::~FixPropertyAtom() // deallocate per-atom vectors in Atom class // set ptrs to a null pointer, 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 = nullptr; - } else if (style[m] == CHARGE) { + } else if (style[nv] == CHARGE) { atom->q_flag = 0; memory->destroy(atom->q); atom->q = nullptr; - } else if (style[m] == RMASS) { + } else if (style[nv] == RMASS) { atom->rmass_flag = 0; memory->destroy(atom->rmass); atom->rmass = nullptr; - } 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; } @@ -202,10 +254,9 @@ 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,m; + int j,k,m,ncol; tagint itag; char *next; @@ -228,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 @@ -247,16 +297,23 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, atom->q[m] = values.next_double(); } else if (style[j] == RMASS) { atom->rmass[m] = values.next_double(); - } else if (style[j] == INTEGER) { + } else if (style[j] == IVEC) { atom->ivector[index[j]][m] = values.next_int(); - } else if (style[j] == DOUBLE) { + } else if (style[j] == DVEC) { atom->dvector[index[j]][m] = values.next_double(); + } else if (style[j] == IARRAY) { + ncol = cols[j]; + for (k = 0; k < ncol; k++) + atom->iarray[index[j]][m][k] = values.next_int(); + } else if (style[j] == DARRAY) { + ncol = cols[j]; + for (k = 0; k < ncol; k++) + atom->darray[index[j]][m][k] = values.next_double(); } } } } 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; } @@ -280,13 +337,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; } /* ---------------------------------------------------------------------- @@ -296,7 +353,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 @@ -306,23 +363,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] = darray[i][k]; + icol += ncol; } } } @@ -345,8 +421,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); } @@ -362,16 +440,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"); } @@ -388,42 +483,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); } } @@ -436,17 +541,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]; + } } } @@ -456,40 +572,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]; + } } } @@ -502,35 +634,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++]; } } @@ -543,14 +689,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; } /* ---------------------------------------------------------------------- @@ -559,19 +718,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; } /* ---------------------------------------------------------------------- @@ -580,19 +752,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; } /* ---------------------------------------------------------------------- @@ -601,6 +785,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 @@ -610,17 +795,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++]; + } } } @@ -630,7 +824,7 @@ void FixPropertyAtom::unpack_restart(int nlocal, int nth) int FixPropertyAtom::maxsize_restart() { - return nvalue+1; + return values_peratom+1; } /* ---------------------------------------------------------------------- @@ -639,5 +833,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 4d25545f9d..d7f2b56751 100644 --- a/src/fix_property_atom.h +++ b/src/fix_property_atom.h @@ -52,11 +52,14 @@ 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 nmax_old; // length of peratom arrays the last time they grew + int values_peratom; // # of values per atom, including multiple for arrays + int nmax_old; // length of peratom arrays the last time they grew }; } // namespace LAMMPS_NS diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index 2a97ebceb6..1d3d48a06b 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -17,17 +17,18 @@ #include "arg_info.h" #include "atom.h" #include "compute.h" +#include "update.h" #include "domain.h" -#include "error.h" +#include "force.h" +#include "modify.h" #include "fix.h" #include "group.h" #include "input.h" -#include "memory.h" -#include "modify.h" -#include "update.h" #include "variable.h" - -#include +#include "variable.h" +#include "utils.h" +#include "memory.h" +#include "error.h" using namespace LAMMPS_NS; using namespace FixConst; @@ -141,86 +142,72 @@ 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 + } else { ArgInfo argi(arg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE |ArgInfo::DNAME|ArgInfo::INAME); @@ -234,6 +221,7 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : ids[nvalues] = argi.copy_name(); nvalues++; } + iarg++; } @@ -274,20 +262,6 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR, "Fix store/state compute array is accessed out-of-range"); - } else if (which[i] == ArgInfo::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] == ArgInfo::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] == ArgInfo::FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) @@ -315,6 +289,42 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : 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[i] == ArgInfo::DNAME) { + 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::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"); + } } } @@ -392,22 +402,6 @@ void FixStoreState::init() error->all(FLERR,"Compute ID for fix store/state does not exist"); value2index[m] = icompute; - } else if (which[m] == ArgInfo::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] == ArgInfo::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] == ArgInfo::FIX) { int ifix = modify->find_fix(ids[m]); if (ifix < 0) @@ -419,6 +413,13 @@ 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] == ArgInfo::INAME || which[m] == ArgInfo::DNAME) { + int icustom,iflag,cols; + icustom = atom->find_custom(ids[m],iflag,cols); + if (icustom < 0) + error->all(FLERR,"Custom vector/array for fix store/state does not exist"); + value2index[m] = icustom; } } } @@ -504,22 +505,37 @@ 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] == ArgInfo::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] == ArgInfo::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] == ArgInfo::VARIABLE) { input->variable->compute_atom(n,igroup,&values[0][m],nvalues,0); + + + // access custom atom vector/array fields + + } 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::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/imbalance_store.cpp b/src/imbalance_store.cpp index d03e44bca6..2437395dda 100644 --- a/src/imbalance_store.cpp +++ b/src/imbalance_store.cpp @@ -44,18 +44,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/library.cpp b/src/library.cpp index f534af0925..db609351f7 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2804,9 +2804,10 @@ void lammps_gather_bonds(void *handle, void *data) 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 @@ -2827,12 +2828,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; @@ -2844,10 +2846,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 && utils::strmatch(name,"^f_")) { // fix + // fix + + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -2880,7 +2883,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 && utils::strmatch(name,"^c_")) { // compute + // compute + + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -2907,42 +2912,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 + // custom fix property/atom vector or array + + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { + + 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 ((vptr == nullptr) && (utils::strmatch(name,"^[di]_"))) { - fcid = lmp->atom->find_custom(&name[2], ltype); 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]; + } } + // no match + 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; @@ -2984,7 +3005,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; @@ -3024,9 +3044,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 @@ -3050,9 +3071,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; @@ -3062,12 +3084,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 && utils::strmatch(name,"^f_")) { // fix + // fix + + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3078,22 +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; } @@ -3101,7 +3118,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 && utils::strmatch(name,"^c_")) { // compute + // compute + + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3112,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; } @@ -3128,39 +3145,51 @@ 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 && utils::strmatch(name,"^[di]_")) { // property / atom + // custom per-atom vector or array + + if ((vptr==nullptr) && utils::strmatch(name,"^[id]2?_")) { + + if (utils::strmatch(name,"^[id]_")) fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); - fcid = lmp->atom->find_custom(&name[2], ltype); 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) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_concat: " - "property/atom has count=1"); + 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"); 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]; + } } + // no match + 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; } @@ -3175,6 +3204,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; @@ -3265,9 +3295,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 @@ -3290,13 +3321,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; @@ -3308,7 +3340,9 @@ void lammps_gather_subset(void *handle, char *name, void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && utils::strmatch(name,"^f_")) { // fix + // fix + + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3323,17 +3357,13 @@ 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"); + 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; } @@ -3341,7 +3371,9 @@ void lammps_gather_subset(void *handle, char *name, else vptr = (void *) lmp->modify->fix[fcid]->array_atom; } - if (vptr==nullptr && utils::strmatch(name,"^c_")) { // compute + // compute + + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3352,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; } @@ -3368,39 +3398,52 @@ 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 && utils::strmatch(name,"^[di]_")) { // property / atom + // custom fix property/atom vector or array + + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { + + if (utils::strmatch(name,"^[id]_")) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); - fcid = lmp->atom->find_custom(&name[2], ltype); 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) { + if (count == 1 && icol != 0) { if (lmp->comm->me == 0) - lmp->error->warning(FLERR,"lammps_gather_subset: " - "property/atom has count=1"); + lmp->error->warning(FLERR,"lammps_gather_subset: 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]; + } } + // no match + 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; } @@ -3458,6 +3501,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; @@ -3500,9 +3544,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 @@ -3526,7 +3571,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? @@ -3543,10 +3588,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 && utils::strmatch(name,"^f_")) { // fix + // fix + + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3572,7 +3618,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 && utils::strmatch(name,"^c_")) { // compute + // compute + + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3599,33 +3647,49 @@ 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 && utils::strmatch(name,"^[di]_")) { // property / atom + // custom fix property/atom vector or array + + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { + + if (utils::strmatch(name,"^[id]_")) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); - fcid = lmp->atom->find_custom(&name[2], ltype); 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]; + } } + // no match + if (vptr == nullptr) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter: unknown property name"); @@ -3702,7 +3766,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 @@ -3726,7 +3793,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 @@ -3744,7 +3811,9 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, void *vptr = lmp->atom->extract(name); - if (vptr==nullptr && utils::strmatch(name,"^f_")) { // fix + // fix + + if (vptr==nullptr && utils::strmatch(name,"^f_")) { fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { @@ -3770,7 +3839,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 && utils::strmatch(name,"^c_")) { // compute + // compute + + if (vptr==nullptr && utils::strmatch(name,"^c_")) { fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { @@ -3799,31 +3870,47 @@ void lammps_scatter_subset(void *handle, char *name,int type, int count, else vptr = (void *) lmp->modify->compute[fcid]->array_atom; } - if (vptr==nullptr && utils::strmatch(name,"^[di]_")) { // property / atom + // custom fix property/atom vector or array + + if ((vptr == nullptr) && utils::strmatch(name,"^[id]2?_")) { + + if (utils::strmatch(name,"^[id]_")) + fcid = lmp->atom->find_custom(&name[2],ltype,icol); + else fcid = lmp->atom->find_custom(&name[3],ltype,icol); - fcid = lmp->atom->find_custom(&name[2], ltype); 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) { + 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]; + } } + // no match + if (vptr == nullptr) { if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter_atoms_subset: " diff --git a/src/modify.cpp b/src/modify.cpp index 06b3c6cdb9..cac26ffe51 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); diff --git a/src/nbin_multi.cpp b/src/nbin_multi.cpp index 1ddb1d69bd..c58f2b9a94 100644 --- a/src/nbin_multi.cpp +++ b/src/nbin_multi.cpp @@ -202,7 +202,7 @@ void NBinMulti::setup_bins(int /*style*/) // test for too many global bins in any dimension due to huge global domain if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT || - bbox[2]*binsizeinv > MAXSMALLINT) + bbox[2]*binsizeinv > MAXSMALLINT) error->all(FLERR,"Domain too large for neighbor bins"); // create actual bins @@ -233,7 +233,7 @@ void NBinMulti::setup_bins(int /*style*/) bininvz_multi[n] = 1.0 / binsizez_multi[n]; if (binsize_optimal*bininvx_multi[n] > CUT2BIN_RATIO || - binsize_optimal*bininvy_multi[n] > CUT2BIN_RATIO) + binsize_optimal*bininvy_multi[n] > CUT2BIN_RATIO) error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); if ((dimension == 3) && (binsize_optimal*bininvz_multi[n] > CUT2BIN_RATIO)) error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 5b4b1c4923..b7217926ca 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -528,6 +528,7 @@ void Neighbor::init() for (int isub=0; isub < ph->nstyles; ++isub) { if (force->pair_match("coul/wolf",0,isub) || force->pair_match("coul/dsf",0,isub) + || force->pair_match("coul/exclude",0) || force->pair_match("thole",0,isub)) ++flag; } @@ -536,6 +537,7 @@ void Neighbor::init() } else { if (force->pair_match("coul/wolf",0) || force->pair_match("coul/dsf",0) + || force->pair_match("coul/exclude",0) || force->pair_match("thole",0)) special_flag[1] = special_flag[2] = special_flag[3] = 2; } diff --git a/src/npair_full_multi.cpp b/src/npair_full_multi.cpp index 6a9ba8e700..34b7a7bfa8 100644 --- a/src/npair_full_multi.cpp +++ b/src/npair_full_multi.cpp @@ -89,7 +89,7 @@ void NPairFullMulti::build(NeighList *list) // if same collection use own bin if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in surrounding bins in stencil including self // skip i = j @@ -99,34 +99,34 @@ void NPairFullMulti::build(NeighList *list) ns = nstencil_multi[icollection][jcollection]; for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (i == j) continue; + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { + if (i == j) continue; jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } } } diff --git a/src/npair_half_multi_newtoff.cpp b/src/npair_half_multi_newtoff.cpp index 9aa9628fd6..cef28f4cb4 100644 --- a/src/npair_half_multi_newtoff.cpp +++ b/src/npair_half_multi_newtoff.cpp @@ -91,7 +91,7 @@ void NPairHalfMultiNewtoff::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in other bins in stencil including self // only store pair if i < j @@ -103,16 +103,16 @@ void NPairHalfMultiNewtoff::build(NeighList *list) ns = nstencil_multi[icollection][jcollection]; for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { + if (j <= i) continue; jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq <= cutneighsq[itype][jtype]) { diff --git a/src/npair_half_multi_newton.cpp b/src/npair_half_multi_newton.cpp index 3b1b34579b..3ee4ce5fde 100644 --- a/src/npair_half_multi_newton.cpp +++ b/src/npair_half_multi_newton.cpp @@ -90,7 +90,7 @@ void NPairHalfMultiNewton::build(NeighList *list) // if same collection use own bin if(icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // if same size: uses half stencil so check central bin if(cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -106,41 +106,41 @@ void NPairHalfMultiNewton::build(NeighList *list) // if j is owned atom, store it if j > i // if j is ghost, only store if j coords are "above and to the right" of i - for (j = js; j >= 0; j = bins[j]) { + for (j = js; j >= 0; j = bins[j]) { if((icollection != jcollection) && (j < i)) continue; - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } } // for all collections, loop over all atoms in other bins in stencil, store every pair @@ -148,38 +148,38 @@ void NPairHalfMultiNewton::build(NeighList *list) // stencil is half if i same size as j // stencil is full if i smaller than j - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } } ilist[inum++] = i; diff --git a/src/npair_half_multi_newton_tri.cpp b/src/npair_half_multi_newton_tri.cpp index 4cc88a3755..4a8bb8e19f 100644 --- a/src/npair_half_multi_newton_tri.cpp +++ b/src/npair_half_multi_newton_tri.cpp @@ -90,7 +90,7 @@ void NPairHalfMultiNewtonTri::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in bins in stencil // stencil is empty if i larger than j @@ -101,12 +101,12 @@ void NPairHalfMultiNewtonTri::build(NeighList *list) // (equal zyx and j <= i) // latter excludes self-self interaction but allows superposed atoms - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { // if same size (same collection), use half stencil if(cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -123,28 +123,28 @@ void NPairHalfMultiNewtonTri::build(NeighList *list) jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular != Atom::ATOMIC) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - } + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular != Atom::ATOMIC) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } } ilist[inum++] = i; diff --git a/src/npair_half_size_multi_newtoff.cpp b/src/npair_half_size_multi_newtoff.cpp index f11f8c49cc..cb06ddfb6f 100644 --- a/src/npair_half_size_multi_newtoff.cpp +++ b/src/npair_half_size_multi_newtoff.cpp @@ -81,7 +81,7 @@ void NPairHalfSizeMultiNewtoff::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in other bins in stencil including self // only store pair if i < j @@ -93,27 +93,27 @@ void NPairHalfSizeMultiNewtoff::build(NeighList *list) ns = nstencil_multi[icollection][jcollection]; for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { - if (j <= i) continue; + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { + if (j <= i) continue; jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } + } } } diff --git a/src/npair_half_size_multi_newton.cpp b/src/npair_half_size_multi_newton.cpp index 376bf5f3b4..8af60aa435 100644 --- a/src/npair_half_size_multi_newton.cpp +++ b/src/npair_half_size_multi_newton.cpp @@ -78,7 +78,7 @@ void NPairHalfSizeMultiNewton::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // if same size: uses half stencil so check central bin if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -94,33 +94,33 @@ void NPairHalfSizeMultiNewton::build(NeighList *list) // if j is owned atom, store it if j > i // if j is ghost, only store if j coords are "above and to the right" of i - for (j = js; j >= 0; j = bins[j]) { + for (j = js; j >= 0; j = bins[j]) { if ((icollection != jcollection) && (j < i)) continue; - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } } } @@ -129,30 +129,30 @@ void NPairHalfSizeMultiNewton::build(NeighList *list) // stencil is half if i same size as j // stencil is full if i smaller than j - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } + } } } diff --git a/src/npair_half_size_multi_newton_tri.cpp b/src/npair_half_size_multi_newton_tri.cpp index 6b96fd4849..20d4d8b421 100644 --- a/src/npair_half_size_multi_newton_tri.cpp +++ b/src/npair_half_size_multi_newton_tri.cpp @@ -78,7 +78,7 @@ void NPairHalfSizeMultiNewtonTri::build(NeighList *list) // if same collection use own bin if (icollection == jcollection) jbin = ibin; - else jbin = coord2bin(x[i], jcollection); + else jbin = coord2bin(x[i], jcollection); // loop over all atoms in bins in stencil // stencil is empty if i larger than j @@ -89,12 +89,12 @@ void NPairHalfSizeMultiNewtonTri::build(NeighList *list) // (equal zyx and j <= i) // latter excludes self-self interaction but allows superposed atoms - s = stencil_multi[icollection][jcollection]; - ns = nstencil_multi[icollection][jcollection]; + s = stencil_multi[icollection][jcollection]; + ns = nstencil_multi[icollection][jcollection]; - for (k = 0; k < ns; k++) { - js = binhead_multi[jcollection][jbin + s[k]]; - for (j = js; j >= 0; j = bins[j]) { + for (k = 0; k < ns; k++) { + js = binhead_multi[jcollection][jbin + s[k]]; + for (j = js; j >= 0; j = bins[j]) { // if same size (same collection), use half stencil if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){ @@ -111,21 +111,21 @@ void NPairHalfSizeMultiNewtonTri::build(NeighList *list) jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - radsum = radi + radius[j]; - cutdistsq = (radsum+skin) * (radsum+skin); + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + radsum = radi + radius[j]; + cutdistsq = (radsum+skin) * (radsum+skin); - if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; - } - } - } + if (rsq <= cutdistsq) { + if (history && rsq < radsum*radsum) + neighptr[n++] = j ^ mask_history; + else + neighptr[n++] = j; + } + } + } } ilist[inum++] = i; diff --git a/src/nstencil.cpp b/src/nstencil.cpp index 3d1f71a890..fdd0ddfb1b 100644 --- a/src/nstencil.cpp +++ b/src/nstencil.cpp @@ -335,7 +335,7 @@ void NStencil::create_setup() for (i = 0; i < n; ++i) { stencil_multi[i] = new int*[n](); for (j = 0; j < n; ++j) { - maxstencil_multi[i][j] = 0; + maxstencil_multi[i][j] = 0; nstencil_multi[i][j] = 0; stencil_multi[i][j] = nullptr; } @@ -390,7 +390,7 @@ void NStencil::create_setup() if(stencil_multi[i][j]) memory->destroy(stencil_multi[i][j]); memory->create(stencil_multi[i][j], smax, - "neighstencil::stencil_multi"); + "neighstencil::stencil_multi"); } } } diff --git a/src/nstencil_full_multi_2d.cpp b/src/nstencil_full_multi_2d.cpp index 7899ce7ad1..893798ce31 100644 --- a/src/nstencil_full_multi_2d.cpp +++ b/src/nstencil_full_multi_2d.cpp @@ -77,7 +77,7 @@ void NStencilFullMulti2d::create() for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance_multi(i,j,0,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; + stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; nstencil_multi[icollection][jcollection] = ns; } diff --git a/src/nstencil_full_multi_3d.cpp b/src/nstencil_full_multi_3d.cpp index 746906bf47..3265dac884 100644 --- a/src/nstencil_full_multi_3d.cpp +++ b/src/nstencil_full_multi_3d.cpp @@ -80,8 +80,8 @@ void NStencilFullMulti3d::create() for (k = -sz; k <= sz; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i,j,k,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = + if (bin_distance_multi(i,j,k,bin_collection) < cutsq) + stencil_multi[icollection][jcollection][ns++] = k*mbiny*mbinx + j*mbinx + i; nstencil_multi[icollection][jcollection] = ns; diff --git a/src/nstencil_half_multi_2d.cpp b/src/nstencil_half_multi_2d.cpp index 3428388ef1..ebcf26b290 100644 --- a/src/nstencil_half_multi_2d.cpp +++ b/src/nstencil_half_multi_2d.cpp @@ -92,12 +92,12 @@ void NStencilHalfMulti2d::create() if (j > 0 || (j == 0 && i > 0)) { if (bin_distance_multi(i,j,0,bin_collection) < cutsq) stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; - } + } } else { for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance_multi(i,j,0,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; + stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; } nstencil_multi[icollection][jcollection] = ns; diff --git a/src/nstencil_half_multi_2d_tri.cpp b/src/nstencil_half_multi_2d_tri.cpp index 5b647902fb..621e033fb6 100644 --- a/src/nstencil_half_multi_2d_tri.cpp +++ b/src/nstencil_half_multi_2d_tri.cpp @@ -90,12 +90,12 @@ void NStencilHalfMulti2dTri::create() for (j = 0; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance_multi(i,j,0,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; + stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; } else { for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i,j,0,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; + if (bin_distance_multi(i,j,0,bin_collection) < cutsq) + stencil_multi[icollection][jcollection][ns++] = j*mbinx + i; } nstencil_multi[icollection][jcollection] = ns; diff --git a/src/nstencil_half_multi_3d.cpp b/src/nstencil_half_multi_3d.cpp index 3623fd14ea..a3392f164a 100644 --- a/src/nstencil_half_multi_3d.cpp +++ b/src/nstencil_half_multi_3d.cpp @@ -92,17 +92,17 @@ void NStencilHalfMulti3d::create() for (k = 0; k <= sz; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) { - if (bin_distance_multi(i,j,k,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = + if (k > 0 || j > 0 || (j == 0 && i > 0)) { + if (bin_distance_multi(i,j,k,bin_collection) < cutsq) + stencil_multi[icollection][jcollection][ns++] = k*mbiny*mbinx + j*mbinx + i; - } + } } else { for (k = -sz; k <= sz; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i,j,k,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = + if (bin_distance_multi(i,j,k,bin_collection) < cutsq) + stencil_multi[icollection][jcollection][ns++] = k*mbiny*mbinx + j*mbinx + i; } diff --git a/src/nstencil_half_multi_3d_tri.cpp b/src/nstencil_half_multi_3d_tri.cpp index 9a680cf610..160d04bd61 100644 --- a/src/nstencil_half_multi_3d_tri.cpp +++ b/src/nstencil_half_multi_3d_tri.cpp @@ -93,14 +93,14 @@ void NStencilHalfMulti3dTri::create() for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance_multi(i,j,k,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = + stencil_multi[icollection][jcollection][ns++] = k*mbiny*mbinx + j*mbinx + i; } else { for (k = -sz; k <= sz; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (bin_distance_multi(i,j,k,bin_collection) < cutsq) - stencil_multi[icollection][jcollection][ns++] = + if (bin_distance_multi(i,j,k,bin_collection) < cutsq) + stencil_multi[icollection][jcollection][ns++] = k*mbiny*mbinx + j*mbinx + i; } diff --git a/src/pair.h b/src/pair.h index 0c082fa1c5..f37c0732ed 100644 --- a/src/pair.h +++ b/src/pair.h @@ -143,8 +143,6 @@ class Pair : protected Pointers { void v_tally2_newton(int, double *, double *); void v_tally3(int, int, int, double *, double *, double *, double *); void v_tally4(int, int, int, int, double *, double *, double *, double *, double *, double *); - void ev_tally_xyz(int, int, int, int, double, double, double, double, double, double, double, - double); // general child-class methods @@ -274,6 +272,8 @@ class Pair : protected Pointers { void ev_tally4(int, int, int, int, double, double *, double *, double *, double *, double *, double *); void ev_tally_tip4p(int, int *, double *, double, double); + void ev_tally_xyz(int, int, int, int, double, double, double, double, double, double, double, + double); void v_tally2(int, int, double, double *); void v_tally_tensor(int, int, int, int, double, double, double, double, double, double); void virial_fdotr_compute(); diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 550f5c6873..0ba16f29fa 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -581,18 +581,17 @@ void PairHybrid::init_style() for (i = 1; i < 4; ++i) { if (((force->special_lj[i] == 0.0) || (force->special_lj[i] == 1.0)) && (force->special_lj[i] != special_lj[istyle][i])) - error->all(FLERR,"Pair_modify special setting for pair hybrid " - "incompatible with global special_bonds setting"); + error->all(FLERR,"Pair_modify special lj 1-{} setting for pair hybrid substyle {} " + "incompatible with global special_bonds setting", i+1, keywords[istyle]); } } if (special_coul[istyle]) { for (i = 1; i < 4; ++i) { - if (((force->special_coul[i] == 0.0) - || (force->special_coul[i] == 1.0)) + if (((force->special_coul[i] == 0.0) || (force->special_coul[i] == 1.0)) && (force->special_coul[i] != special_coul[istyle][i])) - error->all(FLERR,"Pair_modify special setting for pair hybrid " - "incompatible with global special_bonds setting"); + error->all(FLERR,"Pair_modify special coul 1-{} setting for pair hybrid substyle {} " + "incompatible with global special_bonds setting", i+1, keywords[istyle]); } } } diff --git a/src/pair_hybrid.h b/src/pair_hybrid.h index e3a2b1a562..ab696e279c 100644 --- a/src/pair_hybrid.h +++ b/src/pair_hybrid.h @@ -28,13 +28,14 @@ class PairHybrid : public Pair { friend class ComputeSpin; friend class FixGPU; friend class FixIntel; - friend class FixOMP; friend class FixNVESpin; + friend class FixOMP; friend class Force; friend class Info; friend class Neighbor; - friend class Respa; friend class PairDeprecated; + friend class Respa; + friend class Scafacos; public: PairHybrid(class LAMMPS *); 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/set.cpp b/src/set.cpp index e8555774ac..2966106345 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" @@ -44,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 @@ -570,29 +571,64 @@ void Set::command(int narg, char **arg) set(DPDTHETA); iarg += 2; - } 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; - 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 { - } 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; - 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); - iarg += 2; + // set custom per-atom vector or array or error out - } else error->all(FLERR,"Illegal set command"); + int flag,cols; + 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); + + switch (argi.get_type()) { + + 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; + } // statistics // for CC option, include species index @@ -967,20 +1003,29 @@ void Set::set(int keyword) (((imageint) (zbox + IMGMAX) & IMGMASK) << IMG2BITS); } - // set value for custom integer or double vector + // set value for custom property 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 35d258b5db..f3ccefbd9d 100644 --- a/src/set.h +++ b/src/set.h @@ -32,7 +32,7 @@ class Set : public Command { 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; diff --git a/src/special.cpp b/src/special.cpp index 8a3b991fea..dcc0d0c0ad 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -237,10 +237,8 @@ void Special::onetwo_build_newton() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), - 0,proclist, - rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -371,10 +369,8 @@ void Special::onethree_build() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), - 0,proclist, - rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -475,10 +471,8 @@ void Special::onefour_build() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), - 0,proclist, - rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -898,10 +892,8 @@ void Special::angle_trim() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), - 0,proclist, - rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -1111,10 +1103,8 @@ void Special::dihedral_trim() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), - 0,proclist, - rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -1246,9 +1236,8 @@ int Special::rendezvous_ids(int n, char *inbuf, outbuf = same list of N PairRvous datums, routed to different procs ------------------------------------------------------------------------- */ -int Special::rendezvous_pairs(int n, char *inbuf, - int &flag, int *&proclist, char *&outbuf, - void *ptr) +int Special::rendezvous_pairs(int n, char *inbuf, int &flag, int *&proclist, + char *&outbuf, void *ptr) { Special *sptr = (Special *) ptr; Atom *atom = sptr->atom; diff --git a/src/utils.cpp b/src/utils.cpp index d70ae6f000..528908807c 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" @@ -213,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]; @@ -242,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]; @@ -542,18 +543,26 @@ 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/property ID, the wildcard and trailing text - // split off the compute/fix 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); + // compute + if (word[0] == 'c') { int icompute = lmp->modify->find_compute(id); @@ -575,6 +584,9 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod expandflag = 1; } } + + // fix + } else if (word[0] == 'f') { int ifix = lmp->modify->find_fix(id); @@ -597,9 +609,28 @@ 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 + + } 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)) { + + // check for custom per-atom array + + if (((word[0] == 'i') && (flag == 0)) || ((word[0] == 'd') && (flag == 1))) { + nmax = cols; + expandflag = 1; + } + } } } + // expansion will take place + if (expandflag) { // expand wild card string to nlo/nhi numbers @@ -611,11 +642,9 @@ 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)); + earg[newarg] = utils::strdup(fmt::format("{}2_{}[{}]{}", word[0], id, index, tail)); newarg++; } - } else { // no expansion: duplicate original string if (newarg == maxarg) { diff --git a/tools/valgrind/OpenMP.supp b/tools/valgrind/OpenMP.supp index 0820100b94..e1870e668c 100644 --- a/tools/valgrind/OpenMP.supp +++ b/tools/valgrind/OpenMP.supp @@ -123,3 +123,14 @@ ... obj:* } +{ + OpnMP_init_part11 + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + ... + fun:allocate_dtv + ... + fun:GOMP_parallel + obj:* +} diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 23858f93b9..a14e568fb7 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -278,6 +278,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // init_stress auto stress = lmp->force->pair->virial; + // avoid false positives on tiny stresses. force to zero instead. + for (int i = 0; i < 6; ++i) if (fabs(stress[i]) < 1.0e-13) stress[i] = 0.0; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("init_stress", block); @@ -302,6 +304,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // run_stress stress = lmp->force->pair->virial; + // avoid false positives on tiny stresses. force to zero instead. + for (int i = 0; i < 6; ++i) if (fabs(stress[i]) < 1.0e-13) stress[i] = 0.0; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); diff --git a/unittest/force-styles/tests/data.bilayer b/unittest/force-styles/tests/data.bilayer new file mode 100644 index 0000000000..101bb02480 --- /dev/null +++ b/unittest/force-styles/tests/data.bilayer @@ -0,0 +1,72 @@ +LAMMPS data file. CGCMM style. atom_style full generated by VMD/TopoTools v1.8 on Sun Aug 15 17:12:56 EDT 2021 + 48 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + 3 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + 0 7.38 xlo xhi + 0 8.58 ylo yhi + 0 10.0 zlo zhi + + Masses + + 1 11.000000 # 1 + 2 14.000000 # 2 + 3 12.000000 # 3 + + Atoms # full + +1 1 2 -0.420000 0.000000 0.715000 0.000000 # 2 +2 1 1 0.420000 0.000000 2.145000 0.000000 # 1 +3 1 2 -0.420000 1.238416 2.860000 0.000000 # 2 +4 1 1 0.420000 1.238416 4.290000 0.000000 # 1 +5 1 2 -0.420000 0.000000 5.005000 0.000000 # 2 +6 1 1 0.420000 0.000000 6.435000 0.000000 # 1 +7 1 2 -0.420000 1.238416 7.150000 0.000000 # 2 +8 1 1 0.420000 1.238416 8.580000 0.000000 # 1 +9 1 2 -0.420000 2.476833 0.715000 0.000000 # 2 +10 1 1 0.420000 2.476833 2.145000 0.000000 # 1 +11 1 2 -0.420000 3.715249 2.860000 0.000000 # 2 +12 1 1 0.420000 3.715249 4.290000 0.000000 # 1 +13 1 2 -0.420000 2.476833 5.005000 0.000000 # 2 +14 1 1 0.420000 2.476833 6.435000 0.000000 # 1 +15 1 2 -0.420000 3.715249 7.150000 0.000000 # 2 +16 1 1 0.420000 3.715249 8.580000 0.000000 # 1 +17 1 2 -0.420000 4.953665 0.715000 0.000000 # 2 +18 1 1 0.420000 4.953665 2.145000 0.000000 # 1 +19 1 2 -0.420000 6.192081 2.860000 0.000000 # 2 +20 1 1 0.420000 6.192081 4.290000 0.000000 # 1 +21 1 2 -0.420000 4.953665 5.005000 0.000000 # 2 +22 1 1 0.420000 4.953665 6.435000 0.000000 # 1 +23 1 2 -0.420000 6.192081 7.150000 0.000000 # 2 +24 1 1 0.420000 6.192081 8.580000 0.000000 # 1 +25 2 3 0.000000 1.238416 1.430000 3.330000 # 3 +26 2 3 0.000000 0.000000 2.145000 3.330000 # 3 +27 2 3 0.000000 0.000000 3.575000 3.330000 # 3 +28 2 3 0.000000 1.238416 4.290000 3.330000 # 3 +29 2 3 0.000000 1.238416 5.720000 3.330000 # 3 +30 2 3 0.000000 0.000000 6.435000 3.330000 # 3 +31 2 3 0.000000 0.000000 7.865000 3.330000 # 3 +32 2 3 0.000000 1.238416 8.580000 3.330000 # 3 +33 2 3 0.000000 3.715249 1.430000 3.330000 # 3 +34 2 3 0.000000 2.476833 2.145000 3.330000 # 3 +35 2 3 0.000000 2.476833 3.575000 3.330000 # 3 +36 2 3 0.000000 3.715249 4.290000 3.330000 # 3 +37 2 3 0.000000 3.715249 5.720000 3.330000 # 3 +38 2 3 0.000000 2.476833 6.435000 3.330000 # 3 +39 2 3 0.000000 2.476833 7.865000 3.330000 # 3 +40 2 3 0.000000 3.715249 8.580000 3.330000 # 3 +41 2 3 0.000000 6.192081 1.430000 3.330000 # 3 +42 2 3 0.000000 4.953665 2.145000 3.330000 # 3 +43 2 3 0.000000 4.953665 3.575000 3.330000 # 3 +44 2 3 0.000000 6.192081 4.290000 3.330000 # 3 +45 2 3 0.000000 6.192081 5.720000 3.330000 # 3 +46 2 3 0.000000 4.953665 6.435000 3.330000 # 3 +47 2 3 0.000000 4.953665 7.865000 3.330000 # 3 +48 2 3 0.000000 6.192081 8.580000 3.330000 # 3 + diff --git a/unittest/force-styles/tests/in.bilayer b/unittest/force-styles/tests/in.bilayer new file mode 100644 index 0000000000..6ce26ecc71 --- /dev/null +++ b/unittest/force-styles/tests/in.bilayer @@ -0,0 +1,16 @@ +variable newton_pair index on +variable newton_bond index on +variable units index metal +variable input_dir index . +variable data_file index ${input_dir}/data.bilayer +variable pair_style index 'zero 8.0' + +atom_style full +atom_modify map array +neigh_modify delay 2 every 2 check no +units ${units} +timestep 0.0001 +newton ${newton_pair} ${newton_bond} + +pair_style ${pair_style} +read_data ${data_file} diff --git a/unittest/force-styles/tests/manybody-pair-drip.yaml b/unittest/force-styles/tests/manybody-pair-drip.yaml new file mode 100644 index 0000000000..e5d4915c4d --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-drip.yaml @@ -0,0 +1,125 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Tue Aug 17 15:09:48 2021 +epsilon: 5e-14 +skip_tests: single +prerequisites: ! | + pair drip + atom full +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on +post_commands: ! "" +input_file: in.bilayer +pair_style: hybrid/overlay drip +pair_coeff: ! | + * * drip C.drip C C C +extract: ! "" +natoms: 48 +init_vdwl: -1.1171061429439093 +init_coul: 0 +init_stress: ! |- + -6.9372049706365035e-01 -6.9064113154966333e-01 1.1515233668963607e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.4292420626121039e-02 +init_forces: ! |2 + 1 1.4969082430352958e-03 -3.2939836241196573e-05 -1.3240430862322900e-02 + 2 8.0767187286290179e-04 1.0588928659053852e-03 -3.1123566690577253e-02 + 3 -3.4497099855045673e-04 3.4248846132303140e-05 -1.0175437155229471e-02 + 4 -2.4589156252144417e-04 1.8156645561760292e-05 -2.9695125191752228e-02 + 5 1.4969082430352932e-03 -3.2939836241182343e-05 -1.3240430862323165e-02 + 6 8.0767187286288694e-04 1.0588928659049949e-03 -3.1123566690577420e-02 + 7 -3.4497099855038821e-04 3.4248846132523362e-05 -1.0175437155229110e-02 + 8 -2.4589156252142683e-04 1.8156645561707817e-05 -2.9695125191752388e-02 + 9 -1.3423014800966740e-04 7.4485503462573500e-08 -1.0127230298720345e-02 + 10 -1.2282979196216780e-04 -5.3179137282562149e-06 -2.9857221873835556e-02 + 11 1.3420646745295351e-04 7.2570324572774139e-08 -1.0127289412755367e-02 + 12 1.2281957667447806e-04 -5.2981576756526129e-06 -2.9857246714720800e-02 + 13 -1.3423014800966089e-04 7.4485503475472118e-08 -1.0127230298720606e-02 + 14 -1.2282979196215913e-04 -5.3179137286977698e-06 -2.9857221873835549e-02 + 15 1.3420646745295687e-04 7.2570324835217239e-08 -1.0127289412755180e-02 + 16 1.2281957667447502e-04 -5.2981576756378754e-06 -2.9857246714720957e-02 + 17 3.4500424726267094e-04 3.4247597717764226e-05 -1.0175497243327751e-02 + 18 2.4590943990438825e-04 1.8176873676577221e-05 -2.9695147824251051e-02 + 19 -1.4969178111888977e-03 -3.2939169475935731e-05 -1.3240431836380913e-02 + 20 -8.0767953495986997e-04 1.0588933379664879e-03 -3.1123564482199977e-02 + 21 3.4500424726266232e-04 3.4247597717770589e-05 -1.0175497243328002e-02 + 22 2.4590943990438212e-04 1.8176873676178533e-05 -2.9695147824251072e-02 + 23 -1.4969178111887745e-03 -3.2939169475980779e-05 -1.3240431836380712e-02 + 24 -8.0767953495988450e-04 1.0588933379664870e-03 -3.1123564482199943e-02 + 25 -3.4497099855045933e-04 -3.4248846132324567e-05 1.0175437155229457e-02 + 26 8.0767187286290309e-04 -1.0588928659053826e-03 3.1123566690577247e-02 + 27 1.4969082430351102e-03 3.2939836241083992e-05 1.3240430862322843e-02 + 28 -2.4589156252142509e-04 -1.8156645561688708e-05 2.9695125191752263e-02 + 29 -3.4497099855046193e-04 -3.4248846132538534e-05 1.0175437155229280e-02 + 30 8.0767187286257902e-04 -1.0588928659051909e-03 3.1123566690576712e-02 + 31 1.4969082430352915e-03 3.2939836241593784e-05 1.3240430862323165e-02 + 32 -2.4589156252143897e-04 -1.8156645561741183e-05 2.9695125191752519e-02 + 33 1.3420646745296197e-04 -7.2570324595813435e-08 1.0127289412755341e-02 + 34 -1.2282979196217170e-04 5.3179137282585121e-06 2.9857221873835549e-02 + 35 -1.3423014800966349e-04 -7.4485503448870201e-08 1.0127230298720332e-02 + 36 1.2281957667447611e-04 5.2981576756533134e-06 2.9857246714720946e-02 + 37 1.3420646745295709e-04 -7.2570324815599003e-08 1.0127289412755423e-02 + 38 -1.2282979196223502e-04 5.3179137282683716e-06 2.9857221873835008e-02 + 39 -1.3423014800966436e-04 -7.4485503047341829e-08 1.0127230298720473e-02 + 40 1.2281957667448912e-04 5.2981576756629069e-06 2.9857246714721068e-02 + 41 -1.4969178111890833e-03 3.2939169476025510e-05 1.3240431836380942e-02 + 42 2.4590943990438738e-04 -1.8176873676568727e-05 2.9695147824251211e-02 + 43 3.4500424726266921e-04 -3.4247597717747861e-05 1.0175497243327740e-02 + 44 -8.0767953495988342e-04 -1.0588933379665052e-03 3.1123564482200137e-02 + 45 -1.4969178111890772e-03 3.2939169475814605e-05 1.3240431836381151e-02 + 46 2.4590943990439947e-04 -1.8176873676638302e-05 2.9695147824250822e-02 + 47 3.4500424726267181e-04 -3.4247597717339300e-05 1.0175497243327872e-02 + 48 -8.0767953495988081e-04 -1.0588933379665191e-03 3.1123564482200175e-02 +run_vdwl: -1.117107802396835 +run_coul: 0 +run_stress: ! |- + -6.9372331738514981e-01 -6.9064389597684106e-01 1.1514755915204005e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.4292266024218578e-02 +run_forces: ! |2 + 1 1.4968783498999268e-03 -3.2942052376323016e-05 -1.3240066826206463e-02 + 2 8.0765258918550525e-04 1.0588876993623385e-03 -3.1122680612106914e-02 + 3 -3.4497601095719033e-04 3.4248722599748424e-05 -1.0175117216209249e-02 + 4 -2.4589406964898274e-04 1.8152777475380989e-05 -2.9694273916151235e-02 + 5 1.4968783498999624e-03 -3.2942052376244425e-05 -1.3240066826206844e-02 + 6 8.0765258918545808e-04 1.0588876993621239e-03 -3.1122680612107538e-02 + 7 -3.4497601095719900e-04 3.4248722599828465e-05 -1.0175117216209020e-02 + 8 -2.4589406964903478e-04 1.8152777475390449e-05 -2.9694273916151363e-02 + 9 -1.3423039571159017e-04 7.4352071961005858e-08 -1.0126910355491514e-02 + 10 -1.2282852371682442e-04 -5.3193547176900636e-06 -2.9856374341201718e-02 + 11 1.3420671579929917e-04 7.2436845184776077e-08 -1.0126969468728588e-02 + 12 1.2281830883230783e-04 -5.2995986749039537e-06 -2.9856399181457216e-02 + 13 -1.3423039571157673e-04 7.4352071584718248e-08 -1.0126910355491585e-02 + 14 -1.2282852371668521e-04 -5.3193547179922104e-06 -2.9856374341201371e-02 + 15 1.3420671579938970e-04 7.2436845150855372e-08 -1.0126969468727908e-02 + 16 1.2281830883232204e-04 -5.2995986749016624e-06 -2.9856399181457466e-02 + 17 3.4500925912102327e-04 3.4247474141055654e-05 -1.0175177303529336e-02 + 18 2.4591194664583894e-04 1.8173005537505662e-05 -2.9694296547973523e-02 + 19 -1.4968879181501723e-03 -3.2941385606868446e-05 -1.3240067800288987e-02 + 20 -8.0766025129906183e-04 1.0588881713794161e-03 -3.1122678403683279e-02 + 21 3.4500925912095290e-04 3.4247474141253548e-05 -1.0175177303529138e-02 + 22 2.4591194664620069e-04 1.8173005537513167e-05 -2.9694296547973627e-02 + 23 -1.4968879181501166e-03 -3.2941385606789733e-05 -1.3240067800288646e-02 + 24 -8.0766025129901347e-04 1.0588881713797244e-03 -3.1122678403683594e-02 + 25 -3.4497543410367832e-04 -3.4248542243049007e-05 1.0175095227569254e-02 + 26 8.0765525409005174e-04 -1.0588882853031821e-03 3.1122706902410268e-02 + 27 1.4968776819200879e-03 3.2942887158314040e-05 1.3240038417764373e-02 + 28 -2.4589307728119323e-04 -1.8153131107501511e-05 2.9694296702257997e-02 + 29 -3.4497543410356470e-04 -3.4248542242962311e-05 1.0175095227569283e-02 + 30 8.0765525408991665e-04 -1.0588882853032810e-03 3.1122706902410369e-02 + 31 1.4968776819200670e-03 3.2942887158584385e-05 1.3240038417764520e-02 + 32 -2.4589307728105619e-04 -1.8153131107580197e-05 2.9694296702258274e-02 + 33 1.3420649407712329e-04 -7.2457679971971299e-08 1.0126947778852728e-02 + 34 -1.2282857182875856e-04 5.3192999898934757e-06 2.9856397351700922e-02 + 35 -1.3423017399030691e-04 -7.4372916307303659e-08 1.0126888665729796e-02 + 36 1.2281835687551147e-04 5.2995439452943477e-06 2.9856422192021229e-02 + 37 1.3420649407688346e-04 -7.2457680016867857e-08 1.0126947778853273e-02 + 38 -1.2282857182861024e-04 5.3192999901346361e-06 2.9856397351700859e-02 + 39 -1.3423017399036286e-04 -7.4372916328267513e-08 1.0126888665730093e-02 + 40 1.2281835687550854e-04 5.2995439452834599e-06 2.9856422192021292e-02 + 41 -1.4968872501543050e-03 3.2942220392413755e-05 1.3240039391837519e-02 + 42 2.4591095432896623e-04 -1.8173359176526104e-05 2.9694319334136906e-02 + 43 3.4500868225182334e-04 -3.4247293770650532e-05 1.0175155314768796e-02 + 44 -8.0766291618553391e-04 -1.0588887573257195e-03 3.1122704693977713e-02 + 45 -1.4968872501544524e-03 3.2942220392554349e-05 1.3240039391837150e-02 + 46 2.4591095432885027e-04 -1.8173359176560751e-05 2.9694319334136628e-02 + 47 3.4500868225184405e-04 -3.4247293770696435e-05 1.0175155314768848e-02 + 48 -8.0766291618553099e-04 -1.0588887573256150e-03 3.1122704693978008e-02 +... diff --git a/unittest/force-styles/tests/manybody-pair-drip_real.yaml b/unittest/force-styles/tests/manybody-pair-drip_real.yaml new file mode 100644 index 0000000000..3f680a8c96 --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-drip_real.yaml @@ -0,0 +1,126 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Tue Aug 17 15:09:48 2021 +epsilon: 1e-13 +skip_tests: single +prerequisites: ! | + pair drip + atom full +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + variable units index real +post_commands: ! "" +input_file: in.bilayer +pair_style: hybrid/overlay drip +pair_coeff: ! | + * * drip C.drip C C C +extract: ! "" +natoms: 48 +init_vdwl: -25.761080947558458 +init_coul: 0 +init_stress: ! |- + -1.5997575514840701e+01 -1.5926563655516432e+01 2.6554761026958538e+01 0.0000000000000000e+00 0.0000000000000000e+00 -3.2959106617730394e-01 +init_forces: ! |2 + 1 3.4519525887018621e-02 -7.5961070769214878e-04 -3.0533160468170939e-01 + 2 1.8625356800076362e-02 2.4418650819961668e-02 -7.1772653472282411e-01 + 3 -7.9552206156518063e-03 7.8979719442743949e-04 -2.3465116711459008e-01 + 4 -5.6703944262123662e-03 4.1870221465274693e-04 -6.8478588954553776e-01 + 5 3.4519525887018870e-02 -7.5961070769172225e-04 -3.0533160468171572e-01 + 6 1.8625356800076116e-02 2.4418650819952412e-02 -7.1772653472282877e-01 + 7 -7.9552206156503213e-03 7.8979719443244851e-04 -2.3465116711458173e-01 + 8 -5.6703944262118111e-03 4.1870221465155517e-04 -6.8478588954554198e-01 + 9 -3.0954209054540674e-03 1.7176766023297568e-06 -2.3353949053792569e-01 + 10 -2.8325224362034315e-03 -1.2263401010803219e-04 -6.8852392802545803e-01 + 11 3.0948748188155822e-03 1.6735115258234307e-06 -2.3354085374002706e-01 + 12 2.8322868660610179e-03 -1.2217842468890391e-04 -6.8852450086990813e-01 + 13 -3.0954209054540466e-03 1.7176766026706842e-06 -2.3353949053793166e-01 + 14 -2.8325224362032025e-03 -1.2263401011821111e-04 -6.8852392802545703e-01 + 15 3.0948748188158390e-03 1.6735115316409009e-06 -2.3354085374002267e-01 + 16 2.8322868660610422e-03 -1.2217842468845727e-04 -6.8852450086991235e-01 + 17 7.9559873492091142e-03 7.8976840530281534e-04 -2.3465255277912508e-01 + 18 5.6708066884776521e-03 4.1916868608569068e-04 -6.8478641146338481e-01 + 19 -3.4519746533893940e-02 -7.5959533171951130e-04 -3.0533162714402262e-01 + 20 -1.8625533492238975e-02 2.4418661705949665e-02 -7.1772648379643234e-01 + 21 7.9559873492090170e-03 7.8976840530288451e-04 -2.3465255277913122e-01 + 22 5.6708066884775948e-03 4.1916868607656490e-04 -6.8478641146338504e-01 + 23 -3.4519746533890970e-02 -7.5959533171988253e-04 -3.0533162714401807e-01 + 24 -1.8625533492239343e-02 2.4418661705949762e-02 -7.1772648379643167e-01 + 25 -7.9552206156520144e-03 -7.8979719442783024e-04 2.3465116711458947e-01 + 26 1.8625356800076404e-02 -2.4418650819961502e-02 7.1772653472282488e-01 + 27 3.4519525887014679e-02 7.5961070768970737e-04 3.0533160468170817e-01 + 28 -5.6703944262120054e-03 -4.1870221465108506e-04 6.8478588954553898e-01 + 29 -7.9552206156520144e-03 -7.8979719443283481e-04 2.3465116711458581e-01 + 30 1.8625356800069229e-02 -2.4418650819957533e-02 7.1772653472281345e-01 + 31 3.4519525887018704e-02 7.5961070770124480e-04 3.0533160468171566e-01 + 32 -5.6703944262122274e-03 -4.1870221465243294e-04 6.8478588954554442e-01 + 33 3.0948748188157731e-03 -1.6735115261055401e-06 2.3354085374002662e-01 + 34 -2.8325224362035009e-03 1.2263401010814570e-04 6.8852392802545770e-01 + 35 -3.0954209054540674e-03 -1.7176766021075496e-06 2.3353949053792544e-01 + 36 2.8322868660609277e-03 1.2217842468872730e-04 6.8852450086991090e-01 + 37 3.0948748188157002e-03 -1.6735115312395288e-06 2.3354085374002845e-01 + 38 -2.8325224362050205e-03 1.2263401010865604e-04 6.8852392802544404e-01 + 39 -3.0954209054541784e-03 -1.7176765926834780e-06 2.3353949053792869e-01 + 40 2.8322868660613752e-03 1.2217842468919974e-04 6.8852450086991468e-01 + 41 -3.4519746533897999e-02 7.5959533172142307e-04 3.0533162714402334e-01 + 42 5.6708066884776503e-03 -4.1916868608571941e-04 6.8478641146338692e-01 + 43 7.9559873492091281e-03 -7.8976840530235466e-04 2.3465255277912495e-01 + 44 -1.8625533492239322e-02 -2.4418661705950095e-02 7.1772648379643567e-01 + 45 -3.4519746533897937e-02 7.5959533171621586e-04 3.0533162714402778e-01 + 46 5.6708066884779687e-03 -4.1916868608703228e-04 6.8478641146337782e-01 + 47 7.9559873492089893e-03 -7.8976840529313373e-04 2.3465255277912772e-01 + 48 -1.8625533492239322e-02 -2.4418661705950414e-02 7.1772648379643678e-01 +run_vdwl: -25.76108094759681 +run_coul: 0 +run_stress: ! |- + -1.5997575514905400e+01 -1.5926563655580109e+01 2.6554761025857829e+01 0.0000000000000000e+00 0.0000000000000000e+00 -3.2959106617393824e-01 +run_forces: ! |2 + 1 3.4519525886308772e-02 -7.5961070774262620e-04 -3.0533160467333686e-01 + 2 1.8625356799616053e-02 2.4418650819844623e-02 -7.1772653470240710e-01 + 3 -7.9552206157541827e-03 7.8979719442180435e-04 -2.3465116710721118e-01 + 4 -5.6703944262564421e-03 4.1870221456883055e-04 -6.8478588952590880e-01 + 5 3.4519525886310021e-02 -7.5961070774873795e-04 -3.0533160467333753e-01 + 6 1.8625356799618166e-02 2.4418650819839099e-02 -7.1772653470240300e-01 + 7 -7.9552206157587901e-03 7.8979719441955800e-04 -2.3465116710720937e-01 + 8 -5.6703944262596895e-03 4.1870221457031374e-04 -6.8478588952590624e-01 + 9 -3.0954209054729134e-03 1.7176766005387110e-06 -2.3353949053056158e-01 + 10 -2.8325224361802070e-03 -1.2263401013539680e-04 -6.8852392800592355e-01 + 11 3.0948748188260634e-03 1.6735115258329308e-06 -2.3354085373267006e-01 + 12 2.8322868660322353e-03 -1.2217842471453093e-04 -6.8852450085037853e-01 + 13 -3.0954209054753073e-03 1.7176766069530950e-06 -2.3353949053056008e-01 + 14 -2.8325224361808454e-03 -1.2263401013228948e-04 -6.8852392800592477e-01 + 15 3.0948748188205331e-03 1.6735115311816390e-06 -2.3354085373266414e-01 + 16 2.8322868660327627e-03 -1.2217842471338395e-04 -6.8852450085039274e-01 + 17 7.9559873493214514e-03 7.8976840529372907e-04 -2.3465255277175306e-01 + 18 5.6708066885325613e-03 4.1916868600858607e-04 -6.8478641144376085e-01 + 19 -3.4519746533186305e-02 -7.5959533177047444e-04 -3.0533162713566037e-01 + 20 -1.8625533491780335e-02 2.4418661705826062e-02 -7.1772648377602155e-01 + 21 7.9559873493208408e-03 7.8976840529406105e-04 -2.3465255277176264e-01 + 22 5.6708066885322672e-03 4.1916868600612250e-04 -6.8478641144375973e-01 + 23 -3.4519746533190690e-02 -7.5959533177689758e-04 -3.0533162713565520e-01 + 24 -1.8625533491779738e-02 2.4418661705826118e-02 -7.1772648377601034e-01 + 25 -7.9552206157391669e-03 -7.8979719442920414e-04 2.3465116710670758e-01 + 26 1.8625356799678291e-02 -2.4418650819855600e-02 7.1772653470301284e-01 + 27 3.4519525886291424e-02 7.5961070776537666e-04 3.0533160467268600e-01 + 28 -5.6703944262409822e-03 -4.1870221457090788e-04 6.8478588952643626e-01 + 29 -7.9552206157410682e-03 -7.8979719442770382e-04 2.3465116710671441e-01 + 30 1.8625356799682243e-02 -2.4418650819853061e-02 7.1772653470300518e-01 + 31 3.4519525886292479e-02 7.5961070776900104e-04 3.0533160467267750e-01 + 32 -5.6703944262390393e-03 -4.1870221457093217e-04 6.8478588952643404e-01 + 33 3.0948748188169527e-03 -1.6735115285445503e-06 2.3354085373217337e-01 + 34 -2.8325224361862578e-03 1.2263401013536189e-04 6.8852392800645301e-01 + 35 -3.0954209054732881e-03 -1.7176766016382667e-06 2.3353949053006548e-01 + 36 2.8322868660402949e-03 1.2217842471530459e-04 6.8852450085089545e-01 + 37 3.0948748188168972e-03 -1.6735115254575963e-06 2.3354085373216871e-01 + 38 -2.8325224361834475e-03 1.2263401013282052e-04 6.8852392800645179e-01 + 39 -3.0954209054684656e-03 -1.7176766061726881e-06 2.3353949053006878e-01 + 40 2.8322868660383624e-03 1.2217842471120666e-04 6.8852450085090100e-01 + 41 -3.4519746533171393e-02 7.5959533179549132e-04 3.0533162713500450e-01 + 42 5.6708066885105355e-03 -4.1916868600979897e-04 6.8478641144428143e-01 + 43 7.9559873493117838e-03 -7.8976840530148860e-04 2.3465255277124522e-01 + 44 -1.8625533491841401e-02 -2.4418661705844322e-02 7.1772648377662540e-01 + 45 -3.4519746533172420e-02 7.5959533179765766e-04 3.0533162713500039e-01 + 46 5.6708066885161846e-03 -4.1916868600924408e-04 6.8478641144429175e-01 + 47 7.9559873493104671e-03 -7.8976840529732212e-04 2.3465255277125016e-01 + 48 -1.8625533491844991e-02 -2.4418661705839853e-02 7.1772648377662085e-01 +... diff --git a/unittest/force-styles/tests/manybody-pair-ilp-graphene-hbn.yaml b/unittest/force-styles/tests/manybody-pair-ilp-graphene-hbn.yaml new file mode 100644 index 0000000000..81f72ec0a9 --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-ilp-graphene-hbn.yaml @@ -0,0 +1,125 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Tue Aug 17 15:09:49 2021 +epsilon: 5e-12 +skip_tests: single +prerequisites: ! | + pair ilp/graphene/hbn + atom full +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on +post_commands: ! "" +input_file: in.bilayer +pair_style: hybrid/overlay ilp/graphene/hbn 16.0 1 +pair_coeff: ! | + * * ilp/graphene/hbn BNCH.ILP B N C +extract: ! "" +natoms: 48 +init_vdwl: -1.387500902597699 +init_coul: 0 +init_stress: ! |- + -1.0950745163741815e+00 -1.0965448791525116e+00 -5.5691185658268150e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.1949269093120441e-03 +init_forces: ! |2 + 1 2.0033364707962020e-03 3.2526065174565133e-18 -4.7626541030897668e-02 + 2 -1.1368359972830505e-05 9.1814113875668727e-05 4.2488212564737199e-02 + 3 -5.5278100417535583e-05 -1.1058862159352145e-17 -4.4732824814754067e-02 + 4 -2.3915922842134181e-04 2.2249364734195330e-06 4.0890453270282665e-02 + 5 2.0033364707962020e-03 4.1199682554449168e-18 -4.7626541030897619e-02 + 6 -1.1368359972813158e-05 9.1814113875680762e-05 4.2488212564737102e-02 + 7 -5.5278100417523006e-05 -3.7404974950749903e-17 -4.4732824814753921e-02 + 8 -2.3915922842133140e-04 2.2249364733897175e-06 4.0890453270282998e-02 + 9 -5.2020828171993284e-05 -2.0193265462542520e-18 -4.4737801821738435e-02 + 10 -1.2511640292790002e-04 -4.3335410390344704e-06 4.1581628715790360e-02 + 11 5.1983198952135928e-05 -1.1150341717655610e-17 -4.4737856331164172e-02 + 12 1.2512171341779051e-04 -4.3318158884542686e-06 4.1581659199143604e-02 + 13 -5.2020828171995019e-05 -1.0299920638612292e-18 -4.4737801821738400e-02 + 14 -1.2511640292792257e-04 -4.3335410390036926e-06 4.1581628715790221e-02 + 15 5.1983198952134085e-05 -2.2639496614212939e-17 -4.4737856331164047e-02 + 16 1.2512171341781285e-04 -4.3318158884359524e-06 4.1581659199143896e-02 + 17 5.5317942397928804e-05 -1.3694193416497087e-17 -4.4732879184470137e-02 + 18 2.3916128102602216e-04 2.2268062502434974e-06 4.0890470745578923e-02 + 19 -2.0033386835566994e-03 5.0537162006743762e-18 -4.7626540891187855e-02 + 20 1.1360996878247132e-05 9.1814258501936069e-05 4.2488199556680040e-02 + 21 5.5317942397930972e-05 2.0466433588032032e-18 -4.4732879184470033e-02 + 22 2.3916128102602656e-04 2.2268062502461309e-06 4.0890470745578937e-02 + 23 -2.0033386835567038e-03 -4.0058358597583202e-17 -4.7626540891187820e-02 + 24 1.1360996878233309e-05 9.1814258501946586e-05 4.2488199556680414e-02 + 25 -1.6486800709624230e-04 -1.8127313551345855e-05 -1.0796056549805585e-03 + 26 9.7415698381275641e-04 -8.3284301802344016e-04 5.3751455194570915e-03 + 27 1.0178111270105904e-03 7.4102890414775549e-04 -6.3746876686657586e-04 + 28 -1.2956932174262685e-04 1.5902377077926376e-05 5.3232551286718586e-03 + 29 -1.6486800709624447e-04 -1.8127313551316636e-05 -1.0796056549805698e-03 + 30 9.7415698381273170e-04 -8.3284301802343886e-04 5.3751455194570958e-03 + 31 1.0178111270106190e-03 7.4102890414773901e-04 -6.3746876686670770e-04 + 32 -1.2956932174261818e-04 1.5902377077917892e-05 5.3232551286718872e-03 + 33 9.2654152308404886e-05 4.0850279627708816e-06 -1.6053564303655610e-03 + 34 -8.4466761317455313e-05 2.6270005211736469e-07 4.7609191024683460e-03 + 35 -9.2670469782459453e-05 4.0708409869095536e-06 -1.6053645864696963e-03 + 36 8.4450760061533046e-05 2.4678792568258345e-07 4.7609196893467782e-03 + 37 9.2654152308405103e-05 4.0850279628000907e-06 -1.6053564303655061e-03 + 38 -8.4466761317482635e-05 2.6270005213547426e-07 4.7609191024683400e-03 + 39 -9.2670469782453165e-05 4.0708409868783421e-06 -1.6053645864697198e-03 + 40 8.4450760061528275e-05 2.4678792566386402e-07 4.7609196893469690e-03 + 41 -1.0178163233209149e-03 7.4102846801620556e-04 -6.3745882808595152e-04 + 42 1.2958970254336804e-04 1.5886756456806513e-05 5.3232663025057810e-03 + 43 1.6488952088059271e-04 -1.8113562707041957e-05 -1.0795875600957813e-03 + 44 -9.7416136335758238e-04 -8.3284272651813762e-04 5.3751561064124811e-03 + 45 -1.0178163233209125e-03 7.4102846801622031e-04 -6.3745882808583789e-04 + 46 1.2958970254337579e-04 1.5886756456791148e-05 5.3232663025058772e-03 + 47 1.6488952088058748e-04 -1.8113562707049496e-05 -1.0795875600958203e-03 + 48 -9.7416136335759366e-04 -8.3284272651814803e-04 5.3751561064124855e-03 +run_vdwl: -1.3875037702379507 +run_coul: 0 +run_stress: ! |- + -1.0950798483072388e+00 -1.0965501776879543e+00 -5.5691866561084535e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.1949322419481606e-03 +run_forces: ! |2 + 1 2.0033030003525137e-03 8.9435705391029130e-10 -4.7625968392020532e-02 + 2 -1.1367384359795837e-05 9.1815719224718032e-05 4.2487909883465465e-02 + 3 -5.5282089115551557e-05 -2.6135646989168017e-09 -4.4732313434801885e-02 + 4 -2.3915909829547773e-04 2.2249799837368439e-06 4.0890200928313990e-02 + 5 2.0033030003524860e-03 8.9435706106602564e-10 -4.7625968392020428e-02 + 6 -1.1367384359823613e-05 9.1815719224701660e-05 4.2487909883465430e-02 + 7 -5.5282089115578446e-05 -2.6135647671131183e-09 -4.4732313434801836e-02 + 8 -2.3915909829547773e-04 2.2249799837172199e-06 4.0890200928314566e-02 + 9 -5.2020641072548406e-05 6.7005638625767475e-10 -4.4737290402994602e-02 + 10 -1.2511670468712049e-04 -4.3337535831548628e-06 4.1581350530843775e-02 + 11 5.1983012539478048e-05 6.7012239660759799e-10 -4.4737344911317957e-02 + 12 1.2512201515433533e-04 -4.3320284013805789e-06 4.1581381013272169e-02 + 13 -5.2020641072554044e-05 6.7005629369391428e-10 -4.4737290402994609e-02 + 14 -1.2511670468714348e-04 -4.3337535831713291e-06 4.1581350530843830e-02 + 15 5.1983012539505370e-05 6.7012235105247202e-10 -4.4737344911317853e-02 + 16 1.2512201515432167e-04 -4.3320284013572685e-06 4.1581381013272294e-02 + 17 5.5321930482132663e-05 -2.6135608037222913e-09 -4.4732367803430914e-02 + 18 2.3916115092586794e-04 2.2268497947506605e-06 4.0890218403155591e-02 + 19 -2.0033052131855867e-03 8.9429471662265853e-10 -4.7625968252325866e-02 + 20 1.1360021262163687e-05 9.1815863853997803e-05 4.2487896875878589e-02 + 21 5.5321930482154889e-05 -2.6135608655374853e-09 -4.4732367803430817e-02 + 22 2.3916115092584907e-04 2.2268497947312516e-06 4.0890218403155654e-02 + 23 -2.0033052131855616e-03 8.9429479706876566e-10 -4.7625968252325804e-02 + 24 1.1360021262174096e-05 9.1815863853997342e-05 4.2487896875878825e-02 + 25 -1.6486945106528091e-04 -1.8126101379958718e-05 -1.0797429438547676e-03 + 26 9.7414016722233848e-04 -8.3283489942476445e-04 5.3750161101709729e-03 + 27 1.0177937442917731e-03 7.4101905540415944e-04 -6.3761022896437550e-04 + 28 -1.2957001720401498e-04 1.5902818724243767e-05 5.3231291183569798e-03 + 29 -1.6486945106529950e-04 -1.8126101379940937e-05 -1.0797429438548231e-03 + 30 9.7414016722235670e-04 -8.3283489942476228e-04 5.3750161101709625e-03 + 31 1.0177937442917692e-03 7.4101905540416161e-04 -6.3761022896433907e-04 + 32 -1.2957001720399937e-04 1.5902818724231570e-05 5.3231291183569417e-03 + 33 9.2652190820307180e-05 4.0847599754035413e-06 -1.6054772616410785e-03 + 34 -8.4465929960344556e-05 2.6265700116475746e-07 4.7608118750052195e-03 + 35 -9.2668507953961839e-05 4.0705731901608693e-06 -1.6054854176848882e-03 + 36 8.4449929025630626e-05 2.4674500177709956e-07 4.7608124618308432e-03 + 37 9.2652190820296772e-05 4.0847599754594472e-06 -1.6054772616411949e-03 + 38 -8.4465929960378383e-05 2.6265700123594889e-07 4.7608118750052542e-03 + 39 -9.2668507953971814e-05 4.0705731901478047e-06 -1.6054854176848756e-03 + 40 8.4449929025618483e-05 2.4674500176496539e-07 4.7608124618310956e-03 + 41 -1.0177989405882203e-03 7.4101861929748436e-04 -6.3760029049130570e-04 + 42 1.2959039767826896e-04 1.5887198241880077e-05 5.3231402917910302e-03 + 43 1.6489096449514255e-04 -1.8112350701529705e-05 -1.0797248493375658e-03 + 44 -9.7414454676205060e-04 -8.3283460790769116e-04 5.3750266967793276e-03 + 45 -1.0177989405881721e-03 7.4101861929751580e-04 -6.3760029049122590e-04 + 46 1.2959039767822169e-04 1.5887198241890099e-05 5.3231402917910502e-03 + 47 1.6489096449514865e-04 -1.8112350701541984e-05 -1.0797248493375228e-03 + 48 -9.7414454676203553e-04 -8.3283460790775058e-04 5.3750266967792192e-03 +... diff --git a/unittest/force-styles/tests/manybody-pair-ilp-graphene-hbn_notaper.yaml b/unittest/force-styles/tests/manybody-pair-ilp-graphene-hbn_notaper.yaml new file mode 100644 index 0000000000..f54aa4f85b --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-ilp-graphene-hbn_notaper.yaml @@ -0,0 +1,126 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Tue Aug 17 15:09:49 2021 +epsilon: 5e-12 +skip_tests: single +prerequisites: ! | + pair ilp/graphene/hbn + atom full +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + comm_modify cutoff 16.0 +post_commands: ! "" +input_file: in.bilayer +pair_style: hybrid/overlay ilp/graphene/hbn 16.0 0 +pair_coeff: ! | + * * ilp/graphene/hbn BNCH.ILP B N C +extract: ! "" +natoms: 48 +init_vdwl: -1.743417069575419 +init_coul: 0 +init_stress: ! |- + -1.4159677678324094e+00 -1.4175957592828763e+00 -8.2079275196077894e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.2386435158561861e-03 +init_forces: ! |2 + 1 2.0850484065019883e-03 3.6862873864507151e-18 -5.0318618251118635e-02 + 2 -6.3446817540543932e-06 9.5024077809279612e-05 4.2760561141837801e-02 + 3 -4.9554482434026152e-05 -8.1315162936412833e-18 -4.7333694009245655e-02 + 4 -2.3873708476733480e-04 1.4944038076278483e-06 4.1104339963197040e-02 + 5 2.0850484065019900e-03 3.0357660829594124e-18 -5.0318618251118601e-02 + 6 -6.3446817540370459e-06 9.5024077809283949e-05 4.2760561141837863e-02 + 7 -4.9554482434004034e-05 -2.0003530082357557e-17 -4.7333694009245551e-02 + 8 -2.3873708476732872e-04 1.4944038076165726e-06 4.1104339963197123e-02 + 9 -5.1133673114476565e-05 -4.2825985813177425e-18 -4.7328374000982235e-02 + 10 -1.2855382161618828e-04 -3.5892733150040340e-06 4.1845863048816843e-02 + 11 5.1094314571888079e-05 -9.2394353886499081e-18 -4.7328430254607333e-02 + 12 1.2855900637380436e-04 -3.5874635791496971e-06 4.1845894619109855e-02 + 13 -5.1133673114468758e-05 5.4210108624275222e-20 -4.7328374000982200e-02 + 14 -1.2855382161621300e-04 -3.5892733149839627e-06 4.1845863048816802e-02 + 15 5.1094314571888079e-05 -1.8460236052460222e-17 -4.7328430254607312e-02 + 16 1.2855900637382496e-04 -3.5874635791107064e-06 4.1845894619109890e-02 + 17 4.9595925523595848e-05 -4.7802304378296440e-18 -4.7333750316999074e-02 + 18 2.3873932915433548e-04 1.4963296466885558e-06 4.1104357563481929e-02 + 19 -2.0850504910489491e-03 1.0522849122417783e-17 -5.0318618305247004e-02 + 20 6.3372526094387688e-06 9.5024193912500820e-05 4.2760547171829859e-02 + 21 4.9595925523599209e-05 1.0509561293057731e-18 -4.7333750316998997e-02 + 22 2.3873932915433646e-04 1.4963296466837175e-06 4.1104357563481873e-02 + 23 -2.0850504910489630e-03 -4.2831809164689798e-17 -5.0318618305246844e-02 + 24 6.3372526094248910e-06 9.5024193912522829e-05 4.2760547171829762e-02 + 25 -1.6288457344696859e-04 -1.8238152247257184e-05 9.5379191188832164e-05 + 26 1.0182995551939961e-03 -8.6641525713797730e-04 6.5970295316636436e-03 + 27 1.0604041695539059e-03 7.7139117932867849e-04 5.4135994220887943e-04 + 28 -1.2540699375438325e-04 1.6743748439636654e-05 6.5543328981639889e-03 + 29 -1.6288457344698247e-04 -1.8238152247225959e-05 9.5379191188821322e-05 + 30 1.0182995551939649e-03 -8.6641525713797123e-04 6.5970295316634528e-03 + 31 1.0604041695539443e-03 7.7139117932868467e-04 5.4135994220893408e-04 + 32 -1.2540699375435983e-04 1.6743748439636546e-05 6.5543328981640713e-03 + 33 9.3725416939480027e-05 3.9426681303011716e-06 -4.6805765375060782e-04 + 34 -8.5944868650094253e-05 -3.3863756950810271e-07 5.9498944235440096e-03 + 35 -9.3742626080580566e-05 3.9279108845123400e-06 -4.6806588898556445e-04 + 36 8.5927904006221408e-05 -3.5520455114131738e-07 5.9498948560586119e-03 + 37 9.3725416939479159e-05 3.9426681303317868e-06 -4.6805765375057583e-04 + 38 -8.5944868650128080e-05 -3.3863756950880066e-07 5.9498944235437754e-03 + 39 -9.3742626080576229e-05 3.9279108844955619e-06 -4.6806588898545658e-04 + 40 8.5927904006218372e-05 -3.5520455114406897e-07 5.9498948560586301e-03 + 41 -1.0604093518345942e-03 7.7139074370169154e-04 5.4137060014462714e-04 + 42 1.2542828980921278e-04 1.6727500981786547e-05 6.5543447221730429e-03 + 43 1.6290696486873053e-04 -1.8223830628457046e-05 9.5398084359375981e-05 + 44 -1.0183038866049599e-03 -8.6641493761418803e-04 6.5970409231580918e-03 + 45 -1.0604093518345931e-03 7.7139074370171051e-04 5.4137060014457867e-04 + 46 1.2542828980922080e-04 1.6727500981764446e-05 6.5543447221731157e-03 + 47 1.6290696486873449e-04 -1.8223830628478516e-05 9.5398084359388924e-05 + 48 -1.0183038866049608e-03 -8.6641493761419497e-04 6.5970409231580329e-03 +run_vdwl: -1.7434201284130086 +run_coul: 0 +run_stress: ! |- + -1.4159735399871292e+00 -1.4176014949571309e+00 -8.2080149187142926e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.2386484789055200e-03 +run_forces: ! |2 + 1 2.0850117908114097e-03 1.0161463491389217e-09 -5.0317981439628325e-02 + 2 -6.3437194577726987e-06 9.5025701239061859e-05 4.2760248404172425e-02 + 3 -4.9558828649647491e-05 -2.8627617254290035e-09 -4.7333123186150738e-02 + 4 -2.3873691985811830e-04 1.4944553106552229e-06 4.1104081968794406e-02 + 5 2.0850117908114453e-03 1.0161464421634681e-09 -5.0317981439628387e-02 + 6 -6.3437194577657598e-06 9.5025701239022950e-05 4.2760248404172314e-02 + 7 -4.9558828649683053e-05 -2.8627618450165031e-09 -4.7333123186150801e-02 + 8 -2.3873691985809662e-04 1.4944553106461156e-06 4.1104081968794330e-02 + 9 -5.1133422593300278e-05 7.5547760714921204e-10 -4.7327803360874096e-02 + 10 -1.2855412188890643e-04 -3.5895010384140685e-06 4.1845576403891582e-02 + 11 5.1094064803271807e-05 7.5555079194951369e-10 -4.7327859613308917e-02 + 12 1.2855930662305235e-04 -3.5876912710547494e-06 4.1845607973177879e-02 + 13 -5.1133422593287268e-05 7.5547762723405729e-10 -4.7327803360874242e-02 + 14 -1.2855412188890339e-04 -3.5895010383977919e-06 4.1845576403891596e-02 + 15 5.1094064803272566e-05 7.5555075467328774e-10 -4.7327859613308966e-02 + 16 1.2855930662306232e-04 -3.5876912710024113e-06 4.1845607973177948e-02 + 17 4.9600271065325580e-05 -2.8627573902157001e-09 -4.7333179492726606e-02 + 18 2.3873916427060956e-04 1.4963811844738990e-06 4.1104099568595440e-02 + 19 -2.0850138754365875e-03 1.0160778065162400e-09 -5.0317981493768628e-02 + 20 6.3362903110811795e-06 9.5025817345494392e-05 4.2760234434687100e-02 + 21 4.9600271065314522e-05 -2.8627574752175739e-09 -4.7333179492726564e-02 + 22 2.3873916427059666e-04 1.4963811844658860e-06 4.1104099568595440e-02 + 23 -2.0850138754366235e-03 1.0160777921810544e-09 -5.0317981493768635e-02 + 24 6.3362903110742406e-06 9.5025817345493959e-05 4.2760234434687017e-02 + 25 -1.6288606984034650e-04 -1.8236722175475704e-05 9.5216967993063707e-05 + 26 1.0182812312861281e-03 -8.6640626373293709e-04 6.5968711299294047e-03 + 27 1.0603851126650126e-03 7.7138037180120864e-04 5.4119317677753243e-04 + 28 -1.2540771098643044e-04 1.6744137902604281e-05 6.5541778235511557e-03 + 29 -1.6288606984038928e-04 -1.8236722175416289e-05 9.5216967993082789e-05 + 30 1.0182812312861922e-03 -8.6640626373294402e-04 6.5968711299294082e-03 + 31 1.0603851126649892e-03 7.7138037180129147e-04 5.4119317677749253e-04 + 32 -1.2540771098645993e-04 1.6744137902621953e-05 6.5541778235512944e-03 + 33 9.3723257649716975e-05 3.9423316345507744e-06 -4.6820173818218168e-04 + 34 -8.5943962571135429e-05 -3.3866278074822816e-07 5.9497600753296263e-03 + 35 -9.3740466418232955e-05 3.9275746001192263e-06 -4.6820997335027752e-04 + 36 8.5926998277192305e-05 -3.5522961929919531e-07 5.9497605077923395e-03 + 37 9.3723257649690628e-05 3.9423316345445131e-06 -4.6820173818211392e-04 + 38 -8.5943962571131960e-05 -3.3866278074772671e-07 5.9497600753297061e-03 + 39 -9.3740466418205850e-05 3.9275746001722167e-06 -4.6820997335035645e-04 + 40 8.5926998277160646e-05 -3.5522961930283416e-07 5.9497605077923222e-03 + 41 -1.0603902949286239e-03 7.7137993620434483e-04 5.4120383437409529e-04 + 42 1.2542900668491156e-04 1.6727890598687433e-05 6.5541896471255070e-03 + 43 1.6290846087229721e-04 -1.8222400738173032e-05 9.5235860757960438e-05 + 44 -1.0182855626908293e-03 -8.6640594419860580e-04 6.5968825210400628e-03 + 45 -1.0603902949286009e-03 7.7137993620434917e-04 5.4120383437400075e-04 + 46 1.2542900668490961e-04 1.6727890598721233e-05 6.5541896471255886e-03 + 47 1.6290846087231749e-04 -1.8222400738211376e-05 9.5235860757975237e-05 + 48 -1.0182855626908007e-03 -8.6640594419857295e-04 6.5968825210402865e-03 +... diff --git a/unittest/force-styles/tests/manybody-pair-kolmogorov_crespi_full.yaml b/unittest/force-styles/tests/manybody-pair-kolmogorov_crespi_full.yaml new file mode 100644 index 0000000000..a166d66af1 --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-kolmogorov_crespi_full.yaml @@ -0,0 +1,126 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Tue Aug 17 15:09:49 2021 +epsilon: 5e-12 +skip_tests: single +prerequisites: ! | + pair kolmogorov/crespi/full + atom full +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + comm_modify cutoff 16.0 +post_commands: ! "" +input_file: in.bilayer +pair_style: hybrid/overlay kolmogorov/crespi/full 16.0 1 +pair_coeff: ! | + * * kolmogorov/crespi/full CH_taper.KC C C C +extract: ! "" +natoms: 48 +init_vdwl: -1.2500397419624312 +init_coul: 0 +init_stress: ! |- + -1.0004429195951223e+00 -1.0032930381066463e+00 4.3070815061895146e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.7133324489474716e-02 +init_forces: ! |2 + 1 2.8687289997477317e-03 -7.8062556418956319e-18 3.6613830361686965e-02 + 2 1.3226962450822509e-03 1.2611200091842689e-03 -6.4703224388507563e-02 + 3 -3.4774444393605684e-04 -1.3010426069826053e-17 3.8050724789394384e-02 + 4 -3.4400661847007637e-04 3.0925839103697773e-05 -6.5875665183461635e-02 + 5 2.8687289997477005e-03 -1.5612511283791264e-17 3.6613830361687000e-02 + 6 1.3226962450822808e-03 1.2611200091843045e-03 -6.4703224388507549e-02 + 7 -3.4774444393598919e-04 -5.2150124496552763e-17 3.8050724789394412e-02 + 8 -3.4400661847007550e-04 3.0925839103693002e-05 -6.5875665183461662e-02 + 9 -1.2644907900887740e-04 -8.1315162936412833e-18 3.8649557617062728e-02 + 10 -1.1324543171146572e-04 -5.6284413155996182e-06 -6.5027903599930381e-02 + 11 1.2639947077019444e-04 -2.2215980140585789e-17 3.8649533308935571e-02 + 12 1.1322659571519420e-04 -5.6051326608156769e-06 -6.5027878367048986e-02 + 13 -1.2644907900885008e-04 2.3256136599814070e-17 3.8649557617062749e-02 + 14 -1.1324543171150085e-04 -5.6284413155611291e-06 -6.5027903599930395e-02 + 15 1.2639947077014381e-04 -7.0749273952362690e-17 3.8649533308935564e-02 + 16 1.1322659571522879e-04 -5.6051326608175471e-06 -6.5027878367048930e-02 + 17 3.4780347512676035e-04 3.1573153108904045e-19 3.8050688506524509e-02 + 18 3.4403466466237793e-04 3.0949865189355873e-05 -6.5875656847228403e-02 + 19 -2.8687384226996960e-03 1.2450087305437732e-17 3.6613818386944344e-02 + 20 -1.3227054552782821e-03 1.2611207266151373e-03 -6.4703241285155699e-02 + 21 3.4780347512675867e-04 2.4633623930286376e-17 3.8050688506524544e-02 + 22 3.4403466466237533e-04 3.0949865189391902e-05 -6.5875656847228389e-02 + 23 -2.8687384226997285e-03 -1.2114236094873442e-16 3.6613818386944393e-02 + 24 -1.3227054552782968e-03 1.2611207266151575e-03 -6.4703241285155685e-02 + 25 -3.4774444393599700e-04 -9.2157184661267877e-18 -3.8050724789394322e-02 + 26 1.3226962450822511e-03 -1.2611200091842659e-03 6.4703224388507466e-02 + 27 2.8687289997476766e-03 -2.1250362580715887e-17 -3.6613830361686889e-02 + 28 -3.4400661847007550e-04 -3.0925839103686985e-05 6.5875665183461676e-02 + 29 -3.4774444393599092e-04 3.0357660829594124e-17 -3.8050724789394301e-02 + 30 1.3226962450822149e-03 -1.2611200091842295e-03 6.4703224388507424e-02 + 31 2.8687289997477408e-03 -3.0791341698588326e-17 -3.6613830361686910e-02 + 32 -3.4400661847004514e-04 -3.0925839103694330e-05 6.5875665183461649e-02 + 33 1.2639947077014197e-04 1.9363173174233306e-17 -3.8649533308935488e-02 + 34 -1.1324543171148133e-04 5.6284413156027252e-06 6.5027903599930423e-02 + 35 -1.2644907900888000e-04 -9.8391347153059527e-18 -3.8649557617062437e-02 + 36 1.1322659571522738e-04 5.6051326608073988e-06 6.5027878367048986e-02 + 37 1.2639947077014413e-04 4.6109085516735093e-17 -3.8649533308935564e-02 + 38 -1.1324543171150865e-04 5.6284413156129404e-06 6.5027903599930312e-02 + 39 -1.2644907900887783e-04 -5.0401848493419887e-17 -3.8649557617062492e-02 + 40 1.1322659571519420e-04 5.6051326607950474e-06 6.5027878367048930e-02 + 41 -2.8687384226997710e-03 4.7556214837339464e-17 -3.6613818386944108e-02 + 42 3.4403466466238080e-04 -3.0949865189344834e-05 6.5875656847228375e-02 + 43 3.4780347512678995e-04 2.7966275061258421e-17 -3.8050688506524606e-02 + 44 -1.3227054552783079e-03 -1.2611207266151391e-03 6.4703241285155699e-02 + 45 -2.8687384226997693e-03 3.0234814582462649e-17 -3.6613818386944066e-02 + 46 3.4403466466241371e-04 -3.0949865189357960e-05 6.5875656847228403e-02 + 47 3.4780347512675510e-04 -4.1431557823760033e-17 -3.8050688506524565e-02 + 48 -1.3227054552782990e-03 -1.2611207266151820e-03 6.4703241285155616e-02 +run_vdwl: -1.250048655581655 +run_coul: 0 +run_stress: ! |- + -1.0004370065912216e+00 -1.0032870501278353e+00 4.3059909389948547e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.7133053394138682e-02 +run_forces: ! |2 + 1 2.8687040337510585e-03 -2.1727982419360303e-08 3.6613767230361242e-02 + 2 1.3226761216838419e-03 1.2611192610103965e-03 -6.4700278384581700e-02 + 3 -3.4774048959829596e-04 -6.5329695842506266e-09 3.8050693623452148e-02 + 4 -3.4399690449135600e-04 3.0931288630288282e-05 -6.5872679966618428e-02 + 5 2.8687040337509414e-03 -2.1727982416324537e-08 3.6613767230361215e-02 + 6 1.3226761216838328e-03 1.2611192610103637e-03 -6.4700278384581755e-02 + 7 -3.4774048959831157e-04 -6.5329697417852023e-09 3.8050693623452293e-02 + 8 -3.4399690449132131e-04 3.0931288630341516e-05 -6.5872679966618358e-02 + 9 -1.2644870195377845e-04 -9.8156702533244537e-11 3.8649526065561227e-02 + 10 -1.1324486560407342e-04 -5.6284938931148765e-06 -6.5024950822206537e-02 + 11 1.2639909409585960e-04 -9.8445711624968110e-11 3.8649501756815911e-02 + 12 1.1322602979076438e-04 -5.6051853390437709e-06 -6.5024925590218899e-02 + 13 -1.2644870195375113e-04 -9.8156632886807482e-11 3.8649526065561317e-02 + 14 -1.1324486560405911e-04 -5.6284938930792740e-06 -6.5024950822206565e-02 + 15 1.2639909409583455e-04 -9.8445744733791953e-11 3.8649501756815870e-02 + 16 1.1322602979075462e-04 -5.6051853390539302e-06 -6.5024925590218899e-02 + 17 3.4779952031141985e-04 -6.5333858894565295e-09 3.8050657339932729e-02 + 18 3.4402495029270961e-04 3.0955314710129699e-05 -6.5872671630637689e-02 + 19 -2.8687134566054494e-03 -2.1728110080698652e-08 3.6613755255587549e-02 + 20 -1.3226853316725558e-03 1.2611199785361846e-03 -6.4700295280588876e-02 + 21 3.4779952031157007e-04 -6.5333859204723350e-09 3.8050657339932889e-02 + 22 3.4402495029267491e-04 3.0955314710011826e-05 -6.5872671630637619e-02 + 23 -2.8687134566054233e-03 -2.1728109989627787e-08 3.6613755255587500e-02 + 24 -1.3226853316725203e-03 1.2611199785360946e-03 -6.4700295280588946e-02 + 25 -3.4774026620067611e-04 5.4788299566664936e-09 -3.8050694958508775e-02 + 26 1.3226758258096682e-03 -1.2611202352806649e-03 6.4700279759489457e-02 + 27 2.8687023920407370e-03 2.3305742741057400e-08 -3.6613767021966469e-02 + 28 -3.4399811208785710e-04 -3.0930750484966575e-05 6.5872680514205861e-02 + 29 -3.4774026620052866e-04 5.4788301344756499e-09 -3.8050694958508983e-02 + 30 1.3226758258096626e-03 -1.2611202352806358e-03 6.4700279759489457e-02 + 31 2.8687023920407314e-03 2.3305742749297337e-08 -3.6613767021966427e-02 + 32 -3.4399811208790654e-04 -3.0930750484980141e-05 6.5872680514205958e-02 + 33 1.2639885814274838e-04 1.7430860588435232e-10 -3.8649502722412493e-02 + 34 -1.1324494267667476e-04 5.6283305711724153e-06 6.5024950991958153e-02 + 35 -1.2644846597469278e-04 1.7397032093721936e-10 -3.8649527031188770e-02 + 36 1.1322610689165884e-04 5.6050219889952428e-06 6.5024925759978203e-02 + 37 1.2639885814283360e-04 1.7430877254486095e-10 -3.8649502722412549e-02 + 38 -1.1324494267669341e-04 5.6283305709431489e-06 6.5024950991958139e-02 + 39 -1.2644846597468064e-04 1.7397049817716951e-10 -3.8649527031188825e-02 + 40 1.1322610689166047e-04 5.6050219889600113e-06 6.5024925759978369e-02 + 41 -2.8687118148861238e-03 2.3305846951219172e-08 -3.6613755047197015e-02 + 42 3.4402615788549601e-04 -3.0954776578351879e-05 6.5872672178240693e-02 + 43 3.4779929687850922e-04 5.4792724940850910e-09 -3.8050658674962379e-02 + 44 -1.3226850358229400e-03 -1.2611209527917432e-03 6.4700296655504905e-02 + 45 -2.8687118148861242e-03 2.3305846874457658e-08 -3.6613755047197084e-02 + 46 3.4402615788544478e-04 -3.0954776578295039e-05 6.5872672178240735e-02 + 47 3.4779929687843897e-04 5.4792724213126788e-09 -3.8050658674962212e-02 + 48 -1.3226850358228897e-03 -1.2611209527918239e-03 6.4700296655504780e-02 +... diff --git a/unittest/force-styles/tests/manybody-pair-kolmogorov_crespi_full_notaper.yaml b/unittest/force-styles/tests/manybody-pair-kolmogorov_crespi_full_notaper.yaml new file mode 100644 index 0000000000..8049df3f76 --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-kolmogorov_crespi_full_notaper.yaml @@ -0,0 +1,126 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Tue Aug 17 15:09:50 2021 +epsilon: 5e-12 +skip_tests: single +prerequisites: ! | + pair kolmogorov/crespi/full + atom full +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + comm_modify cutoff 16.0 +post_commands: ! "" +input_file: in.bilayer +pair_style: hybrid/overlay kolmogorov/crespi/full 16.0 0 +pair_coeff: ! | + * * kolmogorov/crespi/full CH.KC C C C +extract: ! "" +natoms: 48 +init_vdwl: -1.2319861234762621 +init_coul: 0 +init_stress: ! |- + -1.1008420461559216e+00 -1.1059574121005133e+00 1.9501897055379741e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.5182584087439038e-02 +init_forces: ! |2 + 1 2.7578315641555162e-03 -3.0357660829594124e-18 4.1533172062176493e-02 + 2 1.2588944124766973e-03 1.1188632453424979e-03 -6.5272327121384435e-02 + 3 -2.7478683204608390e-04 -8.0230960763927328e-18 4.2197936430518210e-02 + 4 -2.9454797299274370e-04 2.5016995713589751e-05 -6.6888523602123898e-02 + 5 2.7578315641554889e-03 -1.5178830414797062e-17 4.1533172062176521e-02 + 6 1.2588944124767164e-03 1.1188632453425370e-03 -6.5272327121384408e-02 + 7 -2.7478683204601537e-04 -5.8221656662471588e-17 4.2197936430518279e-02 + 8 -2.9454797299274544e-04 2.5016995713579072e-05 -6.6888523602123925e-02 + 9 -9.9550461818177349e-05 -4.5672016515951874e-18 4.2881244934310968e-02 + 10 -8.9376686817712898e-05 -3.9953386427702976e-06 -6.5900411970681708e-02 + 11 9.9502582131880363e-05 -1.8143445730187113e-17 4.2881235234728650e-02 + 12 8.9358399770402756e-05 -3.9749130157838919e-06 -6.5900379165394929e-02 + 13 -9.9550461818153496e-05 2.3418766925686896e-17 4.2881244934310996e-02 + 14 -8.9376686817732847e-05 -3.9953386427169006e-06 -6.5900411970681708e-02 + 15 9.9502582131827562e-05 -7.7708496647004022e-17 4.2881235234728796e-02 + 16 8.9358399770424440e-05 -3.9749130157734564e-06 -6.5900379165394957e-02 + 17 2.7484214272895964e-04 -4.4452289071905682e-18 4.2197913495242940e-02 + 18 2.9457391733397659e-04 2.5037988057733265e-05 -6.6888509865507970e-02 + 19 -2.7578389951520565e-03 1.2809996898682004e-17 4.1533158826483590e-02 + 20 -1.2589020697706256e-03 1.1188638120596694e-03 -6.5272346190055328e-02 + 21 2.7484214272896311e-04 2.3479753297889205e-17 4.2197913495243079e-02 + 22 2.9457391733397653e-04 2.5037988057775138e-05 -6.6888509865507970e-02 + 23 -2.7578389951520709e-03 -1.2185643619304939e-16 4.1533158826483604e-02 + 24 -1.2589020697706512e-03 1.1188638120596733e-03 -6.5272346190055328e-02 + 25 -2.7478683204603272e-04 -1.2468324983583301e-18 -4.2197936430518238e-02 + 26 1.2588944124767121e-03 -1.1188632453425023e-03 6.5272327121384421e-02 + 27 2.7578315641554356e-03 -2.6020852139652106e-17 -4.1533172062176479e-02 + 28 -2.9454797299273850e-04 -2.5016995713583283e-05 6.6888523602123814e-02 + 29 -2.7478683204602925e-04 3.7892865928368380e-17 -4.2197936430518307e-02 + 30 1.2588944124766739e-03 -1.1188632453424724e-03 6.5272327121384463e-02 + 31 2.7578315641555275e-03 -4.0115480381963664e-17 -4.1533172062176452e-02 + 32 -2.9454797299271942e-04 -2.5016995713586458e-05 6.6888523602123898e-02 + 33 9.9502582131834392e-05 -3.7269449679189215e-20 -4.2881235234728567e-02 + 34 -8.9376686817722005e-05 3.9953386427603932e-06 6.5900411970681694e-02 + 35 -9.9550461818180818e-05 -1.3674499900473425e-17 -4.2881244934310996e-02 + 36 8.9358399770429102e-05 3.9749130157800633e-06 6.5900379165395040e-02 + 37 9.9502582131827453e-05 5.1780818131549888e-17 -4.2881235234728608e-02 + 38 -8.9376686817744123e-05 3.9953386427840043e-06 6.5900411970681763e-02 + 39 -9.9550461818177349e-05 -5.0740661672321608e-17 -4.2881244934311093e-02 + 40 8.9358399770403624e-05 3.9749130157660754e-06 6.5900379165395012e-02 + 41 -2.7578389951520938e-03 4.5756190415085270e-17 -4.1533158826483570e-02 + 42 2.9457391733397973e-04 -2.5037988057731659e-05 6.6888509865507983e-02 + 43 2.7484214272898382e-04 2.2246473326686944e-17 -4.2197913495242927e-02 + 44 -1.2589020697706568e-03 -1.1188638120596731e-03 6.5272346190055355e-02 + 45 -2.7578389951520886e-03 4.0782412948808019e-17 -4.1533158826483549e-02 + 46 2.9457391733400050e-04 -2.5037988057726919e-05 6.6888509865508053e-02 + 47 2.7484214272895785e-04 -3.1658915194813543e-17 -4.2197913495243017e-02 + 48 -1.2589020697706581e-03 -1.1188638120597041e-03 6.5272346190055328e-02 +run_vdwl: -1.23199571764252 +run_coul: 0 +run_stress: ! |- + -1.1008368563459114e+00 -1.1059521765455493e+00 1.9490358494782456e-01 0.0000000000000000e+00 0.0000000000000000e+00 -1.5182325192586004e-02 +run_forces: ! |2 + 1 2.7578115049012742e-03 -1.9626239461520076e-08 4.1533149398200540e-02 + 2 1.2588780003755895e-03 1.1188632817004094e-03 -6.5269251575709356e-02 + 3 -2.7478278369621328e-04 -8.0919896562527821e-09 4.2197938643984578e-02 + 4 -2.9453830408723066e-04 2.5020943380932455e-05 -6.6885376194640786e-02 + 5 2.7578115049012399e-03 -1.9626239401238435e-08 4.1533149398200533e-02 + 6 1.2588780003755804e-03 1.1188632817005241e-03 -6.5269251575709369e-02 + 7 -2.7478278369620027e-04 -8.0919897266175031e-09 4.2197938643984703e-02 + 8 -2.9453830408726275e-04 2.5020943380984985e-05 -6.6885376194640717e-02 + 9 -9.9547742435301782e-05 5.3780414950783170e-10 4.2881247142594836e-02 + 10 -8.9376031411733843e-05 -3.9945836714521966e-06 -6.5897312884941883e-02 + 11 9.9499863028555701e-05 5.3758629572208002e-10 4.2881237442533686e-02 + 12 8.9357744478893550e-05 -3.9741580967872346e-06 -6.5897280081132562e-02 + 13 -9.9547742435326502e-05 5.3780415244873009e-10 4.2881247142594815e-02 + 14 -8.9376031411742083e-05 -3.9945836714029874e-06 -6.5897312884941855e-02 + 15 9.9499863028584324e-05 5.3758624475780164e-10 4.2881237442533790e-02 + 16 8.9357744478909922e-05 -3.9741580967885712e-06 -6.5897280081132506e-02 + 17 2.7483809396297375e-04 -8.0923733428147151e-09 4.2197915708206225e-02 + 18 2.9456424811194113e-04 2.5041935720938094e-05 -6.6885362458577291e-02 + 19 -2.7578189357608937e-03 -1.9626405105166717e-08 4.1533136162484115e-02 + 20 -1.2588856574676647e-03 1.1188638484657578e-03 -6.5269270643456764e-02 + 21 2.7483809396295635e-04 -8.0923732598465674e-09 4.2197915708206198e-02 + 22 2.9456424811196807e-04 2.5041935720825544e-05 -6.6885362458577347e-02 + 23 -2.7578189357608239e-03 -1.9626405201000025e-08 4.1533136162484163e-02 + 24 -1.2588856574676222e-03 1.1188638484657888e-03 -6.5269270643456764e-02 + 25 -2.7478267042781689e-04 7.1340099726084627e-09 -4.2197938717095443e-02 + 26 1.2588775889140107e-03 -1.1188640762445925e-03 6.5269251688086116e-02 + 27 2.7578100488037834e-03 2.0885614337388253e-08 -4.1533148778323065e-02 + 28 -2.9453931478136321e-04 -2.5020438627362798e-05 6.6885376801770646e-02 + 29 -2.7478267042784551e-04 7.1340098782286636e-09 -4.2197938717095346e-02 + 30 1.2588775889140823e-03 -1.1188640762446068e-03 6.5269251688086075e-02 + 31 2.7578100488038111e-03 2.0885614449061077e-08 -4.1533148778323238e-02 + 32 -2.9453931478134934e-04 -2.5020438627452736e-05 6.6885376801770674e-02 + 33 9.9499775923898881e-05 -4.3747681398428797e-10 -4.2881238156016258e-02 + 34 -8.9376188707950260e-05 3.9944719903915248e-06 6.5897312332129893e-02 + 35 -9.9547655306991140e-05 -4.3773580745386231e-10 -4.2881247856090716e-02 + 36 8.9357901801402086e-05 3.9740463921778550e-06 6.5897279528304625e-02 + 37 9.9499775923880232e-05 -4.3747670817970846e-10 -4.2881238156016264e-02 + 38 -8.9376188707982352e-05 3.9944719903545984e-06 6.5897312332129851e-02 + 39 -9.9547655306996777e-05 -4.3773581847206689e-10 -4.2881247856090876e-02 + 40 8.9357901801374873e-05 3.9740463922260334e-06 6.5897279528304431e-02 + 41 -2.7578174796584810e-03 2.0885758518950235e-08 -4.1533135542592893e-02 + 42 2.9456525880115910e-04 -2.5041430978732462e-05 6.6885363065714659e-02 + 43 2.7483798066595783e-04 7.1344129854552851e-09 -4.2197915781289633e-02 + 44 -1.2588852460277825e-03 -1.1188646429977976e-03 6.5269270755856881e-02 + 45 -2.7578174796584042e-03 2.0885758549338389e-08 -4.1533135542592900e-02 + 46 2.9456525880111129e-04 -2.5041430978583333e-05 6.6885363065714618e-02 + 47 2.7483798066597242e-04 7.1344129112194118e-09 -4.2197915781289751e-02 + 48 -1.2588852460277678e-03 -1.1188646429978574e-03 6.5269270755856937e-02 +... diff --git a/unittest/force-styles/tests/mol-pair-coul_exclude.yaml b/unittest/force-styles/tests/mol-pair-coul_exclude.yaml new file mode 100644 index 0000000000..e3bfb9dfc8 --- /dev/null +++ b/unittest/force-styles/tests/mol-pair-coul_exclude.yaml @@ -0,0 +1,87 @@ +--- +lammps_version: 30 Jul 2021 +date_generated: Thu Aug 19 05:44:56 2021 +epsilon: 5e-14 +skip_tests: +prerequisites: ! | + atom full + pair coul/exclude +pre_commands: ! "" +post_commands: ! | + pair_modify mix arithmetic +input_file: in.fourmol +pair_style: coul/exclude 8.0 +pair_coeff: ! | + * * +extract: ! | + cut_coul 0 +natoms: 29 +init_vdwl: 0 +init_coul: 976.7662140166423 +init_stress: ! |2- + 3.5388948320536065e+02 2.5335487380105781e+02 3.6952185701022364e+02 1.3686424356022002e+02 8.7895961622382046e+01 -5.5657699252762978e+00 +init_forces: ! |2 + 1 -2.1370477255985712e+01 -1.4166598766893758e+01 2.9310440052146326e+01 + 2 2.3264732430469657e+01 1.5692001202883613e+01 -2.8641449819420849e+01 + 3 2.2449042305615680e-01 1.4668967160440745e+00 5.1210039450899436e-01 + 4 -7.0490395531893513e-01 -1.3264719224865684e+00 -8.1217625652904202e-01 + 5 -8.8255242947367551e-01 -2.5499496555354710e+00 -1.1751860565740935e-01 + 6 -2.5789282115617354e+01 2.5922083376147825e+01 3.9284668116535428e+01 + 7 6.5887213922755370e+00 -1.1379710951282684e+01 -4.1569698240745815e+01 + 8 1.0165793608296209e+01 -1.9732745647894593e+01 -3.1168434006878172e+01 + 9 6.2278611600582163e+00 7.5490085322004052e+00 3.6053658984732728e+01 + 10 2.9613956094579899e+00 -6.6704022762728634e+00 7.0753413211731742e-01 + 11 7.6925511893250798e-01 -1.0660633894890499e+00 1.5916232833331401e+00 + 12 -2.6730309790123474e+00 1.0151505797685552e+00 2.4428922002007205e+00 + 13 4.2028736668256519e+00 -2.3945364969381782e+00 2.2608110571641327e-01 + 14 -1.0444805762876637e+00 -2.1692594974964866e-01 -4.5361664712630878e+00 + 15 1.0294632170564109e+00 4.2802145197407322e+00 1.1966180837917026e+00 + 16 1.6139881756442762e+01 -1.2595226879230463e+01 -4.8159451500674258e+01 + 17 -1.9109741071175417e+01 1.6173277008988080e+01 4.3679278548085868e+01 + 18 -5.5233108291167312e+00 -3.1467038458483600e+01 1.1751414157603500e+02 + 19 -4.8039195406996384e+01 -2.8078667518868457e+01 -6.9999907578978252e+01 + 20 5.3562506236113109e+01 5.9545705977352057e+01 -4.7514233997056749e+01 + 21 -3.2000540242879481e+01 -3.9305792536444351e+01 1.1575486824768517e+02 + 22 -4.1655033980718414e+01 -6.9415565144852787e+00 -8.1937970834963011e+01 + 23 7.3655574223597895e+01 4.6247349050929628e+01 -3.3816897412722149e+01 + 24 2.5133287180289841e+01 -1.0428031336996401e+02 6.0768019640810614e+01 + 25 -6.6553531734748447e+01 2.0322561261478373e+01 -5.9750075573899906e+01 + 26 4.1420244554458598e+01 8.3957752108485636e+01 -1.0179440669107107e+00 + 27 1.6184779133783991e+01 -1.1478028188716922e+02 4.0330521475487721e+01 + 28 -6.9426784473130638e+01 4.0320458958275808e+01 -4.9831480196977843e+01 + 29 5.3242005339346647e+01 7.4459822928893402e+01 9.5009587214901217e+00 +run_vdwl: 0 +run_coul: 976.5089740760076 +run_stress: ! |2- + 3.5429311069548726e+02 2.5338890902230719e+02 3.6882695435821336e+02 1.3697994178745301e+02 8.8376897487416215e+01 -4.7604760003034263e+00 +run_forces: ! |2 + 1 -2.1374527865789219e+01 -1.4202468442180830e+01 2.9210793601587412e+01 + 2 2.3263825454132370e+01 1.5734731460617787e+01 -2.8542033985914678e+01 + 3 2.2462585109904795e-01 1.4683529055153852e+00 5.1240421813750503e-01 + 4 -7.0182458619184773e-01 -1.3247801518720248e+00 -8.0930989810165044e-01 + 5 -8.8184812299538406e-01 -2.5499921086303359e+00 -1.1763132809557786e-01 + 6 -2.5769520757000304e+01 2.5925263738943752e+01 3.9219964964514880e+01 + 7 6.5906098601140588e+00 -1.1393221625638784e+01 -4.1479783467188192e+01 + 8 1.0136770975699770e+01 -1.9687788806065537e+01 -3.1157177158436330e+01 + 9 6.2325131117568873e+00 7.5029136682374347e+00 3.6011266563600110e+01 + 10 2.9627918492957752e+00 -6.6677419862633922e+00 7.1111494624978899e-01 + 11 7.6684242658501378e-01 -1.0650907890115915e+00 1.5865397504820036e+00 + 12 -2.6640875675365687e+00 1.0092746068515972e+00 2.4201156771591061e+00 + 13 4.2020911135059107e+00 -2.3836918937522000e+00 2.2652733116436718e-01 + 14 -1.0435191142174847e+00 -2.2501596985534378e-01 -4.5261002002201831e+00 + 15 1.0232065551846687e+00 4.2815515515559763e+00 1.2073921411042297e+00 + 16 1.6133578122629647e+01 -1.2611941628990227e+01 -4.8150714173103566e+01 + 17 -1.9101527306272342e+01 1.6189645470538316e+01 4.3676631017060792e+01 + 18 -5.0679097498234569e+00 -3.0925377041375377e+01 1.1693070865584599e+02 + 19 -4.8160088791916564e+01 -2.8252999531559283e+01 -6.9934716985727633e+01 + 20 5.3227998541740021e+01 5.9178376572934660e+01 -4.6995991670118372e+01 + 21 -3.2023145472732139e+01 -3.9029459539316420e+01 1.1553537552520324e+02 + 22 -4.1759300667456344e+01 -7.0799675491211342e+00 -8.1817190857460076e+01 + 23 7.3782446140188483e+01 4.6109427088437556e+01 -3.3718184667743166e+01 + 24 2.5304219247242145e+01 -1.0428415260557270e+02 6.0810156089628336e+01 + 25 -6.6772835122638725e+01 2.0222909012153103e+01 -5.9945279201780089e+01 + 26 4.1468615875396580e+01 8.4061243593419590e+01 -8.6487688784824801e-01 + 27 1.6328783769519674e+01 -1.1474592950014997e+02 4.0113097823544649e+01 + 28 -6.9456403419277834e+01 4.0310251785996094e+01 -4.9735673433675416e+01 + 29 5.3127619649758152e+01 7.4435677714153883e+01 9.6225756101307667e+00 +... diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index d416074b81..71c1ed882f 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; @@ -4637,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(); @@ -4726,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; @@ -4738,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); 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)