diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index e2ffd319e5..7d1b2894c8 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -172,6 +172,7 @@ set(STANDARD_PACKAGES AWPMD BOCS BODY + BPM BROWNIAN CG-DNA CG-SDK diff --git a/cmake/presets/all_off.cmake b/cmake/presets/all_off.cmake index df07aa2989..6a8f70c9ea 100644 --- a/cmake/presets/all_off.cmake +++ b/cmake/presets/all_off.cmake @@ -8,6 +8,7 @@ set(ALL_PACKAGES AWPMD BOCS BODY + BPM BROWNIAN CG-DNA CG-SDK diff --git a/cmake/presets/all_on.cmake b/cmake/presets/all_on.cmake index 7762eef505..4cff7d945d 100644 --- a/cmake/presets/all_on.cmake +++ b/cmake/presets/all_on.cmake @@ -10,6 +10,7 @@ set(ALL_PACKAGES AWPMD BOCS BODY + BPM BROWNIAN CG-DNA CG-SDK diff --git a/cmake/presets/mingw-cross.cmake b/cmake/presets/mingw-cross.cmake index fe828a6d9a..ef7f15fec2 100644 --- a/cmake/presets/mingw-cross.cmake +++ b/cmake/presets/mingw-cross.cmake @@ -4,6 +4,7 @@ set(WIN_PACKAGES AWPMD BOCS BODY + BPM BROWNIAN CG-DNA CG-SDK diff --git a/cmake/presets/most.cmake b/cmake/presets/most.cmake index 27ce57621c..44d668fd83 100644 --- a/cmake/presets/most.cmake +++ b/cmake/presets/most.cmake @@ -6,6 +6,7 @@ set(ALL_PACKAGES ASPHERE BOCS BODY + BPM BROWNIAN CG-DNA CG-SDK diff --git a/cmake/presets/windows.cmake b/cmake/presets/windows.cmake index d4e69c5fca..c83b16d855 100644 --- a/cmake/presets/windows.cmake +++ b/cmake/presets/windows.cmake @@ -2,6 +2,7 @@ set(WIN_PACKAGES ASPHERE BOCS BODY + BPM BROWNIAN CG-DNA CG-SDK diff --git a/doc/src/Commands_bond.rst b/doc/src/Commands_bond.rst index d0083d7c63..40b99a5fb8 100644 --- a/doc/src/Commands_bond.rst +++ b/doc/src/Commands_bond.rst @@ -32,6 +32,8 @@ OPT. * * * + * :doc:`bpm/rotational ` + * :doc:`bpm/spring ` * :doc:`class2 (ko) ` * :doc:`fene (iko) ` * :doc:`fene/expand (o) ` diff --git a/doc/src/Commands_compute.rst b/doc/src/Commands_compute.rst index 6309fe83e2..9b04bbff92 100644 --- a/doc/src/Commands_compute.rst +++ b/doc/src/Commands_compute.rst @@ -91,6 +91,7 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`msd ` * :doc:`msd/chunk ` * :doc:`msd/nongauss ` + * :doc:`nbond/atom ` * :doc:`omega/chunk ` * :doc:`orientorder/atom (k) ` * :doc:`pair ` diff --git a/doc/src/Commands_fix.rst b/doc/src/Commands_fix.rst index c95fdb39b6..fddf3435f9 100644 --- a/doc/src/Commands_fix.rst +++ b/doc/src/Commands_fix.rst @@ -141,6 +141,7 @@ OPT. * :doc:`nve/manifold/rattle ` * :doc:`nve/noforce ` * :doc:`nve/sphere (ko) ` + * :doc:`nve/bpm/sphere ` * :doc:`nve/spin ` * :doc:`nve/tri ` * :doc:`nvk ` @@ -158,7 +159,6 @@ OPT. * :doc:`orient/fcc ` * :doc:`orient/eco ` * :doc:`pafi ` - * :doc:`pair/tracker ` * :doc:`phonon ` * :doc:`pimd ` * :doc:`planeforce ` diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 7a1ed4ee72..d9ee22ce86 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -53,6 +53,7 @@ OPT. * :doc:`born/coul/msm (o) ` * :doc:`born/coul/wolf (go) ` * :doc:`born/coul/wolf/cs (g) ` + * :doc:`bpm/spring ` * :doc:`brownian (o) ` * :doc:`brownian/poly (o) ` * :doc:`buck (giko) ` diff --git a/doc/src/Examples.rst b/doc/src/Examples.rst index 57092a01d7..bbd4db8508 100644 --- a/doc/src/Examples.rst +++ b/doc/src/Examples.rst @@ -54,6 +54,8 @@ Lowercase directories +-------------+------------------------------------------------------------------+ | body | body particles, 2d system | +-------------+------------------------------------------------------------------+ +| bpm | BPM simulations of pouring elastic grains and plate impact | ++-------------+------------------------------------------------------------------+ | cmap | CMAP 5-body contributions to CHARMM force field | +-------------+------------------------------------------------------------------+ | colloid | big colloid particles in a small particle solvent, 2d system | diff --git a/doc/src/Howto.rst b/doc/src/Howto.rst index a96f64145e..0f1abcd7d7 100644 --- a/doc/src/Howto.rst +++ b/doc/src/Howto.rst @@ -23,6 +23,8 @@ General howto Howto_library Howto_couple Howto_mdi + Howto_bpm + Howto_broken_bonds Settings howto ============== diff --git a/doc/src/Howto_bpm.rst b/doc/src/Howto_bpm.rst new file mode 100644 index 0000000000..8da6511213 --- /dev/null +++ b/doc/src/Howto_bpm.rst @@ -0,0 +1,124 @@ +Bonded particle models +====================== + +The BPM package implements bonded particle models which can be used to +simulate mesoscale solids. Solids are constructed as a collection of + +particles which each represent a coarse-grained region of space much +larger than the atomistic scale. Particles within a solid region are +then connected by a network of bonds to provide solid elasticity. + +Unlike traditional bonds in molecular dynamics, the equilibrium bond +length can vary between bonds. Bonds store the reference state. This +includes setting the equilibrium length equal to the initial distance +between the two particles but can also include data on the bond +orientation for rotational models. This produces a stress free initial +state. Furthermore, bonds are allowed to break under large strains +producing fracture. The examples/bpm directory has sample input scripts +for simulations of the fragmentation of an impacted plate and the +pouring of extended, elastic bodies. + +---------- + +Bonds can be created using a :doc:`read data ` or +:doc:`create bonds ` command. Alternatively, a +:doc:`molecule ` template with bonds can be used with +:doc:`fix deposit ` or :doc:`fix pour ` to +create solid grains. + +In this implementation, bonds store their reference state when they are +first computed in the setup of the first simulation run. Data is then +preserved across run commands and is written to :doc:`binary restart +files ` such that restarting the system will not reset the +reference state of a bond. Bonds that are created midway into a run, +such as those created by pouring grains using :doc:`fix pour +`, are initialized on that timestep. + +As bonds can be broken between neighbor list builds, the +:doc:`special_bonds ` command works differently for BPM +bond styles. There are two possible settings which determine how pair +interactions work between bonded particles. First, one can turn off +all pair interactions between bonded particles. Unlike :doc:`bond +quartic `, this is not done by subtracting pair forces +during the bond computation but rather by dynamically updating the +special bond list. This is the default behavior of BPM bond styles and +is done by updating the 1-2 special bond list as bonds break. To do +this, LAMMPS requires :doc:`newton ` bond off such that all +processors containing an atom know when a bond breaks. Additionally, +one must do either (A) or (B). + +(A) + +Use the following special bond settings + +.. code-block:: LAMMPS + + special_bonds lj 0 1 1 coul 1 1 1 + +These settings accomplish two goals. First, they turn off 1-3 and 1-4 +special bond lists, which are not currently supported for BPMs. As +BPMs often have dense bond networks, generating 1-3 and 1-4 special +bond lists is expensive. By setting the lj weight for 1-2 bonds to +zero, this turns off pairwise interactions. Even though there are no +charges in BPM models, setting a nonzero coul weight for 1-2 bonds +ensures all bonded neighbors are still included in the neighbor list +in case bonds break between neighbor list builds. + +(B) + +Alternatively, one can simply overlay pair interactions such that all +bonded particles also feel pair interactions. This can be accomplished +by using the *overlay/pair* keyword present in all bpm bond styles and +by using the following special bond settings + +.. code-block:: LAMMPS + + special_bonds lj/coul 1 1 1 + +See the :doc:`Howto ` page on broken bonds for +more information. + +---------- + +Currently there are two types of bonds included in the BPM +package. The first bond style, :doc:`bond bpm/spring +`, only applies pairwise, central body forces. Point +particles must have :doc:`bond atom style ` and may be +thought of as nodes in a spring network. Alternatively, the second +bond style, :doc:`bond bpm/rotational `, resolves +tangential forces and torques arising with the shearing, bending, and +twisting of the bond due to rotation or displacement of particles. +Particles are similar to those used in the :doc:`granular package +`, :doc:`atom style sphere `. However, +they must also track the current orientation of particles and store bonds +and therefore use a :doc:`bpm/sphere atom style `. +This also requires a unique integrator :doc:`fix nve/bpm/sphere +` which numerically integrates orientation similar +to :doc:`fix nve/asphere `. + +To monitor the fracture of bonds in the system, all BPM bond styles +have the ability to record instances of bond breakage to output using +the :doc:`dump local ` command. Additionally, one can use +:doc:`compute nbond/atom ` to tally the current +number of bonds per atom. + +In addition to bond styles, a new pair style :doc:`pair bpm/spring +` was added to accompany the bpm/spring bond +style. This pair style is simply a hookean repulsion with similar +velocity damping as its sister bond style. + +---------- + +While LAMMPS has many utilities to create and delete bonds, *only* +the following are currently compatible with BPM bond styles: + +* :doc:`create_bonds ` +* :doc:`delete_bonds ` +* :doc:`fix bond/create ` +* :doc:`fix bond/break ` +* :doc:`fix bond/swap ` + +Note :doc:`create_bonds ` requires certain special_bonds settings. +To subtract pair interactions, one will need to switch between different +special_bonds settings in the input script. An example is found in +examples/bpm/impact. diff --git a/doc/src/Howto_broken_bonds.rst b/doc/src/Howto_broken_bonds.rst new file mode 100644 index 0000000000..1a356df510 --- /dev/null +++ b/doc/src/Howto_broken_bonds.rst @@ -0,0 +1,48 @@ +Broken Bonds +============ + +Typically, bond interactions persist for the duration of a simulation +in LAMMPS. However, there are some exceptions that allow for bonds to +break including the :doc:`quartic bond style ` and the +bond styles in the :doc:`BPM package ` which contains the +:doc:`bpm/spring ` and +:doc:`bpm/rotational ` bond styles. In these cases, +a bond can be broken if it is stretched beyond a user-defined threshold. +LAMMPS accomplishes this by setting the bond type to zero such that the +bond force is no longer computed. + +Users are normally able to weight the contribution of pair forces to atoms +that are bonded using the :doc:`special_bonds command `. +When bonds break, this is not always the case. For the quartic bond style, +pair forces are always turned off between bonded particles. LAMMPS does +this via a computational sleight-of-hand. It subtracts the pairwise +interaction as part of the bond computation. When the bond breaks, the +subtraction stops. For this to work, the pairwise interaction must always +be computed by the :doc:`pair_style ` command, whether the bond +is broken or not. This means that :doc:`special_bonds ` must +be set to 1,1,1. After the bond breaks, the pairwise interaction between the +two atoms is turned on, since they are no longer bonded. + +In the BPM package, one can either turn off all pair interactions between +bonded particles or leave them on, overlaying pair forces on top of bond +forces. To remove pair forces, the special bond list is dynamically +updated. More details can be found on the :doc:`Howto BPM ` +page. + +Bonds can also be broken by fixes which change bond topology, including +:doc:`fix bond/break ` and +:doc:`fix bond/react `. These fixes will automatically +trigger a rebuild of the neighbor list and update special bond data structures +when bonds are broken. + +Note that when bonds are dumped to a file via the :doc:`dump local ` command, bonds with type 0 are not included. The +:doc:`delete_bonds ` command can also be used to query the +status of broken bonds or permanently delete them, e.g.: + +.. code-block:: LAMMPS + + delete_bonds all stats + delete_bonds all bond 0 remove + +The compute :doc:`nbond/atom ` can also be used +to tally the current number of bonds per atom, excluding broken bonds. diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index c528e71664..bdc7279e6e 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -32,6 +32,7 @@ page gives those details. * :ref:`AWPMD ` * :ref:`BOCS ` * :ref:`BODY ` + * :ref:`BPM ` * :ref:`BROWNIAN ` * :ref:`CG-DNA ` * :ref:`CG-SDK ` @@ -283,6 +284,33 @@ overview. ---------- +.. _PKG-BPM: + +BPM package +------------ + +**Contents:** + +Pair styles, bond styles, fixes, and computes for bonded particle +models for mesoscale simulations of solids and fracture. See the +:doc:`Howto bpm ` page for an overview. + +**Authors:** Joel T. Clemmer (Sandia National Labs) + +**Supporting info:** + +* src/BPM filenames -> commands +* :doc:`Howto_bpm ` +* :doc:`atom_style bpm/sphere ` +* :doc:`bond_style bpm/rotational ` +* :doc:`bond_style bpm/spring ` +* :doc:`compute nbond/atom ` +* :doc:`fix nve/bpm/sphere ` +* :doc:`pair_style bpm/spring ` +* examples/bpm + +---------- + .. _PKG-BROWNIAN: BROWNIAN package @@ -1545,7 +1573,6 @@ listing, "ls src/MISC", to see the list of commands. * :doc:`pair_style list ` * :doc:`pair_style srp ` * :doc:`pair_style tracker ` -* :doc:`fix pair/tracker ` ---------- diff --git a/doc/src/Packages_list.rst b/doc/src/Packages_list.rst index 89d08b44b9..14d76e0ba3 100644 --- a/doc/src/Packages_list.rst +++ b/doc/src/Packages_list.rst @@ -58,6 +58,11 @@ whether an extra library is needed to build and use the package: - :doc:`Howto body ` - body - no + * - :ref:`BPM ` + - bonded particle models + - :doc:`Howto bpm ` + - bpm + - no * - :ref:`BROWNIAN ` - Brownian dynamics, self-propelled particles - :doc:`fix brownian `, :doc:`fix propel/self ` diff --git a/doc/src/atom_style.rst b/doc/src/atom_style.rst index 3a525b27f5..bd0c193962 100644 --- a/doc/src/atom_style.rst +++ b/doc/src/atom_style.rst @@ -10,7 +10,7 @@ Syntax atom_style style args -* style = *angle* or *atomic* or *body* or *bond* or *charge* or *dipole* or *dpd* or *edpd* or *electron* or *ellipsoid* or *full* or *line* or *mdpd* or *molecular* or *oxdna* or *peri* or *smd* or *sph* or *sphere* or *spin* or *tdpd* or *tri* or *template* or *hybrid* +* style = *angle* or *atomic* or *body* or *bond* or *charge* or *dipole* or *dpd* or *edpd* or *electron* or *ellipsoid* or *full* or *line* or *mdpd* or *molecular* or *oxdna* or *peri* or *smd* or *sph* or *sphere* or *bpm/sphere* or *spin* or *tdpd* or *tri* or *template* or *hybrid* .. parsed-literal:: @@ -21,6 +21,7 @@ Syntax see the :doc:`Howto body ` doc page for details *sphere* arg = 0/1 (optional) for static/dynamic particle radii + *bpm/sphere* arg = 0/1 (optional) for static/dynamic particle radii *tdpd* arg = Nspecies Nspecies = # of chemical species *template* arg = template-ID @@ -120,6 +121,8 @@ quantities. +--------------+-----------------------------------------------------+--------------------------------------+ | *sphere* | diameter, mass, angular velocity | granular models | +--------------+-----------------------------------------------------+--------------------------------------+ +| *bpm/sphere* | diameter, mass, angular velocity, quaternion | granular bonded particle models (BPM)| ++--------------+-----------------------------------------------------+--------------------------------------+ | *spin* | magnetic moment | system with magnetic particles | +--------------+-----------------------------------------------------+--------------------------------------+ | *tdpd* | chemical concentration | tDPD particles | @@ -141,8 +144,9 @@ quantities. output the custom values. All of the above styles define point particles, except the *sphere*, -*ellipsoid*, *electron*, *peri*, *wavepacket*, *line*, *tri*, and -*body* styles, which define finite-size particles. See the :doc:`Howto spherical ` page for an overview of using +*bpm/sphere*, *ellipsoid*, *electron*, *peri*, *wavepacket*, *line*, +*tri*, and *body* styles, which define finite-size particles. See the +:doc:`Howto spherical ` page for an overview of using finite-size particle models with LAMMPS. All of the point-particle styles assign mass to particles on a @@ -150,15 +154,15 @@ per-type basis, using the :doc:`mass ` command, The finite-size particle styles assign mass to individual particles on a per-particle basis. -For the *sphere* style, the particles are spheres and each stores a +For the *sphere* and *bpm/sphere* styles, the particles are spheres and each stores a per-particle diameter and mass. If the diameter > 0.0, the particle is a finite-size sphere. If the diameter = 0.0, it is a point particle. Note that by use of the *disc* keyword with the :doc:`fix nve/sphere `, :doc:`fix nvt/sphere `, :doc:`fix nph/sphere `, :doc:`fix npt/sphere -` commands, spheres can be effectively treated as 2d +` commands for the *sphere* style, spheres can be effectively treated as 2d discs for a 2d simulation if desired. See also the :doc:`set -density/disc ` command. The *sphere* style takes an optional 0 +density/disc ` command. The *sphere* and *bpm/sphere* styles take an optional 0 or 1 argument. A value of 0 means the radius of each sphere is constant for the duration of the simulation. A value of 1 means the radii may vary dynamically during the simulation, e.g. due to use of @@ -195,6 +199,8 @@ position, which is represented by the eradius = electron size. For the *peri* style, the particles are spherical and each stores a per-particle mass and volume. +The *bpm/sphere* style is part of the BPM package. + The *oxdna* style is for coarse-grained nucleotides and stores the 3'-to-5' polarity of the nucleotide strand, which is set through the bond topology in the data file. The first (second) atom in a diff --git a/doc/src/bond_bpm_rotational.rst b/doc/src/bond_bpm_rotational.rst new file mode 100644 index 0000000000..b13d27dfbe --- /dev/null +++ b/doc/src/bond_bpm_rotational.rst @@ -0,0 +1,258 @@ +.. index:: bond_style bpm/rotational + +bond_style bpm/rotational command +================================= + +Syntax +"""""" + +.. code-block:: LAMMPS + + bond_style bpm/rotational keyword value attribute1 attribute2 ... + +* optional keyword = *overlay/pair* or *store/local* or *smooth* + + .. parsed-literal:: + + *store/local* values = fix_ID N attributes ... + * fix_ID = ID of associated internal fix to store data + * N = prepare data for output every this many timesteps + * attributes = zero or more of the below attributes may be appended + + *id1, id2* = IDs of 2 atoms in the bond + *time* = the timestep the bond broke + *x, y, z* = the center of mass position of the 2 atoms when the bond broke (distance units) + *x/ref, y/ref, z/ref* = the initial center of mass position of the 2 atoms (distance units) + + *overlay/pair* value = none + bonded particles will still interact with pair forces + + *smooth* value = *yes* or *no* + smooths bond forces near the breaking point + +Examples +"""""""" + +.. code-block:: LAMMPS + + bond_style bpm/rotational + bond_coeff 1 1.0 0.2 0.02 0.02 0.20 0.04 0.04 0.04 0.1 0.02 0.002 0.002 + + bond_style bpm/rotational myfix 1000 time id1 id2 + fix myfix all store/local 1000 3 + dump 1 all local 1000 dump.broken f_myfix[1] f_myfix[2] f_myfix[3] + dump_modify 1 write_header no + +Description +""""""""""" + +The *bpm/rotational* bond style computes forces and torques based on +deviations from the initial reference state of the two atoms. The +reference state is stored by each bond when it is first computed in +the setup of a run. Data is then preserved across run commands and is +written to :doc:`binary restart files ` such that restarting +the system will not reset the reference state of a bond. + +Forces include a normal and tangential component. The base normal force +has a magnitude of + +.. math:: + + f_r = k_r (r - r_0) + +where :math:`k_r` is a stiffness and :math:`r` is the current distance and +:math:`r_0` is the initial distance between the two particles. + +A tangential force is applied perpendicular to the normal direction +which is proportional to the tangential shear displacement with a +stiffness of :math:`k_s`. This tangential force also induces a torque. +In addition, bending and twisting torques are also applied to +particles which are proportional to angular bending and twisting +displacements with stiffnesses of :math`k_b` and :math:`k_t', +respectively. Details on the calculations of shear displacements and +angular displacements can be found in :ref:`(Wang) ` and +:ref:`(Wang and Mora) `. + +Bonds will break under sufficient stress. A breaking criteria is calculated + +.. math:: + + B = \mathrm{max}\{0, \frac{f_r}{f_{r,c}} + \frac{|f_s|}{f_{s,c}} + + \frac{|\tau_b|}{\tau_{b,c}} + \frac{|\tau_t|}{\tau_{t,c}} \} + +where :math:`|f_s|` is the magnitude of the shear force and +:math:`|\tau_b|` and :math:`|\tau_t|` are the magnitudes of the +bending and twisting forces, respectively. The corresponding variables +:math:`f_{r,c}` :math:`f_{s,c}`, :math:`\tau_{b,c}`, and +:math:`\tau_{t,c}` are critical limits to each force or torque. If +:math:`B` is ever equal to or exceeds one, the bond will break. This +is done by setting by setting its type to 0 such that forces and +torques are no longer computed. + +After computing the base magnitudes of the forces and torques, they +can be optionally multiplied by an extra factor :math:`w` to smoothly +interpolate forces and torques to zero as the bond breaks. This term +is calculated as :math:`w = (1.0 - B^4)`. This smoothing factor can be +added or removed using the *smooth* keyword. + +Finally, additional damping forces and torques are applied to the two +particles. A force is applied proportional to the difference in the +normal velocity of particles using a similar construction as +dissipative particle dynamics (:ref:`(Groot) `): + +.. math:: + + F_D = - \gamma_n w (\hat{r} \bullet \vec{v}) + +where :math:`\gamma_n` is the damping strength, :math:`\hat{r}` is the +radial normal vector, and :math:`\vec{v}` is the velocity difference +between the two particles. Similarly, tangential forces are applied to +each atom proportional to the relative differences in sliding +velocities with a constant prefactor :math:`\gamma_s` (:ref:`(Wang et +al.) `) along with their associated torques. The rolling and +twisting components of the relative angular velocities of the two +atoms are also damped by applying torques with prefactors of +:math:`\gamma_r` and :math:`\gamma_t`, respectively. + +The following coefficients must be defined for each bond type via the +:doc:`bond_coeff ` command as in the example above, or in +the data file or restart files read by the :doc:`read_data ` +or :doc:`read_restart ` commands: + +* :math:`k_r` (force/distance units) +* :math:`k_s` (force/distance units) +* :math:`k_t` (force*distance/radians units) +* :math:`k_b` (force*distance/radians units) +* :math:`f_{r,c}` (force units) +* :math:`f_{s,c}` (force units) +* :math:`\tau_{b,c}` (force*distance units) +* :math:`\tau_{t,c}` (force*distance units) +* :math:`\gamma_n` (force/velocity units) +* :math:`\gamma_s` (force/velocity units) +* :math:`\gamma_r` (force*distance/velocity units) +* :math:`\gamma_t` (force*distance/velocity units) + +By default, pair forces are not calculated between bonded particles. +Pair forces can alternatively be overlaid on top of bond forces using +the *overlay/pair* keyword. These settings require specific +:doc:`special_bonds ` settings described in the +restrictions. Further details can be found in the `:doc: how to +` page on BPMs. + +If the *store/local* keyword is used, this fix will track bonds that +break during the simulation. Whenever a bond breaks, data is processed +and transferred to an internal fix labeled *fix_ID*. This allows the +local data to be accessed by other LAMMPS commands. +Following any optional keyword/value arguments, a list of one or more +attributes is specified. These include the IDs of the two atoms in +the bond. The other attributes for the two atoms include the timestep +during which the bond broke and the current/initial center of mass +position of the two atoms. + +Data is continuously accumulated over intervals of *N* +timesteps. At the end of each interval, all of the saved accumulated +data is deleted to make room for new data. Individual datum may +therefore persist anywhere between *1* to *N* timesteps depending on +when they are saved. This data can be accessed using the *fix_ID* and a +:doc:`dump local ` command. To ensure all data is output, +the dump frequency should correspond to the same interval of *N* +timesteps. A dump frequency of an integer multiple of *N* can be used +to regularly output a sample of the accumulated data. + +Note that when unbroken bonds are dumped to a file via the +:doc:`dump local ` command, bonds with type 0 (broken bonds) +are not included. +The :doc:`delete_bonds ` command can also be used to +query the status of broken bonds or permanently delete them, e.g.: + +.. code-block:: LAMMPS + + delete_bonds all stats + delete_bonds all bond 0 remove + + +---------- + +Restart and other info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This bond style writes the reference state of each bond to +:doc:`binary restart files `. Loading a restart file will +properly resume bonds. + +The single() function of these pair styles returns 0.0 for the energy +of a pairwise interaction, since energy is not conserved in these +dissipative potentials. It also returns only the normal component of +the pairwise interaction force. + +The accumulated data is not written to restart files and should be +output before a restart file is written to avoid missing data. + +The internal fix calculates a local vector or local array depending on the +number of input values. The length of the vector or number of rows in +the array is the number of recorded, lost interactions. If a single +input is specified, a local vector is produced. If two or more inputs +are specified, a local array is produced where the number of columns = +the number of inputs. The vector or array can be accessed by any +command that uses local values from a compute as input. See the +:doc:`Howto output ` page for an overview of LAMMPS +output options. + +The vector or array will be floating point values that correspond to +the specified attribute. + +Restrictions +"""""""""""" + +This bond style can only be used if LAMMPS was built with the BPM +package. See the :doc:`Build package ` doc page for +more info. + +By default if pair interactions are to be disabled, this bond style +requires setting + +.. code-block:: LAMMPS + + special_bonds lj 0 1 1 coul 1 1 1 + +and :doc:`newton ` must be set to bond off. If the +*overlay/pair* option is used, this bond style alternatively requires +setting + +.. code-block:: LAMMPS + + special_bonds lj/coul 1 1 1 + +The *bpm/rotational* style requires :doc:`atom style bpm/sphere `. + +Related commands +"""""""""""""""" + +:doc:`bond_coeff `, :doc:`fix nve/bpm/sphere ` + +Default +""""""" + +The option defaults are *smooth* = *yes* + +---------- + +.. _Wang2009: + +**(Wang)** Wang, Acta Geotechnica, 4, +p 117-127 (2009). + +.. _Wang2009b: + +**(Wang and Mora)** Wang, Mora, Advances in Geocomputing, +119, p 183-228 (2009). + +.. _Groot3: + +**(Groot)** Groot and Warren, J Chem Phys, 107, 4423-35 (1997). + +.. _Wang20152: + +**(Wang et al, 2015)** Wang, Y., Alonso-Marroquin, F., & Guo, +W. W. (2015). Rolling and sliding in 3-D discrete element +models. Particuology, 23, 49-55. diff --git a/doc/src/bond_bpm_spring.rst b/doc/src/bond_bpm_spring.rst new file mode 100644 index 0000000000..1d2f12701d --- /dev/null +++ b/doc/src/bond_bpm_spring.rst @@ -0,0 +1,202 @@ +.. index:: bond_style bpm/spring + +bond_style bpm/spring command +============================= + +Syntax +"""""" + +.. code-block:: LAMMPS + + bond_style bpm/spring keyword value attribute1 attribute2 ... + +* optional keyword = *overlay/pair* or *store/local* or *smooth* + + .. parsed-literal:: + + *store/local* values = fix_ID N attributes ... + * fix_ID = ID of associated internal fix to store data + * N = prepare data for output every this many timesteps + * attributes = zero or more of the below attributes may be appended + + *id1, id2* = IDs of 2 atoms in the bond + *time* = the timestep the bond broke + *x, y, z* = the center of mass position of the 2 atoms when the bond broke (distance units) + *x/ref, y/ref, z/ref* = the initial center of mass position of the 2 atoms (distance units) + + *overlay/pair* value = none + bonded particles will still interact with pair forces + + *smooth* value = *yes* or *no* + smooths bond forces near the breaking point + +Examples +"""""""" + +.. code-block:: LAMMPS + + bond_style bpm/spring + bond_coeff 1 1.0 0.05 0.1 + + bond_style bpm/spring myfix 1000 time id1 id2 + dump 1 all local 1000 dump.broken f_myfix[1] f_myfix[2] f_myfix[3] + dump_modify 1 write_header no + +Description +""""""""""" + +The *bpm/spring* bond style computes forces and torques based on +deviations from the initial reference state of the two atoms. The +reference state is stored by each bond when it is first computed in +the setup of a run. Data is then preserved across run commands and is +written to :doc:`binary restart files ` such that restarting +the system will not reset the reference state of a bond. + +This bond style only applies central-body forces which conserve the +translational and rotational degrees of freedom of a bonded set of +particles. The force has a magnitude of + +.. math:: + + F = k (r - r_0) w + +where :math:`k_r` is a stiffness, :math:`r` is the current distance +and :math:`r_0` is the initial distance between the two particles, and +:math:`w` is an optional smoothing factor discussed below. Bonds will +break at a strain of :math:`\epsilon_c`. This is done by setting by +setting its type to 0 such that forces are no longer computed. + +An additional damping force is applied to the bonded +particles. This forces is proportional to the difference in the +normal velocity of particles using a similar construction as +dissipative particle dynamics (:ref:`(Groot) `): + +.. math:: + + F_D = - \gamma w (\hat{r} \bullet \vec{v}) + +where :math:`\gamma` is the damping strength, :math:`\hat{r}` is the +radial normal vector, and :math:`\vec{v}` is the velocity difference +between the two particles. + +The smoothing factor :math:`w` can be added or removed using the +*smooth* keyword. It is constructed such that forces smoothly go +to zero, avoiding discontinuities, as bonds approach the critical strain + +.. math:: + + w = 1.0 - \left( \frac{r - r_0}{r_0 \epsilon_c} \right)^8 . + +The following coefficients must be defined for each bond type via the +:doc:`bond_coeff ` command as in the example above, or in +the data file or restart files read by the :doc:`read_data +` or :doc:`read_restart ` commands: + +* :math:`k` (force/distance units) +* :math:`\epsilon_c` (unit less) +* :math:`\gamma` (force/velocity units) + +By default, pair forces are not calculated between bonded particles. +Pair forces can alternatively be overlaid on top of bond forces using +the *overlay/pair* keyword. These settings require specific +:doc:`special_bonds ` settings described in the +restrictions. Further details can be found in the `:doc: how to +` page on BPMs. + +If the *store/local* keyword is used, this fix will track bonds that +break during the simulation. Whenever a bond breaks, data is processed +and transferred to an internal fix labeled *fix_ID*. This allows the +local data to be accessed by other LAMMPS commands. +Following any optional keyword/value arguments, a list of one or more +attributes is specified. These include the IDs of the two atoms in +the bond. The other attributes for the two atoms include the timestep +during which the bond broke and the current/initial center of mass +position of the two atoms. + +Data is continuously accumulated over intervals of *N* +timesteps. At the end of each interval, all of the saved accumulated +data is deleted to make room for new data. Individual datum may +therefore persist anywhere between *1* to *N* timesteps depending on +when they are saved. This data can be accessed using the *fix_ID* and a +:doc:`dump local ` command. To ensure all data is output, +the dump frequency should correspond to the same interval of *N* +timesteps. A dump frequency of an integer multiple of *N* can be used +to regularly output a sample of the accumulated data. + +Note that when unbroken bonds are dumped to a file via the +:doc:`dump local ` command, bonds with type 0 (broken bonds) +are not included. +The :doc:`delete_bonds ` command can also be used to +query the status of broken bonds or permanently delete them, e.g.: + +.. code-block:: LAMMPS + + delete_bonds all stats + delete_bonds all bond 0 remove + +---------- + +Restart and other info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This bond style writes the reference state of each bond to +:doc:`binary restart files `. Loading a restart +file will properly resume bonds. + +The single() function of these pair styles returns 0.0 for the energy +of a pairwise interaction, since energy is not conserved in these +dissipative potentials. + +The accumulated data is not written to restart files and should be +output before a restart file is written to avoid missing data. + +The internal fix calculates a local vector or local array depending on the +number of input values. The length of the vector or number of rows in +the array is the number of recorded, lost interactions. If a single +input is specified, a local vector is produced. If two or more inputs +are specified, a local array is produced where the number of columns = +the number of inputs. The vector or array can be accessed by any +command that uses local values from a compute as input. See the +:doc:`Howto output ` page for an overview of LAMMPS +output options. + +The vector or array will be floating point values that correspond to +the specified attribute. + +Restrictions +"""""""""""" + +This bond style can only be used if LAMMPS was built with the BPM +package. See the :doc:`Build package ` doc page for +more info. + +By default if pair interactions are to be disabled, this bond style +requires setting + +.. code-block:: LAMMPS + + special_bonds lj 0 1 1 coul 1 1 1 + +and :doc:`newton ` must be set to bond off. If the +*overlay/pair* option is used, this bond style alternatively requires +setting + +.. code-block:: LAMMPS + + special_bonds lj/coul 1 1 1 + +Related commands +"""""""""""""""" + +:doc:`bond_coeff `, :doc:`pair bpm/spring ` + +Default +""""""" + +The option defaults are *smooth* = *yes* + +---------- + +.. _Groot4: + +**(Groot)** Groot and Warren, J Chem Phys, 107, 4423-35 (1997). diff --git a/doc/src/bond_quartic.rst b/doc/src/bond_quartic.rst index 89c33607ac..1f9f9bf4e9 100644 --- a/doc/src/bond_quartic.rst +++ b/doc/src/bond_quartic.rst @@ -67,7 +67,8 @@ local maximum. If a bond length ever becomes :math:`> R_c`, LAMMPS "breaks" the bond, which means two things. First, the bond potential is turned off by setting its type to 0, and is no longer computed. Second, a pairwise interaction between the two atoms is turned on, since they -are no longer bonded. +are no longer bonded. See the :doc:`Howto ` page +on broken bonds for more information. LAMMPS does the second task via a computational sleight-of-hand. It subtracts the pairwise interaction as part of the bond computation. diff --git a/doc/src/bond_style.rst b/doc/src/bond_style.rst index 4dee48a78d..95ba1572c1 100644 --- a/doc/src/bond_style.rst +++ b/doc/src/bond_style.rst @@ -84,6 +84,8 @@ accelerated styles exist. * :doc:`zero ` - topology but no interactions * :doc:`hybrid ` - define multiple styles of bond interactions +* :doc:`bpm/rotational ` - breakable bond with forces and torques based on deviation from reference state +* :doc:`bpm/spring ` - breakable bond with forces based on deviation from reference length * :doc:`class2 ` - COMPASS (class 2) bond * :doc:`fene ` - FENE (finite-extensible non-linear elastic) bond * :doc:`fene/expand ` - FENE bonds with variable size particles diff --git a/doc/src/compute.rst b/doc/src/compute.rst index a149a752b0..6da8455165 100644 --- a/doc/src/compute.rst +++ b/doc/src/compute.rst @@ -236,6 +236,7 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`msd ` - mean-squared displacement of group of atoms * :doc:`msd/chunk ` - mean-squared displacement for each chunk * :doc:`msd/nongauss ` - MSD and non-Gaussian parameter of group of atoms +* :doc:`nbond/atom ` - calculates number of bonds per atom * :doc:`omega/chunk ` - angular velocity for each chunk * :doc:`orientorder/atom ` - Steinhardt bond orientational order parameters Ql * :doc:`pair ` - values computed by a pair style diff --git a/doc/src/compute_nbond_atom.rst b/doc/src/compute_nbond_atom.rst new file mode 100644 index 0000000000..e86986287f --- /dev/null +++ b/doc/src/compute_nbond_atom.rst @@ -0,0 +1,52 @@ +.. index:: compute nbond/atom + +compute nbond/atom command +========================== + +Syntax +"""""" + +.. parsed-literal:: + + compute ID group-ID nbond/atom + +* ID, group-ID are documented in :doc:`compute ` command +* nbond/atom = style name of this compute command + +Examples +"""""""" + +.. code-block:: LAMMPS + + compute 1 all nbond/atom + +Description +""""""""""" + +Define a computation that computes the number of bonds each atom is +part of. Bonds which are broken are not counted in the tally. See +the :doc:`Howto broken bonds ` page for more information. +The number of bonds will be zero for atoms not in the specified +compute group. This compute does not depend on Newton bond settings. + +Output info +""""""""""" + +This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +the :doc:`Howto output ` doc page for an overview of +LAMMPS output options. + +Restrictions +"""""""""""" + +This fix can only be used if LAMMPS was built with the BPM package. +See the :doc:`Build package ` doc page for more info. + +Related commands +"""""""""""""""" + +Default +""""""" + +none diff --git a/doc/src/dump_modify.rst b/doc/src/dump_modify.rst index 9e3f7f738d..c65cd68a29 100644 --- a/doc/src/dump_modify.rst +++ b/doc/src/dump_modify.rst @@ -474,8 +474,9 @@ The *fileper* keyword is documented below with the *nfile* keyword. The *header* keyword toggles whether the dump file will include a header. Excluding a header will reduce the size of the dump file for -fixes such as :doc:`fix pair/tracker ` which do not -require the information typically written to the header. +data produced by :doc:`pair tracker ` or +:doc:`bpm bond styles ` which may not require the +information typically written to the header. ---------- diff --git a/doc/src/fix.rst b/doc/src/fix.rst index e492da14f3..3b6ef044c8 100644 --- a/doc/src/fix.rst +++ b/doc/src/fix.rst @@ -284,6 +284,7 @@ accelerated styles exist. * :doc:`nve/manifold/rattle ` - * :doc:`nve/noforce ` - NVE without forces (v only) * :doc:`nve/sphere ` - NVE for spherical particles +* :doc:`nve/bpm/sphere ` - NVE for spherical particles used in the BPM package * :doc:`nve/spin ` - NVE for a spin or spin-lattice system * :doc:`nve/tri ` - NVE for triangles * :doc:`nvk ` - constant kinetic energy time integration @@ -301,7 +302,6 @@ accelerated styles exist. * :doc:`orient/fcc ` - add grain boundary migration force for FCC * :doc:`orient/eco ` - add generalized grain boundary migration force * :doc:`pafi ` - constrained force averages on hyper-planes to compute free energies (PAFI) -* :doc:`pair/tracker ` - track properties of pairwise interactions * :doc:`phonon ` - calculate dynamical matrix from MD simulations * :doc:`pimd ` - Feynman path integral molecular dynamics * :doc:`planeforce ` - constrain atoms to move in a plane diff --git a/doc/src/fix_bond_break.rst b/doc/src/fix_bond_break.rst index 9538fa8ef3..ba12e154c5 100644 --- a/doc/src/fix_bond_break.rst +++ b/doc/src/fix_bond_break.rst @@ -113,6 +113,9 @@ You can dump out snapshots of the current bond topology via the :doc:`dump local may need to thermostat your system to compensate for energy changes resulting from broken bonds (and angles, dihedrals, impropers). +See the :doc:`Howto ` page on broken bonds for more +information on related features in LAMMPS. + ---------- Restart, fix_modify, output, run start/stop, minimize info diff --git a/doc/src/fix_nve_bpm_sphere.rst b/doc/src/fix_nve_bpm_sphere.rst new file mode 100644 index 0000000000..861586ab2a --- /dev/null +++ b/doc/src/fix_nve_bpm_sphere.rst @@ -0,0 +1,87 @@ +.. index:: fix nve/bpm/sphere + +fix nve/bpm/sphere command +========================== + +Syntax +"""""" + +.. parsed-literal:: + + fix ID group-ID nve/bpm/sphere + +* ID, group-ID are documented in :doc:`fix ` command +* nve/bpm/sphere = style name of this fix command +* zero or more keyword/value pairs may be appended +* keyword = *disc* + + .. parsed-literal:: + + *disc* value = none = treat particles as 2d discs, not spheres + +Examples +"""""""" + +.. code-block:: LAMMPS + + fix 1 all nve/bpm/sphere + fix 1 all nve/bpm/sphere disc + +Description +""""""""""" + +Perform constant NVE integration to update position, velocity, angular +velocity, and quaternion orientation for finite-size spherical +particles in the group each timestep. V is volume; E is energy. This +creates a system trajectory consistent with the microcanonical +ensemble. + +This fix differs from the :doc:`fix nve ` command, which +assumes point particles and only updates their position and velocity. +It also differs from the :doc:`fix nve/sphere ` +command which assumes finite-size spheroid particles which do not +store a quaternion. It thus does not update a particle's orientation +or quaternion. + +If the *disc* keyword is used, then each particle is treated as a 2d +disc (circle) instead of as a sphere. This is only possible for 2d +simulations, as defined by the :doc:`dimension ` keyword. +The only difference between discs and spheres in this context is their +moment of inertia, as used in the time integration. + +---------- + +Restart, fix_modify, output, run start/stop, minimize info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +No information about this fix is written to :doc:`binary restart files +`. 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 `. + +Restrictions +"""""""""""" + +This fix requires that atoms store torque, angular velocity (omega), a +radius, and a quaternion as defined by the :doc:`atom_style bpm/sphere +` command. + +All particles in the group must be finite-size spheres with +quaternions. They cannot be point particles. + +Use of the *disc* keyword is only allowed for 2d simulations, as +defined by the :doc:`dimension ` keyword. + +Related commands +"""""""""""""""" + +:doc:`fix nve `, :doc:`fix nve/sphere ` + +Default +""""""" + +none + diff --git a/doc/src/fix_pair_tracker.rst b/doc/src/fix_pair_tracker.rst deleted file mode 100644 index 5c2ecf5774..0000000000 --- a/doc/src/fix_pair_tracker.rst +++ /dev/null @@ -1,124 +0,0 @@ -.. index:: fix pair/tracker - -fix pair/tracker command -======================== - -Syntax -"""""" - -.. parsed-literal:: - - fix ID group-ID pair/tracker N attribute1 attribute2 ... keyword values ... - -* ID, group-ID are documented in :doc:`fix ` command -* pair/tracker = style name of this fix command -* N = prepare data for output every this many timesteps -* one or more attributes may be appended - - .. parsed-literal:: - - possible attributes = id1 id2 time/created time/broken time/total - rmin rave x y z - - .. parsed-literal:: - - id1, id2 = IDs of the 2 atoms in each pair interaction - time/created = the time that the 2 atoms began interacting - time/broken = the time that the 2 atoms stopped interacting - time/total = the total time the 2 atoms interacted - r/min = the minimum radial distance between the 2 atoms during the interaction - r/ave = the average radial distance between the 2 atoms during the interaction - x, y, z = the center of mass position of the 2 atoms when they stopped interacting - -* zero or more keyword/value pairs may be appended -* keyword = *time/min* or *type/include* - - .. parsed-literal:: - - *time/min* value = T - T = minimum interaction time - *type/include* value = arg1 arg2 - arg = separate lists of types (see below) - -Examples -"""""""" - -.. code-block:: LAMMPS - - fix 1 all pair/tracker 1000 id1 id2 time/min 100 - fix 1 all pair/tracker 1000 time/created time/broken type/include 1 * type/include 2 3,4 - -Description -""""""""""" - -Tracks properties of pairwise interactions between two atoms and records data -whenever the atoms move beyond the interaction cutoff. -Must be used in conjunction with :doc:`pair tracker `. -Data is accumulated over a span of *N* timesteps before being deleted. -The number of datums generated, aggregated across all processors, equals -the number of broken interactions. Interactions are only included if both -atoms are included in the specified fix group. Additional filters can be -applied using the *time/min* or *type/include* keywords described below. - -.. note:: - - For extremely long-lived interactions, the calculation of *r/ave* may not be - correct due to double overflow. - -The *time/min* keyword sets a minimum amount of time that an interaction must -persist to be included. This setting can be used to censor short-lived interactions. -The *type/include* keyword filters interactions based on the types of the two atoms. -Data is only saved for interactions between atoms with types in the two lists. -Each list consists of a series of type -ranges separated by commas. The range can be specified as a -single numeric value, or a wildcard asterisk can be used to specify a range -of values. This takes the form "\*" or "\*n" or "n\*" or "m\*n". For -example, if M = the number of atom types, then an asterisk with no numeric -values means all types from 1 to M. A leading asterisk means all types -from 1 to n (inclusive). A trailing asterisk means all types from n to M -(inclusive). A middle asterisk means all types from m to n (inclusive). -Multiple *type/include* keywords may be added. - ----------- - -Restart, fix_modify, run start/stop, minimize info -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -No information about this fix is written to :doc:`binary restart files `. -None of the :doc:`fix_modify ` options are -relevant to this fix. -No parameter of this fix can be used with the *start/stop* keywords of -the :doc:`run ` command. - -Output info -""""""""""" - -This compute calculates a local vector or local array depending on the -number of input values. The length of the vector or number of rows in -the array is the number of recorded, lost interactions. If a single input is -specified, a local vector is produced. If two or more inputs are -specified, a local array is produced where the number of columns = the -number of inputs. The vector or array can be accessed by any command -that uses local values from a compute as input. See the :doc:`Howto output ` page for an overview of LAMMPS output -options. - -The vector or array values will be doubles that correspond to the -specified attribute. - -Restrictions -"""""""""""" - -Must be used in conjunction with :doc:`pair style tracker `. - -This fix is part of the MISC package. It is only enabled if LAMMPS -was built with that package. See the :doc:`Build package ` page for more info. - -Related commands -"""""""""""""""" - -:doc:`pair tracker ` - -Default -""""""" - -none diff --git a/doc/src/pair_bpm_spring.rst b/doc/src/pair_bpm_spring.rst new file mode 100644 index 0000000000..8235b1c624 --- /dev/null +++ b/doc/src/pair_bpm_spring.rst @@ -0,0 +1,114 @@ +.. index:: pair_style bpm/spring + +pair_style bpm/spring command +============================= + +Syntax +"""""" + +.. code-block:: LAMMPS + + pair_style bpm/spring + +Examples +"""""""" + +.. code-block:: LAMMPS + + pair_style bpm/spring + pair_coeff * * 1.0 1.0 1.0 + pair_coeff 1 1 1.0 1.0 1.0 + +Description +""""""""""" + +Style *bpm/spring* computes pairwise forces with the formula + +.. math:: + + F = k (r - r_c) + +where :math:`k` is a stiffness and :math:`r_c` is the cutoff length. +An additional damping force is also applied to interacting +particles. The force is proportional to the difference in the +normal velocity of particles + +.. math:: + + F_D = - \gamma w (\hat{r} \bullet \vec{v}) + +where :math:`\gamma` is the damping strength, :math:`\hat{r}` is the +radial normal vector, :math:`\vec{v}` is the velocity difference +between the two particles, and :math:`w` is a smoothing factor. +This smoothing factor is constructed such that damping forces go to zero +as particles come out of contact to avoid discontinuities. It is +given by + +.. math:: + + w = 1.0 - \left( \frac{r}{r_c} \right)^8 . + +This pair style is designed for use in a spring-based bonded particle +model. It mirrors the construction of the :doc:`bpm/spring +` bond style. + +This pair interaction is always applied to pairs of non-bonded particles +that are within the interaction distance. For pairs of bonded particles +that are within the interaction distance, there is the option to either +include this pair interaction and overlay the pair force over the bond +force or to exclude this pair interaction such that the two particles +only interact via the bond force. See discussion of the *overlay/pair* +option for BPM bond styles and the :doc:`special_bonds ` +command in the `:doc: how to ` page on BPMs for more details. + +The following coefficients must be defined for each pair of atom types +via the :doc:`pair_coeff ` command as in the examples +above, or in the data file or restart files read by the +:doc:`read_data ` or :doc:`read_restart ` +commands, or by mixing as described below: + +* :math:`k` (force/distance units) +* :math:`r_c` (distance units) +* :math:`\gamma` (force/velocity units) + + +---------- + +Mixing, shift, table, tail correction, restart, rRESPA info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +For atom type pairs I,J and I != J, the A coefficient and cutoff +distance for this pair style can be mixed. A is always mixed via a +*geometric* rule. The cutoff is mixed according to the pair_modify +mix value. The default mix value is *geometric*\ . See the +"pair_modify" command for details. + +This pair style does not support the :doc:`pair_modify ` +shift option, since the pair interaction goes to 0.0 at the cutoff. + +The :doc:`pair_modify ` table and tail options are not +relevant for this pair style. + +This pair style writes its information to :doc:`binary restart files +`, so pair_style and pair_coeff commands do not need to be +specified in an input script that reads a restart file. + +This pair style can only be used via the *pair* keyword of the +:doc:`run_style respa ` command. It does not support the +*inner*, *middle*, *outer* keywords. + +---------- + +Restrictions +"""""""""""" + none + +Related commands +"""""""""""""""" + +:doc:`pair_coeff `, :doc:`bond bpm/spring ` + +Default +""""""" + +none diff --git a/doc/src/pair_style.rst b/doc/src/pair_style.rst index f90a718d95..b42e3c9a50 100644 --- a/doc/src/pair_style.rst +++ b/doc/src/pair_style.rst @@ -131,6 +131,7 @@ accelerated styles exist. * :doc:`born/coul/msm ` - Born with long-range MSM Coulomb * :doc:`born/coul/wolf ` - Born with Wolf potential for Coulomb * :doc:`born/coul/wolf/cs ` - Born with Wolf potential for Coulomb and core/shell model +* :doc:`bpm/spring ` - repulsive harmonic force with damping * :doc:`brownian ` - Brownian potential for Fast Lubrication Dynamics * :doc:`brownian/poly ` - Brownian potential for Fast Lubrication Dynamics with polydispersity * :doc:`buck ` - Buckingham potential diff --git a/doc/src/pair_tracker.rst b/doc/src/pair_tracker.rst index d2cee1d879..04967e952d 100644 --- a/doc/src/pair_tracker.rst +++ b/doc/src/pair_tracker.rst @@ -8,89 +8,182 @@ Syntax .. code-block:: LAMMPS - pair_style tracker keyword + pair_style tracker fix_ID N keyword values attribute1 attribute2 ... -* zero or more keyword/arg pairs may be appended -* keyword = *finite* +* fix_ID = ID of associated internal fix to store data +* N = prepare data for output every this many timesteps +* zero or more keywords may be appended +* keyword = *finite* or *time/min* or *type/include* .. parsed-literal:: *finite* value = none pair style uses atomic diameters to identify contacts + *time/min* value = T + T = minimum number of timesteps of interaction + *type/include* value = list1 list2 + list1,list2 = separate lists of types (see below) + +* one or more attributes may be appended + + .. parsed-literal:: + + possible attributes = id1 id2 time/created time/broken time/total + r/min r/ave x y z + + .. parsed-literal:: + + id1, id2 = IDs of the 2 atoms in each pair interaction + time/created = the timestep that the 2 atoms began interacting + time/broken = the timestep that the 2 atoms stopped interacting + time/total = the total number of timesteps the 2 atoms interacted + r/min = the minimum radial distance between the 2 atoms during the interaction (distance units) + r/ave = the average radial distance between the 2 atoms during the interaction (distance units) + x, y, z = the center of mass position of the 2 atoms when they stopped interacting (distance units) Examples """""""" .. code-block:: LAMMPS - pair_style hybrid/overlay tracker ... + pair_style hybrid/overlay tracker myfix 1000 id1 id2 type/include 1 * type/include 2 3,4 lj/cut 2.5 pair_coeff 1 1 tracker 2.0 - pair_style hybrid/overlay tracker finite ... + pair_style hybrid/overlay tracker myfix 1000 finite x y z time/min 100 granular pair_coeff * * tracker - fix 1 all pair/tracker 1000 time/created time/broken - dump 1 all local 1000 dump.local f_1[1] f_1[2] + dump 1 all local 1000 dump.local f_myfix[1] f_myfix[2] f_myfix[3] dump_modify 1 write_header no Description """"""""""" -Style *tracker* monitors information about pairwise interactions. -It does not calculate any forces on atoms. -:doc:`Pair hybrid/overlay ` can be used to combine this pair -style with another pair style. Style *tracker* must be used in conjunction -with about :doc:`fix pair_tracker ` which contains -information on what data can be output. +Style *tracker* monitors information about pairwise interactions. It +does not calculate any forces on atoms. :doc:`Pair hybrid/overlay +` can be used to combine this pair style with any other +pair style, as shown in the examples above. -If the *finite* keyword is not defined, the following coefficients must be -defined for each pair of atom types via the :doc:`pair_coeff ` -command as in the examples above, or in the data file or restart files -read by the :doc:`read_data ` or :doc:`read_restart ` -commands, or by mixing as described below: +At each timestep, if two neighboring atoms move beyond the interaction +cutoff, pairwise data is processed and transferred to an internal fix +labeled *fix_ID*. This allows the local data to be accessed by other +LAMMPS commands. Additional +filters can be applied using the *time/min* or *type/include* keywords +described below. Note that this is the interaction cutoff defined by +this pair style, not the short-range cutoff defined by the pair style +that is calculating forces on atoms. + +Following any optional keyword/value arguments, a list of one or more +attributes is specified. These include the IDs of the two atoms in +the pair. The other attributes for the pair of atoms are the +duration of time they were "interacting" or at the point in time they +started or stopped interacting. In this context, "interacting" means +the time window during which the two atoms were closer than the +interaction cutoff distance. The attributes for time/* refer to +timesteps. + +Data is continuously accumulated by the internal fix over intervals of *N* +timesteps. At the end of each interval, all of the saved accumulated +data is deleted to make room for new data. Individual datum may +therefore persist anywhere between *1* to *N* timesteps depending on +when they are saved. This data can be accessed using the *fix_ID* and a +:doc:`dump local ` command. To ensure all data is output, +the dump frequency should correspond to the same interval of *N* +timesteps. A dump frequency of an integer multiple of *N* can be used +to regularly output a sample of the accumulated data. + +---------- + +The following optional keywords may be used. + +If the *finite* keyword is not used, the following coefficients must +be defined for each pair of atom types via the :doc:`pair_coeff +` command as in the examples above, or in the data file or +restart files read by the :doc:`read_data ` or +:doc:`read_restart ` commands, or by mixing as described +below: * cutoff (distance units) -If the *finite* keyword is defined, no coefficients may be defined. -Interaction cutoffs are alternatively calculated based on the -diameter of finite particles. +If the *finite* keyword is used, there are no additional coefficients +to set for each pair of atom types via the +:doc:`pair_coeff ` command. Interaction cutoffs are +instead calculated based on the diameter of finite particles. However +you must still use the :doc:`pair_coeff ` for all atom +types. For example the command +.. code-block:: LAMMPS + + pair_coeff * * + +should be used. + +The *time/min* keyword sets a minimum amount of time that an +interaction must persist to be included. This setting can be used to +censor short-lived interactions. + +The *type/include* keyword filters interactions based on the types of +the two atoms. Data is only saved for interactions between atoms +whose two atom types appear in *list1* and *list2*. Atom type 1 must +be in list1 and atom type 2 in list2. Or vice versa. + +Each type list consists of a series of type ranges separated by +commas. Each range can be specified as a single numeric value, or a +wildcard asterisk can be used to specify a range of values. This +takes the form "\*" or "\*n" or "n\*" or "m\*n". For example, if M = +the number of atom types, then an asterisk with no numeric values +means all types from 1 to M. A leading asterisk means all types from +1 to n (inclusive). A trailing asterisk means all types from n to M +(inclusive). A middle asterisk means all types from m to n +(inclusive). Note that the *type/include* keyword can be specified +multiple times. Mixing, shift, table, tail correction, restart, rRESPA info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" For atom type pairs I,J and I != J, the cutoff coefficient and cutoff -distance for this pair style can be mixed. The cutoff is always mixed via a -*geometric* rule. The cutoff is mixed according to the pair_modify -mix value. The default mix value is *geometric*\ . See the -"pair_modify" command for details. +distance for this pair style can be mixed. The cutoff is always mixed +via a *geometric* rule. The cutoff is mixed according to the +pair_modify mix value. The default mix value is *geometric*\ . See +the "pair_modify" command for details. -This pair style writes its information to :doc:`binary restart files `, so -pair_style and pair_coeff commands do not need -to be specified in an input script that reads a restart file. +This pair style writes its information to :doc:`binary restart files +`, so pair_style and pair_coeff commands do not need to be +specified in an input script that reads a restart file. The :doc:`pair_modify ` shift, table, and tail options are not relevant for this pair style. +The accumulated data is not written to restart files and should be +output before a restart file is written to avoid missing data. + +The internal fix calculates a local vector or local array depending on the +number of input values. The length of the vector or number of rows in +the array is the number of recorded, lost interactions. If a single +input is specified, a local vector is produced. If two or more inputs +are specified, a local array is produced where the number of columns = +the number of inputs. The vector or array can be accessed by any +command that uses local values from a compute as input. See the +:doc:`Howto output ` page for an overview of LAMMPS +output options. + +The vector or array will be floating point values that correspond to +the specified attribute. + ---------- Restrictions """""""""""" -A corresponding :doc:`fix pair_tracker ` must be defined -to use this pair style. - -This pair style is currently incompatible with granular pair styles that extend -beyond the contact (e.g. JKR and DMT). - This fix is part of the MISC package. It is only enabled if LAMMPS -was built with that package. See the :doc:`Build package ` page for more info. +was built with that package. See the :doc:`Build package +` page for more info. + +This pair style is currently incompatible with granular pair styles +that extend beyond the contact (e.g. JKR and DMT). Related commands """""""""""""""" -:doc:`fix pair_tracker ` - Default """"""" diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 24f882b658..68e1efc496 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -650,6 +650,8 @@ of analysis. - atom-ID atom-type rho esph cv x y z * - sphere - atom-ID atom-type diameter density x y z + * - bpm/sphere + - atom-ID molecule-ID atom-type diameter density x y z * - spin - atom-ID atom-type x y z spx spy spz sp * - tdpd diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 19fa8661d7..ca62bd9c41 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -328,6 +328,8 @@ boxzlo bp bpclermont bpls +bpm +BPM br Branduardi Branicio @@ -1149,8 +1151,10 @@ gdot GeC Geier gencode +Geocomputing georg Georg +Geotechnica germain Germann Germano @@ -1320,6 +1324,7 @@ Holm holonomic Homebrew hooke +hookean Hookean hostname hotpink @@ -2074,6 +2079,7 @@ monopole monovalent Montalenti Montero +Mora Morefoo Morfill Mori @@ -2203,6 +2209,7 @@ Nbin Nbins nbody Nbody +nbond nbonds nbondtype Nbondtype @@ -3174,6 +3181,7 @@ Steinhauser Stepaniants stepwise Stesmans +stiffnesses Stillinger stk stochastically diff --git a/examples/bpm/impact/brokenDump b/examples/bpm/impact/brokenDump new file mode 100644 index 0000000000..ef78518c91 --- /dev/null +++ b/examples/bpm/impact/brokenDump @@ -0,0 +1,3173 @@ +276 5469 5471 +288 1815 1931 +290 1810 1815 +293 1815 1816 +295 5350 5351 +300 1813 1815 +288 1815 1931 +276 5469 5471 +278 5475 5477 +283 5349 5350 +287 5470 5477 +290 5472 5477 +292 5350 5352 +294 5477 5478 +295 5350 5351 +305 1702 1704 +308 1705 5351 +313 1699 1704 +324 1820 5471 +327 1813 1814 +332 1937 1938 +339 5228 5349 +350 1811 1818 +353 1817 5348 +361 1588 1700 +362 1700 5348 +364 1817 5469 +368 1700 5228 +368 1704 1819 +372 1817 5467 +373 5351 5470 +374 1701 1818 +374 1817 5468 +377 1584 1694 +380 5231 5349 +383 1588 5349 +383 5231 5350 +386 1458 1574 +388 1811 1812 +399 1464 1580 +399 1817 1822 +306 1938 5471 +308 1928 1933 +309 1933 1934 +310 1933 2048 +311 5712 5830 +313 1931 1933 +332 1937 1938 +333 1938 1939 +333 2056 2171 +338 1938 1940 +340 2172 2174 +352 2172 5712 +353 2056 2057 +355 2056 2172 +359 5712 5831 +362 2057 2169 +367 1932 1938 +368 2052 5709 +372 2052 2053 +375 5712 5713 +375 2172 2173 +377 2174 2286 +385 5711 5712 +385 2169 5709 +386 1935 1936 +387 2054 2055 +387 2169 5829 +398 2277 2278 +399 2057 2171 +303 5232 5350 +303 5477 5595 +304 5352 5470 +306 1938 5471 +306 5483 5484 +312 5350 5355 +312 5481 5483 +312 5471 5591 +316 5471 5590 +318 5357 5470 +324 1820 5471 +330 5470 5475 +331 5354 5473 +332 5476 5481 +332 5471 5589 +332 5483 5601 +339 5228 5349 +341 5473 5474 +343 5358 5476 +346 5349 5352 +346 5355 5357 +347 5237 5350 +350 5357 5358 +351 5354 5467 +353 1817 5348 +358 5348 5467 +362 1700 5348 +362 5601 5602 +366 5470 5471 +367 5472 5475 +371 5476 5477 +372 1817 5467 +372 5480 5593 +373 5351 5470 +373 5601 5603 +374 1817 5468 +380 5231 5349 +383 1588 5349 +383 5231 5350 +387 5478 5481 +388 5234 5353 +389 5596 5601 +397 5484 5486 +400 5593 5601 +303 5477 5595 +311 5712 5830 +312 5471 5591 +316 5471 5590 +319 5717 5719 +325 5831 5833 +332 5471 5589 +349 5603 5604 +355 5717 5722 +359 5712 5831 +368 2052 5709 +370 5720 5722 +372 5480 5593 +372 5600 5603 +373 5600 5604 +373 5601 5603 +374 5587 5594 +375 5712 5713 +379 5588 5708 +381 5600 5714 +383 5720 5721 +385 5711 5712 +385 2169 5709 +387 2169 5829 +388 5722 5723 +391 5828 5829 +394 5833 5948 +398 5710 5712 +400 5593 5601 +401 1820 1822 +403 1817 1819 +404 1586 1588 +405 1569 1685 +410 1821 1938 +411 1822 5469 +412 1568 1575 +413 1822 1937 +421 1699 1819 +421 5232 5349 +422 1704 1814 +423 1582 1584 +431 1565 1572 +431 1578 1688 +431 1812 1929 +433 5469 5472 +435 1467 1585 +442 1809 1810 +448 1685 1692 +448 1698 1808 +451 1703 5349 +454 1563 1679 +454 1935 1937 +455 1703 5351 +457 1582 1694 +458 1813 1816 +459 1695 1805 +460 1926 1927 +461 1699 1814 +468 1810 1816 +471 1814 1819 +476 1701 1819 +478 1566 1682 +480 1818 1929 +481 1920 1925 +482 1580 1587 +485 5468 5469 +486 1689 1805 +490 1457 1464 +490 1806 1810 +493 1587 1588 +493 1814 1816 +497 1682 1689 +498 1699 1816 +500 1688 1805 +500 1689 1695 +402 2049 2051 +402 2054 2057 +410 1821 1938 +416 2052 5588 +417 2055 2056 +420 1939 2049 +423 1923 1930 +423 2161 2271 +426 2050 2160 +431 1812 1929 +431 2044 2154 +437 2284 2393 +441 1940 2054 +441 2174 5832 +442 2166 2173 +448 1927 1928 +449 2286 5949 +451 2163 2170 +452 2037 2038 +457 2396 2397 +460 1926 1927 +461 1936 2046 +461 2406 2513 +464 1930 1934 +465 2055 5712 +471 1931 1934 +473 1940 5710 +474 2154 2159 +475 2274 2275 +477 1933 2049 +478 1923 2040 +479 2037 2039 +479 2399 2400 +480 1818 1929 +481 1920 1925 +482 1930 2048 +482 2039 2042 +482 2164 2280 +482 2174 5830 +485 1930 1931 +486 1930 1936 +486 2046 2053 +487 1928 1930 +488 2167 2283 +495 2156 2159 +498 1928 1934 +403 5368 5369 +407 5484 5601 +409 5601 5604 +412 5232 5352 +414 5476 5596 +416 5123 5236 +419 5484 5602 +421 5232 5349 +421 5472 5595 +422 5129 5242 +425 5362 5363 +426 5347 5354 +426 5352 5355 +430 5246 5359 +433 5469 5472 +434 5481 5484 +437 5135 5248 +438 5365 5366 +439 5358 5478 +439 5483 5596 +441 5362 5369 +450 5363 5482 +450 5484 5487 +456 5484 5607 +458 5480 5599 +459 5242 5243 +461 5235 5236 +463 5479 5486 +464 5482 5483 +467 5234 5347 +467 5361 5362 +469 5232 5355 +470 5474 5475 +474 5116 5117 +475 5356 5363 +480 5234 5240 +481 5485 5487 +484 5480 5484 +485 5468 5469 +488 5476 5478 +493 5233 5238 +494 5356 5361 +495 5118 5238 +496 5363 5483 +497 5018 5128 +498 5233 5240 +500 5370 5488 +406 5591 5711 +406 5722 5724 +406 5969 5976 +407 5721 5725 +408 5600 5720 +409 5601 5604 +413 5597 5717 +419 5970 6089 +421 5472 5595 +421 6074 6081 +425 5719 5722 +425 5964 6083 +426 5594 5598 +426 5831 5838 +429 5840 5841 +436 5833 5838 +437 5724 5843 +439 5593 5595 +441 5951 5958 +444 5830 5831 +446 5713 5831 +449 5831 5951 +449 2286 5949 +453 5722 5725 +453 5709 5829 +454 5599 5600 +454 5591 5710 +455 5834 5842 +458 5480 5599 +459 5724 5837 +462 5589 5592 +462 6084 6202 +464 5598 5603 +465 2055 5712 +472 5954 5955 +473 1940 5710 +476 5594 5708 +477 5856 5975 +482 2174 5830 +482 5844 5963 +484 5714 5721 +488 5592 5708 +490 6083 6090 +501 1802 1807 +503 1805 1807 +504 1689 1806 +507 1569 1679 +507 1693 1805 +510 1688 1693 +511 1575 1690 +518 1799 1807 +520 1227 1340 +521 1803 1804 +522 1347 1463 +525 1575 1691 +528 1804 1925 +529 1581 1697 +531 1446 1562 +531 1573 1576 +535 1574 1575 +536 1802 1809 +548 1692 1693 +552 1693 1807 +553 1575 1692 +553 1819 1821 +555 1699 1813 +560 1922 1925 +569 5109 5111 +569 1705 1819 +576 1570 1690 +580 1808 1809 +584 1581 1696 +586 1471 5111 +589 1459 1576 +599 1702 1705 +502 2160 2167 +503 1922 1924 +503 2036 2037 +504 1922 2037 +504 2169 5830 +505 2057 2174 +505 2168 2283 +507 1924 2040 +507 2281 2390 +514 2162 2167 +514 2167 2168 +515 1929 1934 +515 2044 2159 +524 1929 1936 +530 2165 2167 +536 2167 2282 +549 2158 2274 +549 2519 2520 +560 1922 1925 +560 2035 2039 +560 2158 2276 +561 2289 5832 +562 1932 1939 +562 2263 2372 +567 2041 2157 +567 2381 2382 +581 1920 2037 +583 1920 1927 +583 5950 5953 +586 2042 2045 +593 5951 5952 +596 5833 5950 +600 2158 2159 +502 5254 5255 +507 5232 5237 +508 5473 5478 +511 5239 5240 +512 5111 5112 +513 5233 5353 +519 4901 5011 +519 5012 5122 +522 5235 5238 +522 5240 5241 +523 5260 5261 +523 5364 5369 +525 5490 5608 +528 5237 5238 +538 5479 5480 +542 5488 5493 +553 5611 5613 +555 5246 5365 +555 5489 5608 +557 4895 5005 +561 5481 5601 +564 5140 5141 +569 5109 5111 +571 5114 5235 +572 5488 5495 +573 5230 5237 +582 5490 5492 +584 5024 5134 +586 1471 5111 +587 5244 5367 +587 5352 5354 +587 5490 5495 +591 5486 5599 +594 5347 5348 +502 5959 6077 +504 2169 5830 +507 5606 5726 +519 5835 5948 +521 5967 6086 +523 5733 5852 +524 5719 5842 +529 5609 5728 +529 5833 5836 +541 5956 5958 +541 5968 5971 +547 5717 5723 +549 5961 6074 +551 6071 6190 +553 5611 5613 +554 5588 5710 +558 5594 5714 +559 5592 5713 +561 5481 5601 +564 5970 6083 +568 5853 5972 +569 5592 5716 +574 5606 5727 +574 5835 5955 +579 5592 5710 +583 5950 5953 +590 5855 5862 +591 5486 5599 +591 5718 5831 +593 5951 5952 +596 5605 5726 +596 5833 5950 +602 1820 1821 +603 1461 1571 +606 1683 1793 +607 1808 1815 +609 1322 1329 +610 1583 1585 +615 1576 1579 +616 1699 1811 +621 1557 1673 +622 1583 5229 +630 1468 1470 +634 1470 1471 +634 5111 5229 +635 1469 1471 +635 1469 1586 +639 1572 1576 +639 1698 1814 +639 1809 1926 +644 5229 5230 +645 1588 1702 +649 1690 1693 +652 1696 1813 +656 1574 1579 +657 1693 1813 +658 1819 1820 +659 1467 1577 +661 1455 1565 +669 1695 1811 +677 1100 1107 +678 1221 1334 +679 1433 1440 +679 1688 1696 +680 1687 1807 +682 1812 1816 +683 1689 1799 +689 1585 5229 +690 1701 1811 +692 1007 1014 +693 1466 1471 +696 1328 1335 +699 1582 1585 +601 1928 2048 +606 2619 2620 +610 2162 2165 +613 2387 2388 +615 2040 2047 +615 2266 2375 +619 2039 2159 +622 2053 2057 +624 2151 2156 +626 2053 2171 +627 2169 2174 +627 2287 2402 +628 2172 5830 +629 2291 2402 +634 2619 2621 +637 2034 2042 +639 1809 1926 +641 2613 2614 +646 1924 2034 +649 2145 2152 +649 2136 2137 +652 2626 2730 +653 2148 2155 +654 1932 1933 +655 1934 2048 +656 2501 2502 +660 2274 2276 +662 2253 2254 +672 1934 1937 +673 2369 2370 +675 2146 2262 +678 1917 1924 +685 2052 2054 +689 1929 1930 +697 1917 2034 +700 2057 5709 +604 5611 5618 +605 4907 5017 +611 5244 5359 +628 5245 5252 +634 5111 5229 +644 5229 5230 +647 5023 5024 +648 5012 5128 +651 4897 4898 +658 5111 5230 +659 5267 5380 +660 5608 5613 +661 5602 5603 +667 5236 5238 +675 5159 5272 +675 5247 5250 +681 5604 5607 +684 5386 5387 +684 5475 5478 +603 5953 5956 +604 5611 5618 +605 6076 6078 +617 6440 6447 +622 5716 5717 +625 5966 5973 +627 5956 6076 +628 2172 5830 +631 6071 6078 +634 5610 5612 +640 5592 5598 +643 5595 5598 +645 5599 5604 +646 5987 5994 +647 5610 5615 +648 5959 6076 +658 5605 5606 +658 5729 5734 +660 5608 5613 +661 5602 5603 +662 5593 5598 +664 6331 6338 +676 5615 5734 +681 5604 5607 +689 5726 5727 +690 5603 5723 +690 5604 5723 +690 5833 5953 +691 5867 5874 +694 5598 5717 +697 5714 5716 +700 2057 5709 +701 1448 1449 +710 1810 1813 +711 1467 1583 +714 1574 1581 +727 1459 1573 +749 1453 1459 +753 1571 1573 +755 1442 1449 +755 1799 1806 +759 1661 1668 +759 1685 1690 +762 1453 1456 +764 1804 1920 +770 1571 1572 +772 1442 1448 +774 1581 1691 +778 1319 1326 +778 1699 1702 +778 1698 1813 +784 1587 1697 +788 1570 1576 +789 1684 1690 +791 1796 1803 +792 1106 1113 +794 1583 1586 +797 1335 1445 +797 5107 5109 +799 1451 1452 +800 1806 1809 +702 5829 5948 +704 1919 1920 +708 2376 2483 +711 2291 5949 +716 2037 2044 +721 2160 2162 +724 2489 2490 +728 1918 1919 +728 1927 2042 +730 2496 2601 +731 5832 5950 +732 1928 1931 +734 2279 2281 +738 2020 2130 +750 1918 2034 +752 2055 5710 +757 2608 2712 +764 1804 1920 +772 2276 2277 +773 2153 2156 +775 2275 2390 +783 2401 2403 +787 2286 5829 +791 1929 1937 +792 2035 2151 +798 1932 1934 +708 4793 4900 +709 5036 5146 +711 5243 5356 +724 5152 5153 +726 5239 5246 +733 5483 5602 +746 5245 5253 +754 5236 5243 +756 5245 5250 +758 5230 5232 +762 4919 5029 +764 5607 5610 +770 5347 5355 +771 5364 5487 +787 5234 5235 +789 5125 5132 +791 5364 5484 +797 5107 5109 +702 5829 5948 +703 5732 5734 +710 6227 6343 +711 2291 5949 +711 6221 6337 +719 5597 5711 +719 5846 5847 +725 5753 5760 +730 5618 5732 +731 5832 5950 +734 5853 5966 +734 6080 6081 +745 5958 6071 +751 6101 6108 +752 2055 5710 +754 5598 5601 +755 5721 5834 +755 6107 6114 +759 5965 6088 +764 5607 5610 +770 5725 5728 +771 5954 6074 +772 5963 5965 +774 5965 6082 +775 5845 5848 +793 6199 6200 +793 6446 6453 +795 5727 5840 +795 5961 6082 +799 5734 5737 +804 1454 1455 +805 1098 1211 +807 1687 1689 +809 1331 1332 +810 984 1094 +817 1332 1450 +820 1326 1442 +826 1442 1444 +827 1221 1333 +834 1911 1918 +846 1095 1208 +846 1821 1822 +851 1691 1692 +855 1800 1804 +858 1574 1580 +865 1338 1448 +867 995 1002 +871 1703 1704 +872 1196 1203 +872 1687 1799 +876 1819 1822 +880 1197 1310 +882 1332 1333 +883 881 989 +883 1687 1801 +886 1082 1089 +887 1587 1704 +887 1689 1807 +888 1704 5351 +890 1818 1937 +897 1690 1691 +804 1919 1922 +809 2149 2265 +824 1921 2037 +825 2052 5710 +834 1911 1918 +834 2041 2158 +835 2041 2045 +849 1921 2031 +856 2037 2042 +872 1917 1919 +888 5950 5952 +890 1818 1937 +803 5467 5468 +807 5011 5018 +808 5130 5250 +808 5254 5261 +813 5130 5253 +819 5131 5132 +819 5485 5492 +819 5488 5490 +834 4882 4883 +842 5364 5370 +845 5352 5467 +847 5227 5234 +848 5370 5490 +853 5125 5131 +855 5485 5493 +862 5020 5021 +863 5228 5348 +871 5599 5601 +874 5108 5114 +876 5366 5370 +878 5008 5015 +878 5369 5488 +879 5015 5133 +885 5021 5131 +888 1704 5351 +890 5125 5133 +890 5366 5485 +812 6081 6085 +814 5850 5968 +818 6452 6459 +819 5725 5730 +820 5723 5725 +825 2052 5710 +826 5604 5728 +832 5725 5842 +837 6102 6220 +846 5959 6082 +846 5973 6086 +861 6084 6201 +870 5598 5716 +871 5599 5601 +871 5725 5845 +871 6085 6201 +887 6233 6349 +892 6077 6196 +899 6337 6344 +903 1576 1578 +904 1336 1339 +909 1704 1705 +909 1806 1917 +913 1218 1325 +913 1700 1705 +923 1470 1586 +924 1304 1311 +929 880 887 +929 978 1088 +931 875 983 +934 1325 1330 +936 1459 1574 +940 1571 1576 +948 1695 1813 +950 1325 1332 +955 1821 1937 +962 1212 1325 +968 1421 1428 +970 1336 1450 +972 1816 1821 +974 1817 1818 +978 1076 1083 +980 1806 1807 +986 1577 1579 +987 1325 1333 +994 1457 1458 +995 1216 1328 +999 1214 1215 +1000 1810 1925 +904 2162 2277 +907 1923 1924 +907 2172 5832 +909 1806 1917 +909 2396 2403 +916 2291 6070 +917 2391 2504 +918 5829 5830 +919 2157 2158 +921 2405 5952 +923 1915 1916 +923 2259 2266 +940 2043 2050 +948 1913 1916 +951 2040 2048 +952 2279 2398 +955 1821 1937 +955 2405 2519 +964 2276 2282 +964 2498 2505 +967 2256 2263 +973 2043 2160 +979 1932 1937 +984 2390 2392 +998 2392 2395 +1000 1810 1925 +902 5132 5251 +904 5131 5251 +911 4786 4787 +922 5242 5249 +934 5360 5479 +939 5136 5138 +946 5488 5489 +969 5249 5362 +976 5364 5367 +979 5257 5259 +979 5257 5264 +981 5249 5368 +983 5243 5362 +988 5393 5506 +994 5248 5255 +906 5966 5974 +907 2172 5832 +916 2291 6070 +918 5829 5830 +926 6092 6093 +936 5600 5722 +936 5963 5968 +937 5963 5964 +940 5853 5974 +941 5851 5856 +946 5966 5971 +948 5858 5859 +951 5840 5960 +963 5847 5960 +966 5605 5612 +973 5838 5951 +979 5852 5857 +987 5851 5974 +988 5730 5843 +993 5841 5845 +994 6355 6362 +996 5851 5854 +997 5965 5968 +1007 1683 1801 +1015 1575 1581 +1016 1693 1696 +1017 1465 1582 +1018 1676 1677 +1019 1332 1336 +1024 1464 1574 +1026 1532 1539 +1027 1212 1319 +1036 1442 1559 +1042 1087 1090 +1043 1790 1797 +1044 1678 1681 +1044 1804 1919 +1059 1330 1444 +1059 1458 1568 +1066 1690 1692 +1071 1792 1905 +1073 1692 1807 +1074 1212 1216 +1077 1690 1807 +1080 1071 1184 +1083 1326 1436 +1090 1705 5469 +1098 1681 1684 +1003 2505 2610 +1004 2168 2288 +1013 2257 2372 +1029 2372 2373 +1037 2154 2161 +1037 2162 2168 +1040 2279 2282 +1044 1804 1919 +1050 1933 1939 +1055 2276 2279 +1064 2389 2506 +1071 1792 1905 +1073 2162 2282 +1078 2278 2392 +1084 2156 2161 +1085 6072 6190 +1089 2719 2820 +1014 5512 5513 +1019 5370 5487 +1026 5010 5013 +1032 5228 5347 +1032 5244 5362 +1033 5130 5135 +1059 5009 5013 +1064 5240 5244 +1070 5488 5608 +1076 5480 5481 +1078 5015 5016 +1085 5029 5030 +1088 5252 5253 +1089 5130 5133 +1090 5127 5128 +1090 1705 5469 +1091 5118 5241 +1094 5487 5490 +1096 5235 5237 +1002 6081 6199 +1004 5962 5964 +1008 5955 5956 +1010 5841 5847 +1011 5968 5969 +1014 5961 6080 +1015 5954 5961 +1016 6206 6316 +1018 5948 5956 +1020 6671 6678 +1022 5844 5845 +1023 5714 5715 +1023 5841 5842 +1032 5843 5844 +1032 5841 5844 +1033 5967 5968 +1038 5963 5969 +1039 5972 5973 +1041 6238 6245 +1044 5844 5962 +1048 5966 5968 +1052 5839 5841 +1053 6428 6435 +1054 5953 5958 +1056 5961 5967 +1060 6076 6079 +1071 6083 6084 +1071 6322 6323 +1072 5839 5954 +1082 6433 6435 +1085 6072 6190 +1088 5754 5873 +1088 5834 5841 +1097 5728 5729 +1098 5843 5849 +1102 1336 1456 +1113 1688 1695 +1117 1801 1802 +1118 731 738 +1118 1696 1698 +1121 1335 1450 +1132 1327 1330 +1136 1453 1455 +1139 1330 1442 +1139 1686 1801 +1142 646 653 +1149 1802 1803 +1155 1327 1444 +1157 953 960 +1158 1216 1327 +1169 1341 1451 +1173 643 650 +1176 1806 1923 +1178 1696 1699 +1181 552 652 +1184 1216 1330 +1185 1330 1335 +1186 1686 1796 +1198 640 647 +1101 2839 2937 +1102 2044 2160 +1107 2274 2279 +1112 6069 6073 +1114 2152 2268 +1128 1912 2028 +1131 2165 2168 +1144 2043 2048 +1148 2402 6068 +1152 2269 2384 +1156 2051 2171 +1159 2150 2270 +1174 2269 2378 +1176 1806 1923 +1176 2269 2386 +1181 2385 2492 +1193 2404 2407 +1194 2516 2521 +1198 1930 2046 +1199 2384 2385 +1103 5611 5616 +1105 5015 5019 +1111 5014 5021 +1113 5493 5496 +1114 4892 5010 +1115 5250 5253 +1127 4891 4892 +1128 5248 5250 +1131 5132 5245 +1133 5136 5259 +1133 5256 5371 +1135 5253 5256 +1139 5495 5496 +1142 4890 4892 +1144 4880 4884 +1146 5014 5022 +1156 5014 5016 +1157 5244 5249 +1159 5011 5128 +1163 5258 5377 +1164 4483 4582 +1174 4360 4361 +1174 5015 5131 +1176 5014 5019 +1178 5239 5247 +1179 5262 5265 +1181 5247 5249 +1187 4772 4885 +1187 5016 5019 +1187 5130 5248 +1190 4588 4589 +1194 4476 4477 +1200 5247 5248 +1103 5611 5616 +1103 6107 6108 +1105 6204 6207 +1111 6201 6202 +1112 6069 6073 +1112 6210 6324 +1114 5739 5860 +1128 5597 5716 +1135 5852 5858 +1141 6084 6090 +1148 2402 6068 +1148 6200 6204 +1150 5865 5978 +1150 6206 6323 +1152 5720 5727 +1157 5854 5857 +1160 5833 5951 +1168 5604 5606 +1168 5849 5850 +1173 6074 6075 +1175 5743 5860 +1180 5959 5962 +1181 5610 5728 +1190 5960 5967 +1195 5951 5956 +1195 6204 6318 +1212 641 743 +1212 1692 1808 +1213 1680 1796 +1215 557 564 +1216 664 671 +1216 737 744 +1220 1098 1205 +1231 1680 1681 +1234 1451 1457 +1237 1681 1795 +1245 1179 1292 +1247 1576 1690 +1249 1092 1199 +1249 1324 1436 +1254 473 480 +1260 468 563 +1260 551 558 +1260 1695 1696 +1265 1211 1212 +1265 1693 1695 +1269 1332 1442 +1272 1808 1810 +1277 1670 1677 +1280 1178 1185 +1287 1320 1430 +1289 1679 1685 +1291 1694 1696 +1294 1212 1218 +1294 1564 1678 +1296 844 851 +1297 549 649 +1298 1324 1438 +1298 1670 1675 +1210 2165 2171 +1211 2500 2506 +1214 2279 2284 +1227 6068 6069 +1233 2269 2273 +1233 2492 2499 +1235 2153 2270 +1248 2385 2498 +1258 2263 2378 +1267 2516 6187 +1268 2050 2166 +1268 2146 2264 +1268 3111 3198 +1269 1906 1907 +1272 2500 2501 +1273 2493 2604 +1277 2497 2499 +1277 2521 6306 +1280 2395 2398 +1283 2054 2171 +1283 2501 2508 +1292 2401 2407 +1295 2800 2898 +1299 3034 3125 +1201 5258 5379 +1203 4902 5014 +1204 5256 5258 +1207 5248 5249 +1209 4595 4698 +1213 5242 5362 +1214 4704 4705 +1214 4784 4897 +1216 5131 5133 +1220 4367 4464 +1222 5359 5360 +1231 5467 5475 +1232 5244 5361 +1234 4373 4470 +1234 5500 5501 +1235 4168 4255 +1239 5490 5613 +1244 5129 5247 +1254 5607 5608 +1255 5131 5136 +1260 4261 4262 +1262 5124 5241 +1262 5260 5262 +1271 5611 5612 +1272 5124 5129 +1273 5120 5241 +1281 5128 5129 +1282 5020 5027 +1283 5264 5265 +1286 5262 5267 +1293 4370 4467 +1296 4363 4364 +1299 4711 4816 +1202 5957 5958 +1203 5723 5728 +1214 5969 5971 +1215 6329 6437 +1217 5837 5842 +1220 5730 5848 +1221 5610 5731 +1221 5853 5854 +1227 5957 5959 +1227 6068 6069 +1228 6684 6791 +1230 6379 6386 +1230 6477 6590 +1230 6902 6909 +1236 5849 5851 +1239 5490 5613 +1243 5729 5736 +1245 6077 6078 +1253 5610 5734 +1257 5609 5723 +1265 5963 6083 +1267 2516 6187 +1271 5611 5612 +1273 5956 5959 +1278 5745 5858 +1278 5863 5866 +1279 5962 5965 +1279 6079 6082 +1279 6262 6269 +1281 6690 6797 +1284 5840 5847 +1285 6992 7088 +1288 5966 5967 +1288 6584 6591 +1288 6579 6689 +1290 6090 6202 +1293 6780 6884 +1296 5721 5840 +1297 5597 5598 +1297 5853 5857 +1300 5745 5749 +1302 1235 1236 +1303 1455 1573 +1304 1222 1333 +1311 1678 1679 +1313 1210 1216 +1324 548 555 +1328 1796 1797 +1329 1329 1439 +1331 1670 1671 +1341 1210 1213 +1342 1584 1700 +1344 1678 1680 +1356 4995 5109 +1361 1801 1804 +1366 1807 1808 +1367 459 554 +1374 1314 1424 +1374 1287 1403 +1376 1215 1322 +1377 750 856 +1382 1328 1330 +1388 647 749 +1395 1096 1207 +1399 1330 1445 +1307 2689 2790 +1308 2497 2612 +1315 2154 2156 +1316 2521 6188 +1318 2171 2173 +1320 2264 2267 +1325 2695 2796 +1326 2898 2899 +1328 3028 3119 +1329 2799 2800 +1331 3138 3225 +1332 2908 3003 +1334 2045 2048 +1334 2045 2047 +1337 2500 2503 +1338 2161 2277 +1343 2261 2380 +1343 2910 2911 +1349 2045 2051 +1352 2264 2270 +1353 1922 2042 +1353 2565 2566 +1356 2454 2559 +1356 2676 2677 +1358 1917 1918 +1358 2803 2901 +1360 2057 2172 +1364 2577 2578 +1366 2815 2913 +1370 3131 3132 +1374 2707 2808 +1384 2229 2230 +1397 3031 3122 +1399 2162 2274 +1302 4473 4474 +1304 5370 5493 +1305 4364 4461 +1307 4271 4363 +1308 4990 4995 +1310 5263 5270 +1311 4592 4695 +1316 5122 5129 +1316 5133 5136 +1317 5072 5182 +1317 5256 5261 +1318 4274 4366 +1320 4701 4702 +1320 4828 4829 +1321 5375 5493 +1325 4480 4579 +1326 5489 5490 +1330 5241 5242 +1330 5374 5375 +1333 4717 4822 +1333 5024 5141 +1350 4364 4368 +1352 4262 4360 +1355 4363 4368 +1356 4995 5109 +1357 4585 4586 +1362 5370 5373 +1367 5496 5613 +1369 4155 4156 +1369 5239 5241 +1375 5473 5480 +1375 5617 5622 +1376 4708 4813 +1377 4835 4942 +1380 4585 4695 +1388 5132 5138 +1389 4162 4249 +1389 4265 4357 +1393 5241 5247 +1398 5107 5114 +1309 6327 6330 +1310 5898 6017 +1314 6578 6585 +1319 5725 5848 +1321 5717 5718 +1324 5739 5745 +1333 6208 6209 +1341 6322 6437 +1343 5832 5951 +1354 5590 5595 +1363 5957 5964 +1367 5496 5613 +1368 5604 5722 +1374 5745 5866 +1375 5617 5622 +1380 5732 5852 +1380 5839 5845 +1387 5839 5956 +1388 5594 5595 +1393 5749 5866 +1395 5751 5864 +1395 6443 6444 +1401 1286 1293 +1403 1096 1205 +1404 1205 1213 +1407 554 561 +1407 1327 1328 +1410 474 569 +1411 1800 1801 +1420 1575 1576 +1422 1328 1333 +1422 1397 1404 +1426 1448 1450 +1433 1458 1573 +1448 1327 1329 +1451 1070 1077 +1454 560 567 +1454 850 857 +1463 1564 1684 +1464 1684 1687 +1467 1664 1781 +1479 1453 1458 +1481 1324 1326 +1481 1585 1588 +1486 1587 1702 +1489 1468 1471 +1497 1564 1569 +1405 2919 2920 +1407 2157 2162 +1413 2393 2399 +1418 2700 2707 +1435 3021 3022 +1436 2809 2907 +1437 2375 2380 +1442 2391 2392 +1454 2925 2926 +1461 2598 2605 +1463 2157 2164 +1465 2034 2041 +1483 2259 2265 +1483 2393 2395 +1483 2497 2502 +1493 2393 2400 +1405 5246 5250 +1434 5253 5255 +1436 5107 5115 +1449 5373 5493 +1458 5254 5374 +1470 4367 4368 +1476 5467 5469 +1476 5372 5491 +1483 4899 4902 +1485 5116 5123 +1493 5263 5264 +1496 4790 4903 +1499 4707 4708 +1409 5743 5861 +1415 6333 6445 +1419 5616 5737 +1421 5742 5855 +1422 5970 6088 +1434 6367 6374 +1435 6330 6445 +1441 5739 5858 +1451 5856 5969 +1456 5618 5740 +1459 5624 5744 +1459 5739 5852 +1460 5731 5851 +1469 5971 5974 +1473 6356 6470 +1480 5999 6006 +1484 5993 6000 +1486 5840 5842 +1491 5737 5740 +1492 5844 5957 +1496 5871 5984 +1498 5732 5737 +1500 5829 5833 +1502 1450 1451 +1514 1227 1334 +1514 1324 1329 +1515 1464 1465 +1518 1085 1086 +1518 1448 1453 +1532 1085 1087 +1537 1081 1084 +1537 1552 1672 +1543 1093 1096 +1546 1693 1808 +1551 1800 1911 +1556 973 1087 +1559 1676 1683 +1563 1096 1101 +1563 1329 1444 +1566 1086 1087 +1571 1101 1208 +1576 1090 1093 +1576 1466 5108 +1577 985 1099 +1580 1094 1101 +1581 1085 1199 +1583 974 975 +1587 1082 1084 +1600 983 990 +1505 2379 2380 +1506 2049 2056 +1512 3128 3129 +1516 2383 2385 +1519 2700 2701 +1521 2155 2271 +1526 2384 2391 +1532 2606 2609 +1534 2156 2270 +1535 2402 5949 +1536 2170 2286 +1537 2053 2169 +1538 2036 2039 +1539 2507 2508 +1551 1800 1911 +1553 2604 2606 +1555 2498 2500 +1560 2931 2932 +1561 2599 2709 +1562 2035 2041 +1568 2713 2814 +1571 2389 2500 +1577 2694 2701 +1597 2383 2492 +1598 2701 2808 +1503 5491 5493 +1505 5260 5380 +1510 5013 5127 +1526 4889 4999 +1530 5376 5491 +1531 5118 5124 +1532 5142 5259 +1536 4897 4904 +1548 5131 5138 +1550 5246 5367 +1553 4706 4708 +1566 5136 5142 +1571 5371 5379 +1576 1466 5108 +1579 5165 5278 +1580 5352 5475 +1580 5382 5385 +1582 5478 5483 +1501 5977 6094 +1506 6005 6012 +1515 5869 5872 +1526 5954 5959 +1535 2402 5949 +1536 5842 5845 +1537 5871 5991 +1543 5766 5885 +1548 5965 5967 +1550 5849 5856 +1576 5632 5633 +1585 5875 5992 +1590 5844 5850 +1590 6244 6251 +1595 5742 5861 +1595 5990 5991 +1596 5748 5861 +1605 1207 1208 +1614 1235 1237 +1618 1088 1090 +1621 1210 1215 +1652 1088 1095 +1652 1330 1332 +1653 979 981 +1665 1208 1210 +1668 1092 1205 +1672 876 988 +1689 1683 1799 +1700 1451 1453 +1605 2256 2261 +1613 2045 2165 +1625 2155 2272 +1629 2389 2498 +1632 2038 2039 +1644 2381 2388 +1654 2493 2606 +1660 2144 2261 +1660 2279 2392 +1679 2278 2279 +1683 2151 2159 +1689 2254 2255 +1700 2261 2264 +1609 5136 5139 +1612 4789 4796 +1620 5123 5124 +1622 5232 5234 +1645 5237 5355 +1646 4902 5022 +1675 5255 5373 +1679 4905 4908 +1693 5255 5256 +1695 4889 4890 +1609 5621 5735 +1620 5750 5752 +1631 6074 6082 +1632 6098 6099 +1633 5855 5857 +1638 5743 5866 +1639 5725 5727 +1653 5854 5856 +1667 5960 5961 +1670 5977 6092 +1672 5749 5751 +1698 5970 5971 +1699 6080 6085 +1704 979 982 +1707 1106 1108 +1746 1002 1113 +1756 1227 1339 +1759 1685 1686 +1764 1793 1800 +1765 1122 1236 +1771 866 968 +1774 1216 1333 +1779 1689 1693 +1792 1187 1188 +1702 2250 2257 +1704 2387 2394 +1716 2153 2154 +1729 2258 2261 +1744 1903 2013 +1755 2517 2622 +1757 2039 2153 +1759 2045 2050 +1762 2521 2628 +1770 2251 2366 +1772 2265 2272 +1774 2151 2153 +1780 2395 2397 +1786 1922 2036 +1793 2593 2703 +1800 2631 2632 +1702 5251 5252 +1707 5504 5510 +1710 5384 5390 +1711 5254 5256 +1715 5390 5503 +1724 5258 5371 +1726 5503 5504 +1727 5018 5134 +1728 4905 5022 +1728 5121 5124 +1739 5503 5505 +1740 4544 4647 +1759 4996 5004 +1759 5384 5503 +1765 5256 5374 +1767 4431 4432 +1767 4896 5010 +1769 4772 4886 +1778 5384 5504 +1785 5114 5115 +1787 5470 5472 +1790 5149 5150 +1790 5267 5385 +1794 5119 5121 +1795 4886 4890 +1799 5123 5241 +1704 5839 5962 +1716 6217 6218 +1722 5960 5968 +1723 6084 6085 +1726 6080 6088 +1738 6078 6195 +1738 6317 6318 +1741 5720 5725 +1753 6077 6083 +1761 6317 6321 +1763 6090 6091 +1764 6092 6094 +1765 5965 6080 +1771 5974 5975 +1776 6097 6100 +1782 5737 5742 +1789 5967 5973 +1789 6092 6097 +1796 5976 5977 +1796 6215 6325 +1806 1100 1102 +1814 1354 5109 +1825 1324 1327 +1825 1570 1685 +1829 1798 1800 +1832 1575 1685 +1834 1563 1678 +1843 1352 4994 +1844 1576 1581 +1844 1799 1801 +1849 1208 1209 +1851 1579 1582 +1856 1339 1341 +1860 1198 1203 +1860 1218 1333 +1865 1122 1237 +1868 1210 1327 +1877 1554 1670 +1892 1230 1345 +1894 1670 1678 +1898 973 976 +1900 1222 1339 +1807 6305 6306 +1814 2616 2617 +1815 2011 2017 +1816 2034 2035 +1820 2625 2632 +1824 2015 2017 +1833 2264 2266 +1833 2282 2284 +1840 2017 2018 +1841 2017 2133 +1847 2016 2017 +1848 2603 2608 +1851 2010 2018 +1857 2377 2380 +1858 2017 2135 +1859 2603 2717 +1863 2742 6308 +1869 2164 2168 +1871 2608 2717 +1871 2626 2735 +1881 2375 2382 +1890 2150 2153 +1890 2606 2607 +1898 2133 2134 +1804 5266 5268 +1805 5265 5268 +1810 5352 5357 +1813 5259 5260 +1814 1354 5109 +1814 5257 5262 +1814 5377 5379 +1821 5006 5122 +1824 4895 5010 +1831 4759 4760 +1837 5268 5271 +1843 1352 4994 +1843 5270 5271 +1848 4663 4768 +1850 5269 5276 +1850 5268 5273 +1852 5629 5634 +1867 5251 5258 +1877 4992 4995 +1881 5267 5268 +1883 5510 5631 +1884 5256 5373 +1887 5271 5274 +1888 5386 5506 +1889 5635 5636 +1894 5112 5114 +1894 5114 5233 +1803 5977 6097 +1807 6305 6306 +1811 6090 6207 +1812 5972 5974 +1814 6073 6187 +1830 6426 6430 +1833 6331 6332 +1834 6099 6211 +1836 6088 6090 +1837 6093 6094 +1846 6089 6090 +1847 6223 6224 +1848 5630 5750 +1852 5629 5634 +1857 6309 6419 +1860 5960 5965 +1860 6085 6207 +1867 6310 6318 +1872 5865 5986 +1872 5973 5974 +1872 6218 6328 +1874 6444 6448 +1875 6211 6219 +1875 6216 6219 +1880 6310 6311 +1883 5510 5631 +1889 5635 5636 +1889 6230 6340 +1894 6311 6419 +1896 6311 6427 +1897 6098 6105 +1910 1349 4991 +1915 975 1086 +1915 1115 1120 +1922 1463 1464 +1923 1350 4991 +1925 989 990 +1926 990 1094 +1938 1084 1087 +1942 1085 1090 +1942 1089 1196 +1945 1570 1575 +1946 1466 5109 +1950 1213 1215 +1979 860 962 +1980 1095 1202 +1997 1096 1208 +1999 1332 1449 +1918 2168 2282 +1921 2384 2386 +1923 2134 2252 +1923 2520 2631 +1931 2260 2376 +1932 1918 2028 +1933 2255 2374 +1936 2156 2276 +1938 2625 2627 +1939 2519 6189 +1951 2496 2607 +1951 2515 2630 +1955 6191 6307 +1959 2163 2164 +1962 2152 2270 +1967 2056 5712 +1974 2516 2518 +1975 2377 2489 +1977 2028 2035 +1988 2605 2715 +1992 2626 2736 +1994 2493 2598 +1998 2238 2245 +1906 5119 5120 +1910 1349 4991 +1910 5274 5389 +1915 5156 5275 +1920 4760 4761 +1923 1350 4991 +1925 5388 5505 +1929 5017 5024 +1929 5117 5236 +1931 4874 4992 +1931 5508 5511 +1933 5233 5235 +1937 5375 5494 +1943 5011 5012 +1946 1466 5109 +1951 5385 5505 +1953 5386 5393 +1964 5154 5274 +1967 4873 4881 +1976 5508 5513 +1980 5113 5120 +1989 5266 5273 +1991 4886 4996 +1994 5269 5270 +1995 5371 5373 +1904 6434 6441 +1905 6339 6451 +1906 6222 6225 +1906 6445 6446 +1910 5719 5724 +1922 5985 6104 +1924 6085 6090 +1925 6325 6332 +1935 6448 6559 +1937 5867 5868 +1937 6107 6109 +1948 6217 6222 +1955 6191 6307 +1956 5959 5961 +1962 6081 6082 +1965 6456 6563 +1966 6236 6346 +1966 6310 6315 +1979 5730 5849 +1979 6446 6447 +1985 6228 6231 +2002 984 990 +2009 1216 1325 +2019 984 1088 +2024 1081 1195 +2025 1091 1092 +2038 1080 1081 +2039 1078 1189 +2046 1565 1570 +2047 864 970 +2048 752 753 +2057 1079 1080 +2062 1329 1445 +2064 968 976 +2070 1331 1338 +2075 1802 1804 +2076 1073 1074 +2083 974 979 +2088 980 981 +2098 1224 1331 +2014 2389 2394 +2015 2601 2608 +2017 2255 2371 +2017 2379 2494 +2022 2711 2714 +2026 2609 2612 +2034 2709 2716 +2038 2249 2368 +2044 2140 2144 +2044 2156 2271 +2052 2251 2368 +2054 2613 2615 +2056 2282 2398 +2056 2710 2817 +2058 2155 2270 +2059 2489 2495 +2060 2369 2371 +2063 2379 2486 +2067 2028 2034 +2074 2486 2487 +2074 2496 2497 +2086 2491 2494 +2088 2371 2374 +2092 2260 2375 +2092 2374 2375 +2100 2390 2391 +2004 5277 5280 +2006 5386 5392 +2007 5014 5015 +2008 5382 5384 +2021 5138 5259 +2023 5259 5262 +2027 5269 5274 +2027 5490 5493 +2030 5155 5162 +2033 5122 5128 +2040 5378 5379 +2043 5009 5119 +2046 5271 5272 +2061 5277 5279 +2064 5268 5391 +2073 4996 5003 +2074 5162 5163 +2076 5160 5283 +2080 5274 5277 +2089 5233 5234 +2094 4993 5000 +2098 5268 5385 +2014 5850 5969 +2016 6203 6318 +2018 6557 6558 +2021 5849 5854 +2028 5721 5842 +2032 5729 5849 +2034 6449 6450 +2045 5731 5854 +2060 6203 6204 +2070 6663 6764 +2090 6559 6560 +2098 5730 5736 +2099 6210 6325 +2099 6327 6329 +2102 1082 1083 +2105 1330 1450 +2114 1093 1094 +2129 971 976 +2132 1088 1093 +2138 1336 1338 +2159 863 864 +2162 1067 1068 +2166 977 978 +2168 759 859 +2173 861 864 +2173 1076 1078 +2188 869 971 +2198 861 867 +2199 1090 1095 +2103 2704 2811 +2105 2602 2712 +2106 2285 2398 +2107 2503 2615 +2108 2607 2612 +2114 2259 2261 +2117 2368 2369 +2123 2615 2618 +2128 2282 2285 +2129 2255 2369 +2130 2377 2382 +2135 2706 2713 +2136 2382 2495 +2136 2611 2721 +2156 2150 2264 +2159 2255 2368 +2172 2604 2605 +2182 2805 2812 +2195 2708 2819 +2196 2811 2817 +2199 2262 2264 +2103 5153 5272 +2108 5045 5161 +2109 4878 4993 +2110 5278 5285 +2111 5256 5379 +2112 5160 5275 +2113 5161 5162 +2118 5629 5636 +2121 4648 4759 +2121 5044 5051 +2139 5159 5277 +2148 5163 5166 +2156 5273 5392 +2159 5386 5388 +2165 5168 5281 +2176 5166 5169 +2179 5158 5278 +2180 4907 5023 +2185 4794 4911 +2196 5164 5166 +2198 4880 4998 +2114 6353 6461 +2118 5629 5636 +2123 6079 6201 +2125 6327 6332 +2130 6454 6565 +2131 5610 5726 +2137 6564 6668 +2150 6569 6570 +2154 6558 6559 +2158 6234 6237 +2162 5846 5848 +2168 5882 5883 +2172 6322 6324 +2177 6453 6560 +2177 6558 6564 +2184 5964 5965 +2184 6202 6207 +2187 6199 6201 +2187 6562 6670 +2192 6203 6209 +2194 6557 6564 +2196 6207 6209 +2197 6685 6796 +2203 1803 1920 +2206 981 1091 +2211 62 63 +2220 757 861 +2223 860 861 +2223 1079 1086 +2228 1088 1094 +2231 976 978 +2233 859 866 +2233 1095 1207 +2238 419 420 +2239 1321 1327 +2240 1074 1075 +2251 335 419 +2257 413 414 +2258 757 859 +2262 751 754 +2266 1073 1080 +2267 420 509 +2270 145 146 +2271 1319 1327 +2273 414 503 +2273 650 746 +2274 329 413 +2274 979 1093 +2275 328 329 +2275 1797 1914 +2278 1322 1327 +2290 648 650 +2294 753 853 +2202 2265 2267 +2203 1803 1920 +2206 2811 2818 +2207 2621 2729 +2227 2377 2494 +2230 2814 2819 +2234 2602 2713 +2236 2360 2367 +2240 2033 2150 +2243 2609 2723 +2244 2813 2816 +2254 2806 2910 +2256 2361 2474 +2261 2812 2816 +2263 1918 2036 +2265 1916 2030 +2271 2817 2818 +2275 1797 1914 +2281 2373 2379 +2285 2609 2614 +2288 2810 2918 +2291 2148 2150 +2294 2145 2150 +2295 2383 2388 +2201 5159 5278 +2214 5165 5166 +2214 5373 5376 +2224 5165 5284 +2230 5000 5115 +2233 5154 5277 +2234 5465 5578 +2235 5007 5121 +2235 5504 5508 +2238 5168 5287 +2244 5578 5580 +2247 5165 5283 +2247 5168 5289 +2253 4906 4913 +2253 5464 5465 +2254 5273 5391 +2255 4438 4543 +2268 4995 5000 +2273 4990 4991 +2273 5268 5383 +2276 4875 4877 +2280 5003 5113 +2285 5162 5281 +2295 5160 5278 +2297 5173 5180 +2212 6445 6448 +2220 6209 6210 +2226 6080 6082 +2231 6582 6686 +2232 6448 6560 +2232 6568 6571 +2248 5705 5825 +2248 6562 6671 +2261 6580 6582 +2262 6688 6691 +2263 6205 6206 +2265 6575 6576 +2273 6676 6679 +2276 6574 6682 +2277 6557 6559 +2284 5730 5731 +2285 6562 6567 +2286 6582 6694 +2289 6202 6203 +2295 6325 6330 +2296 6451 6565 +2302 1075 1078 +2304 324 327 +2305 859 867 +2307 1092 1207 +2309 1210 1212 +2310 975 1085 +2312 1072 1075 +2317 752 859 +2325 746 751 +2326 1072 1189 +2328 330 418 +2331 1072 1078 +2336 1326 1444 +2340 1576 1688 +2346 757 867 +2348 325 326 +2354 1658 1665 +2355 864 867 +2355 1087 1089 +2356 421 424 +2359 326 410 +2360 1067 1074 +2363 247 325 +2365 756 856 +2371 418 420 +2385 416 417 +2386 420 421 +2396 864 866 +2397 521 522 +2398 975 1079 +2301 3570 3572 +2303 2733 2740 +2303 2814 2821 +2306 2810 2816 +2307 2904 2911 +2315 2261 2266 +2315 2382 2388 +2315 2824 2922 +2325 2922 2930 +2328 2816 2918 +2336 2256 2257 +2340 2804 2912 +2343 3606 3613 +2344 2494 2497 +2352 2147 2150 +2353 2929 3024 +2359 2918 2921 +2373 1942 1948 +2375 2366 2372 +2379 2383 2389 +2383 2264 2265 +2383 2700 2808 +2385 2494 2495 +2389 1942 1947 +2392 1942 1946 +2392 2273 2386 +2395 2267 2272 +2396 2918 2920 +2397 3500 3505 +2398 1948 2064 +2400 2703 2709 +2304 4764 4881 +2304 5167 5174 +2307 5141 5260 +2311 5172 5289 +2323 5170 5171 +2335 5608 5609 +2340 5001 5116 +2346 5287 5288 +2362 5118 5236 +2364 5172 5295 +2365 5372 5485 +2371 5463 5465 +2383 5458 5465 +2384 5276 5277 +2385 5054 5171 +2392 5154 5271 +2395 5290 5297 +2397 4790 4796 +2399 5459 5465 +2304 6329 6443 +2306 6204 6319 +2309 6680 6681 +2319 6204 6321 +2322 6567 6671 +2328 6447 6448 +2335 5608 5609 +2337 7478 7479 +2339 6676 6784 +2344 6332 6440 +2349 6443 6445 +2350 6675 6776 +2351 6448 6450 +2351 6568 6682 +2354 2057 5830 +2361 6570 6574 +2373 7289 7361 +2376 6447 6560 +2378 6444 6557 +2379 6322 6327 +2380 6580 6688 +2390 6077 6082 +2393 6449 6563 +2393 6673 6676 +2396 6680 6685 +2400 6206 6210 +2404 1334 1336 +2410 862 863 +2424 427 520 +2453 421 514 +2456 527 528 +2457 324 412 +2459 861 862 +2464 1181 1188 +2477 749 750 +2488 1183 1186 +2493 326 330 +2497 748 749 +2497 753 754 +2497 1205 1206 +2407 2257 2366 +2408 3430 3500 +2413 3505 3568 +2421 2909 3014 +2422 2496 2608 +2423 2383 2500 +2423 3484 3546 +2439 2468 2475 +2444 3599 3600 +2449 3341 3343 +2451 1954 2064 +2452 2703 2710 +2457 1831 1946 +2464 2711 2712 +2479 3478 3546 +2482 2263 2267 +2483 3702 7498 +2485 2708 2713 +2494 2711 2713 +2413 5272 5279 +2418 5175 5295 +2426 5578 5583 +2434 4684 4795 +2434 5175 5178 +2435 5155 5161 +2435 5272 5274 +2437 5334 5452 +2444 5141 5259 +2451 5452 5459 +2460 4794 4799 +2467 5164 5171 +2469 5451 5452 +2480 5453 5566 +2482 5290 5291 +2482 5605 5613 +2494 4905 4906 +2496 4906 4912 +2499 5127 5129 +2500 5049 5169 +2403 6450 6565 +2408 6674 6680 +2412 6082 6083 +2412 6554 6560 +2434 6329 6445 +2434 6679 6784 +2439 6573 6677 +2444 7144 7230 +2445 6561 6665 +2449 7252 7253 +2451 5833 5956 +2452 6557 6565 +2455 6206 6322 +2461 5592 5711 +2461 7144 7145 +2462 6450 6557 +2463 6668 6675 +2467 6680 6682 +2468 6562 6568 +2468 7221 7222 +2477 7379 7380 +2478 7204 7282 +2478 7416 7472 +2479 7253 7325 +2480 6640 6642 +2482 5605 5613 +2482 6668 6676 +2496 7434 7490 +2502 523 526 +2504 1182 1295 +2512 331 332 +2513 979 984 +2519 648 651 +2535 1199 1205 +2543 425 426 +2544 432 521 +2546 1235 4874 +2556 1074 1187 +2560 864 976 +2562 507 601 +2563 426 520 +2565 427 523 +2568 1079 1084 +2569 644 740 +2573 424 426 +2578 1379 1380 +2582 1092 1096 +2587 751 756 +2594 1573 1574 +2600 648 754 +2513 3702 3703 +2518 2383 2495 +2522 2599 2710 +2527 2808 2810 +2531 2812 2916 +2544 3506 3570 +2551 2703 2811 +2573 2603 2712 +2585 3701 3702 +2587 3504 3511 +2598 2606 2608 +2505 5452 5457 +2510 5583 5586 +2512 5447 5560 +2522 4544 4653 +2524 5446 5447 +2526 5292 5295 +2528 4789 4797 +2542 5243 5361 +2546 1235 4874 +2551 5019 5139 +2555 5119 5126 +2561 5290 5292 +2565 4684 4688 +2567 5008 5014 +2567 5446 5448 +2569 4903 4904 +2572 5440 5447 +2583 5459 5460 +2589 5446 5453 +2590 4647 4654 +2590 5289 5290 +2594 5295 5296 +2597 5445 5447 +2501 5843 5845 +2505 6532 6642 +2508 7307 7379 +2513 5860 5863 +2513 6794 6795 +2515 6562 6676 +2515 7409 7410 +2516 6669 6776 +2517 7264 7265 +2524 6316 6317 +2539 5615 5735 +2539 6554 6561 +2548 6670 6673 +2550 7475 7477 +2556 6562 6668 +2568 5717 5724 +2568 6531 6642 +2568 6782 6783 +2569 7343 7344 +2571 7414 7416 +2572 6784 6785 +2581 6776 6782 +2581 7479 7480 +2585 6321 6324 +2591 6559 6561 +2592 7345 7414 +2592 7480 7526 +2594 5855 5860 +2598 6199 6204 +2607 1289 1296 +2609 601 602 +2616 417 421 +2619 1072 1077 +2621 245 327 +2627 1730 1731 +2628 1180 1186 +2629 512 513 +2629 534 628 +2631 330 333 +2632 1183 1297 +2633 1180 1297 +2641 529 627 +2643 1077 1184 +2644 746 754 +2644 1485 1602 +2647 1731 1842 +2650 547 651 +2658 326 327 +2661 653 755 +2668 1183 1184 +2668 1291 1294 +2669 1290 1406 +2686 653 749 +2695 1731 1848 +2607 2611 2715 +2612 2386 2500 +2612 3437 3509 +2615 3600 3607 +2619 2822 2825 +2628 2497 2604 +2630 2905 3006 +2631 3257 3340 +2635 2614 2723 +2640 3540 3547 +2647 1731 1842 +2653 2822 2827 +2654 2391 2395 +2667 2492 2500 +2668 3567 3570 +2683 2815 2919 +2695 1731 1848 +2615 5460 5575 +2617 5328 5451 +2620 5440 5441 +2631 4103 4110 +2631 5281 5287 +2631 5333 5451 +2634 4462 4567 +2638 4794 4797 +2643 5018 5019 +2658 5440 5442 +2661 5434 5435 +2662 5442 5445 +2665 5260 5267 +2666 5008 5013 +2666 5330 5451 +2669 5233 5241 +2678 5459 5572 +2678 5465 5583 +2679 4902 5016 +2679 5270 5389 +2679 5292 5297 +2682 5328 5445 +2684 5147 5267 +2685 5337 5339 +2687 4682 4797 +2687 5322 5445 +2687 5327 5445 +2688 5122 5127 +2690 5460 5577 +2692 5164 5170 +2694 5324 5445 +2698 5294 5407 +2609 6787 6895 +2618 7436 7437 +2625 7320 7391 +2640 7371 7436 +2643 7435 7437 +2646 6788 6789 +2647 6782 6784 +2654 6890 6897 +2659 6330 6332 +2663 7375 7443 +2665 6781 6889 +2666 6684 6790 +2672 6638 6640 +2674 7409 7414 +2676 6082 6085 +2678 7416 7478 +2692 6638 6642 +2705 645 651 +2710 553 652 +2712 332 416 +2713 1731 1847 +2717 1072 1184 +2722 93 157 +2726 1400 1407 +2731 645 648 +2740 896 1004 +2740 1400 1401 +2744 421 512 +2744 753 757 +2745 546 646 +2748 328 330 +2748 336 424 +2749 553 657 +2750 1290 1296 +2754 422 423 +2755 634 635 +2756 112 113 +2756 429 518 +2762 325 328 +2763 1730 1737 +2767 528 622 +2769 1205 1207 +2770 113 179 +2770 1088 1089 +2771 864 869 +2775 552 651 +2775 1081 1083 +2776 1092 1093 +2786 330 336 +2787 553 649 +2791 111 181 +2791 1078 1083 +2792 1208 1213 +2798 1076 1077 +2800 1288 1408 +2703 2721 2722 +2712 2497 2607 +2714 1916 1918 +2723 2152 2153 +2737 2372 2377 +2744 2052 2057 +2750 2912 2915 +2752 3501 3508 +2793 2495 2502 +2702 5135 5254 +2708 4904 5020 +2716 4683 4690 +2717 5454 5457 +2719 5440 5445 +2728 5251 5259 +2732 5578 5579 +2737 5320 5321 +2739 4891 4898 +2742 5339 5452 +2745 5435 5554 +2748 5137 5138 +2749 5298 5415 +2755 5054 5170 +2756 4685 4688 +2756 4794 4796 +2757 4684 4796 +2759 4684 4797 +2778 5466 5583 +2779 5052 5169 +2783 5460 5462 +2786 4573 4580 +2786 5454 5456 +2787 5300 5413 +2790 5257 5258 +2796 5052 5055 +2797 4903 4910 +2798 5454 5572 +2704 6678 6785 +2707 6206 6324 +2725 7411 7414 +2731 7337 7339 +2733 6684 6785 +2747 6770 6777 +2761 6570 6674 +2763 6784 6787 +2770 6677 6678 +2770 6667 6778 +2771 6085 6202 +2776 5843 5848 +2777 7344 7414 +2788 6691 6694 +2793 7343 7350 +2799 6562 6565 +2806 1189 1192 +2810 111 113 +2810 528 629 +2818 433 526 +2820 250 328 +2821 553 555 +2822 111 114 +2825 1075 1077 +2834 1078 1081 +2841 113 187 +2854 1718 1720 +2858 642 740 +2861 556 559 +2869 640 641 +2872 554 556 +2873 1484 1491 +2874 555 556 +2874 1182 1186 +2890 556 657 +2894 463 554 +2813 2146 2150 +2855 2810 2913 +2869 2257 2374 +2898 2814 2816 +2809 5251 5256 +2809 5583 5584 +2813 5263 5268 +2818 5320 5322 +2826 5294 5415 +2828 4898 5016 +2828 5297 5410 +2837 5275 5282 +2841 5457 5460 +2846 5448 5451 +2846 5460 5465 +2848 5315 5434 +2852 5454 5571 +2852 5582 5583 +2855 4677 4683 +2864 5294 5413 +2871 5171 5290 +2875 4574 4683 +2883 5386 5391 +2884 5243 5244 +2890 5462 5583 +2801 6332 6445 +2812 7339 7342 +2814 6685 6688 +2815 7480 7485 +2832 6692 6693 +2832 6882 6976 +2836 7259 7337 +2842 6982 6983 +2844 6562 6564 +2849 5681 5801 +2849 7406 7414 +2851 6556 6561 +2866 6786 6890 +2866 7265 7266 +2868 7480 7483 +2875 6686 6688 +2876 6670 6778 +2877 7263 7265 +2889 7265 7343 +2891 6881 6889 +2893 7417 7477 +2899 7260 7265 +2901 638 734 +2904 1289 1294 +2910 1183 1185 +2911 1288 1405 +2917 463 562 +2918 1397 1402 +2919 1188 1189 +2926 1212 1213 +2927 1073 1078 +2929 647 743 +2934 1485 1600 +2937 462 557 +2937 1400 1405 +2938 157 164 +2941 1282 1402 +2943 1187 1194 +2953 1205 1210 +2968 642 648 +2969 1399 1402 +2984 1184 1186 +2988 648 748 +2990 1278 1394 +2994 1596 1712 +2994 1718 1725 +2919 2361 2476 +2922 1921 1922 +2927 2262 2263 +2938 2810 2912 +2979 2255 2366 +2985 2809 2913 +2901 4578 4691 +2905 4474 4579 +2905 5277 5278 +2907 5259 5261 +2917 5161 5166 +2921 5419 5420 +2924 5460 5583 +2936 5454 5460 +2938 5560 5567 +2944 4474 4478 +2948 5436 5439 +2950 5273 5386 +2958 5434 5439 +2959 5554 5555 +2963 5436 5554 +2965 5326 5446 +2970 5436 5553 +2973 5333 5446 +2974 5438 5439 +2980 5436 5438 +2982 5428 5435 +2989 5265 5267 +2989 5435 5548 +2993 5431 5436 +2999 5431 5439 +2909 6570 6681 +2909 6772 6775 +2909 6776 6783 +2909 7180 7258 +2922 6783 6889 +2922 7262 7265 +2928 7258 7263 +2934 6675 6784 +2943 7265 7342 +2953 6204 6206 +2954 6665 6672 +2961 6883 6886 +2964 6673 6675 +2973 7260 7336 +2975 6558 6562 +2978 6668 6673 +2981 7256 7260 +2984 6880 6886 +2989 6786 6884 +2990 5957 5962 +2993 5954 5962 +3002 1181 1186 +3005 1290 1408 +3029 1403 1404 +3030 981 1093 +3030 1182 1297 +3034 157 162 +3036 642 647 +3062 981 985 +3063 1085 1092 +3067 756 863 +3067 1723 1725 +3075 1078 1195 +3077 1597 1712 +3080 645 646 +3090 467 468 +3096 469 568 +3006 2909 3009 +3009 2806 2912 +3029 2153 2155 +3039 1800 1919 +3064 2812 2813 +3065 2914 3015 +3006 5298 5413 +3010 5318 5438 +3016 4904 5022 +3020 5452 5453 +3021 5441 5447 +3027 4904 4908 +3031 5321 5322 +3033 5130 5247 +3033 5296 5297 +3034 5241 5244 +3037 5169 5171 +3038 5431 5438 +3048 5453 5454 +3056 5327 5440 +3069 5419 5426 +3073 5166 5168 +3083 5418 5421 +3085 5256 5259 +3085 5419 5424 +3093 5306 5425 +3001 7079 7080 +3026 7339 7414 +3037 6667 6670 +3047 7083 7089 +3053 7422 7478 +3057 6764 6771 +3072 6662 6670 +3073 6881 6883 +3078 7476 7480 +3082 6886 6984 +3084 6085 6088 +3089 6982 6984 +3089 7480 7525 +3091 6884 6886 +3092 6878 6883 +3093 6667 6669 +3099 6777 6883 +3100 5839 5842 +3133 469 563 +3135 560 562 +3139 1607 1614 +3152 464 471 +3152 465 560 +3156 1723 1726 +3157 1597 1717 +3164 1080 1193 +3166 471 560 +3171 472 568 +3174 465 471 +3190 1292 1299 +3103 2709 2710 +3121 2793 2898 +3132 2904 2905 +3149 3000 3007 +3176 2804 2906 +3106 5287 5292 +3106 5421 5423 +3127 4904 4905 +3135 5421 5424 +3137 5304 5424 +3146 5420 5421 +3157 5156 5162 +3157 5295 5297 +3167 5427 5428 +3101 6780 6878 +3107 6775 6878 +3107 6882 6883 +3110 6663 6770 +3113 6878 6880 +3114 6884 6891 +3116 6775 6875 +3119 6875 6878 +3124 6987 7081 +3126 6671 6672 +3126 6880 6883 +3128 6780 6883 +3147 6877 6878 +3149 7480 7527 +3152 7477 7480 +3156 6678 6679 +3191 6986 7082 +3197 6885 6886 +3203 1289 1297 +3205 1180 1185 +3215 552 646 +3215 642 742 +3246 553 651 +3246 631 632 +3249 1290 1294 +3255 636 639 +3264 1404 1405 +3280 756 861 +3284 1520 1521 +3218 2055 2057 +3280 2034 2036 +3220 5419 5425 +3222 5310 5425 +3224 5318 5437 +3236 5266 5267 +3251 5377 5378 +3253 5304 5427 +3254 5276 5280 +3265 5431 5432 +3274 5432 5433 +3285 5312 5425 +3290 5309 5427 +3297 5298 5416 +3298 5160 5162 +3248 6981 6987 +3257 6560 6561 +3273 5837 5844 +3285 6785 6786 +3300 6769 6869 +3303 464 472 +3318 463 557 +3318 636 638 +3318 1083 1196 +3322 380 464 +3338 638 742 +3341 966 1070 +3347 1402 1404 +3366 1077 1190 +3377 469 475 +3377 1640 1647 +3380 1284 1394 +3395 1402 1519 +3397 961 1069 +3302 5592 5594 +3301 5416 5421 +3310 5271 5273 +3314 5306 5427 +3314 5428 5429 +3321 5303 5422 +3324 5310 5427 +3327 5303 5416 +3350 5310 5433 +3358 5174 5287 +3364 5312 5433 +3369 5171 5172 +3302 5592 5594 +3304 6671 6676 +3305 6976 6984 +3309 6983 6987 +3311 6882 6982 +3319 6869 6877 +3335 6769 6877 +3347 7170 7171 +3366 6987 7079 +3367 7080 7084 +3376 6881 6888 +3387 6874 6877 +3389 7080 7170 +3392 6890 6891 +3397 7172 7174 +3402 647 748 +3410 373 374 +3415 1069 1075 +3430 373 375 +3438 647 750 +3441 1399 1519 +3456 1388 1395 +3463 633 639 +3467 1277 1278 +3469 1282 1285 +3471 465 554 +3471 642 645 +3475 961 1072 +3480 535 633 +3482 1168 1279 +3419 2362 2363 +3430 5304 5422 +3456 5421 5422 +3457 5437 5438 +3409 6783 6887 +3434 7255 7256 +3454 7262 7334 +3459 6787 6790 +3459 6984 6986 +3490 6559 6562 +3496 6783 6787 +3501 1164 1271 +3518 1173 1280 +3523 1286 1287 +3527 957 1061 +3532 540 634 +3537 749 754 +3546 1291 1293 +3565 1180 1292 +3569 958 1069 +3589 955 958 +3592 531 625 +3502 2005 2115 +3507 5258 5259 +3529 5316 5439 +3562 5318 5439 +3581 5275 5276 +3597 5293 5294 +3505 6787 6789 +3511 6884 6889 +3524 5622 5624 +3541 7169 7172 +3549 5593 5594 +3561 6983 7079 +3571 6985 6986 +3598 7076 7083 +3604 1280 1286 +3608 533 634 +3639 533 534 +3655 1288 1402 +3658 1162 1271 +3665 1388 1393 +3677 642 743 +3681 1265 1382 +3685 1167 1279 +3625 5462 5575 +3634 5316 5433 +3637 5204 5323 +3646 5508 5510 +3652 5324 5443 +3697 5503 5508 +3674 5839 5844 +3711 529 532 +3718 1167 1274 +3720 1162 1273 +3728 1277 1282 +3730 950 951 +3752 1157 1158 +3759 1067 1069 +3766 527 529 +3795 641 737 +3703 5596 5598 +3714 6581 6582 +3812 1044 1151 +3816 642 748 +3840 1293 1409 +3843 643 648 +3873 1186 1189 +3878 1230 1337 +3830 5593 5600 +3812 5271 5277 +3840 5304 5421 +3827 5598 5600 +3830 5593 5600 +3903 1403 1408 +3910 957 1067 +3918 978 1082 +3960 646 651 +3965 1283 1284 +3968 958 961 +3978 646 647 +3909 5303 5421 +3967 5154 5272 +3974 5459 5578 +3981 5309 5422 +3995 5275 5280 +3979 7252 7259 +4028 1463 1468 +4040 1260 1370 +4064 1071 1072 +4070 1184 1190 +4057 2922 2923 +4038 5321 5440 +4013 7337 7344 +4023 7344 7409 +4041 5968 5970 +4047 7342 7344 +4061 7344 7415 +4129 944 945 +4131 851 958 +4154 1250 1251 +4169 1143 1250 +4171 918 1022 +4186 1138 1250 +4191 1244 1250 +4197 1072 1074 +4122 2614 2718 +4144 1818 1822 +4171 5596 5603 +4114 5434 5441 +4122 5172 5287 +4173 5434 5436 +4178 5453 5572 +4110 7174 7252 +4112 7260 7342 +4171 5596 5603 +4183 7257 7260 +4222 1250 1255 +4280 1229 1237 +4294 1233 1340 +4299 1344 1460 +4218 2139 2140 +4244 2140 2250 +4255 2010 2011 +4202 5171 5289 +4209 5572 5577 +4221 5448 5566 +4242 5178 5295 +4254 5415 5417 +4262 5297 5298 +4280 5417 5418 +4289 5177 5295 +4292 5445 5446 +4211 7413 7477 +4216 7416 7477 +4239 6328 6335 +4245 7409 7416 +4263 7411 7416 +4269 7472 7477 +4272 7417 7475 +4296 7483 7485 +4307 1003 1109 +4317 1149 1256 +4325 1265 1266 +4329 1256 1257 +4336 1137 1244 +4347 999 1109 +4359 1189 1190 +4360 1116 1120 +4365 1228 1339 +4393 1265 1273 +4349 2055 5591 +4377 6078 6079 +4386 2822 2922 +4376 5425 5433 +4381 5442 5447 +4392 5430 5433 +4301 7417 7422 +4304 7416 7417 +4343 7260 7263 +4356 6787 6887 +4367 6578 6689 +4377 6078 6079 +4385 7341 7406 +4425 1224 1230 +4431 1265 1270 +4484 2138 2253 +4427 5439 5442 +4433 5298 5421 +4444 4878 4880 +4449 5433 5553 +4455 4877 4878 +4457 4878 4990 +4464 4880 4883 +4473 4880 4881 +4499 5444 5557 +4452 7413 7469 +4566 1035 1142 +4547 5450 5563 +4614 1136 1137 +4666 1023 1130 +4623 2920 3021 +4626 1887 1888 +4655 1818 1935 +4656 2137 2247 +4665 1770 1881 +4626 5428 5430 +4666 5439 5559 +4703 2808 2815 +4729 1894 2004 +4731 2135 2137 +4750 1897 2007 +4775 1891 2001 +4701 5444 5448 +4731 5456 5569 +4752 5448 5453 +4758 5454 5569 +4733 7082 7089 +4736 6676 6678 +4819 2397 2504 +4822 1886 1891 +4844 2013 2014 +4854 1891 2006 +4825 5444 5563 +4895 5450 5569 +4819 6985 6992 +4957 1532 1533 +4959 1579 1580 +4991 1469 1470 +5003 461 468 +5019 524 525 +5019 1082 1087 +5042 955 960 +5008 5615 5729 +5041 7349 7350 +5046 7258 7265 +5112 960 1064 +5115 846 952 +5145 650 753 +5180 1284 1400 +5183 1398 1514 +5188 973 975 +5197 851 953 +5127 1799 1805 +5167 1937 1940 +5223 518 524 +5226 836 938 +5228 646 648 +5265 1515 1631 +5272 862 864 +5290 421 426 +5257 3001 3098 +5231 6991 6998 +5319 537 631 +5320 1396 1399 +5321 1284 1285 +5336 524 529 +5340 543 643 +5342 530 531 +5360 644 748 +5392 975 976 +5372 5054 5164 +5392 5047 5054 +5401 524 526 +5403 419 424 +5410 429 526 +5410 974 981 +5425 1085 1093 +5431 638 740 +5470 648 653 +5490 973 978 +5447 5272 5277 +5427 6893 6894 +5453 6981 7081 +5523 631 636 +5582 524 531 +5583 427 518 +5503 5585 5698 +5555 4936 4937 +5566 4934 5050 +5573 5052 5053 +5586 5203 5210 +5504 6698 6699 +5563 6984 6987 +5602 631 638 +5607 423 512 +5627 427 432 +5644 427 521 +5646 427 526 +5646 4820 4933 +5673 4933 4934 +5697 5586 5701 +5704 529 531 +5733 416 512 +5740 1920 1921 +5716 4934 4938 +5764 5096 5212 +5772 5212 5219 +5776 5089 5096 +5789 5094 5096 +5800 5212 5214 +5850 535 538 +5853 526 527 +5859 1799 1804 +5802 5091 5096 +5814 5096 5102 +5816 5049 5054 +5862 5101 5106 +5865 5206 5213 +5887 6878 6885 +5901 431 432 +5932 633 634 +5970 341 432 +5992 529 534 +5932 5102 5218 +5966 5103 5223 +6089 2051 2166 +6092 5217 5220 +6574 418 419 +6597 4707 4714 +6640 334 335 +6664 4701 4708 +6773 4713 4720 +6791 4477 4582 +6753 5984 5991 +6773 5991 6110 +6845 534 635 +6812 4689 4696 +6824 4576 4583 +6828 4476 4483 +6854 4586 4695 +6953 6882 6886 +7017 522 616 +7051 2397 2401 +7009 7262 7340 +7033 5865 5866 +7050 6984 6985 +7092 5608 5615 +7114 1282 1399 +7170 5852 5860 +7249 426 427 +7296 979 1087 +7247 5864 5871 +7399 2401 2406 +7387 5048 5054 +7448 1406 1407 +7427 2400 2406 +7443 2406 2518 +7442 4938 5052 +7496 4823 4930 diff --git a/examples/bpm/impact/in.bpm.impact.rotational b/examples/bpm/impact/in.bpm.impact.rotational new file mode 100644 index 0000000000..698fa22fb8 --- /dev/null +++ b/examples/bpm/impact/in.bpm.impact.rotational @@ -0,0 +1,51 @@ +units lj +dimension 3 +boundary f f f +atom_style bpm/sphere +special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0 +newton on off +comm_modify vel yes cutoff 2.6 +lattice fcc 1.0 +region box block -25 15 -22 22 -22 22 +create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50 + +region disk cylinder x 0.0 0.0 20.0 -0.5 0.5 +create_atoms 1 region disk +group plate region disk + +region ball sphere 8.0 0.0 0.0 6.0 +create_atoms 1 region ball +group projectile region ball + +displace_atoms all random 0.1 0.1 0.1 134598738 + +neighbor 1.0 bin +pair_style gran/hooke/history 1.0 NULL 0.5 NULL 0.1 1 +pair_coeff 1 1 + +fix 1 all nve/bpm/sphere + +create_bonds many plate plate 1 0.0 1.5 +create_bonds many projectile projectile 2 0.0 1.5 + +neighbor 0.3 bin +special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0 + +bond_style bpm/rotational store/local brkbond 100 time id1 id2 +bond_coeff 1 1.0 0.2 0.02 0.02 0.05 0.01 0.01 0.01 0.1 0.2 0.002 0.002 +bond_coeff 2 1.0 0.2 0.02 0.02 0.20 0.04 0.04 0.04 0.1 0.2 0.002 0.002 + +velocity projectile set -0.05 0.0 0.0 +compute nbond all nbond/atom +compute tbond all reduce sum c_nbond + +timestep 0.05 +thermo_style custom step ke pe pxx pyy pzz c_tbond +thermo 100 +thermo_modify lost ignore lost/bond ignore +#dump 1 all custom 100 atomDump id radius x y z c_nbond + +dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3] +dump_modify 2 header no + +run 7500 diff --git a/examples/bpm/impact/in.bpm.impact.spring b/examples/bpm/impact/in.bpm.impact.spring new file mode 100644 index 0000000000..7c5c56841b --- /dev/null +++ b/examples/bpm/impact/in.bpm.impact.spring @@ -0,0 +1,53 @@ +units lj +dimension 3 +boundary f f f +atom_style bond +special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0 +newton on off +comm_modify vel yes cutoff 2.6 +lattice fcc 1.0 +region box block -25 15 -22 22 -22 22 +create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50 + +region disk cylinder x 0.0 0.0 20.0 -0.5 0.5 +create_atoms 1 region disk +group plate region disk + +region ball sphere 8.0 0.0 0.0 6.0 +create_atoms 1 region ball +group projectile region ball + +displace_atoms all random 0.1 0.1 0.1 134598738 + +mass 1 1.0 + +neighbor 1.0 bin +pair_style bpm/spring +pair_coeff 1 1 1.0 1.0 1.0 + +fix 1 all nve + +create_bonds many plate plate 1 0.0 1.5 +create_bonds many projectile projectile 2 0.0 1.5 + +neighbor 0.3 bin +special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0 + +bond_style bpm/spring store/local brkbond 100 time id1 id2 +bond_coeff 1 1.0 0.04 1.0 +bond_coeff 2 1.0 0.20 1.0 + +velocity projectile set -0.05 0.0 0.0 +compute nbond all nbond/atom +compute tbond all reduce sum c_nbond + +timestep 0.1 +thermo_style custom step ke pe pxx pyy pzz c_tbond +thermo 100 +thermo_modify lost ignore lost/bond ignore +#dump 1 all custom 100 atomDump id x y z c_nbond + +dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3] +dump_modify 2 header no + +run 7500 diff --git a/examples/bpm/impact/log.17Feb2022.impact.rotational.g++.4 b/examples/bpm/impact/log.17Feb2022.impact.rotational.g++.4 new file mode 100644 index 0000000000..b76854d5d9 --- /dev/null +++ b/examples/bpm/impact/log.17Feb2022.impact.rotational.g++.4 @@ -0,0 +1,219 @@ +LAMMPS (17 Feb 2022) +units lj +dimension 3 +boundary f f f +atom_style bpm/sphere +special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0 +newton on off +comm_modify vel yes cutoff 2.6 +lattice fcc 1.0 +Lattice spacing in x,y,z = 1.5874011 1.5874011 1.5874011 +region box block -25 15 -22 22 -22 22 +create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50 +Created orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823) + 1 by 2 by 2 MPI processor grid + +region disk cylinder x 0.0 0.0 20.0 -0.5 0.5 +create_atoms 1 region disk +Created 7529 atoms + using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823) + create_atoms CPU = 0.002 seconds +group plate region disk +7529 atoms in group plate + +region ball sphere 8.0 0.0 0.0 6.0 +create_atoms 1 region ball +Created 3589 atoms + using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823) + create_atoms CPU = 0.001 seconds +group projectile region ball +3589 atoms in group projectile + +displace_atoms all random 0.1 0.1 0.1 134598738 +Displacing atoms ... + +neighbor 1.0 bin +pair_style gran/hooke/history 1.0 NULL 0.5 NULL 0.1 1 +pair_coeff 1 1 + +fix 1 all nve/bpm/sphere + +create_bonds many plate plate 1 0.0 1.5 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2 + ghost atom cutoff = 2.6 + binsize = 1, bins = 64 70 70 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) command create_bonds, occasional + attributes: full, newton on + pair build: full/bin + stencil: full/bin/3d + bin: standard + (2) pair gran/hooke/history, perpetual + attributes: half, newton on, size, history + pair build: half/size/bin/newton + stencil: half/bin/3d + bin: standard +Added 38559 bonds, new total = 38559 +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 15 = max # of 1-2 neighbors + 101 = max # of special neighbors + special bonds CPU = 0.001 seconds +create_bonds many projectile projectile 2 0.0 1.5 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Bonds are defined but no bond style is set (../force.cpp:192) +WARNING: Likewise 1-2 special neighbor interactions != 1.0 (../force.cpp:194) +Added 21869 bonds, new total = 60428 +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 16 = max # of 1-2 neighbors + 101 = max # of special neighbors + special bonds CPU = 0.001 seconds + +neighbor 0.3 bin +special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0 + +bond_style bpm/rotational store/local brkbond 100 time id1 id2 +bond_coeff 1 1.0 0.2 0.02 0.02 0.05 0.01 0.01 0.01 0.1 0.2 0.002 0.002 +bond_coeff 2 1.0 0.2 0.02 0.02 0.20 0.04 0.04 0.04 0.1 0.2 0.002 0.002 + +velocity projectile set -0.05 0.0 0.0 +compute nbond all nbond/atom +compute tbond all reduce sum c_nbond + +timestep 0.05 +thermo_style custom step ke pe pxx pyy pzz c_tbond +thermo 100 +thermo_modify lost ignore lost/bond ignore +#dump 1 all custom 100 atomDump id radius x y z c_nbond + +dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3] +dump_modify 2 header no + +run 7500 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 2.6 + binsize = 0.65, bins = 98 108 108 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair gran/hooke/history, perpetual + attributes: half, newton on, size, history + pair build: half/size/bin/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 33.34 | 33.34 | 33.35 Mbytes +Step KinEng PotEng Pxx Pyy Pzz c_tbond + 0 0.00053238861 0 3.8217307e-05 0 0 10.8703 + 100 0.00053238861 0 3.8217307e-05 1.2166373e-20 1.2308212e-20 10.8703 + 200 0.00053238861 0 3.8217307e-05 1.2454467e-20 1.2479589e-20 10.8703 + 300 0.00053238861 0 3.8217307e-05 1.2256702e-20 1.2621091e-20 10.8703 + 400 0.00053238861 0 3.8217307e-05 1.2170534e-20 1.2751666e-20 10.8703 + 500 0.00053093549 0 3.8484194e-05 7.645531e-08 1.4861825e-07 10.8703 + 600 0.00051485902 0 4.0340751e-05 3.8615876e-07 4.8663463e-07 10.869221 + 700 0.00049942978 0 3.8684008e-05 4.5363318e-07 4.4560229e-07 10.85501 + 800 0.00049465262 0 3.6604612e-05 1.4755468e-07 2.0062093e-07 10.820651 + 900 0.00048784775 0 3.5333139e-05 3.5118328e-07 6.6697625e-07 10.769563 + 1000 0.00048345699 0 3.4702137e-05 7.0312998e-07 4.0218318e-07 10.730347 + 1100 0.00047945073 0 3.5065961e-05 6.2813891e-07 7.4640359e-07 10.703184 + 1200 0.00047512604 0 3.4833144e-05 8.5208604e-07 8.7277583e-07 10.686634 + 1300 0.00047401428 0 3.4236869e-05 1.0321827e-06 7.4545242e-07 10.678 + 1400 0.00047619121 0 3.4416549e-05 8.7518021e-07 7.3979503e-07 10.671704 + 1500 0.0004668728 0 3.4495751e-05 1.4077823e-06 1.517373e-06 10.666127 + 1600 0.00045088371 0 3.3264301e-05 1.8499661e-06 1.9842415e-06 10.66073 + 1700 0.00044275099 0 3.2471064e-05 1.9028747e-06 2.2248947e-06 10.6458 + 1800 0.0004424362 0 3.1846336e-05 1.6208492e-06 1.9291602e-06 10.620615 + 1900 0.00043678957 0 3.1260936e-05 1.4673956e-06 1.6120523e-06 10.603166 + 2000 0.00042747562 0 3.0652107e-05 1.6455486e-06 1.53127e-06 10.576003 + 2100 0.0004214344 0 3.0240727e-05 1.8873967e-06 1.5258622e-06 10.539845 + 2200 0.00041712779 0 3.0329566e-05 1.8846152e-06 1.4971471e-06 10.49937 + 2300 0.00041095769 0 3.0000572e-05 2.3585924e-06 1.6773177e-06 10.471668 + 2400 0.00040883568 0 2.9625158e-05 1.9105554e-06 1.8720763e-06 10.45116 + 2500 0.00040762685 0 2.9441541e-05 1.6848938e-06 1.8877532e-06 10.437309 + 2600 0.00040579873 0 2.9255988e-05 1.7523874e-06 1.636423e-06 10.422378 + 2700 0.00040340975 0 2.9035693e-05 1.673158e-06 1.9038932e-06 10.410505 + 2800 0.00040170914 0 2.8829361e-05 1.6711978e-06 1.9776001e-06 10.400792 + 2900 0.00040015113 0 2.8614186e-05 1.5982427e-06 1.7994733e-06 10.393416 + 3000 0.00040029253 0 2.8470718e-05 1.5589166e-06 1.6682302e-06 10.385321 + 3100 0.00040037329 0 2.8483376e-05 1.2831526e-06 1.4788005e-06 10.378485 + 3200 0.00040142612 0 2.8481287e-05 1.1577988e-06 1.3495778e-06 10.373988 + 3300 0.00040105092 0 2.8547009e-05 1.2155138e-06 1.2633439e-06 10.370031 + 3400 0.00039950673 0 2.8340939e-05 1.1182251e-06 1.1624668e-06 10.364274 + 3500 0.00039715236 0 2.824813e-05 1.3086462e-06 1.2029185e-06 10.360496 + 3600 0.00039446552 0 2.8112283e-05 1.1232321e-06 1.0077217e-06 10.353121 + 3700 0.00039263296 0 2.7927975e-05 1.1083636e-06 1.2091857e-06 10.346645 + 3800 0.00039061341 0 2.7819957e-05 1.1836841e-06 1.3566272e-06 10.341069 + 3900 0.00038985051 0 2.7681947e-05 1.3588359e-06 1.4099727e-06 10.329196 + 4000 0.00038815347 0 2.7492102e-05 1.1111719e-06 1.1700718e-06 10.318043 + 4100 0.00038651302 0 2.7444105e-05 9.9563429e-07 1.4085969e-06 10.311027 + 4200 0.00038565809 0 2.7177341e-05 9.5736307e-07 1.0404482e-06 10.299155 + 4300 0.0003847255 0 2.7029216e-05 9.6204756e-07 1.140804e-06 10.292319 + 4400 0.0003844421 0 2.6841047e-05 9.6570404e-07 1.2319818e-06 10.286203 + 4500 0.0003842788 0 2.6633558e-05 9.6452478e-07 1.1954945e-06 10.278287 + 4600 0.00038365139 0 2.6514403e-05 9.6185846e-07 1.2002452e-06 10.270732 + 4700 0.00038271503 0 2.6374349e-05 9.4061833e-07 1.1774211e-06 10.264796 + 4800 0.00038233688 0 2.638398e-05 1.1644119e-06 1.3746239e-06 10.25742 + 4900 0.00038223496 0 2.6279821e-05 1.1345508e-06 1.4709213e-06 10.246987 + 5000 0.00038219402 0 2.6188871e-05 1.0115151e-06 1.2024203e-06 10.240511 + 5100 0.00038195153 0 2.6137945e-05 1.009856e-06 1.1961088e-06 10.236014 + 5200 0.00038170903 0 2.6103563e-05 1.0046761e-06 1.1881008e-06 10.232236 + 5300 0.00038194303 0 2.6111938e-05 1.0533375e-06 1.2621634e-06 10.230617 + 5400 0.00038147407 0 2.6078641e-05 1.082228e-06 1.2915223e-06 10.230098 + 5500 0.00038156894 0 2.6084488e-05 1.1395485e-06 1.3592644e-06 10.227759 + 5600 0.00038169434 0 2.6085704e-05 1.1173618e-06 1.3003599e-06 10.2256 + 5700 0.00038219734 0 2.6095279e-05 1.1026614e-06 1.280455e-06 10.223621 + 5800 0.00038268758 0 2.6113437e-05 1.1096198e-06 1.2565503e-06 10.222902 + 5900 0.00038300658 0 2.6131709e-05 1.1123595e-06 1.235992e-06 10.222182 + 6000 0.00038250316 0 2.606995e-05 1.1590744e-06 1.2888416e-06 10.221123 + 6100 0.0003821526 0 2.6025605e-05 1.1434025e-06 1.3141861e-06 10.219503 + 6200 0.00038185711 0 2.5991255e-05 1.1471391e-06 1.3427373e-06 10.219503 + 6300 0.00038197679 0 2.5996965e-05 1.1338082e-06 1.3315258e-06 10.218604 + 6400 0.00038232311 0 2.6035805e-05 1.1353407e-06 1.3306683e-06 10.217884 + 6500 0.00038255543 0 2.6091572e-05 1.1768703e-06 1.3629611e-06 10.217704 + 6600 0.00038251887 0 2.6068968e-05 1.1808094e-06 1.3969697e-06 10.217344 + 6700 0.00038177389 0 2.6004288e-05 1.1659866e-06 1.423638e-06 10.218084 + 6800 0.00038096291 0 2.5969494e-05 1.1377343e-06 1.4348787e-06 10.218103 + 6900 0.00038090601 0 2.5951546e-05 1.1327767e-06 1.4311663e-06 10.217024 + 7000 0.00038088094 0 2.5946255e-05 1.1652568e-06 1.4567559e-06 10.215944 + 7100 0.00038094624 0 2.5972593e-05 1.1558871e-06 1.4692935e-06 10.214684 + 7200 0.00038168738 0 2.6002e-05 1.1562707e-06 1.4881081e-06 10.212705 + 7300 0.00038200854 0 2.6038768e-05 1.1339903e-06 1.4808455e-06 10.212345 + 7400 0.00038187543 0 2.6044759e-05 1.101743e-06 1.4758679e-06 10.213084 + 7500 0.00038165297 0 2.6004536e-05 1.0892731e-06 1.4872621e-06 10.214742 +Loop time of 28.804 on 4 procs for 7500 steps with 11111 atoms + +Performance: 1124843.305 tau/day, 260.380 timesteps/s +97.5% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.26977 | 0.28058 | 0.2866 | 1.3 | 0.97 +Bond | 22.742 | 23.598 | 24.671 | 16.6 | 81.92 +Neigh | 0.54555 | 0.5728 | 0.60272 | 3.2 | 1.99 +Comm | 1.4024 | 2.5619 | 3.5079 | 54.8 | 8.89 +Output | 0.025307 | 0.025833 | 0.027022 | 0.4 | 0.09 +Modify | 1.592 | 1.6506 | 1.7059 | 4.0 | 5.73 +Other | | 0.1147 | | | 0.40 + +Nlocal: 2777.75 ave 2887 max 2682 min +Histogram: 1 0 0 0 2 0 0 0 0 1 +Nghost: 1152.5 ave 1189 max 1125 min +Histogram: 1 0 1 0 0 1 0 0 0 1 +Neighs: 11515.5 ave 12520 max 10831 min +Histogram: 1 1 0 0 1 0 0 0 0 1 + +Total # of neighbors = 46062 +Ave neighs/atom = 4.1456215 +Ave special neighs/atom = 10.214742 +Neighbor list builds = 408 +Dangerous builds = 0 +Total wall time: 0:00:28 diff --git a/examples/bpm/impact/log.17Feb2022.impact.spring.g++.4 b/examples/bpm/impact/log.17Feb2022.impact.spring.g++.4 new file mode 100644 index 0000000000..9b11f62b88 --- /dev/null +++ b/examples/bpm/impact/log.17Feb2022.impact.spring.g++.4 @@ -0,0 +1,221 @@ +LAMMPS (17 Feb 2022) +units lj +dimension 3 +boundary f f f +atom_style bond +special_bonds lj 0.0 1.0 1.0 coul 0.0 1.0 1.0 +newton on off +comm_modify vel yes cutoff 2.6 +lattice fcc 1.0 +Lattice spacing in x,y,z = 1.5874011 1.5874011 1.5874011 +region box block -25 15 -22 22 -22 22 +create_box 1 box bond/types 2 extra/bond/per/atom 20 extra/special/per/atom 50 +Created orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823) + 1 by 2 by 2 MPI processor grid + +region disk cylinder x 0.0 0.0 20.0 -0.5 0.5 +create_atoms 1 region disk +Created 7529 atoms + using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823) + create_atoms CPU = 0.001 seconds +group plate region disk +7529 atoms in group plate + +region ball sphere 8.0 0.0 0.0 6.0 +create_atoms 1 region ball +Created 3589 atoms + using lattice units in orthogonal box = (-39.685026 -34.922823 -34.922823) to (23.811016 34.922823 34.922823) + create_atoms CPU = 0.000 seconds +group projectile region ball +3589 atoms in group projectile + +displace_atoms all random 0.1 0.1 0.1 134598738 +Displacing atoms ... + +mass 1 1.0 + +neighbor 1.0 bin +pair_style bpm/spring +pair_coeff 1 1 1.0 1.0 1.0 + +fix 1 all nve + +create_bonds many plate plate 1 0.0 1.5 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2 + ghost atom cutoff = 2.6 + binsize = 1, bins = 64 70 70 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) command create_bonds, occasional + attributes: full, newton on + pair build: full/bin + stencil: full/bin/3d + bin: standard + (2) pair bpm/spring, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +Added 38559 bonds, new total = 38559 +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 15 = max # of 1-2 neighbors + 101 = max # of special neighbors + special bonds CPU = 0.001 seconds +create_bonds many projectile projectile 2 0.0 1.5 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Bonds are defined but no bond style is set (../force.cpp:192) +WARNING: Likewise 1-2 special neighbor interactions != 1.0 (../force.cpp:194) +Added 21869 bonds, new total = 60428 +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 16 = max # of 1-2 neighbors + 101 = max # of special neighbors + special bonds CPU = 0.001 seconds + +neighbor 0.3 bin +special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0 + +bond_style bpm/spring store/local brkbond 100 time id1 id2 +bond_coeff 1 1.0 0.04 1.0 +bond_coeff 2 1.0 0.20 1.0 + +velocity projectile set -0.05 0.0 0.0 +compute nbond all nbond/atom +compute tbond all reduce sum c_nbond + +timestep 0.1 +thermo_style custom step ke pe pxx pyy pzz c_tbond +thermo 100 +thermo_modify lost ignore lost/bond ignore +#dump 1 all custom 100 atomDump id x y z c_nbond + +dump 2 all local 100 brokenDump f_brkbond[1] f_brkbond[2] f_brkbond[3] +dump_modify 2 header no + +run 7500 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 2.6 + binsize = 0.65, bins = 98 108 108 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair bpm/spring, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 17.74 | 17.74 | 17.74 Mbytes +Step KinEng PotEng Pxx Pyy Pzz c_tbond + 0 0.0010167873 0 7.298968e-05 0 0 10.8703 + 100 0.0010167873 0 7.298968e-05 -8.7429897e-20 -8.8470837e-20 10.8703 + 200 0.0010167873 0 7.298968e-05 -7.2809565e-20 -8.0915788e-20 10.8703 + 300 0.0009951439 0 9.9273671e-05 8.1569216e-06 8.0922512e-06 10.868142 + 400 0.00095142792 0 0.00012669557 -1.3413721e-05 -1.4800745e-05 10.849793 + 500 0.00092272662 0 8.1708784e-05 -9.7488701e-06 -1.3603634e-05 10.819752 + 600 0.00088967612 0 6.2587266e-05 -5.1954127e-06 -6.781587e-06 10.797985 + 700 0.00086070919 0 8.8529902e-05 -9.9431205e-06 -7.9905211e-06 10.776579 + 800 0.00083543943 0 7.5920357e-05 3.6381024e-07 3.7747551e-06 10.759309 + 900 0.00081190799 0 6.3678219e-05 5.4158243e-06 1.2751247e-05 10.744199 + 1000 0.00078828988 0 7.3079869e-05 -6.6410613e-06 -1.198683e-06 10.728368 + 1100 0.00075664718 0 6.2976995e-05 -4.7863299e-06 -3.9814556e-06 10.711819 + 1200 0.00072472205 0 4.9680233e-05 9.3093553e-06 4.4426393e-06 10.69401 + 1300 0.00070176532 0 5.4048176e-05 1.3051954e-05 7.5448558e-06 10.671164 + 1400 0.00068599319 0 5.4062404e-05 9.9930199e-06 1.0353154e-05 10.650117 + 1500 0.0006786164 0 4.5038593e-05 8.067571e-06 9.8825461e-06 10.636266 + 1600 0.00067466823 0 4.6733251e-05 9.8595584e-06 1.1551081e-05 10.621335 + 1700 0.00066847126 0 5.1472453e-05 2.1569974e-07 6.0070599e-06 10.6127 + 1800 0.00065711827 0 5.0355189e-05 -8.030203e-06 -3.1395588e-06 10.599568 + 1900 0.00063882539 0 4.7146888e-05 -2.0596242e-05 -1.6494542e-05 10.581939 + 2000 0.00061717894 0 4.6698781e-05 -2.5473048e-05 -2.7703615e-05 10.567188 + 2100 0.00059261327 0 3.7701055e-05 -2.4637803e-05 -3.3919162e-05 10.552617 + 2200 0.00056527158 0 3.2239421e-05 -1.8786685e-05 -2.4202734e-05 10.538406 + 2300 0.00054054919 0 2.7410334e-05 -6.701111e-06 -7.4354974e-06 10.520777 + 2400 0.00051820065 0 2.2997206e-05 1.5623767e-05 1.8687824e-05 10.501889 + 2500 0.00049647925 0 1.746693e-05 2.8814144e-05 3.5569425e-05 10.487498 + 2600 0.00047837258 0 1.4127067e-05 3.4245611e-05 4.0208577e-05 10.472387 + 2700 0.00046626924 0 1.3714876e-05 3.7922196e-05 4.1550346e-05 10.456377 + 2800 0.0004560167 0 1.5260976e-05 3.5632577e-05 3.7885738e-05 10.440007 + 2900 0.00045331059 0 1.5194832e-05 3.1036124e-05 2.8633755e-05 10.427955 + 3000 0.00045227799 0 1.4877378e-05 1.9327028e-05 2.1189487e-05 10.414283 + 3100 0.00044866178 0 2.0424612e-05 -2.7242288e-06 7.7121438e-06 10.40349 + 3200 0.00044336453 0 2.3276121e-05 -1.979069e-05 -4.2311089e-06 10.395575 + 3300 0.00043526526 0 2.3338132e-05 -2.834945e-05 -1.7302033e-05 10.389998 + 3400 0.00042817758 0 2.4374527e-05 -2.9870076e-05 -3.0623264e-05 10.382803 + 3500 0.00042182658 0 2.6120627e-05 -2.9449521e-05 -3.787776e-05 10.378126 + 3600 0.00041794291 0 2.4736957e-05 -2.4098172e-05 -3.0529166e-05 10.373628 + 3700 0.0004156005 0 2.7543305e-05 -1.2431749e-05 -1.8626096e-05 10.37075 + 3800 0.0004141461 0 2.4630482e-05 -6.345489e-06 -1.7375803e-05 10.368771 + 3900 0.00041328832 0 2.2220142e-05 4.1471034e-07 -1.3339476e-05 10.366972 + 4000 0.00041121725 0 2.3491321e-05 1.1284551e-05 -5.8651834e-06 10.364634 + 4100 0.00040761876 0 2.6688248e-05 1.9721625e-05 3.7536871e-06 10.362655 + 4200 0.00040301362 0 2.7601916e-05 1.9212118e-05 9.7175996e-06 10.359417 + 4300 0.00040001545 0 2.7243769e-05 1.6889359e-05 1.1857147e-05 10.3551 + 4400 0.00039654521 0 2.561083e-05 1.3863551e-05 1.0593597e-05 10.351142 + 4500 0.00039435924 0 2.4366458e-05 1.2545563e-05 1.1323962e-05 10.348804 + 4600 0.00039250006 0 2.3719127e-05 1.1015167e-05 8.5964046e-06 10.348444 + 4700 0.00039145496 0 2.2943915e-05 8.7824224e-06 5.0397129e-06 10.346825 + 4800 0.00039105331 0 2.4005757e-05 7.5899773e-06 9.033741e-07 10.344846 + 4900 0.0003898798 0 2.3819433e-05 4.9673894e-06 -2.3466459e-06 10.343587 + 5000 0.00038747508 0 2.3605028e-05 -1.1717437e-06 -6.1096657e-06 10.343047 + 5100 0.00038549022 0 2.3453798e-05 -9.9256693e-06 -9.3584148e-06 10.341788 + 5200 0.00038283936 0 2.5243567e-05 -1.5877598e-05 -9.9474447e-06 10.340169 + 5300 0.00038140888 0 2.5522223e-05 -1.9331435e-05 -1.1067039e-05 10.33873 + 5400 0.00037916674 0 2.5181488e-05 -2.1581255e-05 -1.1252641e-05 10.336931 + 5500 0.00037782932 0 2.691805e-05 -1.5768241e-05 -5.6704695e-06 10.334952 + 5600 0.00037628832 0 2.5851445e-05 -1.4239811e-05 -1.9122536e-06 10.333153 + 5700 0.00037451913 0 2.4758416e-05 -1.3252284e-05 -1.9222041e-06 10.331714 + 5800 0.00037328662 0 2.2507032e-05 -9.6704092e-06 -7.5470215e-06 10.330095 + 5900 0.00037253111 0 2.3303086e-05 -4.2828034e-06 -7.888056e-06 10.328476 + 6000 0.00037171133 0 2.4042456e-05 -4.7684985e-06 -6.5164336e-06 10.327397 + 6100 0.00036986726 0 2.4938695e-05 -4.8738316e-06 -4.5380007e-06 10.327037 + 6200 0.0003675822 0 2.3322229e-05 -4.6333093e-06 -5.7086464e-06 10.327037 + 6300 0.00036552389 0 2.1435354e-05 -4.8971566e-06 -3.5935426e-06 10.327037 + 6400 0.00036488091 0 2.0813994e-05 -3.8333319e-06 -3.6595059e-06 10.327037 + 6500 0.00036447973 0 2.2241876e-05 8.7797361e-08 -4.141203e-06 10.327037 + 6600 0.00036383343 0 2.269485e-05 4.9364593e-06 1.3062133e-06 10.326677 + 6700 0.00036305076 0 2.1838759e-05 6.4587048e-06 4.7758772e-06 10.326318 + 6800 0.00036226601 0 2.2916622e-05 6.044926e-06 5.0291597e-06 10.325598 + 6900 0.00036175279 0 2.2691667e-05 6.9998847e-06 5.8988637e-06 10.324699 + 7000 0.00036143633 0 2.1725813e-05 8.1268152e-06 5.0390503e-06 10.324519 + 7100 0.0003610248 0 2.1799675e-05 8.65795e-06 3.1360368e-06 10.323439 + 7200 0.00036086259 0 2.2198029e-05 5.1764734e-06 5.4798783e-07 10.32308 + 7300 0.00036099757 0 2.4160496e-05 1.0310325e-06 -5.115075e-07 10.32254 + 7400 0.00036129334 0 2.5325018e-05 -9.4918158e-07 -1.7064957e-06 10.32218 + 7500 0.00036136655 0 2.3513198e-05 -3.8618451e-06 -4.4344772e-06 10.321281 +Loop time of 4.51074 on 4 procs for 7500 steps with 11118 atoms + +Performance: 14365719.597 tau/day, 1662.699 timesteps/s +93.8% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.25733 | 0.26952 | 0.28068 | 1.6 | 5.98 +Bond | 1.9391 | 2.0128 | 2.0851 | 3.7 | 44.62 +Neigh | 0.56308 | 0.5941 | 0.62077 | 2.8 | 13.17 +Comm | 0.68282 | 0.80856 | 0.94406 | 10.7 | 17.93 +Output | 0.19287 | 0.1933 | 0.19426 | 0.1 | 4.29 +Modify | 0.53239 | 0.55343 | 0.57349 | 2.0 | 12.27 +Other | | 0.07902 | | | 1.75 + +Nlocal: 2779.5 ave 2862 max 2686 min +Histogram: 1 0 0 0 0 1 1 0 0 1 +Nghost: 1183.25 ave 1220 max 1134 min +Histogram: 1 0 0 0 1 0 0 0 1 1 +Neighs: 11828.8 ave 12387 max 11053 min +Histogram: 1 0 0 0 1 0 0 0 1 1 + +Total # of neighbors = 47315 +Ave neighs/atom = 4.2557115 +Ave special neighs/atom = 10.321461 +Neighbor list builds = 421 +Dangerous builds = 11 +Total wall time: 0:00:04 diff --git a/examples/bpm/pour/in.bpm.pour b/examples/bpm/pour/in.bpm.pour new file mode 100644 index 0000000000..e4cc8557a3 --- /dev/null +++ b/examples/bpm/pour/in.bpm.pour @@ -0,0 +1,35 @@ +units lj +dimension 3 +boundary m m m +atom_style bpm/sphere +special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0 +newton on off +comm_modify vel yes cutoff 3.3 +region box block -15 15 -15 15 0 60.0 +create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50 + +molecule my_mol "rect.mol" +region wall_cyl cylinder z 0.0 0.0 10.0 EDGE EDGE side in +region dropzone cylinder z 0.0 0.0 10.0 40.0 50.0 side in + +pair_style gran/hertz/history 1.0 NULL 0.5 NULL 0.1 1 +bond_style bpm/rotational +pair_coeff 1 1 +bond_coeff 1 1.0 0.2 0.01 0.01 2.0 0.4 0.02 0.02 0.2 0.04 0.002 0.002 + +compute nbond all nbond/atom +compute tbond all reduce sum c_nbond +compute_modify thermo_temp dynamic/dof yes + +fix 1 all wall/gran hertz/history 1.0 NULL 0.5 NULL 0.1 1 zplane 0.0 NULL +fix 2 all wall/gran/region hertz/history 1.0 NULL 0.5 NULL 0.1 1 region wall_cyl +fix 3 all gravity 1e-4 vector 0 0 -1 +fix 4 all deposit 40 0 1500 712511343 mol my_mol region dropzone near 2.0 vz -0.05 -0.05 +fix 5 all nve/bpm/sphere + +timestep 0.05 +thermo_style custom step ke pe pxx pyy pzz c_tbond +thermo 100 +#dump 1 all custom 500 atomDump id radius x y z c_nbond mol + +run 100000 diff --git a/examples/bpm/pour/log.17Feb2022.pour.g++.4 b/examples/bpm/pour/log.17Feb2022.pour.g++.4 new file mode 100644 index 0000000000..a61c0f1181 --- /dev/null +++ b/examples/bpm/pour/log.17Feb2022.pour.g++.4 @@ -0,0 +1,1091 @@ +LAMMPS (17 Feb 2022) +units lj +dimension 3 +boundary m m m +atom_style bpm/sphere +special_bonds lj 0.0 1.0 1.0 coul 1.0 1.0 1.0 +newton on off +comm_modify vel yes cutoff 3.3 +region box block -15 15 -15 15 0 60.0 +create_box 1 box bond/types 1 extra/bond/per/atom 15 extra/special/per/atom 50 +Created orthogonal box = (-15 -15 0) to (15 15 60) + 1 by 1 by 4 MPI processor grid + +molecule my_mol "rect.mol" +Read molecule template my_mol: + 1 molecules + 0 fragments + 63 atoms with max type 1 + 297 bonds with max type 1 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +region wall_cyl cylinder z 0.0 0.0 10.0 EDGE EDGE side in +region dropzone cylinder z 0.0 0.0 10.0 40.0 50.0 side in + +pair_style gran/hertz/history 1.0 NULL 0.5 NULL 0.1 1 +bond_style bpm/rotational +pair_coeff 1 1 +bond_coeff 1 1.0 0.2 0.01 0.01 2.0 0.4 0.02 0.02 0.2 0.04 0.002 0.002 + +compute nbond all nbond/atom +compute tbond all reduce sum c_nbond +compute_modify thermo_temp dynamic/dof yes + +fix 1 all wall/gran hertz/history 1.0 NULL 0.5 NULL 0.1 1 zplane 0.0 NULL +fix 2 all wall/gran/region hertz/history 1.0 NULL 0.5 NULL 0.1 1 region wall_cyl +fix 3 all gravity 1e-4 vector 0 0 -1 +fix 4 all deposit 40 0 1500 712511343 mol my_mol region dropzone near 2.0 vz -0.05 -0.05 +fix 5 all nve/bpm/sphere + +timestep 0.05 +thermo_style custom step ke pe pxx pyy pzz c_tbond +thermo 100 +#dump 1 all custom 500 atomDump id radius x y z c_nbond mol + +run 100000 + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 3.3 + binsize = 0.65, bins = 47 47 93 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair gran/hertz/history, perpetual + attributes: half, newton on, size, history + pair build: half/size/bin/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.515 | 6.515 | 6.515 Mbytes +Step KinEng PotEng Pxx Pyy Pzz c_tbond + 0 -0 0 0 0 0 0 + 100 0.0018331948 0 2.0050936e-07 1.2082282e-06 2.8712165e-06 9.4285714 + 200 0.0025933558 0 7.3469794e-07 2.0155735e-06 3.3061759e-06 9.4285714 + 300 0.0036964813 0 3.7946479e-07 5.3005435e-06 2.9691719e-06 9.4285714 + 400 0.0060104433 0 1.5778321e-06 8.4396021e-06 4.0232206e-06 9.4285714 + 500 0.0074435972 0 1.6102287e-06 1.1551491e-05 4.2257246e-06 9.4285714 + 600 0.0077862298 0 1.048357e-06 1.3758458e-05 3.3770448e-06 9.4285714 + 700 0.0075577591 0 1.1527593e-06 1.2533681e-05 3.9545936e-06 9.4285714 + 800 0.0073958844 0 1.1164823e-06 1.2917327e-05 3.2263757e-06 9.4285714 + 900 0.007553697 0 1.190904e-06 1.3294768e-05 3.1421027e-06 9.4285714 + 1000 0.0075815901 0 1.0181785e-06 1.3265265e-05 3.4107996e-06 9.4285714 + 1100 0.0075277384 0 2.0708356e-06 1.2219251e-05 3.2773337e-06 9.4285714 + 1200 0.0075026507 0 1.8286317e-06 1.2395764e-05 3.2819583e-06 9.4285714 + 1300 0.0075665473 0 1.8498736e-06 1.2455125e-05 3.3519775e-06 9.4285714 + 1400 0.0076224701 0 3.1234422e-06 1.0777609e-05 3.8865172e-06 9.4285714 + 1500 0.007603467 0 2.8536732e-06 1.1077739e-05 3.8107558e-06 9.4285714 + 1600 0.0059810407 0 4.3809396e-06 1.6996767e-05 6.5539764e-06 9.4285714 + 1700 0.0080230318 0 5.7884097e-06 2.4435559e-05 7.2370109e-06 9.4285714 + 1800 0.0087482398 0 5.9323986e-06 2.7190078e-05 7.7151041e-06 9.4285714 + 1900 0.0086877574 0 6.1023555e-06 2.6625737e-05 7.8193078e-06 9.4285714 + 2000 0.0086771118 0 6.1635853e-06 2.633267e-05 8.0008845e-06 9.4285714 + 2100 0.0084670091 0 6.7873752e-06 2.5434046e-05 9.0971224e-06 9.4285714 + 2200 0.0083650907 0 8.1704442e-06 2.3699108e-05 8.4515642e-06 9.4285714 + 2300 0.0083549595 0 8.2648511e-06 2.2510949e-05 8.2508581e-06 9.4285714 + 2400 0.0083151535 0 7.7718631e-06 2.2224878e-05 8.8086351e-06 9.4285714 + 2500 0.0083898757 0 7.1987828e-06 2.2855932e-05 9.1000336e-06 9.4285714 + 2600 0.0084145705 0 6.968992e-06 2.3030741e-05 9.2694955e-06 9.4285714 + 2700 0.0082712696 0 7.5971438e-06 2.3186553e-05 1.026296e-05 9.4285714 + 2800 0.0073688706 0 1.0092165e-05 1.6341178e-05 1.0496887e-05 9.4285714 + 2900 0.0072732669 0 8.9857642e-06 1.454313e-05 1.0637501e-05 9.4285714 + 3000 0.0072225948 0 8.5616417e-06 1.4225089e-05 1.0924921e-05 9.4285714 + 3100 0.0048244969 0 6.912522e-06 1.30395e-05 1.3824006e-05 9.4285714 + 3200 0.0045717035 0 5.7159512e-06 1.1181938e-05 1.5108391e-05 9.4285714 + 3300 0.0047679567 0 6.0163783e-06 1.1603014e-05 1.5759942e-05 9.4285714 + 3400 0.0048448212 0 6.3252851e-06 1.2378054e-05 1.5212593e-05 9.4285714 + 3500 0.0048364711 0 6.4847771e-06 1.2719874e-05 1.4888067e-05 9.4285714 + 3600 0.0047125947 0 7.5131511e-06 1.375252e-05 1.5244253e-05 9.4285714 + 3700 0.0045641049 0 7.3441262e-06 1.2981907e-05 1.5049034e-05 9.4285714 + 3800 0.0045540235 0 6.8443099e-06 1.1748155e-05 1.4685806e-05 9.4285714 + 3900 0.0047271202 0 6.7919886e-06 1.2153009e-05 1.4801772e-05 9.4285714 + 4000 0.0049115261 0 6.9084016e-06 1.2385892e-05 1.5231153e-05 9.4285714 + 4100 0.0046819157 0 6.4190119e-06 1.1228312e-05 1.5132413e-05 9.4285714 + 4200 0.0035133816 0 3.6896921e-06 6.5442286e-06 1.4368405e-05 9.4285714 + 4300 0.0031933917 0 1.9641761e-06 3.4983806e-06 1.6912795e-05 9.4285714 + 4400 0.0033515272 0 2.3967939e-06 4.0160705e-06 1.7056596e-05 9.4285714 + 4500 0.0034928951 0 3.0724834e-06 4.4355514e-06 1.6962392e-05 9.4285714 + 4600 0.0029992338 0 3.319899e-06 4.3436095e-06 2.0334274e-05 9.4285714 + 4700 0.0030650658 0 3.9633397e-06 5.6588274e-06 1.8991224e-05 9.4285714 + 4800 0.0031180382 0 4.925768e-06 6.3708181e-06 1.7810728e-05 9.4285714 + 4900 0.0030365003 0 4.6849771e-06 5.6291872e-06 1.8029418e-05 9.4285714 + 5000 0.0030259714 0 5.1846803e-06 5.5730554e-06 1.7488984e-05 9.4285714 + 5100 0.0030499975 0 5.6322417e-06 5.9148203e-06 1.6923105e-05 9.4285714 + 5200 0.003005436 0 5.6903188e-06 5.6637593e-06 1.6700127e-05 9.4285714 + 5300 0.0030000941 0 5.7591855e-06 5.3398134e-06 1.6904108e-05 9.4285714 + 5400 0.0031465827 0 6.1148362e-06 6.2148373e-06 1.7041724e-05 9.4285714 + 5500 0.0031981585 0 5.8718482e-06 5.9970835e-06 1.7984043e-05 9.4285714 + 5600 0.0031525115 0 5.3390747e-06 5.1610119e-06 1.8924721e-05 9.4285714 + 5700 0.0032128781 0 5.6775112e-06 5.2023225e-06 1.9109577e-05 9.4285714 + 5800 0.0030092855 0 5.7676512e-06 4.4808095e-06 2.1160289e-05 9.4285714 + 5900 0.0025015767 0 6.5110611e-06 5.0853279e-06 2.290709e-05 9.4285714 + 6000 0.0024438438 0 6.4803568e-06 4.9314657e-06 2.1450483e-05 9.4285714 + 6100 0.0023816456 0 4.2004621e-06 4.3412206e-06 2.3366694e-05 9.4285714 + 6200 0.0024459343 0 3.4052114e-06 2.3122757e-06 2.3018902e-05 9.4285714 + 6300 0.0025205884 0 3.0607555e-06 2.7404005e-06 2.3612151e-05 9.4285714 + 6400 0.0033754198 0 5.4041464e-06 1.0129204e-05 2.3881911e-05 9.4285714 + 6500 0.0037812296 0 6.9287106e-06 1.2845513e-05 2.4385157e-05 9.4285714 + 6600 0.0038043567 0 4.4366794e-06 1.559564e-05 2.4372156e-05 9.4285714 + 6700 0.0038213959 0 5.6461713e-06 1.6081939e-05 2.556403e-05 9.4285714 + 6800 0.0036977776 0 6.1083638e-06 1.3260883e-05 2.8030458e-05 9.4285714 + 6900 0.0034769765 0 4.281986e-06 1.4287795e-05 2.803258e-05 9.4285714 + 7000 0.0031526409 0 4.8687091e-06 1.1290097e-05 2.9635973e-05 9.4285714 + 7100 0.00317737 0 4.866629e-06 9.8108506e-06 3.1076433e-05 9.4285714 + 7200 0.0034448361 0 4.6533797e-06 1.15597e-05 3.0195614e-05 9.4285714 + 7300 0.0036147362 0 3.4867601e-06 1.2192841e-05 3.0431851e-05 9.4285714 + 7400 0.0035651675 0 2.812314e-06 1.0900977e-05 2.9422055e-05 9.4285714 + 7500 0.0036394064 0 2.6684242e-06 1.038371e-05 2.9650533e-05 9.4285714 + 7600 0.0033086177 0 2.6357178e-06 1.0363505e-05 3.3327311e-05 9.4285714 + 7700 0.0033410425 0 3.9955363e-06 9.2059943e-06 3.3580724e-05 9.4285714 + 7800 0.0035764747 0 7.127102e-06 8.9311151e-06 3.402089e-05 9.4285714 + 7900 0.0039500913 0 1.1222589e-05 9.0137729e-06 3.5074285e-05 9.4285714 + 8000 0.0042963353 0 1.5982303e-05 8.4904673e-06 3.5704562e-05 9.4285714 + 8100 0.0048297614 0 2.2809259e-05 7.6782291e-06 3.714467e-05 9.4285714 + 8200 0.0052301447 0 2.8015774e-05 6.9131186e-06 3.8310186e-05 9.4285714 + 8300 0.005169511 0 2.8580467e-05 6.1476914e-06 3.7651259e-05 9.4285714 + 8400 0.005224324 0 2.9402221e-05 5.0117679e-06 3.873174e-05 9.4285714 + 8500 0.0053049309 0 3.0666777e-05 4.125785e-06 3.9482985e-05 9.4285714 + 8600 0.0052459952 0 3.0525628e-05 4.1952646e-06 3.8726938e-05 9.4285714 + 8700 0.0052955657 0 3.0177531e-05 5.0224986e-06 3.8941323e-05 9.4285714 + 8800 0.0053972257 0 3.1021226e-05 5.261711e-06 3.9283466e-05 9.4285714 + 8900 0.0053679679 0 3.1133172e-05 4.9109387e-06 3.9111316e-05 9.4285714 + 9000 0.0053793586 0 3.0629197e-05 5.8147275e-06 3.8870113e-05 9.4285714 + 9100 0.0048447626 0 3.0571485e-05 6.6542996e-06 4.1908678e-05 9.4285714 + 9200 0.0048688926 0 3.0874982e-05 6.5780749e-06 4.2143302e-05 9.4285714 + 9300 0.0048538957 0 3.0564193e-05 8.1762092e-06 4.2503239e-05 9.4285714 + 9400 0.0046986454 0 2.8378911e-05 1.0639019e-05 4.4317403e-05 9.4285714 + 9500 0.0046145139 0 2.513485e-05 1.036053e-05 4.5570422e-05 9.4285714 + 9600 0.0045277961 0 2.056713e-05 9.8647996e-06 4.5858869e-05 9.4285714 + 9700 0.0043935298 0 1.8390341e-05 9.0322729e-06 4.6271482e-05 9.4285714 + 9800 0.0045363488 0 2.0469706e-05 9.7216528e-06 4.5805899e-05 9.4285714 + 9900 0.0046509978 0 1.9525081e-05 9.5233466e-06 4.862056e-05 9.4285714 + 10000 0.0046493894 0 1.7602305e-05 9.4408537e-06 5.0053515e-05 9.4285714 + 10100 0.0046514856 0 1.6724832e-05 9.9699479e-06 4.928713e-05 9.4285714 + 10200 0.0046209533 0 1.4889196e-05 1.0767419e-05 4.9829248e-05 9.4285714 + 10300 0.0044651031 0 1.0578209e-05 1.1339471e-05 5.1024934e-05 9.4285714 + 10400 0.0041834162 0 6.5253227e-06 1.099852e-05 5.0813498e-05 9.4285714 + 10500 0.0043218845 0 7.2170142e-06 1.2622523e-05 5.0759877e-05 9.4285714 + 10600 0.0045795722 0 1.0140572e-05 2.1058806e-05 5.4332689e-05 9.4285714 + 10700 0.0053833569 0 1.2245942e-05 3.2705455e-05 5.5584298e-05 9.4285714 + 10800 0.0056805981 0 9.642689e-06 4.0045088e-05 5.6378884e-05 9.4285714 + 10900 0.0057157307 0 9.8421383e-06 3.9670248e-05 5.7196914e-05 9.4285714 + 11000 0.005696424 0 1.1871435e-05 3.7351501e-05 5.7130853e-05 9.4285714 + 11100 0.0052078884 0 9.5005747e-06 3.612037e-05 5.1606236e-05 9.4285714 + 11200 0.0052849159 0 1.433919e-05 3.596257e-05 4.8371986e-05 9.4285714 + 11300 0.0054074494 0 1.2828165e-05 3.7628808e-05 5.0495681e-05 9.4285714 + 11400 0.0055432168 0 1.1770167e-05 3.7223129e-05 5.4498301e-05 9.4285714 + 11500 0.0054679467 0 1.1215128e-05 3.5612418e-05 5.5880978e-05 9.4285714 + 11600 0.0052706441 0 1.0611988e-05 3.5785457e-05 5.8094083e-05 9.4285714 + 11700 0.0053724243 0 1.1867616e-05 3.484887e-05 5.7967416e-05 9.4285714 + 11800 0.0054759961 0 9.3774866e-06 3.3307362e-05 6.0256027e-05 9.4285714 + 11900 0.0051146604 0 9.5582838e-06 3.1092749e-05 5.4847298e-05 9.4285714 + 12000 0.0049723565 0 8.4734692e-06 3.1240602e-05 5.3118854e-05 9.4285714 + 12100 0.0046920113 0 8.8947651e-06 3.3402795e-05 5.6254952e-05 9.4285714 + 12200 0.0049570244 0 1.0006616e-05 3.306729e-05 6.1049649e-05 9.4285714 + 12300 0.0049181458 0 8.1394364e-06 3.2634327e-05 6.2527089e-05 9.4285714 + 12400 0.0049245342 0 8.1971979e-06 3.3145464e-05 6.2091332e-05 9.4285714 + 12500 0.0049753042 0 8.9911646e-06 3.4018861e-05 6.1487068e-05 9.4285714 + 12600 0.0048148791 0 8.560766e-06 2.9647432e-05 6.2929427e-05 9.4285714 + 12700 0.0043852178 0 7.5889296e-06 1.8576839e-05 6.5947945e-05 9.4285714 + 12800 0.0041967317 0 8.6473249e-06 1.3892779e-05 6.6599779e-05 9.4285714 + 12900 0.0041911278 0 9.3489002e-06 1.8180223e-05 6.3308096e-05 9.4285714 + 13000 0.0043107924 0 8.5274073e-06 2.2286145e-05 5.9964925e-05 9.4285714 + 13100 0.0043976521 0 8.2741734e-06 2.4530103e-05 5.9567889e-05 9.4285714 + 13200 0.0043474635 0 9.2173493e-06 2.7514155e-05 5.4579308e-05 9.4285714 + 13300 0.0044593969 0 9.3356325e-06 3.0558484e-05 5.3771437e-05 9.4285714 + 13400 0.0044814342 0 9.2387466e-06 2.8998024e-05 5.5887559e-05 9.4285714 + 13500 0.0043982498 0 9.4867492e-06 2.5493297e-05 5.7396094e-05 9.4285714 + 13600 0.0039378503 0 1.0789003e-05 1.9448677e-05 6.1667698e-05 9.4285714 + 13700 0.0036474735 0 1.0885233e-05 1.5729573e-05 5.8520214e-05 9.4285714 + 13800 0.0038236277 0 1.3819358e-05 2.0470733e-05 5.4960098e-05 9.4285714 + 13900 0.0040574402 0 1.6741444e-05 2.391221e-05 5.4045411e-05 9.4285714 + 14000 0.0046440817 0 2.2494809e-05 2.9264007e-05 5.6648145e-05 9.4285714 + 14100 0.0048045755 0 2.2568279e-05 3.260884e-05 5.6960992e-05 9.4285714 + 14200 0.004634799 0 2.2650329e-05 2.7912328e-05 5.7597129e-05 9.4285714 + 14300 0.0046822822 0 2.3142295e-05 2.8536673e-05 5.7795199e-05 9.4285714 + 14400 0.0048282958 0 2.2560586e-05 3.2744704e-05 5.8133575e-05 9.4285714 + 14500 0.004799276 0 2.1374014e-05 3.1342428e-05 6.0569089e-05 9.4285714 + 14600 0.0046554419 0 2.0804876e-05 2.8534311e-05 6.0800428e-05 9.4285714 + 14700 0.0045262414 0 2.1835372e-05 2.8168699e-05 6.2901651e-05 9.4285714 + 14800 0.0043347498 0 1.9615887e-05 3.1686326e-05 6.4194237e-05 9.4285714 + 14900 0.0040641791 0 1.8621801e-05 2.7440899e-05 6.4602045e-05 9.4285714 + 15000 0.0040014911 0 1.6461776e-05 2.5832508e-05 6.08965e-05 9.4285714 + 15100 0.0040015198 0 2.2331361e-05 2.6108777e-05 5.9319862e-05 9.4285714 + 15200 0.004656209 0 3.5268101e-05 3.0082568e-05 5.958373e-05 9.4285714 + 15300 0.0047390215 0 4.1830227e-05 2.7233725e-05 5.8274008e-05 9.4285714 + 15400 0.0047219857 0 4.2798722e-05 2.8282959e-05 5.786682e-05 9.4285714 + 15500 0.0049597215 0 4.5190515e-05 2.9504603e-05 6.2435065e-05 9.4285714 + 15600 0.0049081505 0 4.3186089e-05 2.9977425e-05 6.1726635e-05 9.4285714 + 15700 0.0047978977 0 4.1446883e-05 2.7814159e-05 5.7947919e-05 9.4285714 + 15800 0.0048176861 0 3.9941014e-05 2.6548461e-05 5.9246093e-05 9.4285714 + 15900 0.0049895331 0 4.0485733e-05 2.8703855e-05 6.3382653e-05 9.4285714 + 16000 0.0049288669 0 3.892315e-05 2.9191325e-05 6.2118616e-05 9.4285714 + 16100 0.0048010252 0 3.7199431e-05 2.7134167e-05 6.1752588e-05 9.4285714 + 16200 0.0047925554 0 3.5806262e-05 2.5024463e-05 6.3068301e-05 9.4285714 + 16300 0.0047652048 0 3.3940221e-05 2.6543134e-05 6.7111166e-05 9.4285714 + 16400 0.0043495894 0 3.4655351e-05 1.8892916e-05 6.5825804e-05 9.4285714 + 16500 0.0042677893 0 3.4188541e-05 1.7570016e-05 6.3850178e-05 9.4285714 + 16600 0.0039924053 0 3.2417741e-05 1.7848282e-05 6.5817879e-05 9.4285714 + 16700 0.004110225 0 3.3539186e-05 1.9943078e-05 6.4568545e-05 9.4285714 + 16800 0.0041003344 0 3.6503679e-05 2.0546394e-05 6.2227252e-05 9.4285714 + 16900 0.0040916821 0 3.7342085e-05 2.384663e-05 6.0859481e-05 9.4285714 + 17000 0.0039812122 0 3.671505e-05 2.4137888e-05 5.6933083e-05 9.4285714 + 17100 0.0042480582 0 3.9654732e-05 2.4691844e-05 5.8210554e-05 9.4285714 + 17200 0.0044450353 0 4.0933677e-05 3.019578e-05 5.5604765e-05 9.4285714 + 17300 0.0045016689 0 4.0563484e-05 3.4710888e-05 5.2933625e-05 9.4285714 + 17400 0.0044798864 0 4.0768397e-05 3.3076261e-05 5.2287655e-05 9.4285714 + 17500 0.0044624458 0 3.8361144e-05 3.4320802e-05 5.4620342e-05 9.4285714 + 17600 0.0044477024 0 3.6643486e-05 3.6449296e-05 5.4759028e-05 9.4285714 + 17700 0.0044103517 0 3.8319719e-05 3.7509764e-05 5.0738749e-05 9.4285714 + 17800 0.004341948 0 3.8052635e-05 3.6850602e-05 5.0481977e-05 9.4285714 + 17900 0.0042623319 0 3.5909432e-05 3.5619615e-05 5.2184073e-05 9.4285714 + 18000 0.003726239 0 1.8245827e-05 3.791319e-05 5.0575431e-05 9.4285714 + 18100 0.0034893305 0 1.7957847e-05 3.6788428e-05 5.281228e-05 9.4285714 + 18200 0.0035481187 0 2.2513253e-05 3.461697e-05 5.1791689e-05 9.4285714 + 18300 0.0036251402 0 2.5159661e-05 3.4782379e-05 5.0946509e-05 9.4285714 + 18400 0.0036369749 0 2.4150699e-05 3.6305943e-05 5.0273557e-05 9.4285714 + 18500 0.0034279849 0 2.050142e-05 3.3762641e-05 5.0772554e-05 9.4285714 + 18600 0.0033615572 0 1.8397654e-05 3.3183402e-05 5.2215005e-05 9.4285714 + 18700 0.003406225 0 1.9609619e-05 3.4353871e-05 5.1091792e-05 9.4285714 + 18800 0.0034922323 0 1.9330569e-05 3.4176016e-05 5.2688824e-05 9.4285714 + 18900 0.0034820625 0 1.9280274e-05 3.3807796e-05 5.372272e-05 9.4285714 + 19000 0.0033272524 0 1.6873326e-05 3.594881e-05 5.3862535e-05 9.4285714 + 19100 0.0034010912 0 1.8030816e-05 3.582088e-05 5.4236353e-05 9.4285714 + 19200 0.0030932535 0 1.4863995e-05 2.7793367e-05 5.3934101e-05 9.4285714 + 19300 0.002624051 0 1.210198e-05 1.6467088e-05 5.2583223e-05 9.4285714 + 19400 0.0027583806 0 1.2008108e-05 2.1017092e-05 5.309485e-05 9.4285714 + 19500 0.0029775174 0 1.3352592e-05 2.4636522e-05 5.4043107e-05 9.4285714 + 19600 0.0028689969 0 1.3488363e-05 2.4373881e-05 5.7585286e-05 9.4285714 + 19700 0.0026399127 0 1.4002066e-05 2.7370388e-05 5.4220539e-05 9.4285714 + 19800 0.0025439904 0 1.668679e-05 2.7178009e-05 5.3083248e-05 9.4285714 + 19900 0.0027074939 0 1.5155901e-05 2.5194957e-05 5.3757244e-05 9.4285714 + 20000 0.0027181793 0 1.2268581e-05 2.5236301e-05 5.1395997e-05 9.4285714 + 20100 0.0027315362 0 1.2532955e-05 2.4069296e-05 5.2648391e-05 9.4285714 + 20200 0.0027204191 0 1.2457637e-05 2.419839e-05 5.2229242e-05 9.4285714 + 20300 0.0026457344 0 1.3573924e-05 2.3628429e-05 4.9330286e-05 9.4285714 + 20400 0.0026592475 0 1.3439645e-05 2.4469429e-05 5.1570429e-05 9.4285714 + 20500 0.0026129298 0 1.3261647e-05 2.4468607e-05 5.1163936e-05 9.4285714 + 20600 0.0026532045 0 1.5275975e-05 2.3494207e-05 5.0569472e-05 9.4285714 + 20700 0.0026172433 0 1.4720887e-05 2.1839292e-05 5.0769214e-05 9.4285714 + 20800 0.0025282343 0 1.3852135e-05 2.0845003e-05 4.9690546e-05 9.4285714 + 20900 0.0025383322 0 1.353444e-05 2.2097076e-05 5.1303519e-05 9.4285714 + 21000 0.0024848857 0 1.4032657e-05 2.1964185e-05 5.3050324e-05 9.4285714 + 21100 0.0025091105 0 1.5334232e-05 2.1760041e-05 5.508965e-05 9.4285714 + 21200 0.0027229411 0 1.9418427e-05 2.2335523e-05 5.5657372e-05 9.4285714 + 21300 0.0028888226 0 2.3631969e-05 2.2967648e-05 5.5948438e-05 9.4285714 + 21400 0.0029336429 0 2.5044169e-05 2.2567194e-05 5.5413722e-05 9.4285714 + 21500 0.0029354446 0 2.4712642e-05 2.2624219e-05 5.5920832e-05 9.4285714 + 21600 0.0029270648 0 2.3842417e-05 2.3011885e-05 5.6087719e-05 9.4285714 + 21700 0.0029288781 0 2.3942959e-05 2.2810041e-05 5.7045772e-05 9.4285714 + 21800 0.002884005 0 2.4455829e-05 2.3081577e-05 5.6212968e-05 9.4285714 + 21900 0.0028362206 0 2.3350532e-05 2.49708e-05 5.3642917e-05 9.4285714 + 22000 0.0027784436 0 2.3311918e-05 2.3033334e-05 5.4359393e-05 9.4285714 + 22100 0.0027479829 0 2.4623514e-05 2.0287924e-05 5.3550114e-05 9.4285714 + 22200 0.0027598842 0 2.6073037e-05 2.1629185e-05 5.3119193e-05 9.4285714 + 22300 0.0026078138 0 2.6348246e-05 2.3093425e-05 5.4029431e-05 9.4285714 + 22400 0.0026057112 0 2.7316001e-05 2.4771567e-05 5.3484921e-05 9.4285714 + 22500 0.0026641722 0 2.6434166e-05 2.5849367e-05 5.2175653e-05 9.4285714 + 22600 0.0023728105 0 2.4436322e-05 2.4147316e-05 5.3971034e-05 9.4285714 + 22700 0.0021999097 0 2.4191892e-05 2.2725939e-05 5.3125105e-05 9.4285714 + 22800 0.002178124 0 2.4122577e-05 2.0194755e-05 5.3468522e-05 9.4285714 + 22900 0.0022903704 0 2.1332487e-05 1.8921598e-05 5.4657879e-05 9.4285714 + 23000 0.0022114595 0 1.930828e-05 1.4423335e-05 5.5387271e-05 9.4285714 + 23100 0.0022473179 0 2.0911663e-05 1.3467616e-05 5.4325686e-05 9.4285714 + 23200 0.0022787302 0 2.1538492e-05 1.5779872e-05 5.3591578e-05 9.4285714 + 23300 0.002254193 0 2.0552374e-05 1.7158208e-05 5.201196e-05 9.4285714 + 23400 0.0022032528 0 2.0514024e-05 1.6045426e-05 5.1691057e-05 9.4285714 + 23500 0.0022103262 0 2.2570839e-05 1.4990595e-05 5.0102702e-05 9.4285714 + 23600 0.0022767949 0 2.153875e-05 1.5934866e-05 4.9843486e-05 9.4285714 + 23700 0.002283034 0 2.0348727e-05 1.5852737e-05 4.9211887e-05 9.4285714 + 23800 0.0022293403 0 2.045052e-05 1.3951752e-05 4.9265994e-05 9.4285714 + 23900 0.0022421499 0 2.0541393e-05 1.3873188e-05 4.9783702e-05 9.4285714 + 24000 0.0022708179 0 2.0733448e-05 1.4464939e-05 5.0156761e-05 9.4285714 + 24100 0.0022311644 0 2.1753043e-05 1.4644732e-05 5.3630645e-05 9.4285714 + 24200 0.0022566051 0 2.3030277e-05 1.4212031e-05 5.3868685e-05 9.4285714 + 24300 0.0022547585 0 2.3946322e-05 1.331734e-05 5.2948407e-05 9.4285714 + 24400 0.0022901257 0 2.552016e-05 1.4594528e-05 5.3067402e-05 9.4285714 + 24500 0.0023537103 0 2.9369007e-05 1.5861923e-05 5.3200721e-05 9.4285714 + 24600 0.0023613708 0 2.9444021e-05 1.3691716e-05 5.4296289e-05 9.4285714 + 24700 0.0023237992 0 2.8805716e-05 1.1616027e-05 5.4142589e-05 9.4285714 + 24800 0.0024221927 0 3.1070958e-05 1.2059146e-05 5.406912e-05 9.4285714 + 24900 0.0025882547 0 3.7453428e-05 1.2082125e-05 5.4439426e-05 9.4285714 + 25000 0.0027152266 0 4.2549028e-05 1.1637136e-05 5.4292043e-05 9.4285714 + 25100 0.0028201154 0 4.6710609e-05 1.2903782e-05 5.3790595e-05 9.4285714 + 25200 0.0029086169 0 4.756645e-05 1.3260261e-05 5.7165687e-05 9.4285714 + 25300 0.0028528211 0 4.8705176e-05 1.1918164e-05 5.632163e-05 9.4285714 + 25400 0.0027655631 0 4.7538544e-05 1.186744e-05 5.3917832e-05 9.4285714 + 25500 0.0027631455 0 4.7296868e-05 1.2125391e-05 5.2651056e-05 9.4285714 + 25600 0.0027455338 0 4.8477007e-05 1.2403172e-05 5.7029384e-05 9.4285714 + 25700 0.0027314337 0 4.8377711e-05 1.254263e-05 5.7035789e-05 9.4285714 + 25800 0.0026789336 0 4.9232002e-05 1.1749936e-05 5.7580068e-05 9.4285714 + 25900 0.0026686904 0 5.0376929e-05 1.2811492e-05 5.9087927e-05 9.4285714 + 26000 0.0026703643 0 5.0974299e-05 1.3064292e-05 5.7801118e-05 9.4285714 + 26100 0.0026825353 0 4.9500137e-05 1.1676376e-05 5.695664e-05 9.4285714 + 26200 0.0026825174 0 4.972182e-05 1.0546822e-05 5.7622991e-05 9.4285714 + 26300 0.0025517718 0 4.36237e-05 1.082888e-05 5.8496458e-05 9.4285714 + 26400 0.002448155 0 3.6914303e-05 1.1208368e-05 6.0071981e-05 9.4285714 + 26500 0.0023334395 0 3.2968743e-05 1.0745176e-05 6.0011765e-05 9.4285714 + 26600 0.0023097701 0 3.0179184e-05 1.1497687e-05 5.9980393e-05 9.4285714 + 26700 0.0023614287 0 3.1929774e-05 1.4076482e-05 5.767606e-05 9.4285714 + 26800 0.0023955623 0 3.1551792e-05 1.7121208e-05 5.8187883e-05 9.4285714 + 26900 0.0019993736 0 1.8807723e-05 1.6770089e-05 5.7954922e-05 9.4285714 + 27000 0.0019497677 0 1.7354388e-05 1.6608976e-05 5.6225802e-05 9.4285714 + 27100 0.0020363076 0 2.1348268e-05 1.6918233e-05 5.7949239e-05 9.4285714 + 27200 0.0021974785 0 2.5205825e-05 2.0142198e-05 5.5376701e-05 9.4285714 + 27300 0.002350289 0 2.8900121e-05 2.3754068e-05 5.5263555e-05 9.4285714 + 27400 0.0026460053 0 3.2553147e-05 3.227333e-05 5.7954104e-05 9.4285714 + 27500 0.0027599044 0 3.2851254e-05 3.674649e-05 5.6341966e-05 9.4285714 + 27600 0.0026660556 0 3.2389038e-05 3.4626306e-05 5.5414375e-05 9.4285714 + 27700 0.0026060398 0 3.3223431e-05 3.2391399e-05 5.3340397e-05 9.4285714 + 27800 0.002724511 0 3.372415e-05 3.4485846e-05 5.4707128e-05 9.4285714 + 27900 0.0027318479 0 3.3234708e-05 3.5304313e-05 5.5589046e-05 9.4285714 + 28000 0.0026231478 0 3.2741313e-05 3.3225541e-05 5.398932e-05 9.4285714 + 28100 0.0025508556 0 3.3833477e-05 3.1513842e-05 5.4023598e-05 9.4285714 + 28200 0.0025807152 0 3.4548289e-05 3.3420009e-05 5.5627424e-05 9.4285714 + 28300 0.0024074206 0 3.0461599e-05 3.4140994e-05 5.6820341e-05 9.4285714 + 28400 0.0021292859 0 2.3624321e-05 3.4194604e-05 5.3656462e-05 9.4285714 + 28500 0.0022172558 0 1.8989998e-05 3.8241372e-05 5.0308571e-05 9.4285714 + 28600 0.0022653927 0 2.0006228e-05 4.1839298e-05 5.3834698e-05 9.4285714 + 28700 0.0025914898 0 2.4417865e-05 5.4161998e-05 5.2309701e-05 9.4285714 + 28800 0.0028276024 0 2.7173934e-05 5.9987722e-05 5.1277434e-05 9.4285714 + 28900 0.0029326653 0 2.9972273e-05 5.9404465e-05 5.3442041e-05 9.4285714 + 29000 0.002965493 0 3.0732118e-05 5.8813779e-05 5.4010354e-05 9.4285714 + 29100 0.0029096903 0 2.789911e-05 5.6948857e-05 5.3811328e-05 9.4285714 + 29200 0.0028604262 0 2.8541368e-05 5.5433392e-05 5.5266978e-05 9.4285714 + 29300 0.0028093312 0 3.1626568e-05 5.2793462e-05 5.9393321e-05 9.4285714 + 29400 0.0026786162 0 2.6580766e-05 4.1761109e-05 6.3731211e-05 9.4285714 + 29500 0.0025387867 0 2.4586262e-05 3.1439522e-05 6.5207101e-05 9.4285714 + 29600 0.0026569564 0 2.658665e-05 3.344894e-05 6.5578568e-05 9.4285714 + 29700 0.0027207144 0 2.4629031e-05 3.1640582e-05 7.3229358e-05 9.4285714 + 29800 0.0026892821 0 2.0092233e-05 2.9124688e-05 8.0756571e-05 9.4285714 + 29900 0.002643369 0 2.0481401e-05 3.0183662e-05 7.7273404e-05 9.4285714 + 30000 0.0026484998 0 1.9889243e-05 3.0560067e-05 7.7261634e-05 9.4285714 + 30100 0.0028058509 0 2.6399165e-05 3.004015e-05 8.3212623e-05 9.4285714 + 30200 0.0030353215 0 3.6921703e-05 3.4899864e-05 7.8543173e-05 9.4285714 + 30300 0.0030244988 0 4.0706399e-05 3.6091245e-05 7.4921988e-05 9.4285714 + 30400 0.0030855053 0 4.2502388e-05 3.8438853e-05 7.6268037e-05 9.4285714 + 30500 0.0031141819 0 4.3996743e-05 4.3726389e-05 6.8459715e-05 9.4285714 + 30600 0.0030115458 0 4.436657e-05 4.2288168e-05 6.5970726e-05 9.4285714 + 30700 0.0029700178 0 4.2448638e-05 4.1066034e-05 6.7905919e-05 9.4285714 + 30800 0.0029985358 0 4.3581039e-05 4.2782359e-05 6.616813e-05 9.4285714 + 30900 0.0029689517 0 4.3664983e-05 4.0341198e-05 6.6701993e-05 9.4285714 + 31000 0.0029622718 0 4.3233863e-05 3.8109114e-05 6.615517e-05 9.4285714 + 31100 0.0029693917 0 4.3443429e-05 3.6045147e-05 6.6807218e-05 9.4285714 + 31200 0.0027246348 0 3.8812502e-05 2.5969873e-05 6.9745525e-05 9.4285714 + 31300 0.0025368424 0 3.4331267e-05 2.1427734e-05 6.9565964e-05 9.4285714 + 31400 0.0023736698 0 3.2043786e-05 1.9880875e-05 6.6817156e-05 9.4285714 + 31500 0.0023946514 0 3.3170726e-05 1.9958211e-05 7.0242984e-05 9.4285714 + 31600 0.0025648037 0 3.5948214e-05 2.4022282e-05 7.8512704e-05 9.4285714 + 31700 0.0026956511 0 3.9195772e-05 3.3270216e-05 7.4223245e-05 9.4285714 + 31800 0.002677722 0 3.8651034e-05 3.4084086e-05 7.3747643e-05 9.4285714 + 31900 0.0026705496 0 3.8515991e-05 3.3258169e-05 7.4757118e-05 9.4285714 + 32000 0.0026466417 0 4.2241836e-05 3.449171e-05 7.0551161e-05 9.4285714 + 32100 0.0026464292 0 4.0974715e-05 3.6570061e-05 6.5387411e-05 9.4285714 + 32200 0.0023705665 0 2.951869e-05 3.011444e-05 6.6589524e-05 9.4285714 + 32300 0.0023183595 0 2.2729207e-05 3.0010044e-05 7.2706128e-05 9.4285714 + 32400 0.0023882969 0 2.372595e-05 3.1302357e-05 7.3782281e-05 9.4285714 + 32500 0.0023801754 0 2.2337455e-05 3.0476386e-05 7.5659736e-05 9.4285714 + 32600 0.0024127958 0 2.5510841e-05 3.0854572e-05 7.4410799e-05 9.4285714 + 32700 0.0024031675 0 2.7736693e-05 3.1958346e-05 7.1486437e-05 9.4285714 + 32800 0.0023770089 0 2.6385534e-05 3.3252416e-05 7.2822578e-05 9.4285714 + 32900 0.0023568819 0 2.8634678e-05 3.3258031e-05 6.7686839e-05 9.4285714 + 33000 0.0023407285 0 2.6769773e-05 3.2579304e-05 6.6690925e-05 9.4285714 + 33100 0.002327332 0 2.6645781e-05 3.4007498e-05 6.9628993e-05 9.4285714 + 33200 0.0023912585 0 2.3830565e-05 3.3441643e-05 7.4913813e-05 9.4285714 + 33300 0.0022984153 0 2.4483639e-05 3.2969557e-05 7.7726941e-05 9.4285714 + 33400 0.0022416368 0 2.3898793e-05 3.1031269e-05 7.686001e-05 9.4285714 + 33500 0.0022470637 0 2.0975902e-05 3.0084834e-05 7.570705e-05 9.4285714 + 33600 0.002256129 0 2.0520324e-05 2.8645032e-05 7.7384366e-05 9.4285714 + 33700 0.0022125246 0 1.9872713e-05 2.9850887e-05 7.5881174e-05 9.4285714 + 33800 0.0021842197 0 1.9711523e-05 2.983205e-05 7.3213854e-05 9.4285714 + 33900 0.0021690567 0 1.8055303e-05 2.828677e-05 7.3059722e-05 9.4285714 + 34000 0.0022206311 0 1.8792994e-05 2.8714121e-05 7.5766963e-05 9.4285714 + 34100 0.0022494061 0 2.1426406e-05 2.9683277e-05 7.5164305e-05 9.4285714 + 34200 0.0022085859 0 2.1896897e-05 2.8930132e-05 7.2805525e-05 9.4285714 + 34300 0.0021855633 0 2.0480867e-05 2.9992196e-05 7.2354191e-05 9.4285714 + 34400 0.0021798298 0 2.1236448e-05 3.2053048e-05 7.283282e-05 9.4285714 + 34500 0.0021267289 0 2.2129794e-05 2.8881701e-05 7.1551685e-05 9.4285714 + 34600 0.0020466804 0 2.3010184e-05 2.7531882e-05 7.2523946e-05 9.4285714 + 34700 0.0020969555 0 2.1337061e-05 3.0266865e-05 7.0863423e-05 9.4285714 + 34800 0.0022946237 0 2.2123517e-05 3.8911524e-05 7.2703415e-05 9.4285714 + 34900 0.0024490201 0 2.8420828e-05 5.0378173e-05 7.1772848e-05 9.4285714 + 35000 0.0023320217 0 2.8176618e-05 5.1789577e-05 6.8023074e-05 9.4285714 + 35100 0.0021890324 0 2.4442013e-05 5.2547725e-05 6.1661973e-05 9.4285714 + 35200 0.0022124553 0 2.4530724e-05 5.096875e-05 6.5186855e-05 9.4285714 + 35300 0.0022584165 0 2.7542443e-05 5.427333e-05 6.7536963e-05 9.4285714 + 35400 0.0022737238 0 2.504131e-05 5.4367041e-05 6.7123718e-05 9.4285714 + 35500 0.0021537481 0 2.1567488e-05 4.8699315e-05 6.7335416e-05 9.4285714 + 35600 0.0019831613 0 1.8746091e-05 4.3656184e-05 6.3180625e-05 9.4285714 + 35700 0.0019041909 0 1.9945089e-05 4.3868252e-05 5.8115913e-05 9.4285714 + 35800 0.0018216502 0 2.2392614e-05 4.2188069e-05 5.7629004e-05 9.4285714 + 35900 0.0018071574 0 2.1141753e-05 4.1327783e-05 5.630057e-05 9.4285714 + 36000 0.0018645267 0 2.2735521e-05 4.4296822e-05 5.4259075e-05 9.4285714 + 36100 0.0018474198 0 2.5295637e-05 4.6128849e-05 5.7469914e-05 9.4285714 + 36200 0.0017366166 0 2.6021589e-05 4.5563756e-05 5.5296808e-05 9.4285714 + 36300 0.0016630877 0 2.4135763e-05 4.58324e-05 5.2179718e-05 9.4285714 + 36400 0.0016809967 0 2.3427379e-05 4.7533202e-05 4.714932e-05 9.4285714 + 36500 0.0017478488 0 2.4021161e-05 4.6508842e-05 4.3949519e-05 9.4285714 + 36600 0.0017244649 0 2.3504871e-05 4.3628584e-05 4.3171518e-05 9.4285714 + 36700 0.001694793 0 2.2302323e-05 4.2349904e-05 4.396766e-05 9.4285714 + 36800 0.0016321204 0 2.1042421e-05 3.6396346e-05 4.4901304e-05 9.4285714 + 36900 0.0015208954 0 2.0456403e-05 2.7850556e-05 4.5155127e-05 9.4285714 + 37000 0.0014068755 0 2.0241724e-05 2.1785718e-05 4.5528636e-05 9.4285714 + 37100 0.0013361229 0 1.675977e-05 2.1314381e-05 4.6611487e-05 9.4285714 + 37200 0.001331474 0 1.6204509e-05 2.3621819e-05 5.0433204e-05 9.4285714 + 37300 0.0013895388 0 1.6721652e-05 3.0265014e-05 5.0091541e-05 9.4285714 + 37400 0.001407333 0 1.738976e-05 2.8850978e-05 5.1334019e-05 9.4285714 + 37500 0.0013815772 0 1.6241641e-05 3.0837468e-05 4.6825094e-05 9.4285714 + 37600 0.001367937 0 1.1983552e-05 2.9613642e-05 5.0754355e-05 9.4285714 + 37700 0.0013781896 0 1.1915379e-05 2.9242244e-05 4.8777649e-05 9.4285714 + 37800 0.0013938097 0 1.1529951e-05 3.1628776e-05 4.7715639e-05 9.4285714 + 37900 0.0013788852 0 1.2561324e-05 3.1951817e-05 4.7999073e-05 9.4285714 + 38000 0.0013409916 0 1.2473952e-05 3.1146722e-05 4.8401798e-05 9.4285714 + 38100 0.0013548793 0 1.1004651e-05 2.7320574e-05 4.9651495e-05 9.4285714 + 38200 0.0013619894 0 1.2229314e-05 2.574689e-05 4.9387883e-05 9.4285714 + 38300 0.0013593654 0 1.3392954e-05 2.427172e-05 5.1848635e-05 9.4285714 + 38400 0.0013488508 0 1.256534e-05 2.449982e-05 5.4623064e-05 9.4285714 + 38500 0.0013399961 0 1.2037162e-05 2.0814078e-05 5.6078474e-05 9.4285714 + 38600 0.0013473117 0 1.1744489e-05 1.6853428e-05 5.7231621e-05 9.4285714 + 38700 0.0013275262 0 1.093468e-05 1.4795508e-05 5.769577e-05 9.4285714 + 38800 0.001304838 0 1.1068283e-05 1.3115698e-05 6.0324982e-05 9.4285714 + 38900 0.0012981525 0 1.1709325e-05 1.3131645e-05 5.9760468e-05 9.4285714 + 39000 0.0013241474 0 1.261896e-05 1.4616086e-05 6.0256213e-05 9.4285714 + 39100 0.0013302715 0 1.1838509e-05 1.5600129e-05 6.432053e-05 9.4285714 + 39200 0.0013338793 0 1.2403697e-05 1.6279003e-05 6.2961888e-05 9.4285714 + 39300 0.001337749 0 1.3137034e-05 1.6207867e-05 6.0627848e-05 9.4285714 + 39400 0.0014184127 0 1.6180184e-05 1.8165982e-05 5.8887905e-05 9.4285714 + 39500 0.0015076229 0 1.9522159e-05 1.9795428e-05 5.910332e-05 9.4285714 + 39600 0.001584196 0 2.4027089e-05 2.0838917e-05 5.7603421e-05 9.4285714 + 39700 0.0016673141 0 2.9500045e-05 2.3045542e-05 5.5891462e-05 9.4285714 + 39800 0.0016983633 0 3.0305739e-05 2.4453535e-05 5.5981899e-05 9.4285714 + 39900 0.001721388 0 3.1340689e-05 2.4975831e-05 5.5548483e-05 9.4285714 + 40000 0.0016511866 0 3.370998e-05 2.6328206e-05 5.671433e-05 9.4285714 + 40100 0.0015902117 0 3.3681877e-05 2.5663116e-05 5.3013557e-05 9.4285714 + 40200 0.0016248457 0 3.0865269e-05 2.5397352e-05 5.1452424e-05 9.4285714 + 40300 0.001639017 0 3.1973896e-05 2.5525448e-05 5.4813301e-05 9.4285714 + 40400 0.0015947128 0 3.5965857e-05 2.5225505e-05 5.6385827e-05 9.4285714 + 40500 0.0014886812 0 3.7017265e-05 2.4882355e-05 5.2995469e-05 9.4285714 + 40600 0.001483951 0 3.4221499e-05 2.1479298e-05 5.4046331e-05 9.4285714 + 40700 0.0014877422 0 3.362595e-05 1.8839863e-05 5.5203171e-05 9.4285714 + 40800 0.0014974798 0 3.6392277e-05 1.7485578e-05 5.7247772e-05 9.4285714 + 40900 0.0014499802 0 3.3431089e-05 1.9674968e-05 5.6160238e-05 9.4285714 + 41000 0.001395913 0 2.9658496e-05 1.8273286e-05 5.6527772e-05 9.4285714 + 41100 0.0014079985 0 2.9771219e-05 1.6179289e-05 5.9153644e-05 9.4285714 + 41200 0.0014187083 0 2.7845336e-05 1.9035184e-05 5.7573549e-05 9.4285714 + 41300 0.0014072972 0 2.4886378e-05 2.0795562e-05 5.4986012e-05 9.4285714 + 41400 0.0014168981 0 2.358191e-05 2.1908287e-05 5.4674995e-05 9.4285714 + 41500 0.0014248439 0 2.3385735e-05 2.3170658e-05 5.3269277e-05 9.4285714 + 41600 0.0014225044 0 2.376616e-05 2.5694883e-05 5.2138491e-05 9.4285714 + 41700 0.0014075811 0 2.2374247e-05 2.7567814e-05 5.1299283e-05 9.4285714 + 41800 0.0012680617 0 2.2171263e-05 2.5019906e-05 5.4594068e-05 9.4285714 + 41900 0.0010587818 0 1.5440824e-05 2.093143e-05 5.3361822e-05 9.4285714 + 42000 0.0010007004 0 1.2044875e-05 1.7303459e-05 5.3021476e-05 9.4285714 + 42100 0.0011304402 0 1.2464466e-05 1.9304071e-05 5.5030158e-05 9.4285714 + 42200 0.0012833154 0 1.6978814e-05 2.4344322e-05 5.4664913e-05 9.4285714 + 42300 0.0013573853 0 1.8276863e-05 2.7764513e-05 5.4832226e-05 9.4285714 + 42400 0.0013330633 0 1.7445663e-05 2.5994427e-05 5.6219048e-05 9.4285714 + 42500 0.0012896373 0 1.7549999e-05 2.4461263e-05 5.5316804e-05 9.4285714 + 42600 0.001296775 0 1.7579818e-05 2.4729094e-05 5.4786174e-05 9.4285714 + 42700 0.0013193969 0 1.7589942e-05 2.6653321e-05 5.5601741e-05 9.4285714 + 42800 0.0013144903 0 1.7344148e-05 2.7396405e-05 5.6063261e-05 9.4285714 + 42900 0.0013053554 0 1.812017e-05 2.4357577e-05 5.5400672e-05 9.4285714 + 43000 0.0013061323 0 1.7976023e-05 2.5672617e-05 5.5591174e-05 9.4285714 + 43100 0.0013149372 0 1.8049252e-05 2.7694066e-05 5.7517507e-05 9.4285714 + 43200 0.0013063189 0 1.8000018e-05 2.5312637e-05 5.7758611e-05 9.4285714 + 43300 0.0012669853 0 1.7756679e-05 2.3718058e-05 5.7316755e-05 9.4285714 + 43400 0.0012238388 0 2.0194584e-05 2.1983277e-05 5.5573072e-05 9.4285714 + 43500 0.0012053096 0 2.0662764e-05 2.2371854e-05 5.3240833e-05 9.4285714 + 43600 0.001243323 0 2.3521544e-05 2.3272124e-05 5.4438848e-05 9.4285714 + 43700 0.001354992 0 2.8388806e-05 2.6835727e-05 5.1695181e-05 9.4285714 + 43800 0.0015252788 0 3.4452462e-05 3.2972955e-05 5.1148386e-05 9.4285714 + 43900 0.0016845587 0 3.7891883e-05 3.7259267e-05 5.3712665e-05 9.4285714 + 44000 0.0016987088 0 3.794299e-05 3.9188564e-05 5.22906e-05 9.4285714 + 44100 0.0016663634 0 3.6807094e-05 3.9253716e-05 5.2294244e-05 9.4285714 + 44200 0.0016642734 0 3.7043503e-05 3.9518624e-05 5.2702041e-05 9.4285714 + 44300 0.0016877933 0 3.8179716e-05 4.0630461e-05 5.3339506e-05 9.4285714 + 44400 0.0016937941 0 3.7131293e-05 4.1066259e-05 5.432841e-05 9.4285714 + 44500 0.001658184 0 3.5564842e-05 3.9986051e-05 5.4994687e-05 9.4285714 + 44600 0.0016202756 0 3.6182348e-05 4.0514972e-05 5.4343097e-05 9.4285714 + 44700 0.0012624519 0 3.6496068e-05 3.330838e-05 6.0193182e-05 9.4285714 + 44800 0.0012148648 0 3.7546572e-05 2.4531512e-05 6.0795743e-05 9.4285714 + 44900 0.0012565599 0 2.9767991e-05 2.3526786e-05 5.730112e-05 9.4285714 + 45000 0.0012298496 0 3.3326423e-05 2.2497973e-05 5.3986547e-05 9.4285714 + 45100 0.0012274205 0 3.310721e-05 2.2786466e-05 5.5167469e-05 9.4285714 + 45200 0.0012389066 0 3.4925053e-05 2.3497387e-05 5.4884661e-05 9.4285714 + 45300 0.0012251609 0 3.615161e-05 2.3152279e-05 5.3650078e-05 9.4285714 + 45400 0.0012814774 0 3.746516e-05 2.4153096e-05 5.1029288e-05 9.4285714 + 45500 0.0013450626 0 3.9489551e-05 2.6213973e-05 5.0267505e-05 9.4285714 + 45600 0.0013741472 0 4.2751714e-05 2.6741902e-05 4.9140966e-05 9.4285714 + 45700 0.0014351223 0 4.3930849e-05 2.6748326e-05 4.9411273e-05 9.4285714 + 45800 0.0015284371 0 4.6485067e-05 2.8704517e-05 4.9999511e-05 9.4285714 + 45900 0.001575355 0 4.5717321e-05 3.011393e-05 5.1143199e-05 9.4285714 + 46000 0.0015147792 0 4.1325851e-05 3.0384448e-05 5.1923e-05 9.4285714 + 46100 0.0014504182 0 3.9540594e-05 3.1635289e-05 5.0948968e-05 9.4285714 + 46200 0.0014410639 0 3.965176e-05 3.0362005e-05 4.8786102e-05 9.4285714 + 46300 0.0014810525 0 4.1568241e-05 3.0756475e-05 4.8680363e-05 9.4285714 + 46400 0.0014640215 0 4.309465e-05 2.985089e-05 4.9009517e-05 9.4285714 + 46500 0.0014424933 0 4.2309209e-05 2.9280621e-05 4.8629444e-05 9.4285714 + 46600 0.001441165 0 4.2539286e-05 3.0934085e-05 4.9784857e-05 9.4285714 + 46700 0.0015025344 0 4.4979228e-05 3.1000179e-05 4.8462809e-05 9.4285714 + 46800 0.0015582176 0 4.7282405e-05 3.2706414e-05 4.5724526e-05 9.4285714 + 46900 0.0015803324 0 4.7650091e-05 3.4907217e-05 4.4832148e-05 9.4285714 + 47000 0.001675143 0 5.1693701e-05 3.6882816e-05 4.6006875e-05 9.4285714 + 47100 0.0017769921 0 5.6400585e-05 3.9830957e-05 4.6950937e-05 9.4285714 + 47200 0.0018358006 0 5.9232345e-05 4.3665585e-05 4.6768506e-05 9.4285714 + 47300 0.0017951326 0 5.6422198e-05 4.3944608e-05 4.8336201e-05 9.4285714 + 47400 0.0017057371 0 5.4710398e-05 3.9941549e-05 4.7652027e-05 9.4285714 + 47500 0.0016744493 0 5.2852149e-05 3.7232824e-05 4.5384467e-05 9.4285714 + 47600 0.0014031951 0 4.1326626e-05 3.0025176e-05 4.3875657e-05 9.4285714 + 47700 0.0013373039 0 3.7514245e-05 2.9655038e-05 4.316088e-05 9.4285714 + 47800 0.0014704003 0 4.1417238e-05 3.4940895e-05 4.447442e-05 9.4285714 + 47900 0.0014934525 0 4.3132757e-05 3.7137359e-05 4.4062556e-05 9.4285714 + 48000 0.0014895856 0 4.6046202e-05 3.6927333e-05 4.3726122e-05 9.4285714 + 48100 0.00146967 0 4.6872982e-05 3.9649234e-05 4.597459e-05 9.4285714 + 48200 0.0015682986 0 4.8924923e-05 4.738992e-05 4.3767565e-05 9.4285714 + 48300 0.0017163505 0 5.2171663e-05 5.3787554e-05 4.4084292e-05 9.4285714 + 48400 0.0014261936 0 4.3093196e-05 5.6810791e-05 5.4178929e-05 9.4285714 + 48500 0.0014236361 0 3.9093573e-05 4.8266345e-05 5.346877e-05 9.4285714 + 48600 0.0014562257 0 4.0734834e-05 4.2323892e-05 4.8295024e-05 9.4285714 + 48700 0.0013758282 0 3.6847543e-05 3.5139344e-05 4.8073535e-05 9.4285714 + 48800 0.0014316476 0 3.7554019e-05 3.5556116e-05 4.7370089e-05 9.4285714 + 48900 0.0014805023 0 3.5226264e-05 3.3817592e-05 5.2499511e-05 9.4285714 + 49000 0.0013776549 0 3.2439848e-05 2.997493e-05 5.3101978e-05 9.4285714 + 49100 0.0013617488 0 3.2279492e-05 3.0772411e-05 5.1632538e-05 9.4285714 + 49200 0.0013342401 0 2.8600175e-05 3.2651245e-05 5.3349695e-05 9.4285714 + 49300 0.001276486 0 2.7777544e-05 2.96306e-05 5.4374435e-05 9.4285714 + 49400 0.0011795288 0 2.2827442e-05 2.8085944e-05 5.2012108e-05 9.4285714 + 49500 0.0011435859 0 2.2873378e-05 2.7199584e-05 4.8565744e-05 9.4285714 + 49600 0.001247689 0 2.5002038e-05 3.0378272e-05 5.4987332e-05 9.4285714 + 49700 0.0013371245 0 2.6349724e-05 3.4033827e-05 5.8350385e-05 9.4285714 + 49800 0.001301722 0 2.4983049e-05 3.3355962e-05 5.7259996e-05 9.4285714 + 49900 0.0012728363 0 2.4271773e-05 3.366383e-05 5.4969958e-05 9.4285714 + 50000 0.0013286836 0 2.4626397e-05 3.4888455e-05 5.6333036e-05 9.4285714 + 50100 0.0013460063 0 2.5626025e-05 3.4617082e-05 5.8834535e-05 9.4285714 + 50200 0.0012868089 0 2.3749355e-05 3.3262754e-05 5.7555068e-05 9.4285714 + 50300 0.0012765172 0 2.3286644e-05 3.285494e-05 5.6753429e-05 9.4285714 + 50400 0.0012703222 0 2.2664849e-05 3.2123476e-05 5.8001158e-05 9.4285714 + 50500 0.0011906512 0 1.8988144e-05 2.5734872e-05 6.0360828e-05 9.4285714 + 50600 0.0011537339 0 1.7108695e-05 2.2700119e-05 6.3433107e-05 9.4285714 + 50700 0.0011267336 0 1.7970895e-05 2.4672948e-05 5.8568632e-05 9.4285714 + 50800 0.0011753482 0 1.9468991e-05 2.5939765e-05 5.9862885e-05 9.4285714 + 50900 0.0011919232 0 2.0208188e-05 2.7321787e-05 5.9048906e-05 9.4285714 + 51000 0.0011838525 0 2.1827961e-05 2.9118892e-05 5.2803692e-05 9.4285714 + 51100 0.0011883954 0 2.2709257e-05 2.8506733e-05 5.4654615e-05 9.4285714 + 51200 0.0012349694 0 2.5890907e-05 2.8698467e-05 5.7896353e-05 9.4285714 + 51300 0.0012337432 0 2.7687089e-05 2.7653507e-05 5.9917212e-05 9.4285714 + 51400 0.0011577306 0 2.8378044e-05 2.3224364e-05 5.8057014e-05 9.4285714 + 51500 0.0011811724 0 2.8435714e-05 2.1929674e-05 5.9722575e-05 9.4285714 + 51600 0.0012159313 0 3.1521829e-05 2.2796335e-05 5.924849e-05 9.4285714 + 51700 0.0011936762 0 3.4012729e-05 2.3864808e-05 5.7265759e-05 9.4285714 + 51800 0.00119466 0 3.5158377e-05 2.5231988e-05 5.8412082e-05 9.4285714 + 51900 0.0012013641 0 3.3334001e-05 2.6816388e-05 5.861301e-05 9.4285714 + 52000 0.0011652185 0 3.0940041e-05 2.6655324e-05 5.7090011e-05 9.4285714 + 52100 0.0011222289 0 3.1077905e-05 2.4541748e-05 5.5666069e-05 9.4285714 + 52200 0.0011223637 0 3.2939544e-05 2.5096815e-05 5.6416173e-05 9.4285714 + 52300 0.00108781 0 3.4613486e-05 2.7303053e-05 5.6746437e-05 9.4285714 + 52400 0.0010329114 0 3.6196201e-05 2.8068523e-05 5.2439815e-05 9.4285714 + 52500 0.0010414794 0 3.673215e-05 2.7272718e-05 5.143023e-05 9.4285714 + 52600 0.0011160581 0 3.5468006e-05 2.7495373e-05 5.401667e-05 9.4285714 + 52700 0.0011365494 0 3.6522651e-05 2.8130517e-05 5.1952685e-05 9.4285714 + 52800 0.0011528486 0 3.8067909e-05 3.2231442e-05 4.9590134e-05 9.4285714 + 52900 0.001215765 0 4.2804899e-05 3.6927536e-05 5.1170177e-05 9.4285714 + 53000 0.0013368124 0 4.5592002e-05 4.1563931e-05 5.4427869e-05 9.4285714 + 53100 0.0013407312 0 4.5591201e-05 4.3600841e-05 4.9047373e-05 9.4285714 + 53200 0.0013326843 0 4.4821382e-05 4.1764227e-05 4.6186223e-05 9.4285714 + 53300 0.0013239729 0 4.3827862e-05 4.4020784e-05 4.3852213e-05 9.4285714 + 53400 0.0013217143 0 4.3572994e-05 4.7084118e-05 4.3149657e-05 9.4285714 + 53500 0.0012781803 0 4.460572e-05 4.8061498e-05 4.2708059e-05 9.4285714 + 53600 0.001268382 0 4.458824e-05 4.5673787e-05 4.1230488e-05 9.4285714 + 53700 0.0012069904 0 4.1562438e-05 4.2697726e-05 4.1986265e-05 9.4285714 + 53800 0.0011968988 0 4.5963049e-05 4.0317052e-05 4.3564542e-05 9.4285714 + 53900 0.0011731954 0 4.5626132e-05 3.9016561e-05 4.2699438e-05 9.4285714 + 54000 0.0011606061 0 4.2734103e-05 3.8922865e-05 4.2063758e-05 9.4285714 + 54100 0.0011658982 0 3.9764581e-05 3.672962e-05 4.7476053e-05 9.4285714 + 54200 0.0011195165 0 3.5569124e-05 3.3590873e-05 4.8421311e-05 9.4285714 + 54300 0.0010220393 0 3.2252593e-05 3.0968164e-05 4.987935e-05 9.4285714 + 54400 0.0010086172 0 3.6631232e-05 3.0359237e-05 5.1629214e-05 9.4285714 + 54500 0.0010183988 0 3.7406525e-05 2.632072e-05 5.1823266e-05 9.4285714 + 54600 0.0010068716 0 3.6673782e-05 2.3899354e-05 4.883163e-05 9.4285714 + 54700 0.00099012603 0 3.3975738e-05 2.2165277e-05 4.788027e-05 9.4285714 + 54800 0.0009683722 0 3.235553e-05 2.2982659e-05 5.0112286e-05 9.4285714 + 54900 0.00097629715 0 3.2268492e-05 2.5601046e-05 4.8627644e-05 9.4285714 + 55000 0.00095157382 0 3.1040046e-05 2.437472e-05 4.637034e-05 9.4285714 + 55100 0.00090688968 0 2.9340275e-05 2.1953227e-05 4.3141384e-05 9.4285714 + 55200 0.00088813057 0 2.8284065e-05 2.1733676e-05 4.2934237e-05 9.4285714 + 55300 0.00092557007 0 2.8620339e-05 2.3675426e-05 4.3885475e-05 9.4285714 + 55400 0.00091327263 0 2.762239e-05 2.641616e-05 4.4396082e-05 9.4285714 + 55500 0.00079921186 0 2.9224842e-05 2.5168399e-05 4.3290943e-05 9.4285714 + 55600 0.00081947901 0 2.8418244e-05 2.2268749e-05 4.9968371e-05 9.4285714 + 55700 0.00084804465 0 2.1646302e-05 2.3720621e-05 5.205521e-05 9.4285714 + 55800 0.00085118568 0 2.2504085e-05 2.2872302e-05 4.9963437e-05 9.4285714 + 55900 0.00079015144 0 2.1456661e-05 1.9796776e-05 4.8884464e-05 9.4285714 + 56000 0.00077424122 0 2.2875959e-05 1.721853e-05 4.7217244e-05 9.4285714 + 56100 0.00078729859 0 2.750101e-05 1.8189823e-05 4.7065369e-05 9.4285714 + 56200 0.00073803593 0 2.8848488e-05 1.8153302e-05 4.571796e-05 9.4285714 + 56300 0.00072042566 0 2.842146e-05 1.5690166e-05 4.4828579e-05 9.4285714 + 56400 0.00072618636 0 2.7559372e-05 1.5504007e-05 4.399204e-05 9.4285714 + 56500 0.00072889383 0 2.7924251e-05 1.6823511e-05 4.2305183e-05 9.4285714 + 56600 0.00071687768 0 2.9101443e-05 1.6332857e-05 4.2086891e-05 9.4285714 + 56700 0.00070767909 0 3.0080534e-05 1.532979e-05 4.2661404e-05 9.4285714 + 56800 0.0007079533 0 2.8817943e-05 1.6206535e-05 4.2253735e-05 9.4285714 + 56900 0.00068006672 0 2.7371942e-05 1.7051153e-05 3.9711699e-05 9.4285714 + 57000 0.000671041 0 2.6892964e-05 1.5542748e-05 3.8373488e-05 9.4285714 + 57100 0.00074371147 0 2.8066609e-05 1.8321889e-05 3.9806125e-05 9.4285714 + 57200 0.00081400221 0 2.8670502e-05 2.8899856e-05 4.0663376e-05 9.4285714 + 57300 0.000917037 0 2.7824502e-05 3.9014624e-05 4.2174406e-05 9.4285714 + 57400 0.00094626663 0 2.5794485e-05 4.1535293e-05 4.2086614e-05 9.4285714 + 57500 0.00093346301 0 2.5487117e-05 4.0862488e-05 4.1990151e-05 9.4285714 + 57600 0.00093999622 0 2.6720752e-05 4.0748175e-05 4.3650361e-05 9.4285714 + 57700 0.00094337314 0 2.639701e-05 4.0729782e-05 4.5121665e-05 9.4285714 + 57800 0.00092645123 0 2.6909739e-05 4.0150191e-05 4.3822005e-05 9.4285714 + 57900 0.00091253668 0 2.5642193e-05 3.6671075e-05 4.4028328e-05 9.4285714 + 58000 0.0009262852 0 2.4409205e-05 3.4409346e-05 4.4000636e-05 9.4285714 + 58100 0.00093298888 0 2.3677747e-05 3.2551966e-05 4.3694114e-05 9.4285714 + 58200 0.00093354721 0 2.2375814e-05 3.2117822e-05 4.4639312e-05 9.4285714 + 58300 0.00093283167 0 2.2884257e-05 3.090895e-05 4.5086768e-05 9.4285714 + 58400 0.00093485322 0 2.3712272e-05 3.0236548e-05 4.5930955e-05 9.4285714 + 58500 0.00092566721 0 2.405659e-05 2.87637e-05 4.8903625e-05 9.4285714 + 58600 0.00093205032 0 2.3525309e-05 2.8285934e-05 5.2291285e-05 9.4285714 + 58700 0.00094034992 0 2.4008311e-05 2.5804337e-05 5.3505489e-05 9.4285714 + 58800 0.00096489026 0 2.4355825e-05 2.8532919e-05 5.3761099e-05 9.4285714 + 58900 0.00097781296 0 2.6084526e-05 3.1039765e-05 5.2910774e-05 9.4285714 + 59000 0.00095088201 0 2.7035865e-05 3.1452129e-05 5.3165727e-05 9.4285714 + 59100 0.00092096092 0 2.6786706e-05 3.382956e-05 5.0768712e-05 9.4285714 + 59200 0.0009112309 0 2.5867113e-05 3.4359567e-05 4.9291183e-05 9.4285714 + 59300 0.00090372653 0 2.5622941e-05 3.7144276e-05 4.7289805e-05 9.4285714 + 59400 0.00086115007 0 2.2280155e-05 3.5823023e-05 4.6830658e-05 9.4285714 + 59500 0.00078451189 0 2.2220981e-05 2.6156784e-05 4.6914457e-05 9.4285714 + 59600 0.00078587175 0 2.3370931e-05 2.5032607e-05 4.9704371e-05 9.4285714 + 59700 0.00080103949 0 2.387346e-05 2.8536648e-05 4.7938414e-05 9.4285714 + 59800 0.00078782591 0 2.319423e-05 2.8210585e-05 4.7677072e-05 9.4285714 + 59900 0.00077243837 0 2.3631843e-05 2.8691006e-05 4.7228518e-05 9.4285714 + 60000 0.00075159859 0 2.3775193e-05 2.9335754e-05 4.5277107e-05 9.4285714 + 60100 0.00072169229 0 2.1979779e-05 3.0104074e-05 4.5923405e-05 9.4285714 + 60200 0.00067937954 0 2.0306575e-05 2.8735522e-05 4.5275658e-05 9.4285714 + 60300 0.00067260226 0 2.0810173e-05 2.6609433e-05 4.3648953e-05 9.4285714 + 60400 0.00069286984 0 2.4253823e-05 2.5126495e-05 4.258699e-05 9.4285714 + 60500 0.00069736312 0 2.7101459e-05 2.4283276e-05 4.2346847e-05 9.4285714 + 60600 0.00069858614 0 2.5781332e-05 2.4087945e-05 4.2183121e-05 9.4285714 + 60700 0.00069821214 0 2.4965653e-05 2.080958e-05 4.1576529e-05 9.4285714 + 60800 0.0007035508 0 2.5136105e-05 1.82106e-05 4.2416771e-05 9.4285714 + 60900 0.00070770846 0 2.4339709e-05 1.7024772e-05 4.3565509e-05 9.4285714 + 61000 0.00070195965 0 2.4160978e-05 1.561415e-05 4.4516846e-05 9.4285714 + 61100 0.00067865064 0 2.4754436e-05 1.6095324e-05 4.5917833e-05 9.4285714 + 61200 0.00063690893 0 2.2652857e-05 1.7060397e-05 4.715524e-05 9.4285714 + 61300 0.00064194236 0 2.2650362e-05 1.4267909e-05 4.3531168e-05 9.4285714 + 61400 0.00063121847 0 2.1529461e-05 1.2841701e-05 4.0585367e-05 9.4285714 + 61500 0.00065356029 0 2.3536414e-05 1.3344947e-05 4.1167487e-05 9.4285714 + 61600 0.00066743886 0 2.4866121e-05 1.3946269e-05 4.176316e-05 9.4285714 + 61700 0.00064876312 0 2.3723161e-05 1.3749913e-05 4.2058416e-05 9.4285714 + 61800 0.00063251553 0 2.3037843e-05 1.2308212e-05 4.1311007e-05 9.4285714 + 61900 0.00065196202 0 2.371008e-05 1.2119818e-05 4.1136972e-05 9.4285714 + 62000 0.00066211487 0 2.4305587e-05 1.3415536e-05 4.1013521e-05 9.4285714 + 62100 0.00063838911 0 2.3294318e-05 1.377487e-05 4.0954053e-05 9.4285714 + 62200 0.00062154839 0 2.1558175e-05 1.3359191e-05 4.1245046e-05 9.4285714 + 62300 0.00063042258 0 2.1018073e-05 1.3643859e-05 4.2295629e-05 9.4285714 + 62400 0.00064307282 0 2.2417944e-05 1.3691778e-05 4.3440168e-05 9.4285714 + 62500 0.00062261967 0 2.2993973e-05 1.3754566e-05 4.4100385e-05 9.4285714 + 62600 0.00053916399 0 1.5362019e-05 1.2502815e-05 4.4138039e-05 9.4285714 + 62700 0.00057010612 0 1.5796506e-05 1.2697622e-05 4.4452456e-05 9.4285714 + 62800 0.00057237373 0 1.5874305e-05 1.325341e-05 4.3827972e-05 9.4285714 + 62900 0.00056115858 0 1.6555148e-05 1.3080646e-05 4.434918e-05 9.4285714 + 63000 0.0005691916 0 1.7337274e-05 1.3018716e-05 4.5966666e-05 9.4285714 + 63100 0.00056814223 0 1.8372705e-05 1.3213928e-05 4.5013147e-05 9.4285714 + 63200 0.00055359969 0 1.7755667e-05 1.226889e-05 4.4263871e-05 9.4285714 + 63300 0.00053663894 0 1.6493197e-05 1.0859989e-05 4.3835591e-05 9.4285714 + 63400 0.00055318219 0 1.7265416e-05 1.2265785e-05 4.2879248e-05 9.4285714 + 63500 0.0005601025 0 1.7295499e-05 1.4239119e-05 4.3011721e-05 9.4285714 + 63600 0.00054583913 0 1.6525634e-05 1.4678843e-05 4.2469934e-05 9.4285714 + 63700 0.00053483868 0 1.6625875e-05 1.5078172e-05 4.2493824e-05 9.4285714 + 63800 0.00055522493 0 1.7480604e-05 1.5374684e-05 4.272595e-05 9.4285714 + 63900 0.00056121598 0 1.7772973e-05 1.5172133e-05 4.2798662e-05 9.4285714 + 64000 0.00054407633 0 1.6885044e-05 1.413276e-05 4.2546454e-05 9.4285714 + 64100 0.00053661653 0 1.6234338e-05 1.403684e-05 4.2825695e-05 9.4285714 + 64200 0.00055006192 0 1.6649951e-05 1.4056747e-05 4.3482046e-05 9.4285714 + 64300 0.00055163304 0 1.6461598e-05 1.3167903e-05 4.3726787e-05 9.4285714 + 64400 0.00053078787 0 1.6251525e-05 1.19464e-05 4.3358318e-05 9.4285714 + 64500 0.00052058058 0 1.6643557e-05 1.2630836e-05 4.3429169e-05 9.4285714 + 64600 0.00052834957 0 1.7353655e-05 1.364227e-05 4.2400392e-05 9.4285714 + 64700 0.00051311026 0 1.758087e-05 1.4884436e-05 4.228116e-05 9.4285714 + 64800 0.00048606856 0 1.8167314e-05 1.5185881e-05 4.1313198e-05 9.4285714 + 64900 0.00047345864 0 1.8776746e-05 1.5164217e-05 3.998748e-05 9.4285714 + 65000 0.00048454696 0 1.8995386e-05 1.4818088e-05 3.9244802e-05 9.4285714 + 65100 0.00048928041 0 1.8341025e-05 1.3978549e-05 3.9434274e-05 9.4285714 + 65200 0.00047037779 0 1.7440302e-05 1.2970355e-05 3.8631037e-05 9.4285714 + 65300 0.000474477 0 1.7730462e-05 1.2778417e-05 3.8374171e-05 9.4285714 + 65400 0.00047558993 0 1.8645893e-05 1.303845e-05 3.9299974e-05 9.4285714 + 65500 0.00046258212 0 1.8683635e-05 1.2737042e-05 3.99647e-05 9.4285714 + 65600 0.00044433429 0 1.6571796e-05 1.2754279e-05 3.8518715e-05 9.4285714 + 65700 0.00045238336 0 1.5273478e-05 1.2923777e-05 3.6940008e-05 9.4285714 + 65800 0.00045926142 0 1.5338149e-05 1.2009407e-05 3.6438821e-05 9.4285714 + 65900 0.00045814994 0 1.5980648e-05 1.1749036e-05 3.6297575e-05 9.4285714 + 66000 0.00045395179 0 1.7924167e-05 1.2624087e-05 3.7065746e-05 9.4285714 + 66100 0.00044097892 0 1.9034226e-05 1.356976e-05 3.8933851e-05 9.4285714 + 66200 0.00041508101 0 1.8402026e-05 1.4705713e-05 3.8748663e-05 9.4285714 + 66300 0.00041227685 0 1.908236e-05 1.6649716e-05 3.7753553e-05 9.4285714 + 66400 0.00039539458 0 1.8057048e-05 1.6143874e-05 3.7074006e-05 9.4285714 + 66500 0.00038647539 0 1.698015e-05 1.3801339e-05 3.5358951e-05 9.4285714 + 66600 0.00037432719 0 1.7509843e-05 1.4033428e-05 3.5206119e-05 9.4285714 + 66700 0.00035679642 0 1.8373478e-05 1.412795e-05 3.2664378e-05 9.4285714 + 66800 0.00034618795 0 1.9514845e-05 1.4608894e-05 3.2352472e-05 9.4285714 + 66900 0.00032906055 0 1.8736605e-05 1.523461e-05 3.3161408e-05 9.4285714 + 67000 0.00031945785 0 1.6984612e-05 1.4969242e-05 3.3142807e-05 9.4285714 + 67100 0.00031672216 0 1.7483062e-05 1.5927363e-05 3.3297451e-05 9.4285714 + 67200 0.00030445379 0 1.7092794e-05 1.5979956e-05 3.3953736e-05 9.4285714 + 67300 0.00028386109 0 1.6371034e-05 1.4946504e-05 3.3294272e-05 9.4285714 + 67400 0.00028463754 0 1.6562782e-05 1.522773e-05 3.3193414e-05 9.4285714 + 67500 0.00028212316 0 1.7000058e-05 1.688192e-05 3.0305767e-05 9.4285714 + 67600 0.00027447589 0 1.7252228e-05 1.7793217e-05 2.7940287e-05 9.4285714 + 67700 0.00026388856 0 1.788708e-05 1.7737963e-05 2.7767523e-05 9.4285714 + 67800 0.00024769801 0 1.7986182e-05 1.6911674e-05 2.6242072e-05 9.4285714 + 67900 0.00024192231 0 1.8117237e-05 1.6810584e-05 2.5489128e-05 9.4285714 + 68000 0.00023732277 0 1.7792025e-05 1.6237435e-05 2.3955138e-05 9.4285714 + 68100 0.0002230537 0 1.8040504e-05 1.509807e-05 2.4258324e-05 9.4285714 + 68200 0.00020295655 0 1.7396258e-05 1.432954e-05 2.2297953e-05 9.4285714 + 68300 0.0002040692 0 1.4709241e-05 1.3357816e-05 1.9379008e-05 9.4285714 + 68400 0.0001928169 0 1.3319281e-05 1.3285272e-05 1.9247674e-05 9.4285714 + 68500 0.00019326451 0 1.3554406e-05 1.3433023e-05 2.0649044e-05 9.4285714 + 68600 0.00019061041 0 1.3385102e-05 1.3584385e-05 1.9332432e-05 9.4285714 + 68700 0.00017904605 0 1.3288304e-05 1.3807963e-05 1.7099578e-05 9.4285714 + 68800 0.00017200167 0 1.4014515e-05 1.3305447e-05 1.6005157e-05 9.4285714 + 68900 0.00016728354 0 1.4358398e-05 1.4318143e-05 1.7530654e-05 9.4285714 + 69000 0.00015703321 0 1.5503927e-05 1.5119926e-05 1.7369909e-05 9.4285714 + 69100 0.00014835113 0 1.6646462e-05 1.3971022e-05 1.6344915e-05 9.4285714 + 69200 0.00014631648 0 1.5954987e-05 1.2795675e-05 1.6309035e-05 9.4285714 + 69300 0.00014587978 0 1.5293418e-05 1.2677732e-05 1.7233536e-05 9.4285714 + 69400 0.0001418924 0 1.5258493e-05 1.3019793e-05 1.7515483e-05 9.4285714 + 69500 0.00013332024 0 1.4812384e-05 1.303409e-05 1.7383204e-05 9.4285714 + 69600 0.00013320187 0 1.4156146e-05 1.3180657e-05 1.7662244e-05 9.4285714 + 69700 0.00013039836 0 1.3247552e-05 1.2811783e-05 1.6799406e-05 9.4285714 + 69800 0.00012003394 0 1.2945301e-05 1.2559804e-05 1.5746066e-05 9.4285714 + 69900 0.00011651147 0 1.2355239e-05 1.2393181e-05 1.4350427e-05 9.4285714 + 70000 0.00012197106 0 1.1842768e-05 1.3044816e-05 1.4170863e-05 9.4285714 + 70100 0.00011813389 0 1.1625743e-05 1.3313213e-05 1.5063448e-05 9.4285714 + 70200 0.00011097253 0 1.1590401e-05 1.2554923e-05 1.4597134e-05 9.4285714 + 70300 0.00010887364 0 1.1158154e-05 1.1895927e-05 1.31874e-05 9.4285714 + 70400 0.00010916786 0 1.0956876e-05 1.180273e-05 1.2846539e-05 9.4285714 + 70500 0.00010031774 0 1.0360778e-05 1.1514343e-05 1.2521203e-05 9.4285714 + 70600 9.1002834e-05 0 1.0300514e-05 1.117085e-05 1.1527003e-05 9.4285714 + 70700 8.9186179e-05 0 1.0609829e-05 1.0737094e-05 1.0837865e-05 9.4285714 + 70800 9.1206485e-05 0 1.0401734e-05 9.9843249e-06 1.0249157e-05 9.4285714 + 70900 9.2333335e-05 0 1.0193791e-05 9.0808065e-06 9.8992907e-06 9.4285714 + 71000 9.1646266e-05 0 1.0160677e-05 8.7435373e-06 9.7169582e-06 9.4285714 + 71100 8.9976882e-05 0 1.0153135e-05 9.1409494e-06 9.5718498e-06 9.4285714 + 71200 8.7702811e-05 0 9.8902233e-06 9.1879521e-06 9.8218671e-06 9.4285714 + 71300 8.6905185e-05 0 9.5383545e-06 8.7211783e-06 1.0499374e-05 9.4285714 + 71400 8.5684023e-05 0 9.253314e-06 8.3885129e-06 1.0606272e-05 9.4285714 + 71500 8.303695e-05 0 8.8819413e-06 8.3461936e-06 1.0273368e-05 9.4285714 + 71600 8.0199459e-05 0 8.9747038e-06 8.2066881e-06 9.9704252e-06 9.4285714 + 71700 7.8917712e-05 0 9.0271304e-06 7.7429742e-06 9.9361512e-06 9.4285714 + 71800 8.006745e-05 0 8.8187404e-06 7.4107567e-06 9.9020703e-06 9.4285714 + 71900 7.8740588e-05 0 8.5325535e-06 7.4640436e-06 9.6978695e-06 9.4285714 + 72000 7.758597e-05 0 8.4232259e-06 7.4096936e-06 1.0295265e-05 9.4285714 + 72100 7.7221401e-05 0 8.2221646e-06 7.0735469e-06 1.0729758e-05 9.4285714 + 72200 7.6375029e-05 0 7.8256335e-06 6.6839282e-06 1.0036496e-05 9.4285714 + 72300 7.2834947e-05 0 7.3129398e-06 6.5549375e-06 9.3647818e-06 9.4285714 + 72400 7.2648265e-05 0 7.1756961e-06 6.6155121e-06 9.9549307e-06 9.4285714 + 72500 7.3708292e-05 0 7.2472933e-06 6.3958474e-06 1.0123332e-05 9.4285714 + 72600 7.1153221e-05 0 7.3278587e-06 6.1367701e-06 9.7342661e-06 9.4285714 + 72700 6.9093949e-05 0 7.4363962e-06 5.9533119e-06 9.7560578e-06 9.4285714 + 72800 7.0003138e-05 0 7.5425112e-06 5.8275253e-06 1.0368232e-05 9.4285714 + 72900 7.097186e-05 0 7.4852771e-06 5.9091762e-06 1.0469988e-05 9.4285714 + 73000 6.9754446e-05 0 7.1428704e-06 6.0128613e-06 9.845617e-06 9.4285714 + 73100 6.8919462e-05 0 6.8577848e-06 6.0078752e-06 9.5062768e-06 9.4285714 + 73200 7.0813485e-05 0 6.915193e-06 5.8464766e-06 9.5542243e-06 9.4285714 + 73300 7.2448906e-05 0 7.202029e-06 5.9255145e-06 9.366303e-06 9.4285714 + 73400 7.1636811e-05 0 7.3658376e-06 6.0353436e-06 9.0035204e-06 9.4285714 + 73500 7.0735739e-05 0 7.3378932e-06 5.9233113e-06 9.2103137e-06 9.4285714 + 73600 7.103569e-05 0 7.4016369e-06 5.7191072e-06 9.590302e-06 9.4285714 + 73700 7.1516165e-05 0 7.5406525e-06 5.5544712e-06 9.2023549e-06 9.4285714 + 73800 7.0454708e-05 0 7.349261e-06 5.3580841e-06 8.44158e-06 9.4285714 + 73900 7.0921505e-05 0 7.0116409e-06 5.019628e-06 8.392926e-06 9.4285714 + 74000 7.3462894e-05 0 6.8708293e-06 4.6604305e-06 8.6159539e-06 9.4285714 + 74100 7.3200399e-05 0 6.760504e-06 4.5172181e-06 8.6590907e-06 9.4285714 + 74200 7.1848724e-05 0 6.598806e-06 4.5142909e-06 8.9015449e-06 9.4285714 + 74300 7.2382347e-05 0 6.4910604e-06 4.55638e-06 9.5190459e-06 9.4285714 + 74400 7.3931763e-05 0 6.5463337e-06 4.557173e-06 9.9812236e-06 9.4285714 + 74500 7.4402751e-05 0 6.7422317e-06 4.5967137e-06 9.9997382e-06 9.4285714 + 74600 7.3859362e-05 0 6.7302615e-06 4.5719524e-06 9.8667104e-06 9.4285714 + 74700 7.5361374e-05 0 6.6009004e-06 4.5572386e-06 9.8530775e-06 9.4285714 + 74800 7.7630509e-05 0 6.5656345e-06 4.6832234e-06 9.892975e-06 9.4285714 + 74900 7.7455142e-05 0 6.6195469e-06 4.8215952e-06 9.8988386e-06 9.4285714 + 75000 7.6480769e-05 0 6.6957621e-06 4.8937859e-06 1.0118373e-05 9.4285714 + 75100 7.7275693e-05 0 6.8416988e-06 5.0008953e-06 1.0508524e-05 9.4285714 + 75200 7.8822667e-05 0 7.0137661e-06 5.114046e-06 1.0681512e-05 9.4285714 + 75300 7.923137e-05 0 7.0852228e-06 5.2313082e-06 1.088256e-05 9.4285714 + 75400 7.9015035e-05 0 7.0293657e-06 5.2742411e-06 1.1348177e-05 9.4285714 + 75500 8.0621162e-05 0 6.8467092e-06 5.2679705e-06 1.1831246e-05 9.4285714 + 75600 8.2299447e-05 0 6.6752346e-06 5.2465333e-06 1.1929829e-05 9.4285714 + 75700 8.1993378e-05 0 6.6903556e-06 5.2647445e-06 1.1895978e-05 9.4285714 + 75800 8.1758987e-05 0 6.8566142e-06 5.3086877e-06 1.1919614e-05 9.4285714 + 75900 8.3084215e-05 0 7.0165672e-06 5.385502e-06 1.2070322e-05 9.4285714 + 76000 8.197148e-05 0 7.2302761e-06 5.8394738e-06 1.2278973e-05 9.4285714 + 76100 7.3534139e-05 0 7.7489979e-06 6.0492251e-06 1.2550083e-05 9.4285714 + 76200 6.8283079e-05 0 7.2365372e-06 6.0007678e-06 1.2602817e-05 9.4285714 + 76300 7.8227289e-05 0 6.526694e-06 6.0271465e-06 1.2329383e-05 9.4285714 + 76400 8.2994806e-05 0 6.1815571e-06 5.9430881e-06 1.1701935e-05 9.4285714 + 76500 8.3014892e-05 0 6.1364257e-06 5.9854633e-06 1.1722691e-05 9.4285714 + 76600 8.4226362e-05 0 6.1828506e-06 6.107284e-06 1.1920214e-05 9.4285714 + 76700 8.6131526e-05 0 6.3343928e-06 6.350283e-06 1.228658e-05 9.4285714 + 76800 8.5731394e-05 0 6.4776958e-06 6.4683255e-06 1.249724e-05 9.4285714 + 76900 8.5941781e-05 0 6.4853553e-06 6.4244197e-06 1.2593229e-05 9.4285714 + 77000 8.8001094e-05 0 6.5171523e-06 6.6329655e-06 1.2912514e-05 9.4285714 + 77100 8.7224729e-05 0 6.8494875e-06 7.3872568e-06 1.3297612e-05 9.4285714 + 77200 8.4102799e-05 0 7.0894804e-06 7.3299263e-06 1.367949e-05 9.4285714 + 77300 8.0313409e-05 0 7.4098021e-06 7.2858555e-06 1.3836101e-05 9.4285714 + 77400 7.9230413e-05 0 8.2603924e-06 7.7732932e-06 1.3810185e-05 9.4285714 + 77500 7.811033e-05 0 8.7674355e-06 7.5406409e-06 1.4227076e-05 9.4285714 + 77600 7.7683573e-05 0 9.0788292e-06 7.8133163e-06 1.471022e-05 9.4285714 + 77700 7.5680467e-05 0 8.9108768e-06 8.317342e-06 1.4999553e-05 9.4285714 + 77800 7.3449559e-05 0 8.9694781e-06 8.6900526e-06 1.5086204e-05 9.4285714 + 77900 7.3292429e-05 0 9.139058e-06 8.6084679e-06 1.492615e-05 9.4285714 + 78000 7.2392133e-05 0 9.6080208e-06 8.4852396e-06 1.4857893e-05 9.4285714 + 78100 7.0315679e-05 0 9.945291e-06 8.3218765e-06 1.4719636e-05 9.4285714 + 78200 7.1047062e-05 0 9.8105393e-06 8.1347429e-06 1.4828339e-05 9.4285714 + 78300 6.8370248e-05 0 9.9255038e-06 7.8989844e-06 1.558545e-05 9.4285714 + 78400 6.5550877e-05 0 1.0372272e-05 7.8133098e-06 1.6112e-05 9.4285714 + 78500 6.1683926e-05 0 1.0744202e-05 7.939033e-06 1.6539381e-05 9.4285714 + 78600 6.024047e-05 0 1.0791202e-05 7.9498532e-06 1.6361859e-05 9.4285714 + 78700 5.8543178e-05 0 1.0974316e-05 7.8193457e-06 1.5667857e-05 9.4285714 + 78800 5.5383435e-05 0 1.0534755e-05 7.6453258e-06 1.4396004e-05 9.4285714 + 78900 5.6871546e-05 0 1.0546809e-05 7.6401983e-06 1.380849e-05 9.4285714 + 79000 5.7192958e-05 0 1.0550826e-05 8.0833789e-06 1.3441933e-05 9.4285714 + 79100 4.9998926e-05 0 1.0683768e-05 7.9938172e-06 1.3882479e-05 9.4285714 + 79200 4.9597887e-05 0 1.0901088e-05 7.7919421e-06 1.273575e-05 9.4285714 + 79300 4.8603326e-05 0 1.0971813e-05 8.0875397e-06 1.2027443e-05 9.4285714 + 79400 4.7839304e-05 0 1.0874179e-05 8.144737e-06 1.1956832e-05 9.4285714 + 79500 4.5739018e-05 0 1.076245e-05 8.3910868e-06 1.1534616e-05 9.4285714 + 79600 4.2632104e-05 0 1.0609664e-05 8.6397142e-06 1.1473552e-05 9.4285714 + 79700 4.2716432e-05 0 1.0262604e-05 8.711707e-06 1.0969998e-05 9.4285714 + 79800 4.3345358e-05 0 9.9282847e-06 8.9481901e-06 1.0983222e-05 9.4285714 + 79900 4.2476967e-05 0 9.7375039e-06 9.2548149e-06 1.1285625e-05 9.4285714 + 80000 4.0478442e-05 0 9.558123e-06 8.9295053e-06 1.0784448e-05 9.4285714 + 80100 3.7842198e-05 0 9.0334781e-06 8.2704782e-06 1.0278932e-05 9.4285714 + 80200 2.8735215e-05 0 7.9350731e-06 7.8543447e-06 1.0121553e-05 9.4285714 + 80300 2.5008575e-05 0 7.4613405e-06 7.3076318e-06 9.699202e-06 9.4285714 + 80400 2.7560228e-05 0 7.839602e-06 7.0844901e-06 9.4586824e-06 9.4285714 + 80500 3.0888649e-05 0 8.1838091e-06 6.9204111e-06 9.2656765e-06 9.4285714 + 80600 3.2512804e-05 0 8.4973372e-06 6.7089195e-06 9.1713286e-06 9.4285714 + 80700 3.0635649e-05 0 8.6601613e-06 6.5637472e-06 8.8278453e-06 9.4285714 + 80800 2.7803874e-05 0 8.6135955e-06 6.4140616e-06 8.6556889e-06 9.4285714 + 80900 2.7488104e-05 0 8.7028796e-06 6.3379797e-06 8.3509842e-06 9.4285714 + 81000 2.5760367e-05 0 9.2034736e-06 6.7611736e-06 8.6536526e-06 9.4285714 + 81100 2.0516969e-05 0 9.0513498e-06 6.8144281e-06 9.1119465e-06 9.4285714 + 81200 1.7005384e-05 0 8.916831e-06 6.7768397e-06 9.5240286e-06 9.4285714 + 81300 1.8000969e-05 0 8.7376342e-06 6.8615088e-06 9.6206194e-06 9.4285714 + 81400 1.8404948e-05 0 8.2208204e-06 6.7371396e-06 9.0504462e-06 9.4285714 + 81500 1.7001638e-05 0 8.0003097e-06 6.7725682e-06 8.8647013e-06 9.4285714 + 81600 1.718853e-05 0 7.6914646e-06 6.9104324e-06 8.8869789e-06 9.4285714 + 81700 1.7653551e-05 0 7.3471225e-06 6.8867378e-06 8.8253446e-06 9.4285714 + 81800 1.60697e-05 0 7.0404737e-06 6.8479859e-06 8.5427076e-06 9.4285714 + 81900 1.5286837e-05 0 7.0172686e-06 6.9297068e-06 8.2722832e-06 9.4285714 + 82000 1.6023107e-05 0 7.0983015e-06 6.9736613e-06 8.1332821e-06 9.4285714 + 82100 1.5242285e-05 0 7.0688546e-06 6.8167975e-06 7.6908928e-06 9.4285714 + 82200 1.3697011e-05 0 7.0223727e-06 6.4952373e-06 7.3342404e-06 9.4285714 + 82300 1.3126258e-05 0 7.1571217e-06 6.3810604e-06 7.2195212e-06 9.4285714 + 82400 1.3101796e-05 0 7.2890863e-06 6.3506356e-06 6.9818415e-06 9.4285714 + 82500 1.2930812e-05 0 7.151416e-06 6.216239e-06 6.5772477e-06 9.4285714 + 82600 1.2105591e-05 0 6.7542664e-06 6.1120283e-06 6.3663068e-06 9.4285714 + 82700 1.1430058e-05 0 6.5788951e-06 6.0514089e-06 6.4433754e-06 9.4285714 + 82800 1.1220674e-05 0 6.5791612e-06 6.0531604e-06 6.6770698e-06 9.4285714 + 82900 1.0833337e-05 0 6.47818e-06 6.0122996e-06 6.8321143e-06 9.4285714 + 83000 9.6966107e-06 0 6.2531746e-06 5.9309876e-06 6.8402408e-06 9.4285714 + 83100 9.7912048e-06 0 6.1233799e-06 5.8467558e-06 6.8017122e-06 9.4285714 + 83200 1.0342776e-05 0 6.1812546e-06 5.7996644e-06 6.7456475e-06 9.4285714 + 83300 9.1053605e-06 0 6.2862234e-06 5.7715058e-06 6.6864541e-06 9.4285714 + 83400 8.1376574e-06 0 6.3534217e-06 5.8081229e-06 6.6544011e-06 9.4285714 + 83500 8.3013823e-06 0 6.4049353e-06 5.8627471e-06 6.6442675e-06 9.4285714 + 83600 7.5747246e-06 0 6.3101238e-06 5.9294619e-06 6.6505997e-06 9.4285714 + 83700 6.7051973e-06 0 6.1464953e-06 5.8827036e-06 6.6813364e-06 9.4285714 + 83800 6.7732855e-06 0 6.1039107e-06 5.7663207e-06 6.7463747e-06 9.4285714 + 83900 6.455146e-06 0 6.191176e-06 5.719103e-06 6.7193618e-06 9.4285714 + 84000 6.033363e-06 0 6.1987406e-06 5.6639744e-06 6.7404074e-06 9.4285714 + 84100 6.1544361e-06 0 6.1093662e-06 5.4981158e-06 6.9178146e-06 9.4285714 + 84200 5.8120515e-06 0 5.8682237e-06 5.4078594e-06 7.1748608e-06 9.4285714 + 84300 5.5925414e-06 0 5.8299675e-06 5.4425557e-06 7.3447739e-06 9.4285714 + 84400 5.9495987e-06 0 5.8440449e-06 5.5318695e-06 7.3677152e-06 9.4285714 + 84500 5.7713446e-06 0 5.8137185e-06 5.672038e-06 7.2420253e-06 9.4285714 + 84600 5.2346414e-06 0 5.7724697e-06 5.8135669e-06 7.089944e-06 9.4285714 + 84700 5.3677312e-06 0 5.7932199e-06 5.8900538e-06 6.986661e-06 9.4285714 + 84800 5.5545452e-06 0 5.8402198e-06 5.8520541e-06 6.892677e-06 9.4285714 + 84900 5.35857e-06 0 5.8265347e-06 5.8000233e-06 6.8516545e-06 9.4285714 + 85000 5.4081539e-06 0 5.783936e-06 5.7703706e-06 6.8630043e-06 9.4285714 + 85100 5.6686315e-06 0 5.7695537e-06 5.7106213e-06 6.8449127e-06 9.4285714 + 85200 5.6470622e-06 0 5.8250423e-06 5.6629171e-06 6.774264e-06 9.4285714 + 85300 5.4542991e-06 0 5.9016498e-06 5.6655349e-06 6.7281738e-06 9.4285714 + 85400 5.5974388e-06 0 5.9646597e-06 5.6947162e-06 6.6806947e-06 9.4285714 + 85500 5.9109345e-06 0 5.967179e-06 5.6810561e-06 6.6036521e-06 9.4285714 + 85600 5.8895141e-06 0 5.9638498e-06 5.6150965e-06 6.5709969e-06 9.4285714 + 85700 5.8470051e-06 0 6.0226793e-06 5.5476887e-06 6.650327e-06 9.4285714 + 85800 6.060997e-06 0 6.0805171e-06 5.5114717e-06 6.7408394e-06 9.4285714 + 85900 6.1217894e-06 0 6.1343577e-06 5.5394005e-06 6.8609753e-06 9.4285714 + 86000 5.7550467e-06 0 6.1710899e-06 5.6424943e-06 6.9634617e-06 9.4285714 + 86100 5.6513685e-06 0 6.1564873e-06 5.8517272e-06 6.9818339e-06 9.4285714 + 86200 5.7555479e-06 0 6.1071953e-06 5.9846538e-06 6.9607131e-06 9.4285714 + 86300 5.7587322e-06 0 6.1027542e-06 6.0234009e-06 6.969152e-06 9.4285714 + 86400 5.8389333e-06 0 6.1697397e-06 6.0477528e-06 7.0119472e-06 9.4285714 + 86500 5.9431034e-06 0 6.2597537e-06 6.0475988e-06 7.0667343e-06 9.4285714 + 86600 5.9655129e-06 0 6.2896528e-06 6.0010507e-06 7.0437962e-06 9.4285714 + 86700 6.042955e-06 0 6.2709737e-06 5.8440573e-06 6.9441762e-06 9.4285714 + 86800 6.2666413e-06 0 6.1964071e-06 5.6894309e-06 6.8811779e-06 9.4285714 + 86900 6.5118003e-06 0 6.1051139e-06 5.6557711e-06 6.8722493e-06 9.4285714 + 87000 6.7509257e-06 0 6.0291493e-06 5.6830661e-06 6.916898e-06 9.4285714 + 87100 6.9118143e-06 0 6.0183397e-06 5.6796551e-06 7.0011007e-06 9.4285714 + 87200 6.9983412e-06 0 6.040127e-06 5.6529434e-06 7.127229e-06 9.4285714 + 87300 7.2267392e-06 0 6.0286797e-06 5.6230076e-06 7.2573882e-06 9.4285714 + 87400 7.3928522e-06 0 6.0129878e-06 5.5947139e-06 7.4524445e-06 9.4285714 + 87500 7.1675783e-06 0 6.0469379e-06 5.7445703e-06 7.5694621e-06 9.4285714 + 87600 6.9310557e-06 0 6.1331355e-06 5.8982521e-06 7.5787155e-06 9.4285714 + 87700 6.8020949e-06 0 6.312632e-06 5.9646e-06 7.5159198e-06 9.4285714 + 87800 6.7871509e-06 0 6.4438446e-06 5.8625717e-06 7.4014079e-06 9.4285714 + 87900 7.1459737e-06 0 6.5483239e-06 5.7458287e-06 7.3742373e-06 9.4285714 + 88000 7.4791665e-06 0 6.6494489e-06 5.7733829e-06 7.5763999e-06 9.4285714 + 88100 7.4418527e-06 0 6.7353307e-06 5.903551e-06 7.7655167e-06 9.4285714 + 88200 6.8171325e-06 0 6.9359356e-06 6.0764899e-06 8.0003945e-06 9.4285714 + 88300 5.9535317e-06 0 7.0673476e-06 6.2127209e-06 8.2558166e-06 9.4285714 + 88400 5.8054385e-06 0 7.0393025e-06 6.295728e-06 8.3249618e-06 9.4285714 + 88500 5.7381974e-06 0 6.986322e-06 6.3150237e-06 8.3161166e-06 9.4285714 + 88600 5.8193958e-06 0 6.9610838e-06 6.2643723e-06 8.3456298e-06 9.4285714 + 88700 5.7843884e-06 0 7.025256e-06 6.1780449e-06 8.4360622e-06 9.4285714 + 88800 5.36122e-06 0 7.1886768e-06 6.1335975e-06 8.6566218e-06 9.4285714 + 88900 4.9662584e-06 0 7.2896286e-06 6.1156834e-06 8.7588271e-06 9.4285714 + 89000 5.0244565e-06 0 7.2730496e-06 6.083749e-06 8.7659659e-06 9.4285714 + 89100 5.2140172e-06 0 7.1617638e-06 6.0498839e-06 8.7631514e-06 9.4285714 + 89200 5.4241028e-06 0 7.0779466e-06 6.0064798e-06 8.7654482e-06 9.4285714 + 89300 5.354843e-06 0 7.0385405e-06 5.9746409e-06 8.8526601e-06 9.4285714 + 89400 4.9583346e-06 0 6.9725874e-06 5.9883731e-06 8.8784101e-06 9.4285714 + 89500 4.7804845e-06 0 6.8896169e-06 6.0555358e-06 8.7411283e-06 9.4285714 + 89600 4.5353969e-06 0 6.8441433e-06 6.1441445e-06 8.5998496e-06 9.4285714 + 89700 4.3528727e-06 0 6.9096594e-06 6.2696259e-06 8.4806368e-06 9.4285714 + 89800 4.0677397e-06 0 7.0681849e-06 6.3600745e-06 8.3821485e-06 9.4285714 + 89900 3.4743886e-06 0 7.208934e-06 6.2417154e-06 8.2590362e-06 9.4285714 + 90000 2.9448035e-06 0 7.2648444e-06 6.1025056e-06 8.1567217e-06 9.4285714 + 90100 2.8584378e-06 0 7.2361844e-06 6.0292519e-06 8.1323675e-06 9.4285714 + 90200 3.0154097e-06 0 7.1912833e-06 5.9880227e-06 8.1509776e-06 9.4285714 + 90300 3.0998012e-06 0 7.1621354e-06 5.9387681e-06 8.1447795e-06 9.4285714 + 90400 3.0622205e-06 0 7.1346468e-06 5.8551087e-06 8.0849875e-06 9.4285714 + 90500 2.8987354e-06 0 7.0808755e-06 5.7480505e-06 8.0655448e-06 9.4285714 + 90600 2.6710434e-06 0 7.0205199e-06 5.7165534e-06 8.0846444e-06 9.4285714 + 90700 2.4095074e-06 0 6.9439805e-06 5.7493599e-06 8.0259105e-06 9.4285714 + 90800 2.202904e-06 0 6.9317463e-06 5.8100449e-06 7.9027214e-06 9.4285714 + 90900 2.3181295e-06 0 7.0034101e-06 5.8778489e-06 7.7654197e-06 9.4285714 + 91000 2.3141951e-06 0 7.0766754e-06 5.9435646e-06 7.6679494e-06 9.4285714 + 91100 2.0683071e-06 0 7.0355929e-06 5.9830977e-06 7.5547272e-06 9.4285714 + 91200 1.8857219e-06 0 6.886975e-06 5.9803391e-06 7.3843659e-06 9.4285714 + 91300 1.8327584e-06 0 6.7232199e-06 5.8972482e-06 7.172749e-06 9.4285714 + 91400 1.804747e-06 0 6.6658239e-06 5.7775933e-06 6.9879557e-06 9.4285714 + 91500 1.6349771e-06 0 6.6744755e-06 5.6582742e-06 6.8615206e-06 9.4285714 + 91600 1.5216476e-06 0 6.6865456e-06 5.5795361e-06 6.7883528e-06 9.4285714 + 91700 1.6141413e-06 0 6.68539e-06 5.5586295e-06 6.7422583e-06 9.4285714 + 91800 1.6435107e-06 0 6.6317895e-06 5.6102143e-06 6.7060043e-06 9.4285714 + 91900 1.5649292e-06 0 6.5474777e-06 5.6787362e-06 6.6783459e-06 9.4285714 + 92000 1.5598003e-06 0 6.4984086e-06 5.7448839e-06 6.6563568e-06 9.4285714 + 92100 1.5645521e-06 0 6.502615e-06 5.7854556e-06 6.6299693e-06 9.4285714 + 92200 1.5384794e-06 0 6.5324855e-06 5.791917e-06 6.5998087e-06 9.4285714 + 92300 1.5428705e-06 0 6.5828146e-06 5.7573607e-06 6.564701e-06 9.4285714 + 92400 1.5481835e-06 0 6.6310796e-06 5.6780865e-06 6.551415e-06 9.4285714 + 92500 1.5193765e-06 0 6.6560684e-06 5.5916813e-06 6.568409e-06 9.4285714 + 92600 1.4779648e-06 0 6.6374647e-06 5.5138194e-06 6.605645e-06 9.4285714 + 92700 1.4401385e-06 0 6.5783557e-06 5.466179e-06 6.6343577e-06 9.4285714 + 92800 1.4263884e-06 0 6.5032532e-06 5.4548714e-06 6.6667781e-06 9.4285714 + 92900 1.4318392e-06 0 6.4100939e-06 5.475169e-06 6.7074201e-06 9.4285714 + 93000 1.4336111e-06 0 6.3386325e-06 5.5075916e-06 6.7333938e-06 9.4285714 + 93100 1.4541758e-06 0 6.3430387e-06 5.5366002e-06 6.7522163e-06 9.4285714 + 93200 1.4657669e-06 0 6.4329416e-06 5.581062e-06 6.8176723e-06 9.4285714 + 93300 1.4040886e-06 0 6.5434258e-06 5.6428482e-06 6.9238384e-06 9.4285714 + 93400 1.2988064e-06 0 6.6210628e-06 5.7043118e-06 7.0589134e-06 9.4285714 + 93500 1.2005872e-06 0 6.6510605e-06 5.7583138e-06 7.1470838e-06 9.4285714 + 93600 1.1148329e-06 0 6.6739621e-06 5.8031724e-06 7.198744e-06 9.4285714 + 93700 1.0710007e-06 0 6.7180944e-06 5.8357751e-06 7.2627754e-06 9.4285714 + 93800 1.0923979e-06 0 6.7838026e-06 5.857069e-06 7.3553254e-06 9.4285714 + 93900 1.1070785e-06 0 6.8474162e-06 5.8724205e-06 7.4260353e-06 9.4285714 + 94000 1.0836182e-06 0 6.9184593e-06 5.9063218e-06 7.4593908e-06 9.4285714 + 94100 1.0712532e-06 0 6.9659007e-06 5.9417663e-06 7.4976223e-06 9.4285714 + 94200 1.1089242e-06 0 6.9714436e-06 5.970624e-06 7.55674e-06 9.4285714 + 94300 1.1709624e-06 0 6.9375714e-06 5.9802014e-06 7.6084264e-06 9.4285714 + 94400 1.1698851e-06 0 6.8899943e-06 5.96701e-06 7.6232022e-06 9.4285714 + 94500 1.1331311e-06 0 6.8607818e-06 5.9576831e-06 7.6330828e-06 9.4285714 + 94600 1.1611176e-06 0 6.8775071e-06 5.9659895e-06 7.6539239e-06 9.4285714 + 94700 1.2014763e-06 0 6.9225704e-06 5.978896e-06 7.6602657e-06 9.4285714 + 94800 1.1833928e-06 0 6.9903173e-06 5.9981741e-06 7.6474584e-06 9.4285714 + 94900 1.1648449e-06 0 7.0650539e-06 6.0150496e-06 7.633387e-06 9.4285714 + 95000 1.1252279e-06 0 7.1072978e-06 6.0184786e-06 7.6094493e-06 9.4285714 + 95100 1.0516851e-06 0 7.1142631e-06 6.0065025e-06 7.5761571e-06 9.4285714 + 95200 1.0245214e-06 0 7.1018948e-06 5.993948e-06 7.5486922e-06 9.4285714 + 95300 1.0235812e-06 0 7.0867307e-06 6.0211446e-06 7.52964e-06 9.4285714 + 95400 9.6956254e-07 0 7.0870353e-06 6.072303e-06 7.5090138e-06 9.4285714 + 95500 8.9262312e-07 0 7.0987772e-06 6.1168082e-06 7.5033557e-06 9.4285714 + 95600 8.6064987e-07 0 7.1067297e-06 6.1317068e-06 7.4962696e-06 9.4285714 + 95700 8.7096432e-07 0 7.0919507e-06 6.1268237e-06 7.4461295e-06 9.4285714 + 95800 8.5278957e-07 0 7.0664924e-06 6.1151121e-06 7.3946799e-06 9.4285714 + 95900 7.9717781e-07 0 7.0485109e-06 6.0993542e-06 7.3743405e-06 9.4285714 + 96000 7.7875968e-07 0 7.0534076e-06 6.0721804e-06 7.38935e-06 9.4285714 + 96100 7.8525813e-07 0 7.0843748e-06 6.0420863e-06 7.4393684e-06 9.4285714 + 96200 7.7518366e-07 0 7.1238098e-06 6.028226e-06 7.5045929e-06 9.4285714 + 96300 7.6015915e-07 0 7.1481733e-06 6.0364027e-06 7.5368435e-06 9.4285714 + 96400 7.4067407e-07 0 7.1459565e-06 6.041338e-06 7.4989132e-06 9.4285714 + 96500 7.0061605e-07 0 7.1268071e-06 6.029068e-06 7.4151813e-06 9.4285714 + 96600 6.6164038e-07 0 7.098925e-06 6.0009667e-06 7.3139003e-06 9.4285714 + 96700 6.5255615e-07 0 7.0627067e-06 5.9576708e-06 7.2100844e-06 9.4285714 + 96800 6.5992528e-07 0 7.023092e-06 5.8964071e-06 7.1287006e-06 9.4285714 + 96900 6.618124e-07 0 6.9850613e-06 5.8360203e-06 7.0798167e-06 9.4285714 + 97000 6.7139818e-07 0 6.9588277e-06 5.8062928e-06 7.0552706e-06 9.4285714 + 97100 6.8703272e-07 0 6.9537175e-06 5.8222057e-06 7.0414456e-06 9.4285714 + 97200 6.9368757e-07 0 6.9628009e-06 5.8702813e-06 7.0384753e-06 9.4285714 + 97300 6.9652913e-07 0 6.9734824e-06 5.9290926e-06 7.0544858e-06 9.4285714 + 97400 6.9671901e-07 0 6.9846061e-06 6.0012529e-06 7.083092e-06 9.4285714 + 97500 6.891306e-07 0 6.9869142e-06 6.0395379e-06 7.0939696e-06 9.4285714 + 97600 6.76426e-07 0 6.9788679e-06 6.0215323e-06 7.0606545e-06 9.4285714 + 97700 6.5763751e-07 0 6.9653816e-06 5.9723094e-06 7.0096441e-06 9.4285714 + 97800 6.4854556e-07 0 6.9554426e-06 5.9303617e-06 6.9747745e-06 9.4285714 + 97900 6.5336861e-07 0 6.9405484e-06 5.9124736e-06 6.9578336e-06 9.4285714 + 98000 6.6394525e-07 0 6.9149722e-06 5.9089903e-06 6.9531064e-06 9.4285714 + 98100 6.8885885e-07 0 6.8891311e-06 5.9064849e-06 6.9546779e-06 9.4285714 + 98200 7.2201864e-07 0 6.8704207e-06 5.8899045e-06 6.9512899e-06 9.4285714 + 98300 7.3816538e-07 0 6.8523223e-06 5.8601846e-06 6.9459414e-06 9.4285714 + 98400 7.3631403e-07 0 6.8416192e-06 5.8365194e-06 6.9566027e-06 9.4285714 + 98500 7.2568853e-07 0 6.8359315e-06 5.8202579e-06 6.9826678e-06 9.4285714 + 98600 7.0490905e-07 0 6.8305302e-06 5.8023655e-06 7.0037387e-06 9.4285714 + 98700 6.8484202e-07 0 6.8328514e-06 5.7856688e-06 7.0152903e-06 9.4285714 + 98800 6.6994522e-07 0 6.8665586e-06 5.776709e-06 7.0248186e-06 9.4285714 + 98900 6.2867752e-07 0 6.922678e-06 5.7832988e-06 7.0496494e-06 9.4285714 + 99000 5.6999626e-07 0 6.9604759e-06 5.803298e-06 7.0910089e-06 9.4285714 + 99100 5.2675078e-07 0 6.9689516e-06 5.8313501e-06 7.1326482e-06 9.4285714 + 99200 4.9993032e-07 0 6.9639452e-06 5.8639097e-06 7.1679106e-06 9.4285714 + 99300 4.8034362e-07 0 6.9673566e-06 5.8886473e-06 7.2061899e-06 9.4285714 + 99400 4.633455e-07 0 6.9801545e-06 5.9075721e-06 7.2565116e-06 9.4285714 + 99500 4.423417e-07 0 6.9834282e-06 5.9253367e-06 7.3084834e-06 9.4285714 + 99600 4.2336865e-07 0 6.967599e-06 5.9390331e-06 7.3503483e-06 9.4285714 + 99700 4.0950396e-07 0 6.9366188e-06 5.9452518e-06 7.3763135e-06 9.4285714 + 99800 3.8946719e-07 0 6.9087461e-06 5.9409744e-06 7.3965059e-06 9.4285714 + 99900 3.5789226e-07 0 6.9005219e-06 5.9283255e-06 7.4220159e-06 9.4285714 + 100000 3.23165e-07 0 6.8942094e-06 5.9113196e-06 7.4570026e-06 9.4285714 +Loop time of 178.804 on 4 procs for 100000 steps with 2520 atoms + +Performance: 2416052.451 tau/day, 559.271 timesteps/s +99.5% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.068905 | 1.0142 | 3.632 | 150.2 | 0.57 +Bond | 2.4179 | 45.255 | 152.45 | 922.4 | 25.31 +Neigh | 2.7318 | 2.7504 | 2.7587 | 0.7 | 1.54 +Comm | 2.2428 | 62.076 | 153.59 | 708.9 | 34.72 +Output | 0.14703 | 1.3253 | 2.7063 | 102.7 | 0.74 +Modify | 0.66661 | 4.887 | 15.428 | 276.1 | 2.73 +Other | | 61.5 | | | 34.39 + +Nlocal: 630 ave 2513 max 0 min +Histogram: 3 0 0 0 0 0 0 0 0 1 +Nghost: 39.25 ave 150 max 0 min +Histogram: 3 0 0 0 0 0 0 0 0 1 +Neighs: 2458 ave 9821 max 0 min +Histogram: 3 0 0 0 0 0 0 0 0 1 + +Total # of neighbors = 9832 +Ave neighs/atom = 3.9015873 +Ave special neighs/atom = 36.31746 +Neighbor list builds = 5178 +Dangerous builds = 314 +Total wall time: 0:02:58 diff --git a/examples/bpm/pour/rect.mol b/examples/bpm/pour/rect.mol new file mode 100644 index 0000000000..16edb17682 --- /dev/null +++ b/examples/bpm/pour/rect.mol @@ -0,0 +1,568 @@ +#Made with create_mol.py + +63 atoms +297 bonds + +Coords +#ID x y z +1 0.0 0.0 0.0 +2 0.7348518971806154 0.7348518971806154 0.0 +3 0.7348518971806154 0.0 0.7348518971806154 +4 0.0 0.7348518971806154 0.7348518971806154 +5 1.4697037943612308 0.0 0.0 +6 1.4697037943612308 0.7348518971806154 0.7348518971806154 +7 0.0 1.4697037943612308 0.0 +8 0.7348518971806154 1.4697037943612308 0.7348518971806154 +9 1.4697037943612308 1.4697037943612308 0.0 +10 0.0 0.0 1.4697037943612308 +11 0.7348518971806154 0.7348518971806154 1.4697037943612308 +12 0.7348518971806154 0.0 2.204555691541846 +13 0.0 0.7348518971806154 2.204555691541846 +14 1.4697037943612308 0.0 1.4697037943612308 +15 1.4697037943612308 0.7348518971806154 2.204555691541846 +16 0.0 1.4697037943612308 1.4697037943612308 +17 0.7348518971806154 1.4697037943612308 2.204555691541846 +18 1.4697037943612308 1.4697037943612308 1.4697037943612308 +19 0.0 0.0 2.9394075887224616 +20 0.7348518971806154 0.7348518971806154 2.9394075887224616 +21 0.7348518971806154 0.0 3.674259485903077 +22 0.0 0.7348518971806154 3.674259485903077 +23 1.4697037943612308 0.0 2.9394075887224616 +24 1.4697037943612308 0.7348518971806154 3.674259485903077 +25 0.0 1.4697037943612308 2.9394075887224616 +26 0.7348518971806154 1.4697037943612308 3.674259485903077 +27 1.4697037943612308 1.4697037943612308 2.9394075887224616 +28 0.0 0.0 4.409111383083692 +29 0.7348518971806154 0.7348518971806154 4.409111383083692 +30 0.7348518971806154 0.0 5.143963280264308 +31 0.0 0.7348518971806154 5.143963280264308 +32 1.4697037943612308 0.0 4.409111383083692 +33 1.4697037943612308 0.7348518971806154 5.143963280264308 +34 0.0 1.4697037943612308 4.409111383083692 +35 0.7348518971806154 1.4697037943612308 5.143963280264308 +36 1.4697037943612308 1.4697037943612308 4.409111383083692 +37 0.0 0.0 5.878815177444923 +38 0.7348518971806154 0.7348518971806154 5.878815177444923 +39 0.7348518971806154 0.0 6.613667074625538 +40 0.0 0.7348518971806154 6.613667074625538 +41 1.4697037943612308 0.0 5.878815177444923 +42 1.4697037943612308 0.7348518971806154 6.613667074625538 +43 0.0 1.4697037943612308 5.878815177444923 +44 0.7348518971806154 1.4697037943612308 6.613667074625538 +45 1.4697037943612308 1.4697037943612308 5.878815177444923 +46 0.0 0.0 7.348518971806154 +47 0.7348518971806154 0.7348518971806154 7.348518971806154 +48 0.7348518971806154 0.0 8.08337086898677 +49 0.0 0.7348518971806154 8.08337086898677 +50 1.4697037943612308 0.0 7.348518971806154 +51 1.4697037943612308 0.7348518971806154 8.08337086898677 +52 0.0 1.4697037943612308 7.348518971806154 +53 0.7348518971806154 1.4697037943612308 8.08337086898677 +54 1.4697037943612308 1.4697037943612308 7.348518971806154 +55 0.0 0.0 8.818222766167384 +56 0.7348518971806154 0.7348518971806154 8.818222766167384 +57 0.7348518971806154 0.0 9.553074663348 +58 0.0 0.7348518971806154 9.553074663348 +59 1.4697037943612308 0.0 8.818222766167384 +60 1.4697037943612308 0.7348518971806154 9.553074663348 +61 0.0 1.4697037943612308 8.818222766167384 +62 0.7348518971806154 1.4697037943612308 9.553074663348 +63 1.4697037943612308 1.4697037943612308 8.818222766167384 + +Types +#ID type +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +44 1 +45 1 +46 1 +47 1 +48 1 +49 1 +50 1 +51 1 +52 1 +53 1 +54 1 +55 1 +56 1 +57 1 +58 1 +59 1 +60 1 +61 1 +62 1 +63 1 + +Diameters +#ID diameter +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +44 1 +45 1 +46 1 +47 1 +48 1 +49 1 +50 1 +51 1 +52 1 +53 1 +54 1 +55 1 +56 1 +57 1 +58 1 +59 1 +60 1 +61 1 +62 1 +63 1 + +Masses +#ID mass +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +44 1 +45 1 +46 1 +47 1 +48 1 +49 1 +50 1 +51 1 +52 1 +53 1 +54 1 +55 1 +56 1 +57 1 +58 1 +59 1 +60 1 +61 1 +62 1 +63 1 + +Bonds +#ID type atom1 atom2 +1 1 1 2 +2 1 1 3 +3 1 1 4 +4 1 1 5 +5 1 1 7 +6 1 1 10 +7 1 2 3 +8 1 2 4 +9 1 2 5 +10 1 2 6 +11 1 2 7 +12 1 2 8 +13 1 2 9 +14 1 2 11 +15 1 3 4 +16 1 3 5 +17 1 3 6 +18 1 3 8 +19 1 3 10 +20 1 3 11 +21 1 3 12 +22 1 3 14 +23 1 4 6 +24 1 4 7 +25 1 4 8 +26 1 4 10 +27 1 4 11 +28 1 4 13 +29 1 4 16 +30 1 5 6 +31 1 5 9 +32 1 5 14 +33 1 6 8 +34 1 6 9 +35 1 6 11 +36 1 6 14 +37 1 6 18 +38 1 7 8 +39 1 7 9 +40 1 7 16 +41 1 8 9 +42 1 8 11 +43 1 8 16 +44 1 8 17 +45 1 8 18 +46 1 9 18 +47 1 10 11 +48 1 10 12 +49 1 10 13 +50 1 10 14 +51 1 10 16 +52 1 10 19 +53 1 11 12 +54 1 11 13 +55 1 11 14 +56 1 11 15 +57 1 11 16 +58 1 11 17 +59 1 11 18 +60 1 12 13 +61 1 12 14 +62 1 12 15 +63 1 12 17 +64 1 12 19 +65 1 12 20 +66 1 12 21 +67 1 12 23 +68 1 13 15 +69 1 13 16 +70 1 13 17 +71 1 13 19 +72 1 13 20 +73 1 13 22 +74 1 13 25 +75 1 14 15 +76 1 14 18 +77 1 14 23 +78 1 15 17 +79 1 15 18 +80 1 15 20 +81 1 15 23 +82 1 15 27 +83 1 16 17 +84 1 16 18 +85 1 16 25 +86 1 17 18 +87 1 17 20 +88 1 17 25 +89 1 17 27 +90 1 18 27 +91 1 19 20 +92 1 19 21 +93 1 19 22 +94 1 19 23 +95 1 19 25 +96 1 19 28 +97 1 20 21 +98 1 20 22 +99 1 20 23 +100 1 20 24 +101 1 20 25 +102 1 20 26 +103 1 20 27 +104 1 20 29 +105 1 21 22 +106 1 21 23 +107 1 21 24 +108 1 21 26 +109 1 21 28 +110 1 21 29 +111 1 21 30 +112 1 21 32 +113 1 22 24 +114 1 22 25 +115 1 22 26 +116 1 22 28 +117 1 22 29 +118 1 22 34 +119 1 23 24 +120 1 23 27 +121 1 23 32 +122 1 24 26 +123 1 24 27 +124 1 24 29 +125 1 24 32 +126 1 24 36 +127 1 25 26 +128 1 25 27 +129 1 25 34 +130 1 26 27 +131 1 26 29 +132 1 26 34 +133 1 26 35 +134 1 26 36 +135 1 27 36 +136 1 28 29 +137 1 28 30 +138 1 28 31 +139 1 28 32 +140 1 28 34 +141 1 28 37 +142 1 29 30 +143 1 29 31 +144 1 29 32 +145 1 29 33 +146 1 29 34 +147 1 29 35 +148 1 29 36 +149 1 29 38 +150 1 30 31 +151 1 30 32 +152 1 30 33 +153 1 30 35 +154 1 30 37 +155 1 30 38 +156 1 30 41 +157 1 31 33 +158 1 31 34 +159 1 31 35 +160 1 31 37 +161 1 31 38 +162 1 31 40 +163 1 31 43 +164 1 32 33 +165 1 32 36 +166 1 32 41 +167 1 33 35 +168 1 33 36 +169 1 33 38 +170 1 33 41 +171 1 33 42 +172 1 33 45 +173 1 34 35 +174 1 34 36 +175 1 34 43 +176 1 35 36 +177 1 35 38 +178 1 35 43 +179 1 35 45 +180 1 36 45 +181 1 37 38 +182 1 37 39 +183 1 37 40 +184 1 37 41 +185 1 37 43 +186 1 37 46 +187 1 38 39 +188 1 38 40 +189 1 38 41 +190 1 38 42 +191 1 38 43 +192 1 38 44 +193 1 38 45 +194 1 38 47 +195 1 39 40 +196 1 39 41 +197 1 39 42 +198 1 39 44 +199 1 39 46 +200 1 39 47 +201 1 39 50 +202 1 40 42 +203 1 40 43 +204 1 40 44 +205 1 40 46 +206 1 40 47 +207 1 40 52 +208 1 41 42 +209 1 41 45 +210 1 41 50 +211 1 42 44 +212 1 42 45 +213 1 42 47 +214 1 42 50 +215 1 42 51 +216 1 42 54 +217 1 43 44 +218 1 43 45 +219 1 43 52 +220 1 44 45 +221 1 44 47 +222 1 44 52 +223 1 44 53 +224 1 44 54 +225 1 45 54 +226 1 46 47 +227 1 46 48 +228 1 46 49 +229 1 46 50 +230 1 46 52 +231 1 46 55 +232 1 47 48 +233 1 47 49 +234 1 47 50 +235 1 47 51 +236 1 47 52 +237 1 47 53 +238 1 47 54 +239 1 47 56 +240 1 48 49 +241 1 48 50 +242 1 48 51 +243 1 48 53 +244 1 48 55 +245 1 48 56 +246 1 48 57 +247 1 48 59 +248 1 49 51 +249 1 49 52 +250 1 49 53 +251 1 49 55 +252 1 49 56 +253 1 49 58 +254 1 49 61 +255 1 50 51 +256 1 50 54 +257 1 50 59 +258 1 51 53 +259 1 51 54 +260 1 51 56 +261 1 51 59 +262 1 51 63 +263 1 52 53 +264 1 52 54 +265 1 52 61 +266 1 53 54 +267 1 53 56 +268 1 53 61 +269 1 53 62 +270 1 53 63 +271 1 54 63 +272 1 55 56 +273 1 55 57 +274 1 55 58 +275 1 55 59 +276 1 55 61 +277 1 56 57 +278 1 56 58 +279 1 56 59 +280 1 56 60 +281 1 56 61 +282 1 56 62 +283 1 56 63 +284 1 57 58 +285 1 57 59 +286 1 57 60 +287 1 57 62 +288 1 58 60 +289 1 58 61 +290 1 58 62 +291 1 59 60 +292 1 59 63 +293 1 60 62 +294 1 60 63 +295 1 61 62 +296 1 61 63 +297 1 62 63 diff --git a/src/.gitignore b/src/.gitignore index 97e6590a2b..65077aa295 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -254,6 +254,21 @@ /pair_mesont_tpm.cpp /pair_mesont_tpm.h +/atom_vec_bpm_sphere.cpp +/atom_vec_bpm_sphere.h +/bond_bpm.cpp +/bond_bpm.h +/bond_bpm_rotational.cpp +/bond_bpm_rotational.h +/bond_bpm_spring.cpp +/bond_bpm_spring.h +/compute_nbond_atom.cpp +/compute_nbond_atom.h +/fix_nve_bpm_sphere.cpp +/fix_nve_bpm_sphere.h +/pair_bpm_spring.cpp +/pair_bpm_spring.h + /compute_adf.cpp /compute_adf.h /compute_contact_atom.cpp @@ -792,8 +807,6 @@ /fix_orient_eco.h /fix_orient_fcc.cpp /fix_orient_fcc.h -/fix_pair_tracker.cpp -/fix_pair_tracker.h /fix_peri_neigh.cpp /fix_peri_neigh.h /fix_phonon.cpp @@ -1524,3 +1537,4 @@ /pair_smtbq.h /pair_vashishta*.cpp /pair_vashishta*.h + diff --git a/src/BPM/atom_vec_bpm_sphere.cpp b/src/BPM/atom_vec_bpm_sphere.cpp new file mode 100644 index 0000000000..3b775cdd83 --- /dev/null +++ b/src/BPM/atom_vec_bpm_sphere.cpp @@ -0,0 +1,245 @@ +/* ---------------------------------------------------------------------- + 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 "atom_vec_bpm_sphere.h" + +#include "atom.h" +#include "error.h" +#include "fix.h" +#include "fix_adapt.h" +#include "math_const.h" +#include "modify.h" +#include "utils.h" + +#include + +using namespace LAMMPS_NS; +using MathConst::MY_PI; + +/* ---------------------------------------------------------------------- */ + +AtomVecBPMSphere::AtomVecBPMSphere(LAMMPS *_lmp) : AtomVec(_lmp) +{ + mass_type = PER_ATOM; + molecular = Atom::MOLECULAR; + bonds_allow = 1; + + atom->molecule_flag = 1; + atom->sphere_flag = 1; + atom->radius_flag = atom->rmass_flag = atom->omega_flag = atom->torque_flag = atom->quat_flag = 1; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in a string does not matter + // except: fields_data_atom & fields_data_vel must match data file + + // clang-format off + fields_grow = (char *) "molecule num_bond bond_type bond_atom nspecial special radius rmass " + "omega torque quat"; + fields_copy = (char *) "molecule num_bond bond_type bond_atom nspecial special radius rmass " + "omega quat"; + fields_comm = (char *) ""; + fields_comm_vel = (char *) "omega quat"; + fields_reverse = (char *) "torque"; + fields_border = (char *) "molecule radius rmass"; + fields_border_vel = (char *) "molecule radius rmass omega quat"; + fields_exchange = (char *) "molecule num_bond bond_type bond_atom nspecial special radius rmass " + "omega quat"; + fields_restart = (char *) "molecule num_bond bond_type bond_atom radius rmass omega quat"; + fields_create = (char *) "molecule num_bond nspecial radius rmass omega quat"; + fields_data_atom = (char *) "id molecule type radius rmass x"; + fields_data_vel = (char *) "id v omega"; + // clang-format on + + bond_per_atom = 0; + bond_negative = NULL; +} + +/* ---------------------------------------------------------------------- + process sub-style args + optional arg = 0/1 for static/dynamic particle radii +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::process_args(int narg, char **arg) +{ + if (narg != 0 && narg != 1) error->all(FLERR, "Illegal atom_style bpm/sphere command"); + + radvary = 0; + if (narg == 1) { + radvary = utils::numeric(FLERR, arg[0], true, lmp); + if (radvary < 0 || radvary > 1) error->all(FLERR, "Illegal atom_style bpm/sphere command"); + } + + // dynamic particle radius and mass must be communicated every step + + if (radvary) { + fields_comm = (char *) "radius rmass"; + fields_comm_vel = (char *) "radius rmass omega"; + } + + // delay setting up of fields until now + + setup_fields(); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBPMSphere::init() +{ + AtomVec::init(); + + // check if optional radvary setting should have been set to 1 + + for (int i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style, "adapt") == 0) { + FixAdapt *fix = (FixAdapt *) modify->fix[i]; + if (fix->diamflag && radvary == 0) + error->all(FLERR, "Fix adapt changes atom radii but atom_style bpm/sphere is not dynamic"); + } +} + +/* ---------------------------------------------------------------------- + set local copies of all grow ptrs used by this class, except defaults + needed in replicate when 2 atom classes exist and it calls pack_restart() +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::grow_pointers() +{ + radius = atom->radius; + rmass = atom->rmass; + omega = atom->omega; + quat = atom->quat; + + num_bond = atom->num_bond; + bond_type = atom->bond_type; + nspecial = atom->nspecial; +} + +/* ---------------------------------------------------------------------- + initialize non-zero atom quantities +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::create_atom_post(int ilocal) +{ + radius[ilocal] = 0.5; + rmass[ilocal] = 4.0 * MY_PI / 3.0 * 0.5 * 0.5 * 0.5; + + quat[ilocal][0] = 1.0; + quat[ilocal][1] = 0.0; + quat[ilocal][2] = 0.0; + quat[ilocal][3] = 0.0; +} + +/* ---------------------------------------------------------------------- + modify values for AtomVec::pack_restart() to pack +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::pack_restart_pre(int ilocal) +{ + // insure bond_negative vector is needed length + + if (bond_per_atom < atom->bond_per_atom) { + delete[] bond_negative; + bond_per_atom = atom->bond_per_atom; + bond_negative = new int[bond_per_atom]; + } + + // flip any negative types to positive and flag which ones + + any_bond_negative = 0; + for (int m = 0; m < num_bond[ilocal]; m++) { + if (bond_type[ilocal][m] < 0) { + bond_negative[m] = 1; + bond_type[ilocal][m] = -bond_type[ilocal][m]; + any_bond_negative = 1; + } else + bond_negative[m] = 0; + } +} + +/* ---------------------------------------------------------------------- + unmodify values packed by AtomVec::pack_restart() +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::pack_restart_post(int ilocal) +{ + // restore the flagged types to their negative values + + if (any_bond_negative) { + for (int m = 0; m < num_bond[ilocal]; m++) + if (bond_negative[m]) bond_type[ilocal][m] = -bond_type[ilocal][m]; + } +} + +/* ---------------------------------------------------------------------- + initialize other atom quantities after AtomVec::unpack_restart() +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::unpack_restart_init(int ilocal) +{ + nspecial[ilocal][0] = 0; + nspecial[ilocal][1] = 0; + nspecial[ilocal][2] = 0; +} + +/* ---------------------------------------------------------------------- + modify what AtomVec::data_atom() just unpacked + or initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::data_atom_post(int ilocal) +{ + radius_one = 0.5 * atom->radius[ilocal]; + radius[ilocal] = radius_one; + if (radius_one > 0.0) rmass[ilocal] *= 4.0 * MY_PI / 3.0 * radius_one * radius_one * radius_one; + + if (rmass[ilocal] <= 0.0) error->one(FLERR, "Invalid density in Atoms section of data file"); + + omega[ilocal][0] = 0.0; + omega[ilocal][1] = 0.0; + omega[ilocal][2] = 0.0; + + quat[ilocal][0] = 1.0; + quat[ilocal][1] = 0.0; + quat[ilocal][2] = 0.0; + quat[ilocal][3] = 0.0; + + num_bond[ilocal] = 0; + nspecial[ilocal][0] = 0; + nspecial[ilocal][1] = 0; + nspecial[ilocal][2] = 0; +} + +/* ---------------------------------------------------------------------- + modify values for AtomVec::pack_data() to pack +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::pack_data_pre(int ilocal) +{ + radius_one = radius[ilocal]; + rmass_one = rmass[ilocal]; + + radius[ilocal] *= 2.0; + if (radius_one != 0.0) + rmass[ilocal] = rmass_one / (4.0 * MY_PI / 3.0 * radius_one * radius_one * radius_one); +} + +/* ---------------------------------------------------------------------- + unmodify values packed by AtomVec::pack_data() +------------------------------------------------------------------------- */ + +void AtomVecBPMSphere::pack_data_post(int ilocal) +{ + radius[ilocal] = radius_one; + rmass[ilocal] = rmass_one; +} diff --git a/src/BPM/atom_vec_bpm_sphere.h b/src/BPM/atom_vec_bpm_sphere.h new file mode 100644 index 0000000000..e7672eeb3c --- /dev/null +++ b/src/BPM/atom_vec_bpm_sphere.h @@ -0,0 +1,82 @@ +/* -*- 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 ATOM_CLASS +// clang-format off +AtomStyle(bpm/sphere,AtomVecBPMSphere); +// clang-format on +#else + +#ifndef LMP_ATOM_VEC_BPM_SPHERE_H +#define LMP_ATOM_VEC_BPM_SPHERE_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecBPMSphere : public AtomVec { + public: + AtomVecBPMSphere(class LAMMPS *); + void process_args(int, char **) override; + void init() override; + + void grow_pointers() override; + void create_atom_post(int) override; + void pack_restart_pre(int) override; + void pack_restart_post(int) override; + void unpack_restart_init(int) override; + void data_atom_post(int) override; + void pack_data_pre(int) override; + void pack_data_post(int) override; + + private: + int *num_bond; + int **bond_type; + int **nspecial; + + double *radius, *rmass; + double **omega, **torque, **quat; + + int any_bond_negative; + int bond_per_atom; + int *bond_negative; + + int radvary; + double radius_one, rmass_one; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + +E: Invalid radius in Atoms section of data file + +Radius must be >= 0.0. + +E: Invalid density in Atoms section of data file + +Density value cannot be <= 0.0. + +*/ diff --git a/src/BPM/bond_bpm.cpp b/src/BPM/bond_bpm.cpp new file mode 100644 index 0000000000..b019815cfa --- /dev/null +++ b/src/BPM/bond_bpm.cpp @@ -0,0 +1,415 @@ +/* ---------------------------------------------------------------------- + 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 "bond_bpm.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "fix_bond_history.h" +#include "fix_store_local.h" +#include "fix_update_special_bonds.h" +#include "force.h" +#include "memory.h" +#include "modify.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +BondBPM::BondBPM(LAMMPS *_lmp) : + Bond(_lmp), id_fix_dummy(nullptr), id_fix_dummy2(nullptr), id_fix_update(nullptr), + id_fix_bond_history(nullptr), id_fix_store_local(nullptr), id_fix_prop_atom(nullptr), + fix_store_local(nullptr), fix_bond_history(nullptr), fix_update_special_bonds(nullptr), + pack_choice(nullptr), output_data(nullptr) + +{ + overlay_flag = 0; + prop_atom_flag = 0; + nvalues = 0; + + r0_max_estimate = 0.0; + max_stretch = 1.0; + + // create dummy fix as placeholder for FixUpdateSpecialBonds & BondHistory + // this is so final order of Modify:fix will conform to input script + // BondHistory technically only needs this if updateflag = 1 + + id_fix_dummy = utils::strdup("BPM_DUMMY"); + modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy)); + + id_fix_dummy2 = utils::strdup("BPM_DUMMY2"); + modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy2)); +} + +/* ---------------------------------------------------------------------- */ + +BondBPM::~BondBPM() +{ + delete[] pack_choice; + + if (id_fix_dummy) modify->delete_fix(id_fix_dummy); + if (id_fix_dummy2) modify->delete_fix(id_fix_dummy2); + if (id_fix_update) modify->delete_fix(id_fix_update); + if (id_fix_bond_history) modify->delete_fix(id_fix_bond_history); + if (id_fix_store_local) modify->delete_fix(id_fix_store_local); + if (id_fix_prop_atom) modify->delete_fix(id_fix_prop_atom); + + delete[] id_fix_dummy; + delete[] id_fix_dummy2; + delete[] id_fix_update; + delete[] id_fix_bond_history; + delete[] id_fix_store_local; + delete[] id_fix_prop_atom; + + memory->destroy(output_data); +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::init_style() +{ + if (id_fix_store_local) { + auto ifix = modify->get_fix_by_id(id_fix_store_local); + if (!ifix) error->all(FLERR, "Cannot find fix store/local"); + if (strcmp(ifix->style, "STORE_LOCAL") != 0) + error->all(FLERR, "Incorrect fix style matched, not store/local"); + fix_store_local = dynamic_cast(ifix); + fix_store_local->nvalues = nvalues; + } + + if (overlay_flag) { + if (force->special_lj[1] != 1.0) + error->all(FLERR, + "With overlay/pair, BPM bond styles require special_bonds weight of 1.0 for " + "first neighbors"); + if (id_fix_update) { + modify->delete_fix(id_fix_update); + delete[] id_fix_update; + id_fix_update = nullptr; + } + } else { + // Require atoms know about all of their bonds and if they break + if (force->newton_bond) + error->all(FLERR, "Without overlay/pair, BPM bond styles require Newton bond off"); + + // special lj must be 0 1 1 to censor pair forces between bonded particles + // special coulomb must be 1 1 1 to ensure all pairs are included in the + // neighbor list and 1-3 and 1-4 special bond lists are skipped + if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) + error->all(FLERR, + "Without overlay/pair, BPM bond sytles requires special LJ weights = 0,1,1"); + if (force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 || + force->special_coul[3] != 1.0) + error->all(FLERR, + "Without overlay/pair, BPM bond sytles requires special Coulomb weights = 1,1,1"); + + if (id_fix_dummy) { + id_fix_update = utils::strdup("BPM_UPDATE_SPECIAL_BONDS"); + fix_update_special_bonds = dynamic_cast(modify->replace_fix( + id_fix_dummy, fmt::format("{} all UPDATE_SPECIAL_BONDS", id_fix_update), 1)); + delete[] id_fix_dummy; + id_fix_dummy = nullptr; + } + } + + if (force->angle || force->dihedral || force->improper) + error->all(FLERR, "Bond style bpm cannot be used with 3,4-body interactions"); + if (atom->molecular == 2) + error->all(FLERR, "Bond style bpm cannot be used with atom style template"); + + // special 1-3 and 1-4 weights must be 1 to prevent building 1-3 and 1-4 special bond lists + if (force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0 || force->special_coul[2] != 1.0 || + force->special_coul[3] != 1.0) + error->all(FLERR, "Bond style bpm requires 1-3 and 1-4 special weights of 1.0"); +} + +/* ---------------------------------------------------------------------- + global settings + All args before store/local command are saved for potential args + for specific bond BPM substyles + All args after optional store/local command are variables stored + in the compute store/local +------------------------------------------------------------------------- */ + +void BondBPM::settings(int narg, char **arg) +{ + leftover_iarg.clear(); + + int iarg = 0; + while (iarg < narg) { + if (strcmp(arg[iarg], "store/local") == 0) { + nvalues = 0; + id_fix_store_local = utils::strdup(arg[iarg + 1]); + store_local_freq = utils::inumeric(FLERR, arg[iarg + 2], false, lmp); + pack_choice = new FnPtrPack[narg - iarg - 1]; + iarg += 3; + while (iarg < narg) { + if (strcmp(arg[iarg], "id1") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_id1; + } else if (strcmp(arg[iarg], "id2") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_id2; + } else if (strcmp(arg[iarg], "time") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_time; + } else if (strcmp(arg[iarg], "x") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_x; + } else if (strcmp(arg[iarg], "y") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_y; + } else if (strcmp(arg[iarg], "z") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_z; + } else if (strcmp(arg[iarg], "x/ref") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_x_ref; + prop_atom_flag = 1; + } else if (strcmp(arg[iarg], "y/ref") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_y_ref; + prop_atom_flag = 1; + } else if (strcmp(arg[iarg], "z/ref") == 0) { + pack_choice[nvalues++] = &BondBPM::pack_z_ref; + prop_atom_flag = 1; + } else { + break; + } + iarg++; + } + } else if (strcmp(arg[iarg], "overlay/pair") == 0) { + overlay_flag = 1; + iarg++; + } else { + leftover_iarg.push_back(iarg); + iarg++; + } + } + + if (id_fix_store_local) { + + if (nvalues == 0) + error->all(FLERR, "Storing local data must include at least one value to output"); + memory->create(output_data, nvalues, "bond/bpm:output_data"); + + auto ifix = modify->get_fix_by_id(id_fix_store_local); + if (!ifix) + ifix = modify->add_fix( + fmt::format("{} all STORE_LOCAL {} {}", id_fix_store_local, store_local_freq, nvalues)); + fix_store_local = dynamic_cast(ifix); + + // Use property/atom to save reference positions as it can transfer to ghost atoms + // This won't work for instances where bonds are added (e.g. fix pour) but in those cases + // a reference state isn't well defined + if (prop_atom_flag == 1) { + + id_fix_prop_atom = utils::strdup("BPM_property_atom"); + char *x_ref_id = utils::strdup("BPM_X_REF"); + char *y_ref_id = utils::strdup("BPM_Y_REF"); + char *z_ref_id = utils::strdup("BPM_Z_REF"); + + ifix = modify->get_fix_by_id(id_fix_prop_atom); + if (!ifix) + ifix = modify->add_fix(fmt::format("{} all property/atom {} {} {} ghost yes", + id_fix_prop_atom, x_ref_id, y_ref_id, z_ref_id)); + + int type_flag; + int col_flag; + index_x_ref = atom->find_custom(x_ref_id, type_flag, col_flag); + index_y_ref = atom->find_custom(y_ref_id, type_flag, col_flag); + index_z_ref = atom->find_custom(z_ref_id, type_flag, col_flag); + + delete[] x_ref_id; + delete[] y_ref_id; + delete[] z_ref_id; + + if (ifix->restart_reset) { + ifix->restart_reset = 0; + } else { + double *x_ref = atom->dvector[index_x_ref]; + double *y_ref = atom->dvector[index_y_ref]; + double *z_ref = atom->dvector[index_z_ref]; + + double **x = atom->x; + for (int i = 0; i < atom->nlocal; i++) { + x_ref[i] = x[i][0]; + y_ref[i] = x[i][1]; + z_ref[i] = x[i][2]; + } + } + } + } +} + +/* ---------------------------------------------------------------------- + used to check bond communiction cutoff - not perfect, estimates based on local-local only +------------------------------------------------------------------------- */ + +double BondBPM::equilibrium_distance(int /*i*/) +{ + // Ghost atoms may not yet be communicated, this may only be an estimate + if (r0_max_estimate == 0) { + int type, j; + double delx, dely, delz, r; + double **x = atom->x; + for (int i = 0; i < atom->nlocal; i++) { + for (int m = 0; m < atom->num_bond[i]; m++) { + type = atom->bond_type[i][m]; + if (type == 0) continue; + + j = atom->map(atom->bond_atom[i][m]); + if (j == -1) continue; + + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + domain->minimum_image(delx, dely, delz); + + r = sqrt(delx * delx + dely * dely + delz * delz); + if (r > r0_max_estimate) r0_max_estimate = r; + } + } + + double temp; + MPI_Allreduce(&r0_max_estimate, &temp, 1, MPI_DOUBLE, MPI_MAX, world); + r0_max_estimate = temp; + } + + // Divide out heuristic prefactor added in comm class + return max_stretch * r0_max_estimate / 1.5; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::process_broken(int i, int j) +{ + if (fix_store_local) { + for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n, i, j); + + fix_store_local->add_data(output_data, i, j); + } + + if (fix_update_special_bonds) fix_update_special_bonds->add_broken_bond(i, j); + + // Manually search and remove from atom arrays + // need to remove in case special bonds arrays rebuilt + int m, n; + int nlocal = atom->nlocal; + + tagint *tag = atom->tag; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + int *num_bond = atom->num_bond; + + if (i < nlocal) { + for (m = 0; m < num_bond[i]; m++) { + if (bond_atom[i][m] == tag[j]) { + bond_type[i][m] = 0; + n = num_bond[i]; + bond_type[i][m] = bond_type[i][n - 1]; + bond_atom[i][m] = bond_atom[i][n - 1]; + fix_bond_history->shift_history(i, m, n - 1); + fix_bond_history->delete_history(i, n - 1); + num_bond[i]--; + break; + } + } + } + + if (j < nlocal) { + for (m = 0; m < num_bond[j]; m++) { + if (bond_atom[j][m] == tag[i]) { + bond_type[j][m] = 0; + n = num_bond[j]; + bond_type[j][m] = bond_type[j][n - 1]; + bond_atom[j][m] = bond_atom[j][n - 1]; + fix_bond_history->shift_history(j, m, n - 1); + fix_bond_history->delete_history(j, n - 1); + num_bond[j]--; + break; + } + } + } +} + +/* ---------------------------------------------------------------------- + one method for every keyword bond bpm can output + the atom property is packed into array or vector +------------------------------------------------------------------------- */ + +void BondBPM::pack_id1(int n, int i, int /*j*/) +{ + tagint *tag = atom->tag; + output_data[n] = tag[i]; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_id2(int n, int /*i*/, int j) +{ + tagint *tag = atom->tag; + output_data[n] = tag[j]; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_time(int n, int /*i*/, int /*j*/) +{ + bigint time = update->ntimestep; + output_data[n] = time; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_x(int n, int i, int j) +{ + double **x = atom->x; + output_data[n] = (x[i][0] + x[j][0]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_y(int n, int i, int j) +{ + double **x = atom->x; + output_data[n] = (x[i][1] + x[j][1]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_z(int n, int i, int j) +{ + double **x = atom->x; + output_data[n] = (x[i][2] + x[j][2]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_x_ref(int n, int i, int j) +{ + double *x = atom->dvector[index_x_ref]; + output_data[n] = (x[i] + x[j]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_y_ref(int n, int i, int j) +{ + double *y = atom->dvector[index_y_ref]; + output_data[n] = (y[i] + y[j]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void BondBPM::pack_z_ref(int n, int i, int j) +{ + double *z = atom->dvector[index_z_ref]; + output_data[n] = (z[i] + z[j]) * 0.5; +} diff --git a/src/BPM/bond_bpm.h b/src/BPM/bond_bpm.h new file mode 100644 index 0000000000..ca9eb4f846 --- /dev/null +++ b/src/BPM/bond_bpm.h @@ -0,0 +1,98 @@ +/* -*- 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. +------------------------------------------------------------------------- */ + +#ifndef LMP_BOND_BPM_H +#define LMP_BOND_BPM_H + +#include "bond.h" + +#include + +namespace LAMMPS_NS { + +class BondBPM : public Bond { + public: + BondBPM(class LAMMPS *); + ~BondBPM() override; + void compute(int, int) override = 0; + void coeff(int, char **) override = 0; + void init_style() override; + void settings(int, char **) override; + double equilibrium_distance(int) override; + void write_restart(FILE *) override{}; + void read_restart(FILE *) override{}; + void write_data(FILE *) override{}; + double single(int, double, int, int, double &) override = 0; + + protected: + double r0_max_estimate; + double max_stretch; + int store_local_freq; + + std::vector leftover_iarg; + + char *id_fix_dummy, *id_fix_dummy2; + char *id_fix_update, *id_fix_bond_history; + char *id_fix_store_local, *id_fix_prop_atom; + class FixStoreLocal *fix_store_local; + class FixBondHistory *fix_bond_history; + class FixUpdateSpecialBonds *fix_update_special_bonds; + + void process_broken(int, int); + typedef void (BondBPM::*FnPtrPack)(int, int, int); + FnPtrPack *pack_choice; // ptrs to pack functions + double *output_data; + + int prop_atom_flag, nvalues, overlay_flag; + int index_x_ref, index_y_ref, index_z_ref; + + void pack_id1(int, int, int); + void pack_id2(int, int, int); + void pack_time(int, int, int); + void pack_x(int, int, int); + void pack_y(int, int, int); + void pack_z(int, int, int); + void pack_x_ref(int, int, int); + void pack_y_ref(int, int, int); + void pack_z_ref(int, int, int); +}; + +} // namespace LAMMPS_NS + +#endif + +/* ERROR/WARNING messages: + +E: Cannot find fix store/local + +Fix id cannot be found. + +E: Illegal bond_style command + +Self-explanatory. + +E: Bond style bpm must include at least one value to output + +Must include at least one bond property to store in fix store/local + +E: Bond style bpm cannot be used with 3,4-body interactions + +No angle, dihedral, or improper styles can be defined when using +bond style bpm. + +E: Bond style bpm cannot be used with atom style template + +This bond style can change the bond topology which is not +allowed with this atom style. + +*/ diff --git a/src/BPM/bond_bpm_rotational.cpp b/src/BPM/bond_bpm_rotational.cpp new file mode 100644 index 0000000000..a43b4c7500 --- /dev/null +++ b/src/BPM/bond_bpm_rotational.cpp @@ -0,0 +1,796 @@ +/* ---------------------------------------------------------------------- + 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 "bond_bpm_rotational.h" + +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "fix_bond_history.h" +#include "force.h" +#include "math_const.h" +#include "math_extra.h" +#include "memory.h" +#include "modify.h" +#include "neighbor.h" + +#include + +#define EPSILON 1e-10 + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +BondBPMRotational::BondBPMRotational(LAMMPS *_lmp) : BondBPM(_lmp) +{ + Kr = nullptr; + Ks = nullptr; + Kt = nullptr; + Kb = nullptr; + Fcr = nullptr; + Fcs = nullptr; + Tct = nullptr; + Tcb = nullptr; + gnorm = nullptr; + gslide = nullptr; + groll = nullptr; + gtwist = nullptr; + partial_flag = 1; + smooth_flag = 1; +} + +/* ---------------------------------------------------------------------- */ + +BondBPMRotational::~BondBPMRotational() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(Kr); + memory->destroy(Ks); + memory->destroy(Kt); + memory->destroy(Kb); + memory->destroy(Fcr); + memory->destroy(Fcs); + memory->destroy(Tct); + memory->destroy(Tcb); + memory->destroy(gnorm); + memory->destroy(gslide); + memory->destroy(groll); + memory->destroy(gtwist); + } +} + +/* ---------------------------------------------------------------------- */ + +double BondBPMRotational::acos_limit(double c) +{ + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + return acos(c); +} + +/* ---------------------------------------------------------------------- + Store data for a single bond - if bond added after LAMMPS init (e.g. pour) +------------------------------------------------------------------------- */ + +double BondBPMRotational::store_bond(int n, int i, int j) +{ + double delx, dely, delz, r, rinv; + double **x = atom->x; + tagint *tag = atom->tag; + double **bondstore = fix_bond_history->bondstore; + + if (tag[i] < tag[j]) { + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + } else { + delx = x[j][0] - x[i][0]; + dely = x[j][1] - x[i][1]; + delz = x[j][2] - x[i][2]; + } + + r = sqrt(delx * delx + dely * dely + delz * delz); + rinv = 1.0 / r; + + bondstore[n][0] = r; + bondstore[n][1] = delx * rinv; + bondstore[n][2] = dely * rinv; + bondstore[n][3] = delz * rinv; + + if (i < atom->nlocal) { + for (int m = 0; m < atom->num_bond[i]; m++) { + if (atom->bond_atom[i][m] == tag[j]) { + fix_bond_history->update_atom_value(i, m, 0, r); + fix_bond_history->update_atom_value(i, m, 1, delx * rinv); + fix_bond_history->update_atom_value(i, m, 2, dely * rinv); + fix_bond_history->update_atom_value(i, m, 3, delz * rinv); + } + } + } + + if (j < atom->nlocal) { + for (int m = 0; m < atom->num_bond[j]; m++) { + if (atom->bond_atom[j][m] == tag[i]) { + fix_bond_history->update_atom_value(j, m, 0, r); + fix_bond_history->update_atom_value(j, m, 1, delx * rinv); + fix_bond_history->update_atom_value(j, m, 2, dely * rinv); + fix_bond_history->update_atom_value(j, m, 3, delz * rinv); + } + } + } + + return r; +} + +/* ---------------------------------------------------------------------- + Store data for all bonds called once +------------------------------------------------------------------------- */ + +void BondBPMRotational::store_data() +{ + int i, j, m, type; + double delx, dely, delz, r, rinv; + double **x = atom->x; + int **bond_type = atom->bond_type; + tagint *tag = atom->tag; + + for (i = 0; i < atom->nlocal; i++) { + for (m = 0; m < atom->num_bond[i]; m++) { + type = bond_type[i][m]; + + //Skip if bond was turned off + if (type < 0) continue; + + // map to find index n for tag + j = atom->map(atom->bond_atom[i][m]); + if (j == -1) error->one(FLERR, "Atom missing in BPM bond"); + + // Save orientation as pointing towards small tag + if (tag[i] < tag[j]) { + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + } else { + delx = x[j][0] - x[i][0]; + dely = x[j][1] - x[i][1]; + delz = x[j][2] - x[i][2]; + } + + // Get closest image in case bonded with ghost + domain->minimum_image(delx, dely, delz); + r = sqrt(delx * delx + dely * dely + delz * delz); + rinv = 1.0 / r; + + fix_bond_history->update_atom_value(i, m, 0, r); + fix_bond_history->update_atom_value(i, m, 1, delx * rinv); + fix_bond_history->update_atom_value(i, m, 2, dely * rinv); + fix_bond_history->update_atom_value(i, m, 3, delz * rinv); + } + } + + fix_bond_history->post_neighbor(); +} + +/* ---------------------------------------------------------------------- + Calculate forces using formulation in: + 1) Y. Wang Acta Geotechnica 2009 + 2) P. Mora & Y. Wang Advances in Geomcomputing 2009 +---------------------------------------------------------------------- */ + +double BondBPMRotational::elastic_forces(int i1, int i2, int type, double &Fr, double r_mag, + double r0_mag, double r_mag_inv, double * /*rhat*/, + double *r, double *r0, double *force1on2, + double *torque1on2, double *torque2on1) +{ + double breaking, temp, r0_dot_rb, c, gamma; + double psi, theta, cos_phi, sin_phi; + double mag_in_plane, mag_out_plane; + double Fs_mag, Tt_mag, Tb_mag; + + double q1[4], q2[4]; + double q2inv[4], mq[4], mqinv[4], qp21[4], q21[4], qtmp[4]; + double rb[3], rb_x_r0[3], s[3], t[3]; + double Fs[3], Fsp[3], F_rot[3], Ftmp[3]; + double Ts[3], Tb[3], Tt[3], Tbp[3], Ttp[3], Tsp[3], T_rot[3], Ttmp[3]; + + double **quat = atom->quat; + + q1[0] = quat[i1][0]; + q1[1] = quat[i1][1]; + q1[2] = quat[i1][2]; + q1[3] = quat[i1][3]; + + q2[0] = quat[i2][0]; + q2[1] = quat[i2][1]; + q2[2] = quat[i2][2]; + q2[3] = quat[i2][3]; + + // Calculate normal forces, rb = bond vector in particle 1's frame + MathExtra::qconjugate(q2, q2inv); + MathExtra::quatrotvec(q2inv, r, rb); + Fr = Kr[type] * (r_mag - r0_mag); + + MathExtra::scale3(Fr * r_mag_inv, rb, F_rot); + + // Calculate forces due to tangential displacements (no rotation) + r0_dot_rb = MathExtra::dot3(r0, rb); + c = r0_dot_rb * r_mag_inv / r0_mag; + gamma = acos_limit(c); + + MathExtra::cross3(rb, r0, rb_x_r0); + MathExtra::cross3(rb, rb_x_r0, s); + MathExtra::norm3(s); + + MathExtra::scale3(Ks[type] * r_mag * gamma, s, Fs); + + // Calculate torque due to tangential displacements + MathExtra::cross3(r0, rb, t); + MathExtra::norm3(t); + + MathExtra::scale3(0.5 * r_mag * Ks[type] * r_mag * gamma, t, Ts); + + // Relative rotation force/torque + // Use representation of X'Y'Z' rotations from Wang, Mora 2009 + temp = r_mag + rb[2]; + if (temp < 0.0) temp = 0.0; + mq[0] = sqrt(2) * 0.5 * sqrt(temp * r_mag_inv); + + temp = sqrt(rb[0] * rb[0] + rb[1] * rb[1]); + if (temp != 0.0) { + mq[1] = -sqrt(2) * 0.5 / temp; + temp = r_mag - rb[2]; + if (temp < 0.0) temp = 0.0; + mq[1] *= sqrt(temp * r_mag_inv); + mq[2] = -mq[1]; + mq[1] *= rb[1]; + mq[2] *= rb[0]; + } else { + // If aligned along z axis, x,y terms zero (r_mag-rb[2] = 0) + mq[1] = 0.0; + mq[2] = 0.0; + } + mq[3] = 0.0; + + // qp21 = opposite of r^\circ_21 in Wang + // q21 = opposite of r_21 in Wang + MathExtra::quatquat(q2inv, q1, qp21); + MathExtra::qconjugate(mq, mqinv); + MathExtra::quatquat(mqinv, qp21, qtmp); + MathExtra::quatquat(qtmp, mq, q21); + + temp = sqrt(q21[0] * q21[0] + q21[3] * q21[3]); + if (temp != 0.0) { + c = q21[0] / temp; + psi = 2.0 * acos_limit(c); + } else { + c = 0.0; + psi = 0.0; + } + + // Map negative rotations + if (q21[3] < 0.0) // sin = q21[3]/temp + psi = -psi; + + if (q21[3] == 0.0) psi = 0.0; + + c = q21[0] * q21[0] - q21[1] * q21[1] - q21[2] * q21[2] + q21[3] * q21[3]; + theta = acos_limit(c); + + // Separately calculte magnitude of quaternion in x-y and out of x-y planes + // to avoid dividing by zero + mag_out_plane = (q21[0] * q21[0] + q21[3] * q21[3]); + mag_in_plane = (q21[1] * q21[1] + q21[2] * q21[2]); + + if (mag_in_plane == 0.0) { + // No rotation => no bending/shear torque or extra shear force + // achieve by setting cos/sin = 0 + cos_phi = 0.0; + sin_phi = 0.0; + } else if (mag_out_plane == 0.0) { + // Calculate angle in plane + cos_phi = q21[2] / sqrt(mag_in_plane); + sin_phi = -q21[1] / sqrt(mag_in_plane); + } else { + // Default equations in Mora, Wang 2009 + cos_phi = q21[1] * q21[3] + q21[0] * q21[2]; + sin_phi = q21[2] * q21[3] - q21[0] * q21[1]; + + cos_phi /= sqrt(mag_out_plane * mag_in_plane); + sin_phi /= sqrt(mag_out_plane * mag_in_plane); + } + + Tbp[0] = -Kb[type] * theta * sin_phi; + Tbp[1] = Kb[type] * theta * cos_phi; + Tbp[2] = 0.0; + + Ttp[0] = 0.0; + Ttp[1] = 0.0; + Ttp[2] = Kt[type] * psi; + + Fsp[0] = -0.5 * Ks[type] * r_mag * theta * cos_phi; + Fsp[1] = -0.5 * Ks[type] * r_mag * theta * sin_phi; + Fsp[2] = 0.0; + + Tsp[0] = 0.25 * Ks[type] * r_mag * r_mag * theta * sin_phi; + Tsp[1] = -0.25 * Ks[type] * r_mag * r_mag * theta * cos_phi; + Tsp[2] = 0.0; + + // Rotate forces/torques back to 1st particle's frame + + MathExtra::quatrotvec(mq, Fsp, Ftmp); + MathExtra::quatrotvec(mq, Tsp, Ttmp); + for (int m = 0; m < 3; m++) { + Fs[m] += Ftmp[m]; + Ts[m] += Ttmp[m]; + } + + MathExtra::quatrotvec(mq, Tbp, Tb); + MathExtra::quatrotvec(mq, Ttp, Tt); + + // Sum forces and calculate magnitudes + F_rot[0] += Fs[0]; + F_rot[1] += Fs[1]; + F_rot[2] += Fs[2]; + MathExtra::quatrotvec(q2, F_rot, force1on2); + + T_rot[0] = Ts[0] + Tt[0] + Tb[0]; + T_rot[1] = Ts[1] + Tt[1] + Tb[1]; + T_rot[2] = Ts[2] + Tt[2] + Tb[2]; + MathExtra::quatrotvec(q2, T_rot, torque1on2); + + T_rot[0] = Ts[0] - Tt[0] - Tb[0]; + T_rot[1] = Ts[1] - Tt[1] - Tb[1]; + T_rot[2] = Ts[2] - Tt[2] - Tb[2]; + MathExtra::quatrotvec(q2, T_rot, torque2on1); + + Fs_mag = MathExtra::len3(Fs); + Tt_mag = MathExtra::len3(Tt); + Tb_mag = MathExtra::len3(Tb); + + breaking = Fr / Fcr[type] + Fs_mag / Fcs[type] + Tb_mag / Tcb[type] + Tt_mag / Tct[type]; + if (breaking < 0.0) breaking = 0.0; + + return breaking; +} + +/* ---------------------------------------------------------------------- + Calculate damping using formulation in + Y. Wang, F. Alonso-Marroquin, W. Guo 2015 + Note: n points towards 1 vs pointing towards 2 +---------------------------------------------------------------------- */ + +void BondBPMRotational::damping_forces(int i1, int i2, int type, double &Fr, double *rhat, + double *r, double *force1on2, double *torque1on2, + double *torque2on1) +{ + double v1dotr, v2dotr, w1dotr, w2dotr; + double s1[3], s2[3], tdamp[3], tmp[3]; + double vn1[3], vn2[3], vt1[3], vt2[3], vroll[3]; + double wxn1[3], wxn2[3], wn1[3], wn2[3]; + + double **v = atom->v; + double **omega = atom->omega; + + // Damp normal velocity difference + v1dotr = MathExtra::dot3(v[i1], rhat); + v2dotr = MathExtra::dot3(v[i2], rhat); + + MathExtra::scale3(v1dotr, rhat, vn1); + MathExtra::scale3(v2dotr, rhat, vn2); + + MathExtra::sub3(vn1, vn2, tmp); + MathExtra::scale3(gnorm[type], tmp); + Fr = MathExtra::lensq3(tmp); + MathExtra::add3(force1on2, tmp, force1on2); + + // Damp tangential objective velocities + MathExtra::sub3(v[i1], vn1, vt1); + MathExtra::sub3(v[i2], vn2, vt2); + + MathExtra::sub3(vt2, vt1, tmp); + MathExtra::scale3(0.5, tmp); + + MathExtra::cross3(omega[i1], r, s1); + MathExtra::scale3(-0.5, s1); + MathExtra::sub3(s1, tmp, s1); // Eq 12 + + MathExtra::cross3(omega[i2], r, s2); + MathExtra::scale3(0.5, s2); + MathExtra::add3(s2, tmp, s2); // Eq 13 + + MathExtra::sub3(s1, s2, tmp); + MathExtra::scale3(gslide[type], tmp); + MathExtra::add3(force1on2, tmp, force1on2); + + // Apply corresponding torque + MathExtra::cross3(r, tmp, tdamp); + MathExtra::scale3(0.5, tdamp); + MathExtra::add3(torque1on2, tdamp, torque1on2); + MathExtra::add3(torque2on1, tdamp, torque2on1); + + // Damp rolling + MathExtra::cross3(omega[i1], rhat, wxn1); + MathExtra::cross3(omega[i2], rhat, wxn2); + MathExtra::sub3(wxn1, wxn2, vroll); // Eq. 31 + MathExtra::cross3(r, vroll, tdamp); + + MathExtra::scale3(0.5 * groll[type], tdamp); + MathExtra::add3(torque1on2, tdamp, torque1on2); + MathExtra::scale3(-1.0, tdamp); + MathExtra::add3(torque2on1, tdamp, torque2on1); + + // Damp twist + w1dotr = MathExtra::dot3(omega[i1], rhat); + w2dotr = MathExtra::dot3(omega[i2], rhat); + + MathExtra::scale3(w1dotr, rhat, wn1); + MathExtra::scale3(w2dotr, rhat, wn2); + + MathExtra::sub3(wn1, wn2, tdamp); // Eq. 38 + MathExtra::scale3(0.5 * gtwist[type], tdamp); + MathExtra::add3(torque1on2, tdamp, torque1on2); + MathExtra::scale3(-1.0, tdamp); + MathExtra::add3(torque2on1, tdamp, torque2on1); +} + +/* ---------------------------------------------------------------------- */ + +void BondBPMRotational::compute(int eflag, int vflag) +{ + + if (!fix_bond_history->stored_flag) { + fix_bond_history->stored_flag = true; + store_data(); + } + + int i1, i2, itmp, n, type; + double r[3], r0[3], rhat[3]; + double rsq, r0_mag, r_mag, r_mag_inv; + double Fr, breaking, smooth; + double force1on2[3], torque1on2[3], torque2on1[3]; + + ev_init(eflag, vflag); + + double **x = atom->x; + double **f = atom->f; + double **torque = atom->torque; + tagint *tag = atom->tag; + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + double **bondstore = fix_bond_history->bondstore; + + for (n = 0; n < nbondlist; n++) { + + // skip bond if already broken + if (bondlist[n][2] <= 0) continue; + + i1 = bondlist[n][0]; + i2 = bondlist[n][1]; + type = bondlist[n][2]; + r0_mag = bondstore[n][0]; + + // Ensure pair is always ordered such that r0 points in + // a consistent direction and to ensure numerical operations + // are identical to minimize the possibility that a bond straddling + // an mpi grid (newton off) doesn't break on one proc but not the other + if (tag[i2] < tag[i1]) { + itmp = i1; + i1 = i2; + i2 = itmp; + } + + // If bond hasn't been set - should be initialized to zero + if (r0_mag < EPSILON || std::isnan(r0_mag)) r0_mag = store_bond(n, i1, i2); + + r0[0] = bondstore[n][1]; + r0[1] = bondstore[n][2]; + r0[2] = bondstore[n][3]; + MathExtra::scale3(r0_mag, r0); + + // Note this is the reverse of Mora & Wang + MathExtra::sub3(x[i1], x[i2], r); + + rsq = MathExtra::lensq3(r); + r_mag = sqrt(rsq); + r_mag_inv = 1.0 / r_mag; + MathExtra::scale3(r_mag_inv, r, rhat); + + // ------------------------------------------------------// + // Calculate forces, check if bond breaks + // ------------------------------------------------------// + + breaking = elastic_forces(i1, i2, type, Fr, r_mag, r0_mag, r_mag_inv, rhat, r, r0, force1on2, + torque1on2, torque2on1); + + if (breaking >= 1.0) { + bondlist[n][2] = 0; + process_broken(i1, i2); + continue; + } + + damping_forces(i1, i2, type, Fr, rhat, r, force1on2, torque1on2, torque2on1); + + if (smooth_flag) { + smooth = breaking * breaking; + smooth = 1.0 - smooth * smooth; + } else { + smooth = 1.0; + } + + // ------------------------------------------------------// + // Apply forces and torques to particles + // ------------------------------------------------------// + + if (newton_bond || i1 < nlocal) { + f[i1][0] -= force1on2[0] * smooth; + f[i1][1] -= force1on2[1] * smooth; + f[i1][2] -= force1on2[2] * smooth; + + torque[i1][0] += torque2on1[0] * smooth; + torque[i1][1] += torque2on1[1] * smooth; + torque[i1][2] += torque2on1[2] * smooth; + } + + if (newton_bond || i2 < nlocal) { + f[i2][0] += force1on2[0] * smooth; + f[i2][1] += force1on2[1] * smooth; + f[i2][2] += force1on2[2] * smooth; + + torque[i2][0] += torque1on2[0] * smooth; + torque[i2][1] += torque1on2[1] * smooth; + torque[i2][2] += torque1on2[2] * smooth; + } + + if (evflag) ev_tally(i1, i2, nlocal, newton_bond, 0.0, Fr * smooth, r[0], r[1], r[2]); + } +} + +/* ---------------------------------------------------------------------- */ + +void BondBPMRotational::allocate() +{ + allocated = 1; + const int np1 = atom->nbondtypes + 1; + + memory->create(Kr, np1, "bond:Kr"); + memory->create(Ks, np1, "bond:Ks"); + memory->create(Kt, np1, "bond:Kt"); + memory->create(Kb, np1, "bond:Kb"); + memory->create(Fcr, np1, "bond:Fcr"); + memory->create(Fcs, np1, "bond:Fcs"); + memory->create(Tct, np1, "bond:Tct"); + memory->create(Tcb, np1, "bond:Tcb"); + memory->create(gnorm, np1, "bond:gnorm"); + memory->create(gslide, np1, "bond:gslide"); + memory->create(groll, np1, "bond:groll"); + memory->create(gtwist, np1, "bond:gtwist"); + + memory->create(setflag, np1, "bond:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more types +------------------------------------------------------------------------- */ + +void BondBPMRotational::coeff(int narg, char **arg) +{ + if (narg != 13) error->all(FLERR, "Incorrect args for bond coefficients"); + if (!allocated) allocate(); + + int ilo, ihi; + utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error); + + double Kr_one = utils::numeric(FLERR, arg[1], false, lmp); + double Ks_one = utils::numeric(FLERR, arg[2], false, lmp); + double Kt_one = utils::numeric(FLERR, arg[3], false, lmp); + double Kb_one = utils::numeric(FLERR, arg[4], false, lmp); + double Fcr_one = utils::numeric(FLERR, arg[5], false, lmp); + double Fcs_one = utils::numeric(FLERR, arg[6], false, lmp); + double Tct_one = utils::numeric(FLERR, arg[7], false, lmp); + double Tcb_one = utils::numeric(FLERR, arg[8], false, lmp); + double gnorm_one = utils::numeric(FLERR, arg[9], false, lmp); + double gslide_one = utils::numeric(FLERR, arg[10], false, lmp); + double groll_one = utils::numeric(FLERR, arg[11], false, lmp); + double gtwist_one = utils::numeric(FLERR, arg[12], false, lmp); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + Kr[i] = Kr_one; + Ks[i] = Ks_one; + Kt[i] = Kt_one; + Kb[i] = Kb_one; + Fcr[i] = Fcr_one; + Fcs[i] = Fcs_one; + Tct[i] = Tct_one; + Tcb[i] = Tcb_one; + gnorm[i] = gnorm_one; + gslide[i] = gslide_one; + groll[i] = groll_one; + gtwist[i] = gtwist_one; + setflag[i] = 1; + count++; + + if (Fcr[i] / Kr[i] > max_stretch) max_stretch = Fcr[i] / Kr[i]; + } + + if (count == 0) error->all(FLERR, "Incorrect args for bond coefficients"); +} + +/* ---------------------------------------------------------------------- + check for correct settings and create fix +------------------------------------------------------------------------- */ + +void BondBPMRotational::init_style() +{ + BondBPM::init_style(); + + if (!atom->quat_flag || !atom->sphere_flag) + error->all(FLERR, "Bond bpm/rotational requires atom style bpm/sphere"); + if (comm->ghost_velocity == 0) + error->all(FLERR, "Bond bpm/rotational requires ghost atoms store velocity"); + + if (domain->dimension == 2) + error->warning(FLERR, "Bond style bpm/rotational not intended for 2d use"); + + if (!id_fix_bond_history) { + id_fix_bond_history = utils::strdup("HISTORY_BPM_ROTATIONAL"); + fix_bond_history = dynamic_cast(modify->replace_fix( + id_fix_dummy2, fmt::format("{} all BOND_HISTORY 0 4", id_fix_bond_history), 1)); + delete[] id_fix_dummy2; + id_fix_dummy2 = nullptr; + } +} + +/* ---------------------------------------------------------------------- */ + +void BondBPMRotational::settings(int narg, char **arg) +{ + BondBPM::settings(narg, arg); + + int iarg; + for (std::size_t i = 0; i < leftover_iarg.size(); i++) { + iarg = leftover_iarg[i]; + if (strcmp(arg[iarg], "smooth") == 0) { + if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command"); + smooth_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); + i += 1; + } else { + error->all(FLERR, "Illegal bond_style command"); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes out coeffs to restart file +------------------------------------------------------------------------- */ + +void BondBPMRotational::write_restart(FILE *fp) +{ + fwrite(&Kr[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Ks[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Kt[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Kb[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Fcr[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Fcs[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Tct[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&Tcb[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&gnorm[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&gslide[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&groll[1], sizeof(double), atom->nbondtypes, fp); + fwrite(>wist[1], sizeof(double), atom->nbondtypes, fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads coeffs from restart file, bcasts them +------------------------------------------------------------------------- */ + +void BondBPMRotational::read_restart(FILE *fp) +{ + allocate(); + + if (comm->me == 0) { + utils::sfread(FLERR, &Kr[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Ks[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Kt[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Kb[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Fcr[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Fcs[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Tct[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &Tcb[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &gnorm[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &gslide[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &groll[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, >wist[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + } + MPI_Bcast(&Kr[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Ks[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Kt[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Kb[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Fcr[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Fcs[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Tct[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&Tcb[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&gnorm[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&gslide[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&groll[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(>wist[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + + for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void BondBPMRotational::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->nbondtypes; i++) + fprintf(fp, "%d %g %g %g %g %g %g %g %g %g %g %g %g\n", i, Kr[i], Ks[i], Kt[i], Kb[i], Fcr[i], + Fcs[i], Tct[i], Tcb[i], gnorm[i], gslide[i], groll[i], gtwist[i]); +} + +/* ---------------------------------------------------------------------- */ + +double BondBPMRotational::single(int type, double rsq, int i, int j, double &fforce) +{ + // Not yet enabled + if (type <= 0) return 0.0; + + int itmp; + if (atom->tag[j] < atom->tag[i]) { + itmp = i; + i = j; + j = itmp; + } + + double r0_mag, r_mag, r_mag_inv; + double r0[3], r[3], rhat[3]; + for (int n = 0; n < atom->num_bond[i]; n++) { + if (atom->bond_atom[i][n] == atom->tag[j]) { + r0_mag = fix_bond_history->get_atom_value(i, n, 0); + r0[0] = fix_bond_history->get_atom_value(i, n, 1); + r0[1] = fix_bond_history->get_atom_value(i, n, 2); + r0[2] = fix_bond_history->get_atom_value(i, n, 3); + } + } + + double **x = atom->x; + MathExtra::scale3(r0_mag, r0); + MathExtra::sub3(x[i], x[j], r); + + r_mag = sqrt(rsq); + r_mag_inv = 1.0 / r_mag; + MathExtra::scale3(r_mag_inv, r, rhat); + + double breaking, smooth, Fr; + double force1on2[3], torque1on2[3], torque2on1[3]; + breaking = elastic_forces(i, j, type, Fr, r_mag, r0_mag, r_mag_inv, rhat, r, r0, force1on2, + torque1on2, torque2on1); + fforce = Fr; + damping_forces(i, j, type, Fr, rhat, r, force1on2, torque1on2, torque2on1); + fforce += Fr; + + if (smooth_flag) { + smooth = breaking * breaking; + smooth = 1.0 - smooth * smooth; + fforce *= smooth; + } + return 0.0; +} diff --git a/src/BPM/bond_bpm_rotational.h b/src/BPM/bond_bpm_rotational.h new file mode 100644 index 0000000000..7244afe213 --- /dev/null +++ b/src/BPM/bond_bpm_rotational.h @@ -0,0 +1,83 @@ +/* -*- 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 BOND_CLASS +// clang-format off +BondStyle(bpm/rotational,BondBPMRotational); +// clang-format on +#else + +#ifndef LMP_BOND_BPM_ROTATIONAL_H +#define LMP_BOND_BPM_ROTATIONAL_H + +#include "bond_bpm.h" + +namespace LAMMPS_NS { + +class BondBPMRotational : public BondBPM { + public: + BondBPMRotational(class LAMMPS *); + ~BondBPMRotational() override; + void compute(int, int) override; + void coeff(int, char **) override; + void init_style() override; + void settings(int, char **) override; + void write_restart(FILE *) override; + void read_restart(FILE *) override; + void write_data(FILE *) override; + double single(int, double, int, int, double &) override; + + protected: + double *Kr, *Ks, *Kt, *Kb, *gnorm, *gslide, *groll, *gtwist; + double *Fcr, *Fcs, *Tct, *Tcb; + int smooth_flag; + + double acos_limit(double); + + double elastic_forces(int, int, int, double &, double, double, double, double *, double *, + double *, double *, double *, double *); + void damping_forces(int, int, int, double &, double *, double *, double *, double *, double *); + + void allocate(); + void store_data(); + double store_bond(int, int, int); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Atom missing in BPM bond + +Bonded atom cannot be found + +E: Incorrect args for bond coefficients + +Self-explanatory. Check the input script or data file. + +E: Bond bpm/rotational requires atom style bpm/sphere + +Self-explanatory. + +E: Bond style bpm requires 1-3 and 1-4 special weights of 1.0 + +Self-explanatory. + +W: Bond style bpm/rotational not intended for 2d use, may be inefficient + +This bond style will perform a lot of unnecessary calculations in 2d + +*/ diff --git a/src/BPM/bond_bpm_spring.cpp b/src/BPM/bond_bpm_spring.cpp new file mode 100644 index 0000000000..e2cbe5949e --- /dev/null +++ b/src/BPM/bond_bpm_spring.cpp @@ -0,0 +1,380 @@ +/* ---------------------------------------------------------------------- + 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 "bond_bpm_spring.h" + +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "fix_bond_history.h" +#include "force.h" +#include "memory.h" +#include "modify.h" +#include "neighbor.h" + +#define EPSILON 1e-10 + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +BondBPMSpring::BondBPMSpring(LAMMPS *_lmp) : BondBPM(_lmp), k(nullptr), ecrit(nullptr), gamma(nullptr) +{ + partial_flag = 1; + smooth_flag = 1; +} + +/* ---------------------------------------------------------------------- */ + +BondBPMSpring::~BondBPMSpring() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(k); + memory->destroy(ecrit); + memory->destroy(gamma); + } +} + +/* ---------------------------------------------------------------------- + Store data for a single bond - if bond added after LAMMPS init (e.g. pour) +------------------------------------------------------------------------- */ + +double BondBPMSpring::store_bond(int n, int i, int j) +{ + double delx, dely, delz, r; + double **x = atom->x; + double **bondstore = fix_bond_history->bondstore; + tagint *tag = atom->tag; + + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + r = sqrt(delx * delx + dely * dely + delz * delz); + bondstore[n][0] = r; + + if (i < atom->nlocal) { + for (int m = 0; m < atom->num_bond[i]; m++) { + if (atom->bond_atom[i][m] == tag[j]) { fix_bond_history->update_atom_value(i, m, 0, r); } + } + } + + if (j < atom->nlocal) { + for (int m = 0; m < atom->num_bond[j]; m++) { + if (atom->bond_atom[j][m] == tag[i]) { fix_bond_history->update_atom_value(j, m, 0, r); } + } + } + + return r; +} + +/* ---------------------------------------------------------------------- + Store data for all bonds called once +------------------------------------------------------------------------- */ + +void BondBPMSpring::store_data() +{ + int i, j, m, type; + double delx, dely, delz, r; + double **x = atom->x; + int **bond_type = atom->bond_type; + + for (i = 0; i < atom->nlocal; i++) { + for (m = 0; m < atom->num_bond[i]; m++) { + type = bond_type[i][m]; + + //Skip if bond was turned off + if (type < 0) continue; + + // map to find index n + j = atom->map(atom->bond_atom[i][m]); + if (j == -1) error->one(FLERR, "Atom missing in BPM bond"); + + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + // Get closest image in case bonded with ghost + domain->minimum_image(delx, dely, delz); + r = sqrt(delx * delx + dely * dely + delz * delz); + + fix_bond_history->update_atom_value(i, m, 0, r); + } + } + + fix_bond_history->post_neighbor(); +} + +/* ---------------------------------------------------------------------- */ + +void BondBPMSpring::compute(int eflag, int vflag) +{ + + if (!fix_bond_history->stored_flag) { + fix_bond_history->stored_flag = true; + store_data(); + } + + int i1, i2, itmp, n, type; + double delx, dely, delz, delvx, delvy, delvz; + double e, rsq, r, r0, rinv, smooth, fbond, dot; + + ev_init(eflag, vflag); + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + tagint *tag = atom->tag; + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + double **bondstore = fix_bond_history->bondstore; + + for (n = 0; n < nbondlist; n++) { + + // skip bond if already broken + if (bondlist[n][2] <= 0) continue; + + i1 = bondlist[n][0]; + i2 = bondlist[n][1]; + type = bondlist[n][2]; + r0 = bondstore[n][0]; + + // Ensure pair is always ordered to ensure numerical operations + // are identical to minimize the possibility that a bond straddling + // an mpi grid (newton off) doesn't break on one proc but not the other + if (tag[i2] < tag[i1]) { + itmp = i1; + i1 = i2; + i2 = itmp; + } + + // If bond hasn't been set - should be initialized to zero + if (r0 < EPSILON || std::isnan(r0)) r0 = store_bond(n, i1, i2); + + delx = x[i1][0] - x[i2][0]; + dely = x[i1][1] - x[i2][1]; + delz = x[i1][2] - x[i2][2]; + + rsq = delx * delx + dely * dely + delz * delz; + r = sqrt(rsq); + e = (r - r0) / r0; + + if (fabs(e) > ecrit[type]) { + bondlist[n][2] = 0; + process_broken(i1, i2); + continue; + } + + rinv = 1.0 / r; + fbond = k[type] * (r0 - r); + + delvx = v[i1][0] - v[i2][0]; + delvy = v[i1][1] - v[i2][1]; + delvz = v[i1][2] - v[i2][2]; + dot = delx * delvx + dely * delvy + delz * delvz; + fbond -= gamma[type] * dot * rinv; + fbond *= rinv; + + if (smooth_flag) { + smooth = (r - r0) / (r0 * ecrit[type]); + smooth *= smooth; + smooth *= smooth; + smooth *= smooth; + smooth = 1 - smooth; + fbond *= smooth; + } + + if (newton_bond || i1 < nlocal) { + f[i1][0] += delx * fbond; + f[i1][1] += dely * fbond; + f[i1][2] += delz * fbond; + } + + if (newton_bond || i2 < nlocal) { + f[i2][0] -= delx * fbond; + f[i2][1] -= dely * fbond; + f[i2][2] -= delz * fbond; + } + + if (evflag) ev_tally(i1, i2, nlocal, newton_bond, 0.0, fbond, delx, dely, delz); + } +} + +/* ---------------------------------------------------------------------- */ + +void BondBPMSpring::allocate() +{ + allocated = 1; + const int np1 = atom->nbondtypes + 1; + + memory->create(k, np1, "bond:k"); + memory->create(ecrit, np1, "bond:ecrit"); + memory->create(gamma, np1, "bond:gamma"); + + memory->create(setflag, np1, "bond:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more types +------------------------------------------------------------------------- */ + +void BondBPMSpring::coeff(int narg, char **arg) +{ + if (narg != 4) error->all(FLERR, "Incorrect args for bond coefficients"); + if (!allocated) allocate(); + + int ilo, ihi; + utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error); + + double k_one = utils::numeric(FLERR, arg[1], false, lmp); + double ecrit_one = utils::numeric(FLERR, arg[2], false, lmp); + double gamma_one = utils::numeric(FLERR, arg[3], false, lmp); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + k[i] = k_one; + ecrit[i] = ecrit_one; + gamma[i] = gamma_one; + setflag[i] = 1; + count++; + + if (1.0 + ecrit[i] > max_stretch) max_stretch = 1.0 + ecrit[i]; + } + + if (count == 0) error->all(FLERR, "Incorrect args for bond coefficients"); +} + +/* ---------------------------------------------------------------------- + check for correct settings and create fix +------------------------------------------------------------------------- */ + +void BondBPMSpring::init_style() +{ + BondBPM::init_style(); + + if (comm->ghost_velocity == 0) + error->all(FLERR, "Bond bpm/spring requires ghost atoms store velocity"); + + if (!id_fix_bond_history) { + id_fix_bond_history = utils::strdup("HISTORY_BPM_SPRING"); + fix_bond_history = dynamic_cast(modify->replace_fix( + id_fix_dummy2, fmt::format("{} all BOND_HISTORY 0 1", id_fix_bond_history), 1)); + delete[] id_fix_dummy2; + id_fix_dummy2 = nullptr; + } +} + +/* ---------------------------------------------------------------------- */ + +void BondBPMSpring::settings(int narg, char **arg) +{ + BondBPM::settings(narg, arg); + + int iarg; + for (std::size_t i = 0; i < leftover_iarg.size(); i++) { + iarg = leftover_iarg[i]; + if (strcmp(arg[iarg], "smooth") == 0) { + if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command"); + smooth_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); + i += 1; + } else { + error->all(FLERR, "Illegal bond_style command"); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes out coeffs to restart file +------------------------------------------------------------------------- */ + +void BondBPMSpring::write_restart(FILE *fp) +{ + fwrite(&k[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&ecrit[1], sizeof(double), atom->nbondtypes, fp); + fwrite(&gamma[1], sizeof(double), atom->nbondtypes, fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads coeffs from restart file, bcasts them +------------------------------------------------------------------------- */ + +void BondBPMSpring::read_restart(FILE *fp) +{ + allocate(); + + if (comm->me == 0) { + utils::sfread(FLERR, &k[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &ecrit[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + utils::sfread(FLERR, &gamma[1], sizeof(double), atom->nbondtypes, fp, nullptr, error); + } + MPI_Bcast(&k[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&ecrit[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&gamma[1], atom->nbondtypes, MPI_DOUBLE, 0, world); + + for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void BondBPMSpring::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->nbondtypes; i++) + fprintf(fp, "%d %g %g %g\n", i, k[i], ecrit[i], gamma[i]); +} + +/* ---------------------------------------------------------------------- */ + +double BondBPMSpring::single(int type, double rsq, int i, int j, double &fforce) +{ + if (type <= 0) return 0.0; + + double r0; + for (int n = 0; n < atom->num_bond[i]; n++) { + if (atom->bond_atom[i][n] == atom->tag[j]) r0 = fix_bond_history->get_atom_value(i, n, 0); + } + + double r = sqrt(rsq); + double rinv = 1.0 / r; + fforce = k[type] * (r0 - r); + + double **x = atom->x; + double **v = atom->v; + double delx = x[i][0] - x[j][0]; + double dely = x[i][1] - x[j][1]; + double delz = x[i][2] - x[j][2]; + double delvx = v[i][0] - v[j][0]; + double delvy = v[i][1] - v[j][1]; + double delvz = v[i][2] - v[j][2]; + double dot = delx * delvx + dely * delvy + delz * delvz; + fforce -= gamma[type] * dot * rinv; + fforce *= rinv; + + if (smooth_flag) { + double smooth = (r - r0) / (r0 * ecrit[type]); + smooth *= smooth; + smooth *= smooth; + smooth *= smooth; + smooth = 1 - smooth; + fforce *= smooth; + } + + return 0.0; +} diff --git a/src/BPM/bond_bpm_spring.h b/src/BPM/bond_bpm_spring.h new file mode 100644 index 0000000000..a847ed56a1 --- /dev/null +++ b/src/BPM/bond_bpm_spring.h @@ -0,0 +1,68 @@ +/* -*- 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 BOND_CLASS +// clang-format off +BondStyle(bpm/spring,BondBPMSpring); +// clang-format on +#else + +#ifndef LMP_BOND_BPM_SPRING_H +#define LMP_BOND_BPM_SPRING_H + +#include "bond_bpm.h" + +namespace LAMMPS_NS { + +class BondBPMSpring : public BondBPM { + public: + BondBPMSpring(class LAMMPS *); + ~BondBPMSpring() override; + void compute(int, int) override; + void coeff(int, char **) override; + void init_style() override; + void settings(int, char **) override; + void write_restart(FILE *) override; + void read_restart(FILE *) override; + void write_data(FILE *) override; + double single(int, double, int, int, double &) override; + + protected: + double *k, *ecrit, *gamma; + int smooth_flag; + + void allocate(); + void store_data(); + double store_bond(int, int, int); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Atom missing in BPM bond + +Bonded atom cannot be found + +E: Incorrect args for bond coefficients + +Self-explanatory. Check the input script or data file. + +E: Bond style bpm requires 1-3 and 1-4 special weights of 1.0 + +Self-explanatory. + +*/ diff --git a/src/BPM/compute_nbond_atom.cpp b/src/BPM/compute_nbond_atom.cpp new file mode 100644 index 0000000000..cc16473767 --- /dev/null +++ b/src/BPM/compute_nbond_atom.cpp @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------- + 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 "compute_nbond_atom.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "update.h" + +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +ComputeNBondAtom::ComputeNBondAtom(LAMMPS *_lmp, int narg, char **arg) : + Compute(_lmp, narg, arg), nbond(nullptr) +{ + if (narg < 3) error->all(FLERR, "Illegal compute nbond/atom command"); + + peratom_flag = 1; + size_peratom_cols = 0; + peatomflag = 1; + timeflag = 1; + comm_reverse = 1; + + nmax = 0; +} + +/* ---------------------------------------------------------------------- */ + +ComputeNBondAtom::~ComputeNBondAtom() +{ + memory->destroy(nbond); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeNBondAtom::compute_peratom() +{ + + invoked_peratom = update->ntimestep; + if (update->eflag_atom != invoked_peratom) + error->all(FLERR, "Per-atom nbond was not tallied on needed timestep"); + + // grow local nbond array if necessary + // needs to be atom->nmax in length + + if (atom->nmax > nmax) { + memory->destroy(nbond); + nmax = atom->nmax; + memory->create(nbond, nmax, "nbond/atom:nbond"); + vector_atom = nbond; + } + + // npair includes ghosts if either newton flag is set + // b/c some bonds/dihedrals call pair::ev_tally with pairwise info + // nbond includes ghosts if newton_bond is set + // ntotal includes ghosts if either newton flag is set + // KSpace includes ghosts if tip4pflag is set + + int nlocal = atom->nlocal; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + + int ntotal = nlocal; + if (force->newton) ntotal += atom->nghost; + + // set local nbond array + int i, j, k; + int *num_bond = atom->num_bond; + int newton_bond = force->newton_bond; + + for (i = 0; i < ntotal; i++) nbond[i] = 0; + + for (i = 0; i < nlocal; i++) { + for (j = 0; j < num_bond[i]; j++) { + if (bond_type[i][j] <= 0) continue; + + k = atom->map(bond_atom[i][j]); + if (k < 0) continue; + + nbond[i] += 1; + if (newton_bond) nbond[k] += 1; + } + } + + // communicate ghost nbond between neighbor procs + if (force->newton) comm->reverse_comm(this); + + // zero nbond of atoms not in group + // only do this after comm since ghost contributions must be included + int *mask = atom->mask; + + for (i = 0; i < nlocal; i++) + if (!(mask[i] & groupbit)) nbond[i] = 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int ComputeNBondAtom::pack_reverse_comm(int n, int first, double *buf) +{ + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) buf[m++] = nbond[i]; + return m; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeNBondAtom::unpack_reverse_comm(int n, int *list, double *buf) +{ + int i, j, m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + nbond[j] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based array +------------------------------------------------------------------------- */ + +double ComputeNBondAtom::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} diff --git a/src/BPM/compute_nbond_atom.h b/src/BPM/compute_nbond_atom.h new file mode 100644 index 0000000000..32a979a9e9 --- /dev/null +++ b/src/BPM/compute_nbond_atom.h @@ -0,0 +1,61 @@ +/* -*- 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 COMPUTE_CLASS +// clang-format off +ComputeStyle(nbond/atom,ComputeNBondAtom); +// clang-format on +#else + +#ifndef LMP_COMPUTE_NBOND_ATOM_H +#define LMP_COMPUTE_NBOND_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeNBondAtom : public Compute { + public: + ComputeNBondAtom(class LAMMPS *, int, char **); + ~ComputeNBondAtom() override; + void init() override {} + void compute_peratom() override; + int pack_reverse_comm(int, int, double *) override; + void unpack_reverse_comm(int, int *, double *) override; + double memory_usage() override; + + private: + int nmax; + double *nbond; +}; + +} // 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: Per-atom energy was not tallied on needed timestep + +You are using a thermo keyword that requires potentials to +have tallied energy, but they didn't on this timestep. See the +variable doc page for ideas on how to make this work. + +*/ diff --git a/src/BPM/fix_nve_bpm_sphere.cpp b/src/BPM/fix_nve_bpm_sphere.cpp new file mode 100644 index 0000000000..77e2441618 --- /dev/null +++ b/src/BPM/fix_nve_bpm_sphere.cpp @@ -0,0 +1,157 @@ +/* ---------------------------------------------------------------------- + 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 "fix_nve_bpm_sphere.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "math_extra.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathExtra; + +/* ---------------------------------------------------------------------- */ + +FixNVEBPMSphere::FixNVEBPMSphere(LAMMPS *_lmp, int narg, char **arg) : FixNVE(_lmp, narg, arg) +{ + if (narg < 3) error->all(FLERR, "Illegal fix nve/bpm/sphere command"); + + time_integrate = 1; + + // process extra keywords + // inertia = moment of inertia prefactor for sphere or disc + + inertia = 0.4; + + int iarg = 3; + while (iarg < narg) { + if (strcmp(arg[iarg], "disc") == 0) { + inertia = 0.5; + if (domain->dimension != 2) + error->all(FLERR, "Fix nve/bpm/sphere disc requires 2d simulation"); + iarg++; + } else + error->all(FLERR, "Illegal fix nve/bpm/sphere command"); + } + + inv_inertia = 1.0 / inertia; + + // error checks + + if (!atom->quat_flag || !atom->sphere_flag) + error->all(FLERR, "Fix nve/bpm/sphere requires atom style bpm/sphere"); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVEBPMSphere::init() +{ + FixNVE::init(); + + // check that all particles are finite-size spheres + // no point particles allowed + + double *radius = atom->radius; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + if (radius[i] == 0.0) error->one(FLERR, "Fix nve/bpm/sphere requires extended particles"); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVEBPMSphere::initial_integrate(int /*vflag*/) +{ + double dtq, dtfm, dtirotate, particle_inertia; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double **quat = atom->quat; + double *radius = atom->radius; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + dtq = 0.5 * dtv; + + // update v,x,omega,quat for all particles + // d_omega/dt = torque / inertia + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + x[i][2] += dtv * v[i][2]; + + particle_inertia = inertia * (radius[i] * radius[i] * rmass[i]); + dtirotate = dtf / particle_inertia; + omega[i][0] += dtirotate * torque[i][0]; + omega[i][1] += dtirotate * torque[i][1]; + omega[i][2] += dtirotate * torque[i][2]; + + MathExtra::richardson_sphere(quat[i], omega[i], dtq); + } + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNVEBPMSphere::final_integrate() +{ + double dtfm, dtirotate, particle_inertia; + + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *rmass = atom->rmass; + double *radius = atom->radius; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // update v,omega for all particles + // d_omega/dt = torque / inertia + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + + particle_inertia = inertia * (radius[i] * radius[i] * rmass[i]); + dtirotate = dtf / particle_inertia; + omega[i][0] += dtirotate * torque[i][0]; + omega[i][1] += dtirotate * torque[i][1]; + omega[i][2] += dtirotate * torque[i][2]; + } +} diff --git a/src/BPM/fix_nve_bpm_sphere.h b/src/BPM/fix_nve_bpm_sphere.h new file mode 100644 index 0000000000..48b65eb96b --- /dev/null +++ b/src/BPM/fix_nve_bpm_sphere.h @@ -0,0 +1,71 @@ +/* -*- 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 FIX_CLASS +// clang-format off +FixStyle(nve/bpm/sphere,FixNVEBPMSphere); +// clang-format on +#else + +#ifndef LMP_FIX_NVE_BPM_SPHERE_H +#define LMP_FIX_NVE_BPM_SPHERE_H + +#include "fix_nve.h" + +namespace LAMMPS_NS { + +class FixNVEBPMSphere : public FixNVE { + public: + FixNVEBPMSphere(class LAMMPS *, int, char **); + + void init() override; + void initial_integrate(int) override; + void final_integrate() override; + + protected: + double inertia, inv_inertia; + int extra; + int dlm; +}; + +} // 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: Fix nve/bpm/sphere disc requires 2d simulation + +UNDOCUMENTED + +E: Fix nve/bpm/sphere requires atom style bpm/sphere + +Self-explanatory. + +E: Fix nve/bpm/sphere update dipole requires atom attribute mu + +An atom style with this attribute is needed. + +E: Fix nve/bpm/sphere requires extended particles + +This fix can only be used for particles of a finite size. + + +*/ diff --git a/src/BPM/pair_bpm_spring.cpp b/src/BPM/pair_bpm_spring.cpp new file mode 100644 index 0000000000..0dd113e2ed --- /dev/null +++ b/src/BPM/pair_bpm_spring.cpp @@ -0,0 +1,326 @@ +/* ---------------------------------------------------------------------- + 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_bpm_spring.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairBPMSpring::PairBPMSpring(LAMMPS *_lmp) : Pair(_lmp) +{ + writedata = 1; +} + +/* ---------------------------------------------------------------------- */ + +PairBPMSpring::~PairBPMSpring() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(k); + memory->destroy(cut); + memory->destroy(gamma); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairBPMSpring::compute(int eflag, int vflag) +{ + int i, j, ii, jj, inum, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair; + double r, rsq, rinv, factor_lj; + int *ilist, *jlist, *numneigh, **firstneigh; + double vxtmp, vytmp, vztmp, delvx, delvy, delvz, dot, smooth; + + evdwl = 0.0; + if (eflag || vflag) + ev_setup(eflag, vflag); + else + evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + int newton_pair = force->newton_pair; + double *special_lj = force->special_lj; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + + if (factor_lj == 0) continue; + + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r = sqrt(rsq); + + rinv = 1.0 / r; + fpair = k[itype][jtype] * (cut[itype][jtype] - r); + + smooth = rsq / cutsq[itype][jtype]; + smooth *= smooth; + smooth *= smooth; + smooth = 1.0 - smooth; + delvx = vxtmp - v[j][0]; + delvy = vytmp - v[j][1]; + delvz = vztmp - v[j][2]; + dot = delx * delvx + dely * delvy + delz * delvz; + fpair -= gamma[itype][jtype] * dot * smooth * rinv; + + fpair *= factor_lj * rinv; + if (eflag) evdwl = 0.0; + + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; + + if (newton_pair || j < nlocal) { + f[j][0] -= delx * fpair; + f[j][1] -= dely * fpair; + f[j][2] -= delz * fpair; + } + + if (evflag) ev_tally(i, j, nlocal, newton_pair, evdwl, 0.0, fpair, delx, dely, delz); + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairBPMSpring::allocate() +{ + allocated = 1; + const int np1 = atom->ntypes + 1; + + memory->create(setflag, np1, np1, "pair:setflag"); + for (int i = 1; i < np1; i++) + for (int j = i; j < np1; j++) setflag[i][j] = 0; + + memory->create(cutsq, np1, np1, "pair:cutsq"); + + memory->create(k, np1, np1, "pair:k"); + memory->create(cut, np1, np1, "pair:cut"); + memory->create(gamma, np1, np1, "pair:gamma"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairBPMSpring::settings(int narg, char ** /*arg*/) +{ + if (narg != 0) error->all(FLERR, "Illegal pair_style command"); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairBPMSpring::coeff(int narg, char **arg) +{ + if (narg != 5) error->all(FLERR, "Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo, ihi, jlo, jhi; + utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error); + utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error); + + double k_one = utils::numeric(FLERR, arg[2], false, lmp); + double cut_one = utils::numeric(FLERR, arg[3], false, lmp); + double gamma_one = utils::numeric(FLERR, arg[4], false, lmp); + + if (cut_one <= 0.0) error->all(FLERR, "Incorrect args for pair coefficients"); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo, i); j <= jhi; j++) { + k[i][j] = k_one; + cut[i][j] = cut_one; + gamma[i][j] = gamma_one; + + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairBPMSpring::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + cut[i][j] = mix_distance(cut[i][i], cut[j][j]); + k[i][j] = mix_energy(k[i][i], k[j][j], cut[i][i], cut[j][j]); + gamma[i][j] = mix_energy(gamma[i][i], gamma[j][j], cut[i][i], cut[j][j]); + } + + cut[j][i] = cut[i][j]; + k[j][i] = k[i][j]; + gamma[j][i] = gamma[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairBPMSpring::write_restart(FILE *fp) +{ + write_restart_settings(fp); + + int i, j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j], sizeof(int), 1, fp); + if (setflag[i][j]) { + fwrite(&k[i][j], sizeof(double), 1, fp); + fwrite(&cut[i][j], sizeof(double), 1, fp); + fwrite(&gamma[i][j], sizeof(double), 1, fp); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairBPMSpring::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) fread(&setflag[i][j], sizeof(int), 1, fp); + MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world); + if (setflag[i][j]) { + if (me == 0) { + fread(&k[i][j], sizeof(double), 1, fp); + fread(&cut[i][j], sizeof(double), 1, fp); + fread(&gamma[i][j], sizeof(double), 1, fp); + } + MPI_Bcast(&k[i][j], 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&gamma[i][j], 1, MPI_DOUBLE, 0, world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void PairBPMSpring::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + fprintf(fp, "%d %g %g %g\n", i, k[i][i], cut[i][i], gamma[i][i]); +} + +/* ---------------------------------------------------------------------- + proc 0 writes all pairs to data file +------------------------------------------------------------------------- */ + +void PairBPMSpring::write_data_all(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) + fprintf(fp, "%d %d %g %g %g\n", i, j, k[i][j], cut[i][j], gamma[i][j]); +} + +/* ---------------------------------------------------------------------- */ + +double PairBPMSpring::single(int i, int j, int itype, int jtype, double rsq, double /*factor_coul*/, + double factor_lj, double &fforce) +{ + double fpair, r, rinv; + double delx, dely, delz, delvx, delvy, delvz, dot, smooth; + + if (rsq > cutsq[itype][jtype]) return 0.0; + + double **x = atom->x; + double **v = atom->v; + + r = sqrt(rsq); + rinv = 1.0 / r; + + fpair = k[itype][jtype] * (cut[itype][jtype] - r); + + smooth = rsq / cutsq[itype][jtype]; + smooth *= smooth; + smooth = 1.0 - smooth; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + delvx = v[i][0] - v[j][0]; + delvy = v[i][1] - v[j][1]; + delvz = v[i][2] - v[j][2]; + dot = delx * delvx + dely * delvy + delz * delvz; + fpair -= gamma[itype][jtype] * dot * rinv * smooth; + + fpair *= factor_lj; + fforce = fpair; + + return 0.0; +} diff --git a/src/BPM/pair_bpm_spring.h b/src/BPM/pair_bpm_spring.h new file mode 100644 index 0000000000..c868066398 --- /dev/null +++ b/src/BPM/pair_bpm_spring.h @@ -0,0 +1,64 @@ +/* -*- 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(bpm/spring,PairBPMSpring); +// clang-format on +#else + +#ifndef LMP_PAIR_BPM_SPRING_H +#define LMP_PAIR_BPM_SPRING_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairBPMSpring : public Pair { + public: + PairBPMSpring(class LAMMPS *); + ~PairBPMSpring() override; + void compute(int, int) override; + void settings(int, char **) override; + void coeff(int, char **) override; + double init_one(int, int) override; + void write_restart(FILE *) override; + void read_restart(FILE *) override; + void write_data(FILE *) override; + void write_data_all(FILE *) override; + double single(int, int, int, int, double, double, double, double &) override; + + protected: + double **k, **cut, **gamma; + + void allocate(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* 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. + +*/ diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp index ddca6269c6..2a25efc6f2 100644 --- a/src/GRANULAR/fix_pour.cpp +++ b/src/GRANULAR/fix_pour.cpp @@ -136,8 +136,7 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR,"Invalid atom type in fix pour mol command"); if (atom->molecular == Atom::TEMPLATE && onemols != atom->avec->onemols) - error->all(FLERR,"Fix pour molecule template ID must be same " - "as atom style template ID"); + error->all(FLERR,"Fix pour molecule template ID must be same as atom style template ID"); onemols[i]->check_attributes(0); // fix pour uses geoemetric center of molecule for insertion diff --git a/src/GRANULAR/pair_gran_hertz_history.cpp b/src/GRANULAR/pair_gran_hertz_history.cpp index 3901fa6a31..04fc0cf6f0 100644 --- a/src/GRANULAR/pair_gran_hertz_history.cpp +++ b/src/GRANULAR/pair_gran_hertz_history.cpp @@ -45,7 +45,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; - double radi,radj,radsum,rsq,r,rinv,rsqinv; + double radi,radj,radsum,rsq,r,rinv,rsqinv,factor_lj; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; @@ -91,6 +91,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag) int *mask = atom->mask; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; + double *special_lj = force->special_lj; inum = list->inum; ilist = list->ilist; @@ -114,8 +115,11 @@ void PairGranHertzHistory::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; j &= NEIGHMASK; + if (factor_lj == 0) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -247,6 +251,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag) fx = delx*ccel + fs1; fy = dely*ccel + fs2; fz = delz*ccel + fs3; + fx *= factor_lj; + fy *= factor_lj; + fz *= factor_lj; f[i][0] += fx; f[i][1] += fy; f[i][2] += fz; @@ -254,6 +261,9 @@ void PairGranHertzHistory::compute(int eflag, int vflag) tor1 = rinv * (dely*fs3 - delz*fs2); tor2 = rinv * (delz*fs1 - delx*fs3); tor3 = rinv * (delx*fs2 - dely*fs1); + tor1 *= factor_lj; + tor2 *= factor_lj; + tor3 *= factor_lj; torque[i][0] -= radi*tor1; torque[i][1] -= radi*tor2; torque[i][2] -= radi*tor3; diff --git a/src/GRANULAR/pair_gran_hooke.cpp b/src/GRANULAR/pair_gran_hooke.cpp index efac93c0fc..12ce25f7b3 100644 --- a/src/GRANULAR/pair_gran_hooke.cpp +++ b/src/GRANULAR/pair_gran_hooke.cpp @@ -42,7 +42,7 @@ void PairGranHooke::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz; - double radi,radj,radsum,rsq,r,rinv,rsqinv; + double radi,radj,radsum,rsq,r,rinv,rsqinv,factor_lj; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; @@ -82,6 +82,7 @@ void PairGranHooke::compute(int eflag, int vflag) int *mask = atom->mask; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; + double *special_lj = force->special_lj; inum = list->inum; ilist = list->ilist; @@ -101,8 +102,11 @@ void PairGranHooke::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; j &= NEIGHMASK; + if (factor_lj == 0) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -187,6 +191,9 @@ void PairGranHooke::compute(int eflag, int vflag) fx = delx*ccel + fs1; fy = dely*ccel + fs2; fz = delz*ccel + fs3; + fx *= factor_lj; + fy *= factor_lj; + fz *= factor_lj; f[i][0] += fx; f[i][1] += fy; f[i][2] += fz; @@ -194,6 +201,9 @@ void PairGranHooke::compute(int eflag, int vflag) tor1 = rinv * (dely*fs3 - delz*fs2); tor2 = rinv * (delz*fs1 - delx*fs3); tor3 = rinv * (delx*fs2 - dely*fs1); + tor1 *= factor_lj; + tor2 *= factor_lj; + tor3 *= factor_lj; torque[i][0] -= radi*tor1; torque[i][1] -= radi*tor2; torque[i][2] -= radi*tor3; diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 8a1e056d04..b231d50bcf 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -103,7 +103,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag) { int i, j, ii, jj, inum, jnum; double xtmp, ytmp, ztmp, delx, dely, delz, fx, fy, fz; - double radi, radj, radsum, rsq, r, rinv, rsqinv; + double radi, radj, radsum, rsq, r, rinv, rsqinv, factor_lj; double vr1, vr2, vr3, vnnr, vn1, vn2, vn3, vt1, vt2, vt3; double wr1, wr2, wr3; double vtr1, vtr2, vtr3, vrel; @@ -151,6 +151,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag) int *mask = atom->mask; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; + double *special_lj = force->special_lj; inum = list->inum; ilist = list->ilist; @@ -174,8 +175,11 @@ void PairGranHookeHistory::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; j &= NEIGHMASK; + if (factor_lj == 0) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -306,6 +310,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag) fx = delx * ccel + fs1; fy = dely * ccel + fs2; fz = delz * ccel + fs3; + fx *= factor_lj; + fy *= factor_lj; + fz *= factor_lj; f[i][0] += fx; f[i][1] += fy; f[i][2] += fz; @@ -313,6 +320,9 @@ void PairGranHookeHistory::compute(int eflag, int vflag) tor1 = rinv * (dely * fs3 - delz * fs2); tor2 = rinv * (delz * fs1 - delx * fs3); tor3 = rinv * (delx * fs2 - dely * fs1); + tor1 *= factor_lj; + tor2 *= factor_lj; + tor3 *= factor_lj; torque[i][0] -= radi * tor1; torque[i][1] -= radi * tor2; torque[i][2] -= radi * tor3; diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index bfdbef654a..a8e47bb9fc 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -150,7 +150,7 @@ void PairGranular::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv; + double radi,radj,radsum,rsq,r,rinv,factor_lj; double Reff, delta, dR, dR2, dist_to_contact; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; @@ -222,6 +222,7 @@ void PairGranular::compute(int eflag, int vflag) double *rmass = atom->rmass; int *mask = atom->mask; int nlocal = atom->nlocal; + double *special_lj = force->special_lj; inum = list->inum; ilist = list->ilist; @@ -249,8 +250,11 @@ void PairGranular::compute(int eflag, int vflag) for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; j &= NEIGHMASK; + if (factor_lj == 0) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -651,6 +655,9 @@ void PairGranular::compute(int eflag, int vflag) fx = nx*Fntot + fs1; fy = ny*Fntot + fs2; fz = nz*Fntot + fs3; + fx *= factor_lj; + fy *= factor_lj; + fz *= factor_lj; f[i][0] += fx; f[i][1] += fy; @@ -659,6 +666,9 @@ void PairGranular::compute(int eflag, int vflag) tor1 = ny*fs3 - nz*fs2; tor2 = nz*fs1 - nx*fs3; tor3 = nx*fs2 - ny*fs1; + tor1 *= factor_lj; + tor2 *= factor_lj; + tor3 *= factor_lj; dist_to_contact = radi-0.5*delta; torque[i][0] -= dist_to_contact*tor1; @@ -666,9 +676,9 @@ void PairGranular::compute(int eflag, int vflag) torque[i][2] -= dist_to_contact*tor3; if (twist_model[itype][jtype] != TWIST_NONE) { - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; + tortwist1 = magtortwist * nx * factor_lj; + tortwist2 = magtortwist * ny * factor_lj; + tortwist3 = magtortwist * nz * factor_lj; torque[i][0] += tortwist1; torque[i][1] += tortwist2; @@ -676,9 +686,9 @@ void PairGranular::compute(int eflag, int vflag) } if (roll_model[itype][jtype] != ROLL_NONE) { - torroll1 = Reff*(ny*fr3 - nz*fr2); // n cross fr - torroll2 = Reff*(nz*fr1 - nx*fr3); - torroll3 = Reff*(nx*fr2 - ny*fr1); + torroll1 = Reff*(ny*fr3 - nz*fr2) * factor_lj; // n cross fr + torroll2 = Reff*(nz*fr1 - nx*fr3) * factor_lj; + torroll3 = Reff*(nx*fr2 - ny*fr1) * factor_lj; torque[i][0] += torroll1; torque[i][1] += torroll2; diff --git a/src/MC/fix_bond_break.cpp b/src/MC/fix_bond_break.cpp index 1498cd2fd4..71408d8aed 100644 --- a/src/MC/fix_bond_break.cpp +++ b/src/MC/fix_bond_break.cpp @@ -19,11 +19,14 @@ #include "error.h" #include "force.h" #include "memory.h" +#include "modify.h" #include "neighbor.h" #include "random_mars.h" #include "respa.h" #include "update.h" +#include "fix_bond_history.h" + #include using namespace LAMMPS_NS; @@ -258,6 +261,10 @@ void FixBondBreak::post_integrate() commflag = 1; comm->forward_comm(this,2); + // find instances of bond history to delete data + auto histories = modify->get_fix_by_style("BOND_HISTORY"); + int n_histories = histories.size(); + // break bonds // if both atoms list each other as winning bond partner // and probability constraint is satisfied @@ -292,7 +299,13 @@ void FixBondBreak::post_integrate() for (k = m; k < num_bond[i]-1; k++) { bond_atom[i][k] = bond_atom[i][k+1]; bond_type[i][k] = bond_type[i][k+1]; + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->shift_history(i,k,k+1); } + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->delete_history(i,num_bond[i]-1); num_bond[i]--; break; } diff --git a/src/MC/fix_bond_create_angle.cpp b/src/MC/fix_bond_create_angle.cpp index 3ebda59f0d..f3014a4b07 100644 --- a/src/MC/fix_bond_create_angle.cpp +++ b/src/MC/fix_bond_create_angle.cpp @@ -17,21 +17,15 @@ ------------------------------------------------------------------------- */ #include "fix_bond_create_angle.h" + #include "atom.h" + #include using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -FixBondCreateAngle::FixBondCreateAngle(LAMMPS *lmp, int narg, char **arg) : - FixBondCreate(lmp, narg, arg) -{ - -} - -/* ---------------------------------------------------------------------- */ - int FixBondCreateAngle::constrain(int i, int j, double amin, double amax) { double **x = atom->x; diff --git a/src/MC/fix_bond_create_angle.h b/src/MC/fix_bond_create_angle.h index 6c74f0e6d7..ae3d6afa97 100644 --- a/src/MC/fix_bond_create_angle.h +++ b/src/MC/fix_bond_create_angle.h @@ -26,7 +26,7 @@ namespace LAMMPS_NS { class FixBondCreateAngle : public FixBondCreate { public: - FixBondCreateAngle(class LAMMPS *, int, char **); + FixBondCreateAngle(LAMMPS *_lmp, int narg, char **arg) : FixBondCreate(_lmp, narg, arg) {} private: int constrain(int, int, double, double) override; diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp index c4abf31f16..59fabc8ffe 100644 --- a/src/MC/fix_bond_swap.cpp +++ b/src/MC/fix_bond_swap.cpp @@ -22,6 +22,7 @@ #include "compute.h" #include "domain.h" #include "error.h" +#include "fix_bond_history.h" #include "force.h" #include "memory.h" #include "modify.h" @@ -446,6 +447,10 @@ void FixBondSwap::post_integrate() if (!accept) return; naccept++; + // find instances of bond/history to reset history + auto histories = modify->get_fix_by_style("BOND_HISTORY"); + int n_histories = histories.size(); + // change bond partners of affected atoms // on atom i: bond i-inext changes to i-jnext // on atom j: bond j-jnext changes to j-inext @@ -453,13 +458,33 @@ void FixBondSwap::post_integrate() // on atom jnext: bond jnext-j changes to jnext-i for (ibond = 0; ibond < num_bond[i]; ibond++) - if (bond_atom[i][ibond] == tag[inext]) bond_atom[i][ibond] = tag[jnext]; + if (bond_atom[i][ibond] == tag[inext]) { + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->delete_history(i,ibond); + bond_atom[i][ibond] = tag[jnext]; + } for (jbond = 0; jbond < num_bond[j]; jbond++) - if (bond_atom[j][jbond] == tag[jnext]) bond_atom[j][jbond] = tag[inext]; + if (bond_atom[j][jbond] == tag[jnext]) { + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->delete_history(j,jbond); + bond_atom[j][jbond] = tag[inext]; + } for (ibond = 0; ibond < num_bond[inext]; ibond++) - if (bond_atom[inext][ibond] == tag[i]) bond_atom[inext][ibond] = tag[j]; + if (bond_atom[inext][ibond] == tag[i]) { + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->delete_history(inext,ibond); + bond_atom[inext][ibond] = tag[j]; + } for (jbond = 0; jbond < num_bond[jnext]; jbond++) - if (bond_atom[jnext][jbond] == tag[j]) bond_atom[jnext][jbond] = tag[i]; + if (bond_atom[jnext][jbond] == tag[j]) { + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->delete_history(jnext,jbond); + bond_atom[jnext][jbond] = tag[i]; + } // set global tags of 4 atoms in bonds diff --git a/src/MISC/fix_pair_tracker.cpp b/src/MISC/fix_pair_tracker.cpp deleted file mode 100644 index 3616855869..0000000000 --- a/src/MISC/fix_pair_tracker.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "fix_pair_tracker.h" - -#include "atom.h" -#include "error.h" -#include "memory.h" -#include "tokenizer.h" -#include "update.h" - -#include - -using namespace LAMMPS_NS; -using namespace FixConst; - -#define DELTA 1000 - -/* ---------------------------------------------------------------------- */ - -FixPairTracker::FixPairTracker(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), nvalues(0), vector(nullptr), array(nullptr), pack_choice(nullptr) -{ - if (narg < 3) error->all(FLERR, "Illegal fix pair/tracker command"); - local_flag = 1; - - nevery = utils::inumeric(FLERR, arg[3], false, lmp); - if (nevery <= 0) error->all(FLERR, "Illegal fix pair/tracker command"); - local_freq = nevery; - - // If optional arguments included, this will be oversized - nvalues = narg - 4; - pack_choice = new FnPtrPack[nvalues]; - - tmin = -1; - type_filter = nullptr; - int iarg = 4; - nvalues = 0; - while (iarg < narg) { - if (strcmp(arg[iarg], "id1") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_id1; - } else if (strcmp(arg[iarg], "id2") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_id2; - - } else if (strcmp(arg[iarg], "time/created") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_time_created; - } else if (strcmp(arg[iarg], "time/broken") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_time_broken; - } else if (strcmp(arg[iarg], "time/total") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_time_total; - - } else if (strcmp(arg[iarg], "x") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_x; - } else if (strcmp(arg[iarg], "y") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_y; - } else if (strcmp(arg[iarg], "z") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_z; - - } else if (strcmp(arg[iarg], "r/min") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_rmin; - } else if (strcmp(arg[iarg], "r/ave") == 0) { - pack_choice[nvalues++] = &FixPairTracker::pack_rave; - - } else if (strcmp(arg[iarg], "time/min") == 0) { - if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in fix pair/tracker command"); - tmin = utils::numeric(FLERR, arg[iarg + 1], false, lmp); - iarg++; - - } else if (strcmp(arg[iarg], "type/include") == 0) { - if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in fix pair/tracker command"); - int ntypes = atom->ntypes; - int i, j, itype, jtype; - int inlo, inhi, jnlo, jnhi; - - if (!type_filter) { - memory->create(type_filter, ntypes + 1, ntypes + 1, "fix/pair/tracker:type_filter"); - - for (i = 0; i <= ntypes; i++) { - for (j = 0; j <= ntypes; j++) type_filter[i][j] = 0; - } - } - - auto iwords = Tokenizer(arg[iarg + 1], ",").as_vector(); - auto jwords = Tokenizer(arg[iarg + 2], ",").as_vector(); - - for (const auto &ifield : iwords) { - utils::bounds(FLERR, ifield, 1, ntypes, inlo, inhi, error); - for (const auto &jfield : jwords) { - utils::bounds(FLERR, jfield, 1, ntypes, jnlo, jnhi, error); - - for (itype = inlo; itype <= inhi; itype++) { - for (jtype = jnlo; jtype <= jnhi; jtype++) { - type_filter[itype][jtype] = 1; - type_filter[jtype][itype] = 1; - } - } - } - } - iarg += 2; - - } else - error->all(FLERR, "Invalid keyword in fix pair/tracker command"); - - iarg++; - } - - if (nvalues == 1) - size_local_cols = 0; - else - size_local_cols = nvalues; - - nmax = 0; - ncount = 0; - vector = nullptr; - array = nullptr; -} - -/* ---------------------------------------------------------------------- */ - -FixPairTracker::~FixPairTracker() -{ - delete[] pack_choice; - - memory->destroy(vector); - memory->destroy(array); - memory->destroy(type_filter); -} - -/* ---------------------------------------------------------------------- */ - -int FixPairTracker::setmask() -{ - int mask = 0; - mask |= POST_FORCE; - return mask; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::init() -{ - // Set size of array/vector - ncount = 0; - - if (ncount > nmax) reallocate(ncount); - - size_local_rows = ncount; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::lost_contact(int i, int j, double time_tmp, double nstep_tmp, double rsum_tmp, - double rmin_tmp) -{ - - double time = update->atime + (update->ntimestep - update->atimestep) * update->dt; - if ((time - time_tmp) < tmin) return; - - if (type_filter) { - int *type = atom->type; - if (type_filter[type[i]][type[j]] == 0) return; - } - - int *mask = atom->mask; - if (!(mask[i] & groupbit)) return; - if (!(mask[j] & groupbit)) return; - - if (ncount == nmax) reallocate(ncount); - - index_i = i; - index_j = j; - - rmin = rmin_tmp; - rsum = rsum_tmp; - time_initial = time_tmp; - nstep_initial = nstep_tmp; - - // fill vector or array with local values - if (nvalues == 1) { - (this->*pack_choice[0])(0); - } else { - for (int k = 0; k < nvalues; k++) { (this->*pack_choice[k])(k); } - } - - ncount += 1; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::post_force(int /*vflag*/) -{ - if (update->ntimestep % nevery == 0) { - size_local_rows = ncount; - ncount = 0; - } -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::reallocate(int n) -{ - // grow vector or array - while (nmax <= n) nmax += DELTA; - - if (nvalues == 1) { - memory->grow(vector, nmax, "fix_pair_tracker:vector"); - vector_local = vector; - } else { - memory->grow(array, nmax, nvalues, "fix_pair_tracker:array"); - array_local = array; - } -} - -/* ---------------------------------------------------------------------- - memory usage of local data -------------------------------------------------------------------------- */ - -double FixPairTracker::memory_usage() -{ - double bytes = nmax * (double) nvalues * sizeof(double); - bytes += nmax * 2 * sizeof(int); - return bytes; -} - -/* ---------------------------------------------------------------------- - one method for every keyword fix pair/tracker can output - the atom property is packed into a local vector or array -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_time_created(int n) -{ - if (nvalues == 1) - vector[ncount] = time_initial; - else - array[ncount][n] = time_initial; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_time_broken(int n) -{ - double time = update->atime + (update->ntimestep - update->atimestep) * update->dt; - if (nvalues == 1) - vector[ncount] = time; - else - array[ncount][n] = time; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_time_total(int n) -{ - double time = update->atime + (update->ntimestep - update->atimestep) * update->dt; - if (nvalues == 1) - vector[ncount] = time - time_initial; - else - array[ncount][n] = time - time_initial; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_id1(int n) -{ - tagint *tag = atom->tag; - - if (nvalues == 1) - vector[ncount] = tag[index_i]; - else - array[ncount][n] = tag[index_i]; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_id2(int n) -{ - tagint *tag = atom->tag; - - if (nvalues == 1) - vector[ncount] = tag[index_j]; - else - array[ncount][n] = tag[index_j]; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_x(int n) -{ - double **x = atom->x; - - if (nvalues == 1) - vector[ncount] = (x[index_i][0] + x[index_j][0]) / 2; - else - array[ncount][n] = (x[index_i][0] + x[index_j][0]) / 2; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_y(int n) -{ - double **x = atom->x; - - if (nvalues == 1) - vector[ncount] = (x[index_i][1] + x[index_j][1]) / 2; - else - array[ncount][n] = (x[index_i][1] + x[index_j][1]) / 2; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_z(int n) -{ - double **x = atom->x; - - if (nvalues == 1) - vector[ncount] = (x[index_i][2] + x[index_j][2]) / 2; - else - array[ncount][n] = (x[index_i][2] + x[index_j][2]) / 2; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_rmin(int n) -{ - if (nvalues == 1) - vector[ncount] = rmin; - else - array[ncount][n] = rmin; -} - -/* ---------------------------------------------------------------------- */ - -void FixPairTracker::pack_rave(int n) -{ - if (nvalues == 1) - vector[ncount] = rsum / (update->ntimestep - nstep_initial); - else - array[ncount][n] = rsum / (update->ntimestep - nstep_initial); -} diff --git a/src/MISC/pair_tracker.cpp b/src/MISC/pair_tracker.cpp index ab045d4843..df49811a10 100644 --- a/src/MISC/pair_tracker.cpp +++ b/src/MISC/pair_tracker.cpp @@ -19,39 +19,41 @@ #include "fix.h" #include "fix_dummy.h" #include "fix_neigh_history.h" -#include "fix_pair_tracker.h" +#include "fix_store_local.h" #include "force.h" #include "memory.h" #include "modify.h" #include "neigh_list.h" #include "neighbor.h" +#include "tokenizer.h" #include "update.h" +#include "utils.h" -#include #include using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairTracker::PairTracker(LAMMPS *lmp) : Pair(lmp) +PairTracker::PairTracker(LAMMPS *lmp) : + Pair(lmp), onerad_dynamic(nullptr), onerad_frozen(nullptr), maxrad_dynamic(nullptr), + maxrad_frozen(nullptr), id_fix_store_local(nullptr), fix_dummy(nullptr), fix_history(nullptr), + fix_store_local(nullptr), type_filter(nullptr), output_data(nullptr), pack_choice(nullptr) { single_enable = 1; no_virial_fdotr_compute = 1; neighprev = 0; history = 1; - size_history = 4; + size_history = 3; nondefault_history_transfer = 1; finitecutflag = 0; + tmin = -1; // create dummy fix as placeholder for FixNeighHistory // this is so final order of Modify:fix will conform to input script - - fix_history = nullptr; - modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY"); - fix_dummy = dynamic_cast( modify->fix[modify->nfix - 1]); + fix_dummy = dynamic_cast(modify->add_fix("NEIGH_HISTORY_TRACK_DUMMY all DUMMY")); } /* ---------------------------------------------------------------------- */ @@ -62,6 +64,7 @@ PairTracker::~PairTracker() modify->delete_fix("NEIGH_HISTORY_TRACK_DUMMY"); else modify->delete_fix("NEIGH_HISTORY_TRACK"); + if (id_fix_store_local) modify->delete_fix(id_fix_store_local); if (allocated) { memory->destroy(setflag); @@ -73,6 +76,12 @@ PairTracker::~PairTracker() delete[] maxrad_dynamic; delete[] maxrad_frozen; } + + delete[] pack_choice; + delete[] id_fix_store_local; + + memory->destroy(output_data); + memory->destroy(type_filter); } /* ---------------------------------------------------------------------- */ @@ -80,7 +89,7 @@ PairTracker::~PairTracker() void PairTracker::compute(int eflag, int vflag) { int i, j, ii, jj, inum, jnum, itype, jtype; - double xtmp, ytmp, ztmp, delx, dely, delz, time; + double xtmp, ytmp, ztmp, delx, dely, delz; double radi, radj, radsum, rsq, r; int *ilist, *jlist, *numneigh, **firstneigh; int *touch, **firsttouch; @@ -131,27 +140,23 @@ void PairTracker::compute(int eflag, int vflag) if (rsq >= radsum * radsum) { data = &alldata[size_history * jj]; - if (touch[jj] == 1) { - fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]); - } + if (touch[jj] == 1) process_data(i, j, data); + touch[jj] = 0; - data[0] = 0.0; // initial time - data[1] = 0.0; // initial timestep - data[2] = 0.0; // sum of r, may overflow - data[3] = 0.0; // min of r + data[0] = 0.0; // initial timestep + data[1] = 0.0; // sum of r, may be inaccurate over long times + data[2] = 0.0; // min of r } else { data = &alldata[size_history * jj]; if (touch[jj] == 0) { - time = update->atime + (update->ntimestep - update->atimestep) * update->dt; - data[0] = time; - data[1] = (double) update->ntimestep; + data[0] = (double) update->ntimestep; + data[1] = r; data[2] = r; - data[3] = r; } else if (updateflag) { - data[2] += r; - if (data[3] > r) data[3] = r; + data[1] += r; + if (data[2] > r) data[2] = r; } touch[jj] = 1; } @@ -160,28 +165,23 @@ void PairTracker::compute(int eflag, int vflag) if (rsq >= cutsq[itype][jtype]) { data = &alldata[size_history * jj]; - if (touch[jj] == 1) { - fix_pair_tracker->lost_contact(i, j, data[0], data[1], data[2], data[3]); - } + if (touch[jj] == 1) process_data(i, j, data); touch[jj] = 0; - data[0] = 0.0; // initial time - data[1] = 0.0; // initial timestep - data[2] = 0.0; // sum of r, may overflow - data[3] = 0.0; // min of r + data[0] = 0.0; // initial timestep + data[1] = 0.0; // sum of r, may be inaccurate over long times + data[2] = 0.0; // min of r } else { data = &alldata[size_history * jj]; if (touch[jj] == 0) { - time = update->atime + (update->ntimestep - update->atimestep) * update->dt; - data[0] = time; - data[1] = (double) update->ntimestep; + data[0] = (double) update->ntimestep; + data[1] = r; data[2] = r; - data[3] = r; } else if (updateflag) { - data[2] += r; - if (data[3] > r) data[3] = r; + data[1] += r; + if (data[2] > r) data[2] = r; } touch[jj] = 1; } @@ -218,14 +218,89 @@ void PairTracker::allocate() void PairTracker::settings(int narg, char **arg) { - if (narg != 0 && narg != 1) error->all(FLERR, "Illegal pair_style command"); + if (narg < 2) error->all(FLERR, "Illegal pair_style command"); - if (narg == 1) { - if (strcmp(arg[0], "finite") == 0) + id_fix_store_local = utils::strdup(arg[0]); + store_local_freq = utils::inumeric(FLERR, arg[1], false, lmp); + + // If optional arguments included, this will be oversized + pack_choice = new FnPtrPack[narg - 1]; + + nvalues = 0; + int iarg = 2; + while (iarg < narg) { + if (strcmp(arg[iarg], "finite") == 0) { finitecutflag = 1; - else + } else if (strcmp(arg[iarg], "id1") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_id1; + } else if (strcmp(arg[iarg], "id2") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_id2; + } else if (strcmp(arg[iarg], "time/created") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_time_created; + } else if (strcmp(arg[iarg], "time/broken") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_time_broken; + } else if (strcmp(arg[iarg], "time/total") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_time_total; + } else if (strcmp(arg[iarg], "x") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_x; + } else if (strcmp(arg[iarg], "y") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_y; + } else if (strcmp(arg[iarg], "z") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_z; + } else if (strcmp(arg[iarg], "r/min") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_rmin; + } else if (strcmp(arg[iarg], "r/ave") == 0) { + pack_choice[nvalues++] = &PairTracker::pack_rave; + } else if (strcmp(arg[iarg], "time/min") == 0) { + if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in pair tracker command"); + tmin = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg++; + + } else if (strcmp(arg[iarg], "type/include") == 0) { + if (iarg + 1 >= narg) error->all(FLERR, "Invalid keyword in pair tracker command"); + int ntypes = atom->ntypes; + int i, j, itype, jtype; + int inlo, inhi, jnlo, jnhi; + + if (!type_filter) { + memory->create(type_filter, ntypes + 1, ntypes + 1, "pair/tracker:type_filter"); + + for (i = 0; i <= ntypes; i++) { + for (j = 0; j <= ntypes; j++) type_filter[i][j] = 0; + } + } + + auto iwords = Tokenizer(arg[iarg + 1], ",").as_vector(); + auto jwords = Tokenizer(arg[iarg + 2], ",").as_vector(); + + for (const auto &ifield : iwords) { + utils::bounds(FLERR, ifield, 1, ntypes, inlo, inhi, error); + for (const auto &jfield : jwords) { + utils::bounds(FLERR, jfield, 1, ntypes, jnlo, jnhi, error); + + for (itype = inlo; itype <= inhi; itype++) { + for (jtype = jnlo; jtype <= jnhi; jtype++) { + type_filter[itype][jtype] = 1; + type_filter[jtype][itype] = 1; + } + } + } + } + iarg += 2; + + } else { error->all(FLERR, "Illegal pair_style command"); + } + iarg++; } + + if (nvalues == 0) error->all(FLERR, "Must request at least one value to output"); + memory->create(output_data, nvalues, "pair/tracker:output_data"); + + fix_store_local = dynamic_cast(modify->get_fix_by_id(id_fix_store_local)); + if (!fix_store_local) + fix_store_local = dynamic_cast(modify->add_fix( + fmt::format("{} all STORE_LOCAL {} {}", id_fix_store_local, store_local_freq, nvalues))); } /* ---------------------------------------------------------------------- @@ -263,8 +338,6 @@ void PairTracker::coeff(int narg, char **arg) void PairTracker::init_style() { - int i; - // error and warning checks if (!atom->radius_flag && finitecutflag) @@ -283,44 +356,49 @@ void PairTracker::init_style() if (fix_history == nullptr) { modify->replace_fix("NEIGH_HISTORY_TRACK_DUMMY", fmt::format("NEIGH_HISTORY_TRACK all NEIGH_HISTORY {}", size_history), 1); - fix_history = dynamic_cast( modify->get_fix_by_id("NEIGH_HISTORY_TRACK")); + fix_history = dynamic_cast(modify->get_fix_by_id("NEIGH_HISTORY_TRACK")); fix_history->pair = this; fix_history->use_bit_flag = 0; } else { - fix_history = dynamic_cast( modify->get_fix_by_id("NEIGH_HISTORY_TRACK")); + fix_history = dynamic_cast(modify->get_fix_by_id("NEIGH_HISTORY_TRACK")); if (!fix_history) error->all(FLERR, "Could not find pair fix neigh history ID"); } if (finitecutflag) { - if (force->pair->beyond_contact) error->all(FLERR, "Pair tracker incompatible with granular pairstyles that extend beyond contact"); + + // check for FixFreeze and set freeze_group_bit + + auto fixlist = modify->get_fix_by_style("^freeze"); + if (fixlist.size() == 0) + freeze_group_bit = 0; + else if (fixlist.size() > 1) + error->all(FLERR, "Only one fix freeze command at a time allowed"); + else + freeze_group_bit = fixlist.front()->groupbit; + // check for FixPour and FixDeposit so can extract particle radii - int ipour; - for (ipour = 0; ipour < modify->nfix; ipour++) - if (strcmp(modify->fix[ipour]->style, "pour") == 0) break; - if (ipour == modify->nfix) ipour = -1; - - int idep; - for (idep = 0; idep < modify->nfix; idep++) - if (strcmp(modify->fix[idep]->style, "deposit") == 0) break; - if (idep == modify->nfix) idep = -1; + auto pours = modify->get_fix_by_style("^pour"); + auto deps = modify->get_fix_by_style("^deposit"); // set maxrad_dynamic and maxrad_frozen for each type // include future FixPour and FixDeposit particles as dynamic - int itype; - for (i = 1; i <= atom->ntypes; i++) { + int itype = 0; + for (int i = 1; i <= atom->ntypes; i++) { onerad_dynamic[i] = onerad_frozen[i] = 0.0; - if (ipour >= 0) { + for (auto &ipour : pours) { itype = i; - onerad_dynamic[i] = *((double *) modify->fix[ipour]->extract("radius", itype)); + double maxrad = *((double *) ipour->extract("radius", itype)); + if (maxrad > 0.0) onerad_dynamic[i] = maxrad; } - if (idep >= 0) { + for (auto &idep : deps) { itype = i; - onerad_dynamic[i] = *((double *) modify->fix[idep]->extract("radius", itype)); + double maxrad = *((double *) idep->extract("radius", itype)); + if (maxrad > 0.0) onerad_dynamic[i] = maxrad; } } @@ -329,7 +407,7 @@ void PairTracker::init_style() int *type = atom->type; int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & freeze_group_bit) onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]], radius[i]); else @@ -338,11 +416,6 @@ void PairTracker::init_style() MPI_Allreduce(&onerad_dynamic[1], &maxrad_dynamic[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world); MPI_Allreduce(&onerad_frozen[1], &maxrad_frozen[1], atom->ntypes, MPI_DOUBLE, MPI_MAX, world); } - - auto trackfixes = modify->get_fix_by_style("pair/tracker"); - if (trackfixes.size() != 1) - error->all(FLERR, "Must use exactly one fix pair/tracker command with pair style tracker"); - fix_pair_tracker = dynamic_cast( trackfixes.front()); } /* ---------------------------------------------------------------------- @@ -354,8 +427,7 @@ double PairTracker::init_one(int i, int j) if (!allocated) allocate(); // always mix prefactors geometrically - - if (setflag[i][j] == 0) { cut[i][j] = mix_distance(cut[i][i], cut[j][j]); } + if (setflag[i][j] == 0) cut[i][j] = mix_distance(cut[i][i], cut[j][j]); cut[j][i] = cut[i][j]; @@ -384,7 +456,7 @@ void PairTracker::write_restart(FILE *fp) for (i = 1; i <= atom->ntypes; i++) for (j = i; j <= atom->ntypes; j++) { fwrite(&setflag[i][j], sizeof(int), 1, fp); - if (setflag[i][j]) { fwrite(&cut[i][j], sizeof(double), 1, fp); } + if (setflag[i][j]) fwrite(&cut[i][j], sizeof(double), 1, fp); } } @@ -404,7 +476,7 @@ void PairTracker::read_restart(FILE *fp) 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, &cut[i][j], sizeof(double), 1, fp, nullptr, error); } + if (me == 0) utils::sfread(FLERR, &cut[i][j], sizeof(double), 1, fp, nullptr, error); MPI_Bcast(&cut[i][j], 1, MPI_DOUBLE, 0, world); } } @@ -466,3 +538,91 @@ double PairTracker::radii2cut(double r1, double r2) double cut = r1 + r2; return cut; } + +/* ---------------------------------------------------------------------- */ + +void PairTracker::process_data(int i, int j, double *input_data) +{ + if ((update->ntimestep - input_data[0]) < tmin) return; + + if (type_filter) { + int *type = atom->type; + if (type_filter[type[i]][type[j]] == 0) return; + } + + for (int k = 0; k < nvalues; k++) (this->*pack_choice[k])(k, i, j, input_data); + fix_store_local->add_data(output_data, i, j); +} + +/* ---------------------------------------------------------------------- + one method for every keyword fix pair/tracker can output + the atom property is packed into a local vector or array +------------------------------------------------------------------------- */ + +void PairTracker::pack_time_created(int n, int /*i*/, int /*j*/, double *data) +{ + output_data[n] = data[0]; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_time_broken(int n, int /*i*/, int /*j*/, double * /*data*/) +{ + output_data[n] = update->ntimestep; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_time_total(int n, int /*i*/, int /*j*/, double *data) +{ + output_data[n] = update->ntimestep - data[0]; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_id1(int n, int i, int /*j*/, double * /*data*/) +{ + output_data[n] = atom->tag[i]; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_id2(int n, int /*i*/, int j, double * /*data*/) +{ + output_data[n] = atom->tag[j]; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_x(int n, int i, int j, double * /*data*/) +{ + output_data[n] = (atom->x[i][0] + atom->x[j][0]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_y(int n, int i, int j, double * /*data*/) +{ + output_data[n] = (atom->x[i][1] + atom->x[j][1]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_z(int n, int i, int j, double * /*data*/) +{ + output_data[n] = (atom->x[i][2] + atom->x[j][2]) * 0.5; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_rmin(int n, int /*i*/, int /*j*/, double *data) +{ + output_data[n] = data[2]; +} + +/* ---------------------------------------------------------------------- */ + +void PairTracker::pack_rave(int n, int /*i*/, int /*j*/, double *data) +{ + output_data[n] = data[1] / (update->ntimestep - data[0]); +} diff --git a/src/MISC/pair_tracker.h b/src/MISC/pair_tracker.h index 1942408659..75204112bf 100644 --- a/src/MISC/pair_tracker.h +++ b/src/MISC/pair_tracker.h @@ -40,6 +40,7 @@ class PairTracker : public Pair { double single(int, int, int, int, double, double, double, double &) override; double atom2cut(int) override; double radii2cut(double, double) override; + void transfer_history(double *, double *) override; protected: int sizeflag; @@ -50,12 +51,33 @@ class PairTracker : public Pair { double *onerad_dynamic, *onerad_frozen; double *maxrad_dynamic, *maxrad_frozen; int freeze_group_bit; + int store_local_freq; + char *id_fix_store_local; class FixDummy *fix_dummy; class FixNeighHistory *fix_history; - class FixPairTracker *fix_pair_tracker; + class FixStoreLocal *fix_store_local; - void transfer_history(double *, double *) override; + int **type_filter; + double tmin; + + int nvalues, ncount; + double *output_data; + typedef void (PairTracker::*FnPtrPack)(int, int, int, double *); + FnPtrPack *pack_choice; // ptrs to pack functions + + void pack_id1(int, int, int, double *); + void pack_id2(int, int, int, double *); + void pack_time_created(int, int, int, double *); + void pack_time_broken(int, int, int, double *); + void pack_time_total(int, int, int, double *); + void pack_x(int, int, int, double *); + void pack_y(int, int, int, double *); + void pack_z(int, int, int, double *); + void pack_rmin(int, int, int, double *); + void pack_rave(int, int, int, double *); + + void process_data(int, int, double *); void allocate(); }; @@ -72,20 +94,37 @@ 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: Invalid keyword in pair tracker command + +Self-explanatory. + E: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. +E: Must request at least one value to output + +Must include at least one bond property to store in fix store/local + E: Pair tracker requires atom attribute radius for finite cutoffs The atom style defined does not have these attributes. +E: Pair tracker incompatible with granular pairstyles that extend beyond contact + +Self-explanatory. + E: Could not find pair fix neigh history ID The associated fix neigh/history is missing -E: Cannot use pair tracker without fix pair/tracker +E: Cannot use pair tracker without fix store/local -This pairstyle requires one to define a pair/tracker fix +The associated fix store/local does not exist + +E: Inconsistent number of output variables in fix store/local + +The number of values specified in fix store/local disagrees with +the number of values requested in pair tracker */ diff --git a/src/MOLECULE/bond_quartic.cpp b/src/MOLECULE/bond_quartic.cpp index b0028c05e9..88effd6a05 100644 --- a/src/MOLECULE/bond_quartic.cpp +++ b/src/MOLECULE/bond_quartic.cpp @@ -36,6 +36,7 @@ using MathConst::MY_CUBEROOT2; BondQuartic::BondQuartic(LAMMPS *_lmp) : Bond(_lmp), k(nullptr), b1(nullptr), b2(nullptr), rc(nullptr), u0(nullptr) { + partial_flag = 1; } /* ---------------------------------------------------------------------- */ diff --git a/src/Makefile b/src/Makefile index ffd46e3b71..1b0992ab95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -54,6 +54,7 @@ PACKAGE = \ awpmd \ bocs \ body \ + bpm \ brownian \ cg-dna \ cg-sdk \ @@ -147,7 +148,8 @@ PACKMOST = \ asphere \ bocs \ body \ - brownian \ + bpm \ + brownian \ cg-dna \ cg-sdk \ class2 \ diff --git a/src/OPENMP/fix_neigh_history_omp.cpp b/src/OPENMP/fix_neigh_history_omp.cpp index 4db6678721..ec101709c9 100644 --- a/src/OPENMP/fix_neigh_history_omp.cpp +++ b/src/OPENMP/fix_neigh_history_omp.cpp @@ -578,7 +578,7 @@ void FixNeighHistoryOMP::post_neighbor() for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; - rflag = sbmask(j); + rflag = histmask(j); j &= NEIGHMASK; jlist[jj] = j; diff --git a/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp b/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp index 445c2ff286..07082868f6 100644 --- a/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp +++ b/src/OPENMP/npair_half_size_bin_newtoff_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_bin_newtoff_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" #include "npair_omp.h" @@ -40,8 +43,10 @@ NPairHalfSizeBinNewtoffOmp::NPairHalfSizeBinNewtoffOmp(LAMMPS *lmp) : void NPairHalfSizeBinNewtoffOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; @@ -50,7 +55,8 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,ibin; + int i,j,jh,k,n,ibin,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -61,7 +67,14 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -81,6 +94,11 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list) ztmp = x[i][2]; radi = radius[i]; ibin = atom2bin[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in surrounding bins in stencil including self // only store pair if i < j @@ -100,10 +118,23 @@ void NPairHalfSizeBinNewtoffOmp::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/OPENMP/npair_half_size_bin_newton_omp.cpp b/src/OPENMP/npair_half_size_bin_newton_omp.cpp index be110f07e0..42a74f13aa 100644 --- a/src/OPENMP/npair_half_size_bin_newton_omp.cpp +++ b/src/OPENMP/npair_half_size_bin_newton_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_bin_newton_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" #include "npair_omp.h" @@ -39,8 +42,10 @@ NPairHalfSizeBinNewtonOmp::NPairHalfSizeBinNewtonOmp(LAMMPS *lmp) : void NPairHalfSizeBinNewtonOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; @@ -49,7 +54,8 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,ibin; + int i,j,jh,k,n,ibin,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -58,7 +64,14 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -77,6 +90,11 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over rest of atoms in i's bin, ghosts are at end of linked list // if j is owned atom, store it, since j is beyond i in linked list @@ -101,10 +119,23 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } @@ -123,10 +154,23 @@ void NPairHalfSizeBinNewtonOmp::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp index bc3bda1181..5a77de0796 100644 --- a/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp +++ b/src/OPENMP/npair_half_size_bin_newton_tri_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_bin_newton_tri_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" #include "npair_omp.h" @@ -39,8 +42,10 @@ NPairHalfSizeBinNewtonTriOmp::NPairHalfSizeBinNewtonTriOmp(LAMMPS *lmp) : void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -48,7 +53,8 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,ibin; + int i,j,jh,k,n,ibin,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -59,7 +65,14 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -78,6 +91,11 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in bins in stencil // pairs for atoms j "below" i are excluded @@ -107,10 +125,23 @@ void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp b/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp index da2d7a7590..d58d250209 100644 --- a/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_newtoff_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_newtoff_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" @@ -41,8 +44,10 @@ NPairHalfSizeMultiNewtoffOmp::NPairHalfSizeMultiNewtoffOmp(LAMMPS *lmp) : NPair( void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -50,7 +55,9 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -63,7 +70,14 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -84,6 +98,11 @@ void NPairHalfSizeMultiNewtoffOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } ibin = atom2bin[i]; @@ -104,27 +123,40 @@ 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) { + jh = j; + if (history && rsq < radsum*radsum) + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; + } + } } } diff --git a/src/OPENMP/npair_half_size_multi_newton_omp.cpp b/src/OPENMP/npair_half_size_multi_newton_omp.cpp index bcf87d385c..3190131442 100644 --- a/src/OPENMP/npair_half_size_multi_newton_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_newton_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_newton_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" @@ -40,8 +43,10 @@ NPairHalfSizeMultiNewtonOmp::NPairHalfSizeMultiNewtonOmp(LAMMPS *lmp) : NPair(lm void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -49,7 +54,9 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -62,7 +69,14 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -83,6 +97,11 @@ void NPairHalfSizeMultiNewtonOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } ibin = atom2bin[i]; @@ -107,7 +126,7 @@ 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 && j < i) continue; if (j >= nlocal) { @@ -121,19 +140,32 @@ void NPairHalfSizeMultiNewtonOmp::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) { + jh = j; + if (history && rsq < radsum*radsum) + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; + } } } @@ -142,31 +174,43 @@ 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) + j = j ^ mask_history; + + 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_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp index d38e52fe18..717e023f4a 100644 --- a/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_newton_tri_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_newton_tri_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" @@ -41,8 +44,10 @@ NPairHalfSizeMultiNewtonTriOmp::NPairHalfSizeMultiNewtonTriOmp(LAMMPS *lmp) : void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -50,7 +55,9 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -63,7 +70,14 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -84,6 +98,11 @@ void NPairHalfSizeMultiNewtonTriOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } ibin = atom2bin[i]; @@ -104,12 +123,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 +145,34 @@ 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) { + jh = j; + if (history && rsq < radsum*radsum) + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } + } + } } ilist[i] = i; diff --git a/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp b/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp index 65fca6ed17..37dbe9cc53 100644 --- a/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_old_newtoff_omp.cpp @@ -13,8 +13,12 @@ ------------------------------------------------------------------------- */ #include "npair_half_size_multi_old_newtoff_omp.h" + #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" #include "npair_omp.h" @@ -39,8 +43,10 @@ NPairHalfSizeMultiOldNewtoffOmp::NPairHalfSizeMultiOldNewtoffOmp(LAMMPS *lmp) : void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -48,7 +54,8 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,ibin,ns; + int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -58,7 +65,14 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -78,6 +92,11 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in other bins in stencil including self // only store pair if i < j @@ -106,10 +125,23 @@ void NPairHalfSizeMultiOldNewtoffOmp::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp b/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp index 907ce7dca8..789ed33e6b 100644 --- a/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_old_newton_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_old_newton_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" #include "npair_omp.h" @@ -39,8 +42,10 @@ NPairHalfSizeMultiOldNewtonOmp::NPairHalfSizeMultiOldNewtonOmp(LAMMPS *lmp) : void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -48,7 +53,8 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,ibin,ns; + int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -58,7 +64,14 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -78,6 +91,11 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over rest of atoms in i's bin, ghosts are at end of linked list // if j is owned atom, store it, since j is beyond i in linked list @@ -102,10 +120,23 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } @@ -132,10 +163,23 @@ void NPairHalfSizeMultiOldNewtonOmp::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp b/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp index a2bbf9cae0..8302d9fab2 100644 --- a/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp +++ b/src/OPENMP/npair_half_size_multi_old_newton_tri_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_old_newton_tri_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" #include "npair_omp.h" @@ -39,8 +42,10 @@ NPairHalfSizeMultiOldNewtonTriOmp::NPairHalfSizeMultiOldNewtonTriOmp(LAMMPS *lmp void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; #if defined(_OPENMP) @@ -48,7 +53,8 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,k,n,itype,jtype,ibin,ns; + int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -58,7 +64,14 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; int *ilist = list->ilist; int *numneigh = list->numneigh; @@ -78,6 +91,11 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in bins, including self, in stencil // skip if i,j neighbor cutoff is less than bin distance @@ -115,10 +133,23 @@ void NPairHalfSizeMultiOldNewtonTriOmp::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp b/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp index f182492efe..7f4b22e729 100644 --- a/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp +++ b/src/OPENMP/npair_half_size_nsq_newtoff_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_nsq_newtoff_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "group.h" #include "my_page.h" #include "neigh_list.h" @@ -42,8 +45,10 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; @@ -52,7 +57,8 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,n; + int i,j,jh,n,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -61,9 +67,17 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + int nall = atom->nlocal + atom->nghost; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; @@ -81,6 +95,11 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over remaining atoms, owned and ghost @@ -96,10 +115,23 @@ void NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } diff --git a/src/OPENMP/npair_half_size_nsq_newton_omp.cpp b/src/OPENMP/npair_half_size_nsq_newton_omp.cpp index fdea8f4468..9262b869af 100644 --- a/src/OPENMP/npair_half_size_nsq_newton_omp.cpp +++ b/src/OPENMP/npair_half_size_nsq_newton_omp.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_nsq_newton_omp.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "group.h" #include "my_page.h" #include "neigh_list.h" @@ -42,9 +45,11 @@ NPairHalfSizeNsqNewtonOmp::NPairHalfSizeNsqNewtonOmp(LAMMPS *lmp) : void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) { const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;; + const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; + const int molecular = atom->molecular; + const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0; const int history = list->history; - const int mask_history = 3 << SBBITS; + const int mask_history = 1 << HISTBITS; NPAIR_OMP_INIT; @@ -53,7 +58,8 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) #endif NPAIR_OMP_SETUP(nlocal); - int i,j,n,itag,jtag; + int i,j,jh,n,itag,jtag,which,imol,iatom; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -64,6 +70,13 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) int *type = atom->type; int *mask = atom->mask; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + int nall = atom->nlocal + atom->nghost; int *ilist = list->ilist; @@ -84,6 +97,11 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over remaining atoms, owned and ghost @@ -115,10 +133,23 @@ void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 385b5788c1..c05ad4f8b3 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -24,6 +24,7 @@ Contributing Author: Jacob Gissinger (jacob.r.gissinger@gmail.com) #include "comm.h" #include "domain.h" #include "error.h" +#include "fix_bond_history.h" #include "force.h" #include "group.h" #include "input.h" @@ -3093,6 +3094,10 @@ void FixBondReact::update_everything() // next let's update bond info // cool thing is, newton_bond issues are already taken care of in templates // same with class2 improper issues, which is why this fix started in the first place + // also need to find any instances of bond history to update histories + auto histories = modify->get_fix_by_style("BOND_HISTORY"); + int n_histories = histories.size(); + for (int i = 0; i < update_num_mega; i++) { rxnID = update_mega_glove[0][i]; twomol = atom->molecules[reacted_mol[rxnID]]; @@ -3102,6 +3107,14 @@ void FixBondReact::update_everything() if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) { if (landlocked_atoms[j][rxnID] == 1) { delta_bonds -= num_bond[atom->map(update_mega_glove[jj+1][i])]; + // If deleting all bonds, first cache then remove all histories + if (n_histories > 0) + for (auto &ihistory: histories) { + for (int n = 0; n < num_bond[atom->map(update_mega_glove[jj+1][i])]; n++) + dynamic_cast(ihistory)->cache_history(atom->map(update_mega_glove[jj+1][i]), n); + for (int n = 0; n < num_bond[atom->map(update_mega_glove[jj+1][i])]; n++) + dynamic_cast(ihistory)->delete_history(atom->map(update_mega_glove[jj+1][i]), 0); + } num_bond[atom->map(update_mega_glove[jj+1][i])] = 0; } if (landlocked_atoms[j][rxnID] == 0) { @@ -3109,10 +3122,21 @@ void FixBondReact::update_everything() for (int n = 0; n < twomol->natoms; n++) { int nn = equivalences[n][1][rxnID]-1; if (n!=j && bond_atom[atom->map(update_mega_glove[jj+1][i])][p] == update_mega_glove[nn+1][i] && landlocked_atoms[n][rxnID] == 1) { + // Cache history information, shift history, then delete final element + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->cache_history(atom->map(update_mega_glove[jj+1][i]), p); for (int m = p; m < num_bond[atom->map(update_mega_glove[jj+1][i])]-1; m++) { bond_type[atom->map(update_mega_glove[jj+1][i])][m] = bond_type[atom->map(update_mega_glove[jj+1][i])][m+1]; bond_atom[atom->map(update_mega_glove[jj+1][i])][m] = bond_atom[atom->map(update_mega_glove[jj+1][i])][m+1]; + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->shift_history(atom->map(update_mega_glove[jj+1][i]),m,m+1); } + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->delete_history(atom->map(update_mega_glove[jj+1][i]), + num_bond[atom->map(update_mega_glove[jj+1][i])]-1); num_bond[atom->map(update_mega_glove[jj+1][i])]--; delta_bonds--; } @@ -3131,6 +3155,10 @@ void FixBondReact::update_everything() for (int p = 0; p < twomol->num_bond[j]; p++) { bond_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->bond_type[j][p]; bond_atom[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->bond_atom[j][p]-1][1][rxnID]][i]; + // Check cached history data to see if bond regenerated + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->check_cache(atom->map(update_mega_glove[jj+1][i]), p); } } if (landlocked_atoms[j][rxnID] == 0) { @@ -3139,6 +3167,10 @@ void FixBondReact::update_everything() insert_num = num_bond[atom->map(update_mega_glove[jj+1][i])]; bond_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->bond_type[j][p]; bond_atom[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->bond_atom[j][p]-1][1][rxnID]][i]; + // Check cached history data to see if bond regenerated + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->check_cache(atom->map(update_mega_glove[jj+1][i]), insert_num); num_bond[atom->map(update_mega_glove[jj+1][i])]++; if (num_bond[atom->map(update_mega_glove[jj+1][i])] > atom->bond_per_atom) error->one(FLERR,"Bond/react topology/atom exceed system topology/atom"); @@ -3150,6 +3182,10 @@ void FixBondReact::update_everything() } } + if (n_histories > 0) + for (auto &ihistory: histories) + dynamic_cast(ihistory)->clear_cache(); + // Angles! First let's delete all angle info: if (force->angle && twomol->angleflag) { int *num_angle = atom->num_angle; diff --git a/src/atom.cpp b/src/atom.cpp index 6491b3849b..7fc126269c 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -128,6 +128,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) omega = angmom = torque = nullptr; radius = rmass = nullptr; ellipsoid = line = tri = body = nullptr; + quat = nullptr; // molecular systems @@ -426,6 +427,10 @@ void Atom::peratom_create() add_peratom("tri",&tri,INT,0); add_peratom("body",&body,INT,0); + // BPM package + + add_peratom("quat",&quat,DOUBLE,4); + // MOLECULE package add_peratom("molecule",&molecule,tagintsize,0); @@ -646,6 +651,7 @@ void Atom::set_atomflag_defaults() // identical list as 2nd customization in atom.h sphere_flag = ellipsoid_flag = line_flag = tri_flag = body_flag = 0; + quat_flag = 0; peri_flag = electron_flag = 0; wavepacket_flag = sph_flag = 0; molecule_flag = molindex_flag = molatom_flag = 0; @@ -1889,8 +1895,7 @@ void Atom::add_molecule(int narg, char **arg) int index = 1; while (true) { molecules = (Molecule **) - memory->srealloc(molecules,(nmolecule+1)*sizeof(Molecule *), - "atom::molecules"); + memory->srealloc(molecules,(nmolecule+1)*sizeof(Molecule *), "atom::molecules"); molecules[nmolecule] = new Molecule(lmp,narg,arg,index); molecules[nmolecule]->nset = 0; molecules[nmolecule-ifile+1]->nset++; @@ -1920,8 +1925,7 @@ int Atom::find_molecule(char *id) called by fixes and commands that add molecules ------------------------------------------------------------------------- */ -void Atom::add_molecule_atom(Molecule *onemol, int iatom, - int ilocal, tagint offset) +void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint offset) { if (onemol->qflag && q_flag) q[ilocal] = onemol->q[iatom]; if (onemol->radiusflag && radius_flag) radius[ilocal] = onemol->radius[iatom]; @@ -1936,6 +1940,19 @@ void Atom::add_molecule_atom(Molecule *onemol, int iatom, onemol->avec_body->set_quat(ilocal,onemol->quat_external); } + // initialize custom per-atom properties to zero if present + + for (int i = 0; i < nivector; ++i) + ivector[i][ilocal] = 0; + for (int i = 0; i < ndvector; ++i) + dvector[i][ilocal] = 0.0; + for (int i = 0; i < niarray; ++i) + for (int j = 0; j < icols[i]; ++j) + iarray[i][ilocal][j] = 0; + for (int i = 0; i < ndarray; ++i) + for (int j = 0; j < dcols[i]; ++j) + darray[i][ilocal][j] = 0.0; + if (molecular != Atom::MOLECULAR) return; // add bond topology info @@ -2614,6 +2631,10 @@ length of the data area, and a short description. - int - 1 - 1 if the particle is a body particle, 0 if not + * - quat + - double + - 4 + - four quaternion components of the particles * - i_name - int - 1 @@ -2669,6 +2690,7 @@ void *Atom::extract(const char *name) if (strcmp(name,"line") == 0) return (void *) line; if (strcmp(name,"tri") == 0) return (void *) tri; if (strcmp(name,"body") == 0) return (void *) body; + if (strcmp(name,"quat") == 0) return (void *) quat; if (strcmp(name,"vfrac") == 0) return (void *) vfrac; if (strcmp(name,"s0") == 0) return (void *) s0; @@ -2791,6 +2813,7 @@ int Atom::extract_datatype(const char *name) if (strcmp(name,"line") == 0) return LAMMPS_INT; if (strcmp(name,"tri") == 0) return LAMMPS_INT; if (strcmp(name,"body") == 0) return LAMMPS_INT; + if (strcmp(name,"quat") == 0) return LAMMPS_DOUBLE_2D; if (strcmp(name,"vfrac") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"s0") == 0) return LAMMPS_DOUBLE; diff --git a/src/atom.h b/src/atom.h index 2c1acb7805..d412881ea3 100644 --- a/src/atom.h +++ b/src/atom.h @@ -79,6 +79,7 @@ class Atom : protected Pointers { double *radius; double **omega, **angmom, **torque; int *ellipsoid, *line, *tri, *body; + double **quat; // molecular systems @@ -180,7 +181,7 @@ class Atom : protected Pointers { int molecule_flag, molindex_flag, molatom_flag; int q_flag, mu_flag; - int rmass_flag, radius_flag, omega_flag, torque_flag, angmom_flag; + int rmass_flag, radius_flag, omega_flag, torque_flag, angmom_flag, quat_flag; int vfrac_flag, spin_flag, eradius_flag, ervel_flag, erforce_flag; int cs_flag, csforce_flag, vforce_flag, ervelforce_flag, etag_flag; int rho_flag, esph_flag, cv_flag, vest_flag; diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index dead605920..0ca87db80e 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -6,7 +6,7 @@ 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 distributead under + 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. diff --git a/src/bond.cpp b/src/bond.cpp index 332e65de9f..6ae78bc429 100644 --- a/src/bond.cpp +++ b/src/bond.cpp @@ -27,6 +27,10 @@ using namespace LAMMPS_NS; enum { NONE, LINEAR, SPLINE }; +// allocate space for static class instance variable and initialize it + +int Bond::instance_total = 0; + /* ----------------------------------------------------------------------- set bond contribution to Vdwl energy to 0.0 a particular bond style can override this @@ -34,12 +38,17 @@ enum { NONE, LINEAR, SPLINE }; Bond::Bond(LAMMPS *_lmp) : Pointers(_lmp) { + instance_me = instance_total++; + energy = 0.0; virial[0] = virial[1] = virial[2] = virial[3] = virial[4] = virial[5] = 0.0; writedata = 1; + comm_forward = comm_reverse = comm_reverse_off = 0; + allocated = 0; suffix_flag = Suffix::NONE; + partial_flag = 0; maxeatom = maxvatom = 0; eatom = nullptr; diff --git a/src/bond.h b/src/bond.h index 9b9f35180a..47c8687f50 100644 --- a/src/bond.h +++ b/src/bond.h @@ -23,13 +23,20 @@ class Bond : protected Pointers { friend class FixOMP; public: + static int instance_total; // # of Bond classes ever instantiated + int allocated; int *setflag; + int partial_flag; // 1 if bond type can be set to 0 and deleted int writedata; // 1 if writes coeffs to data file double energy; // accumulated energies double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz double *eatom, **vatom; // accumulated per-atom energy/virial + int comm_forward; // size of forward communication (0 if none) + int comm_reverse; // size of reverse communication (0 if none) + int comm_reverse_off; // size of reverse comm even if newton off + int reinitflag; // 1 if compatible with fix adapt and alike // KOKKOS host/device flag and data masks @@ -55,10 +62,15 @@ class Bond : protected Pointers { virtual double memory_usage(); virtual void *extract(const char *, int &) { return nullptr; } virtual void reinit(); + virtual int pack_forward_comm(int, int *, double *, int, int *) {return 0;} + virtual void unpack_forward_comm(int, int, double *) {} + virtual int pack_reverse_comm(int, int, double *) {return 0;} + virtual void unpack_reverse_comm(int, int *, double *) {} void write_file(int, char **); protected: + int instance_me; // which Bond class instantiation I am int suffix_flag; // suffix compatibility flag int evflag; diff --git a/src/comm.cpp b/src/comm.cpp index 3b0195f410..9f46031185 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -218,6 +218,9 @@ void Comm::init() if (force->pair) maxforward = MAX(maxforward,force->pair->comm_forward); if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse); + if (force->bond) maxforward = MAX(maxforward,force->bond->comm_forward); + if (force->bond) maxreverse = MAX(maxreverse,force->bond->comm_reverse); + for (const auto &fix : fix_list) { maxforward = MAX(maxforward,fix->comm_forward); maxreverse = MAX(maxreverse,fix->comm_reverse); @@ -235,6 +238,7 @@ void Comm::init() if (force->newton == 0) maxreverse = 0; if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse_off); + if (force->bond) maxreverse = MAX(maxreverse,force->bond->comm_reverse_off); // maxexchange_atom = size of an exchanged atom, set by AtomVec // only needs to be set if size > BUFEXTRA diff --git a/src/comm.h b/src/comm.h index 3d8d217136..be0e79ad82 100644 --- a/src/comm.h +++ b/src/comm.h @@ -80,10 +80,12 @@ class Comm : protected Pointers { virtual void exchange() = 0; // move atoms to new procs virtual void borders() = 0; // setup list of atoms to comm - // forward/reverse comm from a Pair, Fix, Compute, Dump + // forward/reverse comm from a Pair, Bond, Fix, Compute, Dump virtual void forward_comm(class Pair *) = 0; virtual void reverse_comm(class Pair *) = 0; + virtual void forward_comm(class Bond *) = 0; + virtual void reverse_comm(class Bond *) = 0; virtual void forward_comm(class Fix *, int size = 0) = 0; virtual void reverse_comm(class Fix *, int size = 0) = 0; virtual void reverse_comm_variable(class Fix *) = 0; diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index c2ff19ec74..b4a0cddda8 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -20,6 +20,7 @@ #include "atom.h" #include "atom_vec.h" +#include "bond.h" #include "compute.h" #include "domain.h" #include "dump.h" @@ -490,8 +491,7 @@ void CommBrick::setup() return how many procs away are needed to encompass cutghost away from loc ------------------------------------------------------------------------- */ -int CommBrick::updown(int dim, int dir, int loc, - double prd, int periodicity, double *split) +int CommBrick::updown(int dim, int dir, int loc, double prd, int periodicity, double *split) { int index,count; double frac,delta; @@ -552,19 +552,15 @@ void CommBrick::forward_comm(int /*dummy*/) if (comm_x_only) { if (size_forward_recv[iswap]) { buf = x[firstrecv[iswap]]; - MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE, - recvproc[iswap],0,world,&request); + MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); } - n = avec->pack_comm(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + n = avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); } else if (ghost_velocity) { if (size_forward_recv[iswap]) - MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE, - recvproc[iswap],0,world,&request); - n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); + n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_recv); @@ -572,8 +568,7 @@ void CommBrick::forward_comm(int /*dummy*/) if (size_forward_recv[iswap]) MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE, recvproc[iswap],0,world,&request); - n = avec->pack_comm(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + n = avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); if (n) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (size_forward_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_recv); @@ -585,12 +580,10 @@ void CommBrick::forward_comm(int /*dummy*/) avec->pack_comm(sendnum[iswap],sendlist[iswap], x[firstrecv[iswap]],pbc_flag[iswap],pbc[iswap]); } else if (ghost_velocity) { - avec->pack_comm_vel(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_send); } else { - avec->pack_comm(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + avec->pack_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_send); } } @@ -618,18 +611,15 @@ void CommBrick::reverse_comm() if (sendproc[iswap] != me) { if (comm_f_only) { if (size_reverse_recv[iswap]) - MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE, - sendproc[iswap],0,world,&request); + MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); if (size_reverse_send[iswap]) { buf = f[firstrecv[iswap]]; - MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE, - recvproc[iswap],0,world); + MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE,recvproc[iswap],0,world); } if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); } else { if (size_reverse_recv[iswap]) - MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE, - sendproc[iswap],0,world,&request); + MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); n = avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send); if (n) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world); if (size_reverse_recv[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -639,8 +629,7 @@ void CommBrick::reverse_comm() } else { if (comm_f_only) { if (sendnum[iswap]) - avec->unpack_reverse(sendnum[iswap],sendlist[iswap], - f[firstrecv[iswap]]); + avec->unpack_reverse(sendnum[iswap],sendlist[iswap],f[firstrecv[iswap]]); } else { avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send); avec->unpack_reverse(sendnum[iswap],sendlist[iswap],buf_send); @@ -733,25 +722,21 @@ void CommBrick::exchange() if (procgrid[dim] == 1) nrecv = 0; else { MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0, - &nrecv1,1,MPI_INT,procneigh[dim][1],0,world, - MPI_STATUS_IGNORE); + &nrecv1,1,MPI_INT,procneigh[dim][1],0,world,MPI_STATUS_IGNORE); nrecv = nrecv1; if (procgrid[dim] > 2) { MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0, - &nrecv2,1,MPI_INT,procneigh[dim][0],0,world, - MPI_STATUS_IGNORE); + &nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE); nrecv += nrecv2; } if (nrecv > maxrecv) grow_recv(nrecv); - MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0, - world,&request); + MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request); MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][0],0,world); MPI_Wait(&request,MPI_STATUS_IGNORE); if (procgrid[dim] > 2) { - MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0, - world,&request); + MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request); MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][1],0,world); MPI_Wait(&request,MPI_STATUS_IGNORE); } @@ -925,11 +910,9 @@ void CommBrick::borders() if (nsend*size_border > maxsend) grow_send(nsend*size_border,0); if (ghost_velocity) - n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send, - pbc_flag[iswap],pbc[iswap]); + n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); else - n = avec->pack_border(nsend,sendlist[iswap],buf_send, - pbc_flag[iswap],pbc[iswap]); + n = avec->pack_border(nsend,sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); // swap atoms with other proc // no MPI calls except SendRecv if nsend/nrecv = 0 @@ -938,8 +921,7 @@ void CommBrick::borders() if (sendproc[iswap] != me) { MPI_Sendrecv(&nsend,1,MPI_INT,sendproc[iswap],0, - &nrecv,1,MPI_INT,recvproc[iswap],0,world, - MPI_STATUS_IGNORE); + &nrecv,1,MPI_INT,recvproc[iswap],0,world,MPI_STATUS_IGNORE); if (nrecv*size_border > maxrecv) grow_recv(nrecv*size_border); if (nrecv) MPI_Irecv(buf_recv,nrecv*size_border,MPI_DOUBLE, recvproc[iswap],0,world,&request); @@ -1013,16 +995,14 @@ void CommBrick::forward_comm(Pair *pair) // pack buffer - n = pair->pack_forward_comm(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + n = pair->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); // exchange with another proc // if self, set recv buffer to send buffer if (sendproc[iswap] != me) { if (recvnum[iswap]) - MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE, - recvproc[iswap],0,world,&request); + MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); if (sendnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1059,8 +1039,7 @@ void CommBrick::reverse_comm(Pair *pair) if (sendproc[iswap] != me) { if (sendnum[iswap]) - MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); if (recvnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world); if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1073,6 +1052,80 @@ void CommBrick::reverse_comm(Pair *pair) } } +/* ---------------------------------------------------------------------- + forward communication invoked by a Bond + nsize used only to set recv buffer limit +------------------------------------------------------------------------- */ + +void CommBrick::forward_comm(Bond *bond) +{ + int iswap,n; + double *buf; + MPI_Request request; + + int nsize = bond->comm_forward; + + for (iswap = 0; iswap < nswap; iswap++) { + + // pack buffer + + n = bond->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); + + // exchange with another proc + // if self, set recv buffer to send buffer + + if (sendproc[iswap] != me) { + if (recvnum[iswap]) + MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); + if (sendnum[iswap]) + MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); + if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); + buf = buf_recv; + } else buf = buf_send; + + // unpack buffer + + bond->unpack_forward_comm(recvnum[iswap],firstrecv[iswap],buf); + } +} + +/* ---------------------------------------------------------------------- + reverse communication invoked by a Bond + nsize used only to set recv buffer limit +------------------------------------------------------------------------- */ + +void CommBrick::reverse_comm(Bond *bond) +{ + int iswap,n; + double *buf; + MPI_Request request; + + int nsize = MAX(bond->comm_reverse,bond->comm_reverse_off); + + for (iswap = nswap-1; iswap >= 0; iswap--) { + + // pack buffer + + n = bond->pack_reverse_comm(recvnum[iswap],firstrecv[iswap],buf_send); + + // exchange with another proc + // if self, set recv buffer to send buffer + + if (sendproc[iswap] != me) { + if (sendnum[iswap]) + MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); + if (recvnum[iswap]) + MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world); + if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); + buf = buf_recv; + } else buf = buf_send; + + // unpack buffer + + bond->unpack_reverse_comm(sendnum[iswap],sendlist[iswap],buf); + } +} + /* ---------------------------------------------------------------------- forward communication invoked by a Fix size/nsize used only to set recv buffer limit @@ -1095,16 +1148,14 @@ void CommBrick::forward_comm(Fix *fix, int size) // pack buffer - n = fix->pack_forward_comm(sendnum[iswap],sendlist[iswap], - buf_send,pbc_flag[iswap],pbc[iswap]); + n = fix->pack_forward_comm(sendnum[iswap],sendlist[iswap],buf_send,pbc_flag[iswap],pbc[iswap]); // exchange with another proc // if self, set recv buffer to send buffer if (sendproc[iswap] != me) { if (recvnum[iswap]) - MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); if (sendnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1146,8 +1197,7 @@ void CommBrick::reverse_comm(Fix *fix, int size) if (sendproc[iswap] != me) { if (sendnum[iswap]) - MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); if (recvnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world); if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1185,13 +1235,11 @@ void CommBrick::reverse_comm_variable(Fix *fix) if (sendproc[iswap] != me) { MPI_Sendrecv(&nsend,1,MPI_INT,recvproc[iswap],0, - &nrecv,1,MPI_INT,sendproc[iswap],0,world, - MPI_STATUS_IGNORE); + &nrecv,1,MPI_INT,sendproc[iswap],0,world,MPI_STATUS_IGNORE); if (sendnum[iswap]) { if (nrecv > maxrecv) grow_recv(nrecv); - MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0,world,&request); } if (recvnum[iswap]) MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world); @@ -1230,8 +1278,7 @@ void CommBrick::forward_comm(Compute *compute) if (sendproc[iswap] != me) { if (recvnum[iswap]) - MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); if (sendnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1268,8 +1315,7 @@ void CommBrick::reverse_comm(Compute *compute) if (sendproc[iswap] != me) { if (sendnum[iswap]) - MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); if (recvnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world); if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1307,8 +1353,7 @@ void CommBrick::forward_comm(Dump *dump) if (sendproc[iswap] != me) { if (recvnum[iswap]) - MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); if (sendnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world); if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1345,8 +1390,7 @@ void CommBrick::reverse_comm(Dump *dump) if (sendproc[iswap] != me) { if (sendnum[iswap]) - MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world,&request); if (recvnum[iswap]) MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world); if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); @@ -1394,11 +1438,9 @@ void CommBrick::forward_comm_array(int nsize, double **array) if (sendproc[iswap] != me) { if (recvnum[iswap]) - MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0, - world,&request); + MPI_Irecv(buf_recv,nsize*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world,&request); if (sendnum[iswap]) - MPI_Send(buf_send,nsize*sendnum[iswap],MPI_DOUBLE, - sendproc[iswap],0,world); + MPI_Send(buf_send,nsize*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world); if (recvnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); buf = buf_recv; } else buf = buf_send; @@ -1444,21 +1486,18 @@ int CommBrick::exchange_variable(int n, double *inbuf, double *&outbuf) nrecv += nrecv1; if (procgrid[dim] > 2) { MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0, - &nrecv2,1,MPI_INT,procneigh[dim][0],0,world, - MPI_STATUS_IGNORE); + &nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE); nrecv += nrecv2; } else nrecv2 = 0; if (nrecv > maxrecv) grow_recv(nrecv); - MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0, - world,&request); + MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request); MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][0],0,world); MPI_Wait(&request,MPI_STATUS_IGNORE); if (procgrid[dim] > 2) { - MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0, - world,&request); + MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request); MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][1],0,world); MPI_Wait(&request,MPI_STATUS_IGNORE); } diff --git a/src/comm_brick.h b/src/comm_brick.h index c641ba7e7b..5f18a6c58f 100644 --- a/src/comm_brick.h +++ b/src/comm_brick.h @@ -22,6 +22,7 @@ class CommBrick : public Comm { public: CommBrick(class LAMMPS *); CommBrick(class LAMMPS *, class Comm *); + ~CommBrick() override; void init() override; @@ -33,6 +34,8 @@ class CommBrick : public Comm { void forward_comm(class Pair *) override; // forward comm from a Pair void reverse_comm(class Pair *) override; // reverse comm from a Pair + void forward_comm(class Bond *) override; // forward comm from a Bond + void reverse_comm(class Bond *) override; // reverse comm from a Bond void forward_comm(class Fix *, int size = 0) override; // forward comm from a Fix void reverse_comm(class Fix *, int size = 0) override; // reverse comm from a Fix void reverse_comm_variable(class Fix *) override; // variable size reverse comm from a Fix diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index a7af454a8e..8088ada44b 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -21,6 +21,7 @@ #include "atom.h" #include "atom_vec.h" +#include "bond.h" #include "compute.h" #include "domain.h" #include "dump.h" @@ -512,16 +513,14 @@ void CommTiled::setup() MIN(sbox_multi[3+idim]+cutghostmulti[icollection][idim],subhi[idim]); else sbox_multi[3+idim] = - MIN(sbox_multi[3+idim]-prd[idim]+cutghostmulti[icollection][idim], - subhi[idim]); + MIN(sbox_multi[3+idim]-prd[idim]+cutghostmulti[icollection][idim],subhi[idim]); } else { if (i < noverlap1) sbox_multi[idim] = MAX(sbox_multi[idim]-cutghostmulti[icollection][idim],sublo[idim]); else sbox_multi[idim] = - MAX(sbox_multi[idim]+prd[idim]-cutghostmulti[icollection][idim], - sublo[idim]); + MAX(sbox_multi[idim]+prd[idim]-cutghostmulti[icollection][idim],sublo[idim]); sbox_multi[3+idim] = subhi[idim]; } @@ -588,16 +587,14 @@ void CommTiled::setup() MIN(sbox_multiold[3+idim]+cutghostmultiold[itype][idim],subhi[idim]); else sbox_multiold[3+idim] = - MIN(sbox_multiold[3+idim]-prd[idim]+cutghostmultiold[itype][idim], - subhi[idim]); + MIN(sbox_multiold[3+idim]-prd[idim]+cutghostmultiold[itype][idim],subhi[idim]); } else { if (i < noverlap1) sbox_multiold[idim] = MAX(sbox_multiold[idim]-cutghostmultiold[itype][idim],sublo[idim]); else sbox_multiold[idim] = - MAX(sbox_multiold[idim]+prd[idim]-cutghostmultiold[itype][idim], - sublo[idim]); + MAX(sbox_multiold[idim]+prd[idim]-cutghostmultiold[itype][idim],sublo[idim]); sbox_multiold[3+idim] = subhi[idim]; } @@ -747,8 +744,7 @@ void CommTiled::forward_comm(int /*dummy*/) } if (sendself[iswap]) { avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - x[firstrecv[iswap][nrecv]],pbc_flag[iswap][nsend], - pbc[iswap][nsend]); + x[firstrecv[iswap][nrecv]],pbc_flag[iswap][nsend],pbc[iswap][nsend]); } if (recvother[iswap]) MPI_Waitall(nrecv,requests,MPI_STATUS_IGNORE); @@ -756,8 +752,7 @@ void CommTiled::forward_comm(int /*dummy*/) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]], - size_forward_recv[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + size_forward_recv[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { @@ -769,15 +764,13 @@ void CommTiled::forward_comm(int /*dummy*/) if (sendself[iswap]) { avec->pack_comm_vel(sendnum[iswap][nsend],sendlist[iswap][nsend], buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); - avec->unpack_comm_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); + avec->unpack_comm_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); avec->unpack_comm_vel(recvnum[iswap][irecv],firstrecv[iswap][irecv], - &buf_recv[size_forward* - forward_recv_offset[iswap][irecv]]); + &buf_recv[size_forward*forward_recv_offset[iswap][irecv]]); } } @@ -785,8 +778,7 @@ void CommTiled::forward_comm(int /*dummy*/) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[size_forward*forward_recv_offset[iswap][i]], - size_forward_recv[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + size_forward_recv[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { @@ -798,15 +790,13 @@ void CommTiled::forward_comm(int /*dummy*/) if (sendself[iswap]) { avec->pack_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); - avec->unpack_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); + avec->unpack_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); avec->unpack_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv], - &buf_recv[size_forward* - forward_recv_offset[iswap][irecv]]); + &buf_recv[size_forward*forward_recv_offset[iswap][irecv]]); } } } @@ -839,8 +829,7 @@ void CommTiled::reverse_comm() if (sendother[iswap]) { for (i = 0; i < nsend; i++) { MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]], - size_reverse_recv[iswap][i],MPI_DOUBLE, - sendproc[iswap][i],0,world,&requests[i]); + size_reverse_recv[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); } } if (recvother[iswap]) { @@ -856,8 +845,7 @@ void CommTiled::reverse_comm() for (i = 0; i < nsend; i++) { MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv], - &buf_recv[size_reverse* - reverse_recv_offset[iswap][irecv]]); + &buf_recv[size_reverse*reverse_recv_offset[iswap][irecv]]); } } @@ -865,28 +853,23 @@ void CommTiled::reverse_comm() if (sendother[iswap]) { for (i = 0; i < nsend; i++) MPI_Irecv(&buf_recv[size_reverse*reverse_recv_offset[iswap][i]], - size_reverse_recv[iswap][i],MPI_DOUBLE, - sendproc[iswap][i],0,world,&requests[i]); + size_reverse_recv[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { - n = avec->pack_reverse(recvnum[iswap][i],firstrecv[iswap][i], - buf_send); + n = avec->pack_reverse(recvnum[iswap][i],firstrecv[iswap][i],buf_send); MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world); } } if (sendself[iswap]) { - avec->pack_reverse(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); - avec->unpack_reverse(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send); + avec->pack_reverse(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + avec->unpack_reverse(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); avec->unpack_reverse(sendnum[iswap][irecv],sendlist[iswap][irecv], - &buf_recv[size_reverse* - reverse_recv_offset[iswap][irecv]]); + &buf_recv[size_reverse*reverse_recv_offset[iswap][irecv]]); } } } @@ -989,8 +972,7 @@ void CommTiled::exchange() if (!nexch) continue; for (m = 0; m < nexch; m++) - MPI_Irecv(&exchnum[dim][m],1,MPI_INT, - exchproc[dim][m],0,world,&requests[m]); + MPI_Irecv(&exchnum[dim][m],1,MPI_INT,exchproc[dim][m],0,world,&requests[m]); for (m = 0; m < nexch; m++) MPI_Send(&nsend,1,MPI_INT,exchproc[dim][m],0,world); MPI_Waitall(nexch,requests,MPI_STATUS_IGNORE); @@ -1001,8 +983,7 @@ void CommTiled::exchange() offset = 0; for (m = 0; m < nexch; m++) { - MPI_Irecv(&buf_recv[offset],exchnum[dim][m], - MPI_DOUBLE,exchproc[dim][m],0,world,&requests[m]); + MPI_Irecv(&buf_recv[offset],exchnum[dim][m],MPI_DOUBLE,exchproc[dim][m],0,world,&requests[m]); offset += exchnum[dim][m]; } for (m = 0; m < nexch; m++) @@ -1233,8 +1214,7 @@ void CommTiled::borders() if (recvother[iswap]) for (m = 0; m < nrecv; m++) - MPI_Irecv(&recvnum[iswap][m],1,MPI_INT, - recvproc[iswap][m],0,world,&requests[m]); + MPI_Irecv(&recvnum[iswap][m],1,MPI_INT,recvproc[iswap][m],0,world,&requests[m]); if (sendother[iswap]) for (m = 0; m < nsend; m++) MPI_Send(&sendnum[iswap][m],1,MPI_INT,sendproc[iswap][m],0,world); @@ -1294,17 +1274,14 @@ void CommTiled::borders() } if (sendself[iswap]) { avec->pack_border_vel(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send,pbc_flag[iswap][nsend], - pbc[iswap][nsend]); - avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); + buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); + avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE); avec->unpack_border_vel(recvnum[iswap][m],firstrecv[iswap][m], - &buf_recv[size_border* - forward_recv_offset[iswap][m]]); + &buf_recv[size_border*forward_recv_offset[iswap][m]]); } } @@ -1325,15 +1302,13 @@ void CommTiled::borders() if (sendself[iswap]) { avec->pack_border(sendnum[iswap][nsend],sendlist[iswap][nsend], buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); - avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); + avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE); avec->unpack_border(recvnum[iswap][m],firstrecv[iswap][m], - &buf_recv[size_border* - forward_recv_offset[iswap][m]]); + &buf_recv[size_border*forward_recv_offset[iswap][m]]); } } } @@ -1351,10 +1326,8 @@ void CommTiled::borders() // For molecular systems we lose some bits for local atom indices due // to encoding of special pairs in neighbor lists. Check for overflows. - if ((atom->molecular != Atom::ATOMIC) - && ((atom->nlocal + atom->nghost) > NEIGHMASK)) - error->one(FLERR,"Per-processor number of atoms is too large for " - "molecular neighbor lists"); + if ((atom->molecular != Atom::ATOMIC) && ((atom->nlocal + atom->nghost) > NEIGHMASK)) + error->one(FLERR,"Per-processor number of atoms is too large for molecular neighbor lists"); // insure send/recv buffers are long enough for all forward & reverse comm // send buf is for one forward or reverse sends to one proc @@ -1388,8 +1361,7 @@ void CommTiled::forward_comm(Pair *pair) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]], - nsize*recvnum[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { @@ -1402,17 +1374,14 @@ void CommTiled::forward_comm(Pair *pair) if (sendself[iswap]) { pair->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send,pbc_flag[iswap][nsend], - pbc[iswap][nsend]); - pair->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); + buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); + pair->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); pair->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv], - &buf_recv[nsize* - forward_recv_offset[iswap][irecv]]); + &buf_recv[nsize*forward_recv_offset[iswap][irecv]]); } } } @@ -1436,28 +1405,107 @@ void CommTiled::reverse_comm(Pair *pair) if (sendother[iswap]) { for (i = 0; i < nsend; i++) MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]], - nsize*sendnum[iswap][i],MPI_DOUBLE, - sendproc[iswap][i],0,world,&requests[i]); + nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { - n = pair->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i], - buf_send); + n = pair->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send); MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world); } } if (sendself[iswap]) { - pair->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); - pair->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send); + pair->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + pair->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); pair->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv], - &buf_recv[nsize* - reverse_recv_offset[iswap][irecv]]); + &buf_recv[nsize*reverse_recv_offset[iswap][irecv]]); + } + } + } +} + +/* ---------------------------------------------------------------------- + forward communication invoked by a Bond + nsize used only to set recv buffer limit +------------------------------------------------------------------------- */ + +void CommTiled::forward_comm(Bond *bond) +{ + int i,irecv,n,nsend,nrecv; + + int nsize = bond->comm_forward; + + for (int iswap = 0; iswap < nswap; iswap++) { + nsend = nsendproc[iswap] - sendself[iswap]; + nrecv = nrecvproc[iswap] - sendself[iswap]; + + if (recvother[iswap]) { + for (i = 0; i < nrecv; i++) + MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]], + nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + } + + if (sendother[iswap]) { + for (i = 0; i < nsend; i++) { + n = bond->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i], + buf_send,pbc_flag[iswap][i],pbc[iswap][i]); + MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world); + } + } + + if (sendself[iswap]) { + bond->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], + buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); + bond->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + } + if (recvother[iswap]) { + for (i = 0; i < nrecv; i++) { + MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); + bond->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv], + &buf_recv[nsize*forward_recv_offset[iswap][irecv]]); + } + } + } +} + +/* ---------------------------------------------------------------------- + reverse communication invoked by a Bond + nsize used only to set recv buffer limit +------------------------------------------------------------------------- */ + +void CommTiled::reverse_comm(Bond *bond) +{ + int i,irecv,n,nsend,nrecv; + + int nsize = MAX(bond->comm_reverse,bond->comm_reverse_off); + + for (int iswap = nswap-1; iswap >= 0; iswap--) { + nsend = nsendproc[iswap] - sendself[iswap]; + nrecv = nrecvproc[iswap] - sendself[iswap]; + + if (sendother[iswap]) { + for (i = 0; i < nsend; i++) + MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]], + nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); + } + if (recvother[iswap]) { + for (i = 0; i < nrecv; i++) { + n = bond->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send); + MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world); + } + } + if (sendself[iswap]) { + bond->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + bond->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send); + } + if (sendother[iswap]) { + for (i = 0; i < nsend; i++) { + MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); + bond->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv], + &buf_recv[nsize*reverse_recv_offset[iswap][irecv]]); } } } @@ -1486,8 +1534,7 @@ void CommTiled::forward_comm(Fix *fix, int size) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]], - nsize*recvnum[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { @@ -1498,17 +1545,14 @@ void CommTiled::forward_comm(Fix *fix, int size) } if (sendself[iswap]) { fix->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send,pbc_flag[iswap][nsend], - pbc[iswap][nsend]); - fix->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); + buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); + fix->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); fix->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv], - &buf_recv[nsize* - forward_recv_offset[iswap][irecv]]); + &buf_recv[nsize*forward_recv_offset[iswap][irecv]]); } } } @@ -1537,28 +1581,23 @@ void CommTiled::reverse_comm(Fix *fix, int size) if (sendother[iswap]) { for (i = 0; i < nsend; i++) MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]], - nsize*sendnum[iswap][i],MPI_DOUBLE, - sendproc[iswap][i],0,world,&requests[i]); + nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { - n = fix->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i], - buf_send); + n = fix->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send); MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world); } } if (sendself[iswap]) { - fix->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); - fix->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send); + fix->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + fix->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); fix->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv], - &buf_recv[nsize* - reverse_recv_offset[iswap][irecv]]); + &buf_recv[nsize*reverse_recv_offset[iswap][irecv]]); } } } @@ -1594,31 +1633,26 @@ void CommTiled::forward_comm(Compute *compute) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]], - nsize*recvnum[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { n = compute->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i], - buf_send,pbc_flag[iswap][i], - pbc[iswap][i]); + buf_send,pbc_flag[iswap][i],pbc[iswap][i]); MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world); } } if (sendself[iswap]) { compute->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send,pbc_flag[iswap][nsend], - pbc[iswap][nsend]); - compute->unpack_forward_comm(recvnum[iswap][nrecv], - firstrecv[iswap][nrecv],buf_send); + buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); + compute->unpack_forward_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); compute-> unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv], - &buf_recv[nsize* - forward_recv_offset[iswap][irecv]]); + &buf_recv[nsize*forward_recv_offset[iswap][irecv]]); } } } @@ -1642,29 +1676,24 @@ void CommTiled::reverse_comm(Compute *compute) if (sendother[iswap]) { for (i = 0; i < nsend; i++) MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]], - nsize*sendnum[iswap][i],MPI_DOUBLE, - sendproc[iswap][i],0,world,&requests[i]); + nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { - n = compute->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i], - buf_send); + n = compute->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send); MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world); } } if (sendself[iswap]) { - compute->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); - compute->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send); + compute->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + compute->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); compute-> unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv], - &buf_recv[nsize* - reverse_recv_offset[iswap][irecv]]); + &buf_recv[nsize*reverse_recv_offset[iswap][irecv]]); } } } @@ -1688,21 +1717,18 @@ void CommTiled::forward_comm(Dump *dump) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]], - nsize*recvnum[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { n = dump->pack_forward_comm(sendnum[iswap][i],sendlist[iswap][i], - buf_send,pbc_flag[iswap][i], - pbc[iswap][i]); + buf_send,pbc_flag[iswap][i],pbc[iswap][i]); MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][i],0,world); } } if (sendself[iswap]) { dump->pack_forward_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send,pbc_flag[iswap][nsend], - pbc[iswap][nsend]); + buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]); dump->unpack_forward_comm(recvnum[iswap][nrecv], firstrecv[iswap][nrecv],buf_send); } @@ -1710,8 +1736,7 @@ void CommTiled::forward_comm(Dump *dump) for (i = 0; i < nrecv; i++) { MPI_Waitany(nrecv,requests,&irecv,MPI_STATUS_IGNORE); dump->unpack_forward_comm(recvnum[iswap][irecv],firstrecv[iswap][irecv], - &buf_recv[nsize* - forward_recv_offset[iswap][irecv]]); + &buf_recv[nsize*forward_recv_offset[iswap][irecv]]); } } } @@ -1735,28 +1760,23 @@ void CommTiled::reverse_comm(Dump *dump) if (sendother[iswap]) { for (i = 0; i < nsend; i++) MPI_Irecv(&buf_recv[nsize*reverse_recv_offset[iswap][i]], - nsize*sendnum[iswap][i],MPI_DOUBLE, - sendproc[iswap][i],0,world,&requests[i]); + nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world,&requests[i]); } if (recvother[iswap]) { for (i = 0; i < nrecv; i++) { - n = dump->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i], - buf_send); + n = dump->pack_reverse_comm(recvnum[iswap][i],firstrecv[iswap][i],buf_send); MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap][i],0,world); } } if (sendself[iswap]) { - dump->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv], - buf_send); - dump->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend], - buf_send); + dump->pack_reverse_comm(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],buf_send); + dump->unpack_reverse_comm(sendnum[iswap][nsend],sendlist[iswap][nsend],buf_send); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { MPI_Waitany(nsend,requests,&irecv,MPI_STATUS_IGNORE); dump->unpack_reverse_comm(sendnum[iswap][irecv],sendlist[iswap][irecv], - &buf_recv[nsize* - reverse_recv_offset[iswap][irecv]]); + &buf_recv[nsize*reverse_recv_offset[iswap][irecv]]); } } } @@ -1788,8 +1808,7 @@ void CommTiled::forward_comm_array(int nsize, double **array) if (recvother[iswap]) { for (i = 0; i < nrecv; i++) MPI_Irecv(&buf_recv[nsize*forward_recv_offset[iswap][i]], - nsize*recvnum[iswap][i], - MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); + nsize*recvnum[iswap][i],MPI_DOUBLE,recvproc[iswap][i],0,world,&requests[i]); } if (sendother[iswap]) { for (i = 0; i < nsend; i++) { @@ -1799,8 +1818,7 @@ void CommTiled::forward_comm_array(int nsize, double **array) for (k = 0; k < nsize; k++) buf_send[m++] = array[j][k]; } - MPI_Send(buf_send,nsize*sendnum[iswap][i], - MPI_DOUBLE,sendproc[iswap][i],0,world); + MPI_Send(buf_send,nsize*sendnum[iswap][i],MPI_DOUBLE,sendproc[iswap][i],0,world); } } if (sendself[iswap]) { @@ -1919,8 +1937,7 @@ void CommTiled::box_drop_tiled(int /*idim*/, double *lo, double *hi, int &indexm box_drop_tiled_recurse(lo,hi,0,nprocs-1,indexme); } -void CommTiled::box_drop_tiled_recurse(double *lo, double *hi, - int proclower, int procupper, +void CommTiled::box_drop_tiled_recurse(double *lo, double *hi, int proclower, int procupper, int &indexme) { // end recursion when partition is a single proc @@ -1958,8 +1975,7 @@ void CommTiled::box_drop_tiled_recurse(double *lo, double *hi, return other box owned by proc as lo/hi corner pts ------------------------------------------------------------------------- */ -void CommTiled::box_other_brick(int idim, int idir, - int proc, double *lo, double *hi) +void CommTiled::box_other_brick(int idim, int idir, int proc, double *lo, double *hi) { lo[0] = sublo[0]; lo[1] = sublo[1]; lo[2] = sublo[2]; hi[0] = subhi[0]; hi[1] = subhi[1]; hi[2] = subhi[2]; @@ -2006,8 +2022,7 @@ void CommTiled::box_other_brick(int idim, int idir, return other box owned by proc as lo/hi corner pts ------------------------------------------------------------------------- */ -void CommTiled::box_other_tiled(int /*idim*/, int /*idir*/, - int proc, double *lo, double *hi) +void CommTiled::box_other_tiled(int /*idim*/, int /*idir*/, int proc, double *lo, double *hi) { double (*split)[2] = rcbinfo[proc].mysplit; @@ -2136,8 +2151,7 @@ int CommTiled::point_drop_tiled(int idim, double *x) recursive point drop thru RCB tree ------------------------------------------------------------------------- */ -int CommTiled::point_drop_tiled_recurse(double *x, - int proclower, int procupper) +int CommTiled::point_drop_tiled_recurse(double *x, int proclower, int procupper) { // end recursion when partition is a single proc // return proc @@ -2195,8 +2209,7 @@ void CommTiled::coord2proc_setup() memcpy(&rcbone.mysplit[0][0],&mysplit[0][0],6*sizeof(double)); rcbone.cutfrac = rcbcutfrac; rcbone.dim = rcbcutdim; - MPI_Allgather(&rcbone,sizeof(RCBinfo),MPI_CHAR, - rcbinfo,sizeof(RCBinfo),MPI_CHAR,world); + MPI_Allgather(&rcbone,sizeof(RCBinfo),MPI_CHAR,rcbinfo,sizeof(RCBinfo),MPI_CHAR,world); } /* ---------------------------------------------------------------------- diff --git a/src/comm_tiled.h b/src/comm_tiled.h index 270130844b..be79ec60a5 100644 --- a/src/comm_tiled.h +++ b/src/comm_tiled.h @@ -22,6 +22,7 @@ class CommTiled : public Comm { public: CommTiled(class LAMMPS *); CommTiled(class LAMMPS *, class Comm *); + ~CommTiled() override; void init() override; @@ -33,6 +34,8 @@ class CommTiled : public Comm { void forward_comm(class Pair *) override; // forward comm from a Pair void reverse_comm(class Pair *) override; // reverse comm from a Pair + void forward_comm(class Bond *) override; // forward comm from a Bond + void reverse_comm(class Bond *) override; // reverse comm from a Bond void forward_comm(class Fix *, int size = 0) override; // forward comm from a Fix void reverse_comm(class Fix *, int size = 0) override; // reverse comm from a Fix void reverse_comm_variable(class Fix *) override; // variable size reverse comm from a Fix diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 6cd4415f73..606da288de 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -231,25 +231,25 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"quatw") == 0) { avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); avec_body = dynamic_cast( atom->style_match("body")); - if (!avec_ellipsoid && !avec_body) + if (!avec_ellipsoid && !avec_body && !atom->quat_flag) 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 = dynamic_cast( atom->style_match("ellipsoid")); avec_body = dynamic_cast( atom->style_match("body")); - if (!avec_ellipsoid && !avec_body) + if (!avec_ellipsoid && !avec_body && !atom->quat_flag) 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 = dynamic_cast( atom->style_match("ellipsoid")); avec_body = dynamic_cast( atom->style_match("body")); - if (!avec_ellipsoid && !avec_body) + if (!avec_ellipsoid && !avec_body && !atom->quat_flag) 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 = dynamic_cast( atom->style_match("ellipsoid")); avec_body = dynamic_cast( atom->style_match("body")); - if (!avec_ellipsoid && !avec_body) + if (!avec_ellipsoid && !avec_body && !atom->quat_flag) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatk; @@ -1334,7 +1334,7 @@ void ComputePropertyAtom::pack_quatw(int n) n += nvalues; } - } else { + } else if (avec_body) { AtomVecBody::Bonus *bonus = avec_body->bonus; int *body = atom->body; int *mask = atom->mask; @@ -1346,6 +1346,17 @@ void ComputePropertyAtom::pack_quatw(int n) else buf[n] = 0.0; n += nvalues; } + } else { + double **quat = atom->quat; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) + buf[n] = quat[i][0]; + else buf[n] = 0.0; + n += nvalues; + } } } @@ -1366,7 +1377,7 @@ void ComputePropertyAtom::pack_quati(int n) n += nvalues; } - } else { + } else if (avec_body) { AtomVecBody::Bonus *bonus = avec_body->bonus; int *body = atom->body; int *mask = atom->mask; @@ -1378,6 +1389,17 @@ void ComputePropertyAtom::pack_quati(int n) else buf[n] = 0.0; n += nvalues; } + } else { + double **quat = atom->quat; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) + buf[n] = quat[i][1]; + else buf[n] = 0.0; + n += nvalues; + } } } @@ -1398,7 +1420,7 @@ void ComputePropertyAtom::pack_quatj(int n) n += nvalues; } - } else { + } else if (avec_body) { AtomVecBody::Bonus *bonus = avec_body->bonus; int *body = atom->body; int *mask = atom->mask; @@ -1410,6 +1432,17 @@ void ComputePropertyAtom::pack_quatj(int n) else buf[n] = 0.0; n += nvalues; } + } else { + double **quat = atom->quat; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) + buf[n] = quat[i][2]; + else buf[n] = 0.0; + n += nvalues; + } } } @@ -1430,7 +1463,7 @@ void ComputePropertyAtom::pack_quatk(int n) n += nvalues; } - } else { + } else if (avec_body) { AtomVecBody::Bonus *bonus = avec_body->bonus; int *body = atom->body; int *mask = atom->mask; @@ -1442,6 +1475,17 @@ void ComputePropertyAtom::pack_quatk(int n) else buf[n] = 0.0; n += nvalues; } + } else { + double **quat = atom->quat; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) + buf[n] = quat[i][3]; + else buf[n] = 0.0; + n += nvalues; + } } } diff --git a/src/delete_bonds.cpp b/src/delete_bonds.cpp index 9947434da3..2dcbd4af56 100644 --- a/src/delete_bonds.cpp +++ b/src/delete_bonds.cpp @@ -19,8 +19,10 @@ #include "comm.h" #include "domain.h" #include "error.h" +#include "fix_bond_history.h" #include "force.h" #include "group.h" +#include "modify.h" #include "special.h" #include @@ -116,6 +118,10 @@ void DeleteBonds::command(int narg, char **arg) iarg++; } + // find instances of bond history to delete data + auto histories = modify->get_fix_by_style("BOND_HISTORY"); + int n_histories = histories.size(); + // border swap to insure type and mask is current for off-proc atoms // enforce PBC before in case atoms are outside box @@ -331,6 +337,11 @@ void DeleteBonds::command(int narg, char **arg) n = atom->num_bond[i]; atom->bond_type[i][m] = atom->bond_type[i][n-1]; atom->bond_atom[i][m] = atom->bond_atom[i][n-1]; + if (n_histories > 0) + for (auto &ihistory: histories) { + dynamic_cast(ihistory)->shift_history(i,m,n-1); + dynamic_cast(ihistory)->delete_history(i,n-1); + } atom->num_bond[i]--; } else m++; } else m++; @@ -431,32 +442,28 @@ void DeleteBonds::command(int narg, char **arg) if (atom->avec->bonds_allow) { bigint nbonds = 0; for (i = 0; i < nlocal; i++) nbonds += atom->num_bond[i]; - MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT, - MPI_SUM,world); + MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT,MPI_SUM,world); if (force->newton_bond == 0) atom->nbonds /= 2; } if (atom->avec->angles_allow) { bigint nangles = 0; for (i = 0; i < nlocal; i++) nangles += atom->num_angle[i]; - MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT, - MPI_SUM,world); + MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT,MPI_SUM,world); if (force->newton_bond == 0) atom->nangles /= 3; } if (atom->avec->dihedrals_allow) { bigint ndihedrals = 0; for (i = 0; i < nlocal; i++) ndihedrals += atom->num_dihedral[i]; - MPI_Allreduce(&ndihedrals,&atom->ndihedrals, - 1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&ndihedrals,&atom->ndihedrals,1,MPI_LMP_BIGINT,MPI_SUM,world); if (force->newton_bond == 0) atom->ndihedrals /= 4; } if (atom->avec->impropers_allow) { bigint nimpropers = 0; for (i = 0; i < nlocal; i++) nimpropers += atom->num_improper[i]; - MPI_Allreduce(&nimpropers,&atom->nimpropers, - 1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&nimpropers,&atom->nimpropers,1,MPI_LMP_BIGINT,MPI_SUM,world); if (force->newton_bond == 0) atom->nimpropers /= 4; } @@ -535,21 +542,18 @@ void DeleteBonds::command(int narg, char **arg) } if (comm->me == 0) { + constexpr auto fmtstr = " {} total {}, {} turned on, {} turned off\n"; if (atom->avec->bonds_allow) - utils::logmesg(lmp," {} total bonds, {} turned on, {} turned off\n", - atom->nbonds,bond_on,bond_off); + utils::logmesg(lmp,fmtstr,atom->nbonds,"bonds",bond_on,bond_off); if (atom->avec->angles_allow) - utils::logmesg(lmp," {} total angles, {} turned on, {} turned off\n", - atom->nangles,angle_on,angle_off); + utils::logmesg(lmp,fmtstr,atom->nangles,"angles",angle_on,angle_off); if (atom->avec->dihedrals_allow) - utils::logmesg(lmp," {} total dihedrals, {} turned on, {} turned off\n", - atom->ndihedrals,dihedral_on,dihedral_off); + utils::logmesg(lmp,fmtstr,atom->ndihedrals,"dihedrals",dihedral_on,dihedral_off); if (atom->avec->impropers_allow) - utils::logmesg(lmp," {} total impropers, {} turned on, {} turned off\n", - atom->nimpropers,improper_on,improper_off); + utils::logmesg(lmp,fmtstr,atom->nimpropers,"impropers",improper_on,improper_off); } // re-compute special list if requested diff --git a/src/dump.cpp b/src/dump.cpp index 19682883ff..c9a98cb239 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -1181,7 +1181,7 @@ void Dump::modify_params(int narg, char **arg) } else if (strcmp(arg[iarg],"header") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); - header_flag = utils::logical(FLERR,arg[iarg+1],false,lmp); + write_header_flag = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"maxfiles") == 0) { diff --git a/src/dump.h b/src/dump.h index 34e0677af8..c8712e5909 100644 --- a/src/dump.h +++ b/src/dump.h @@ -66,7 +66,6 @@ class Dump : protected Pointers { char *multiname; // filename with % converted to cluster ID MPI_Comm clustercomm; // MPI communicator within my cluster of procs - int header_flag; // 0 = item, 2 = xyz int flush_flag; // 0 if no flush, 1 if flush every dump int sort_flag; // 1 if sorted output int balance_flag; // 1 if load balanced output diff --git a/src/fix_bond_history.cpp b/src/fix_bond_history.cpp new file mode 100644 index 0000000000..67489e6402 --- /dev/null +++ b/src/fix_bond_history.cpp @@ -0,0 +1,365 @@ +/* ---------------------------------------------------------------------- + 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 "fix_bond_history.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "group.h" +#include "memory.h" +#include "modify.h" +#include "neighbor.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace FixConst; + +#define LB_FACTOR 1.5 +#define DELTA 8192 + +/* ---------------------------------------------------------------------- */ + +FixBondHistory::FixBondHistory(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), bondstore(nullptr), id_fix(nullptr), id_array(nullptr) + +{ + if (narg != 5) error->all(FLERR, "Illegal fix bond/history command"); + update_flag = utils::inumeric(FLERR, arg[3], false, lmp); + ndata = utils::inumeric(FLERR, arg[4], false, lmp); + nbond = atom->bond_per_atom; + + if (nbond == 0) error->all(FLERR, "Cannot store bond variables without any bonds"); + + stored_flag = false; + restart_global = 1; + create_attribute = 1; + + // Flag whether bond arrays are updated such that data may need to be + // copied to atom arrays before exchanging atoms + // Prevents sequential calls to pre_exchange() without post_neighbor() + updated_bond_flag = 0; + + maxbond = 0; + allocate(); +} + +/* ---------------------------------------------------------------------- */ + +FixBondHistory::~FixBondHistory() +{ + if (id_fix && modify->nfix) modify->delete_fix(id_fix); + delete[] id_fix; + delete[] id_array; + + memory->destroy(bondstore); +} + +/* ---------------------------------------------------------------------- */ + +int FixBondHistory::setmask() +{ + int mask = 0; + mask |= PRE_EXCHANGE; + mask |= POST_NEIGHBOR; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::post_constructor() +{ + // Store saved bond quantities for each atom using fix property atom + + id_fix = utils::strdup(id + std::string("_FIX_PROP_ATOM")); + id_array = utils::strdup(std::string("d2_") + id); + modify->add_fix(fmt::format("{} {} property/atom {} {}", id_fix, group->names[igroup], id_array, + nbond * ndata)); + int tmp1, tmp2; + index = atom->find_custom(&id_array[3], tmp1, tmp2); +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::update_atom_value(int i, int m, int idata, double value) +{ + if (idata >= ndata || m > nbond) error->all(FLERR, "Index exceeded in fix bond history"); + atom->darray[index][i][m * ndata + idata] = value; +} + +/* ---------------------------------------------------------------------- */ + +double FixBondHistory::get_atom_value(int i, int m, int idata) +{ + if (idata >= ndata || m > nbond) error->all(FLERR, "Index exceeded in fix bond history"); + return atom->darray[index][i][m * ndata + idata]; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::setup_pre_exchange() +{ + pre_exchange(); +} + +/* ---------------------------------------------------------------------- + If stored values are updated, need to copy to atom arrays before exchanging + If bondstore array has been allocated, call before nlist rebuild + Also call prior to irregular communication in other fixes (e.g. deform) +------------------------------------------------------------------------- */ + +void FixBondHistory::pre_exchange() +{ + if (!update_flag) return; + if (!stored_flag) return; + if (!updated_bond_flag) return; + + int i1, i2, n, m, idata; + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + double **stored = atom->darray[index]; + + int nlocal = atom->nlocal; + tagint **bond_atom = atom->bond_atom; + int *num_bond = atom->num_bond; + tagint *tag = atom->tag; + + for (n = 0; n < nbondlist; n++) { + i1 = bondlist[n][0]; + i2 = bondlist[n][1]; + + // skip bond if already broken + if (bondlist[n][2] <= 0) { continue; } + + if (i1 < nlocal) { + for (m = 0; m < num_bond[i1]; m++) { + if (bond_atom[i1][m] == tag[i2]) { + for (idata = 0; idata < ndata; idata++) { + stored[i1][m * ndata + idata] = bondstore[n][idata]; + } + } + } + } + + if (i2 < nlocal) { + for (m = 0; m < num_bond[i2]; m++) { + if (bond_atom[i2][m] == tag[i1]) { + for (idata = 0; idata < ndata; idata++) { + stored[i2][m * ndata + idata] = bondstore[n][idata]; + } + } + } + } + } + + updated_bond_flag = 0; +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::allocate() +{ + //Ideally would just ask ntopo for maxbond, but protected + if (comm->nprocs == 1) + maxbond = atom->nbonds; + else + maxbond = static_cast(LB_FACTOR * atom->nbonds / comm->nprocs); + memory->create(bondstore, maxbond, ndata, "fix_bond_store:bondstore"); +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::setup_post_neighbor() +{ + //Grow array if number of bonds has increased + while (neighbor->nbondlist >= maxbond) { + maxbond += DELTA; + memory->grow(bondstore, maxbond, ndata, "fix_bond_store:bondstore"); + } + + pre_exchange(); + post_neighbor(); +} + +/* ---------------------------------------------------------------------- + called after neighbor list is build + build array of stored bond quantities from fix property atom +------------------------------------------------------------------------- */ + +void FixBondHistory::post_neighbor() +{ + //Grow array if number of bonds has increased + while (neighbor->nbondlist >= maxbond) { + maxbond += DELTA; + memory->grow(bondstore, maxbond, ndata, "fix_bond_store:bondstore"); + } + + int i1, i2, n, m, idata; + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + double **stored = atom->darray[index]; + + int nlocal = atom->nlocal; + tagint **bond_atom = atom->bond_atom; + int *num_bond = atom->num_bond; + tagint *tag = atom->tag; + + for (n = 0; n < nbondlist; n++) { + i1 = bondlist[n][0]; + i2 = bondlist[n][1]; + + // skip bond if already broken + if (bondlist[n][2] <= 0) { continue; } + + if (i1 < nlocal) { + for (m = 0; m < num_bond[i1]; m++) { + if (bond_atom[i1][m] == tag[i2]) { + for (idata = 0; idata < ndata; idata++) { + bondstore[n][idata] = stored[i1][m * ndata + idata]; + } + } + } + } + + if (i2 < nlocal) { + for (m = 0; m < num_bond[i2]; m++) { + if (bond_atom[i2][m] == tag[i1]) { + for (idata = 0; idata < ndata; idata++) { + bondstore[n][idata] = stored[i2][m * ndata + idata]; + } + } + } + } + } + + updated_bond_flag = 1; +} + +/* ---------------------------------------------------------------------- */ + +double FixBondHistory::memory_usage() +{ + return maxbond * ndata * sizeof(double); +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::write_restart(FILE *fp) +{ + int n = 0; + double list[1]; + list[n++] = stored_flag; + + if (comm->me == 0) { + int size = n * sizeof(double); + fwrite(&size, sizeof(int), 1, fp); + fwrite(list, sizeof(double), n, fp); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixBondHistory::restart(char *buf) +{ + int n = 0; + double *list = (double *) buf; + stored_flag = static_cast(list[n++]); +} + +/* ---------------------------------------------------------------------- + initialize bond values to zero, called when atom is created +------------------------------------------------------------------------- */ + +void FixBondHistory::set_arrays(int i) +{ + double **stored = atom->darray[index]; + for (int m = 0; m < nbond; m++) + for (int idata = 0; idata < ndata; idata++) stored[i][m * ndata + idata] = 0.0; +} + +/* ---------------------------------------------------------------------- + Delete bond by zeroing data +------------------------------------------------------------------------- */ + +void FixBondHistory::delete_history(int i, int m) +{ + double **stored = atom->darray[index]; + for (int idata = 0; idata < ndata; idata++) stored[i][m * ndata + idata] = 0.0; +} + +/* ---------------------------------------------------------------------- + Shift bond data to a new location +------------------------------------------------------------------------- */ + +void FixBondHistory::shift_history(int i, int m, int k) +{ + if (m == k) return; + + double **stored = atom->darray[index]; + for (int idata = 0; idata < ndata; idata++) + stored[i][m * ndata + idata] = stored[i][k * ndata + idata]; +} + +/* ---------------------------------------------------------------------- + Temporarily caches history for a deleted bond which + could be recreated before the cache is emptied + NOTE: the cache methods still need to be tested, need an example first +------------------------------------------------------------------------- */ + +void FixBondHistory::cache_history(int i, int m) +{ + // Order tags to create a unique key pair + tagint max_tag = MAX(atom->tag[i], atom->bond_atom[i][m]); + tagint min_tag = MIN(atom->tag[i], atom->bond_atom[i][m]); + auto key = std::make_pair(min_tag, max_tag); + + // Copy data to vector + double **stored = atom->darray[index]; + std::vector data; + for (int idata = 0; idata < ndata; idata++) data.push_back(stored[i][m * ndata + idata]); + + // Add data to cache + cached_histories.insert(std::make_pair(key, data)); +} + +/* ---------------------------------------------------------------------- + Checks to see if a newly created bond has cached history +------------------------------------------------------------------------- */ + +void FixBondHistory::check_cache(int i, int m) +{ + // Order tags to create a unique key pair + tagint max_tag = MAX(atom->tag[i], atom->bond_atom[i][m]); + tagint min_tag = MIN(atom->tag[i], atom->bond_atom[i][m]); + auto key = std::make_pair(min_tag, max_tag); + + // Check if it exists, if so, copy data + double **stored = atom->darray[index]; + std::vector data; + auto pos = cached_histories.find(key); + if (pos != cached_histories.end()) { + data = pos->second; + for (int idata = 0; idata < ndata; idata++) stored[i][m * ndata + idata] = data[idata]; + } +} + +/* ---------------------------------------------------------------------- + Delete saved memory +------------------------------------------------------------------------- */ + +void FixBondHistory::clear_cache() +{ + cached_histories.clear(); +} diff --git a/src/fix_bond_history.h b/src/fix_bond_history.h new file mode 100644 index 0000000000..511bc57bd2 --- /dev/null +++ b/src/fix_bond_history.h @@ -0,0 +1,94 @@ +/* -*- 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 FIX_CLASS +// clang-format off +FixStyle(BOND_HISTORY,FixBondHistory); +// clang-format on +#else + +#ifndef LMP_FIX_BOND_HISTORY_H +#define LMP_FIX_BOND_HISTORY_H + +#include "fix.h" + +#include +#include +#include + +namespace LAMMPS_NS { + +class FixBondHistory : public Fix { + public: + FixBondHistory(class LAMMPS *, int, char **); + ~FixBondHistory() override; + int setmask() override; + void post_constructor() override; + void setup_post_neighbor() override; + void setup_pre_exchange() override; + void post_neighbor() override; + void pre_exchange() override; + double memory_usage() override; + void write_restart(FILE *fp) override; + void restart(char *buf) override; + void set_arrays(int); + + void update_atom_value(int, int, int, double); + double get_atom_value(int, int, int); + + // methods to reorder/delete elements of atom->bond_atom + void delete_history(int, int); + void shift_history(int, int, int); + void cache_history(int, int); + void check_cache(int, int); + void clear_cache(); + + // if data is temporarily stored while the bond_atom array + // is being reordered, use map of vectors with pairs for keys + // to enable quick look up + std::map, std::vector> cached_histories; + + double **bondstore; + int stored_flag; + + protected: + void allocate(); + + int update_flag; //Flag whether history values can evolve + int updated_bond_flag; + int nbond, maxbond, ndata; + int index; + char *id_fix; + char *id_array; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +UNDOCUMENTED + +E: Index exceeded in fix bond history + +Bond requested non-existant data + +E: Cannot store bond variables without any bonds + +Atoms must have a nonzero number of bonds to store data + +*/ diff --git a/src/fix_neigh_history.cpp b/src/fix_neigh_history.cpp index 05df4d078c..7413b590a7 100644 --- a/src/fix_neigh_history.cpp +++ b/src/fix_neigh_history.cpp @@ -628,14 +628,16 @@ void FixNeighHistory::post_neighbor() j = jlist[jj]; if (use_bit_flag) { - rflag = sbmask(j) | pair->beyond_contact; - j &= NEIGHMASK; + rflag = histmask(j) | pair->beyond_contact; + j &= HISTMASK; jlist[jj] = j; } else { rflag = 1; - j &= NEIGHMASK; } + // Remove special bond bits + j &= NEIGHMASK; + // rflag = 1 if r < radsum in npair_size() method or if pair interactions extend further // preserve neigh history info if tag[j] is in old-neigh partner list // this test could be more geometrically precise for two sphere/line/tri diff --git a/src/fix_neigh_history.h b/src/fix_neigh_history.h index ba31f7cd3c..f932b174e9 100644 --- a/src/fix_neigh_history.h +++ b/src/fix_neigh_history.h @@ -93,7 +93,8 @@ class FixNeighHistory : public Fix { virtual void pre_exchange_no_newton(); void allocate_pages(); - inline int sbmask(int j) const { return j >> SBBITS & 3; } + // Shift by HISTBITS and check the first bit + inline int histmask(int j) const { return j >> HISTBITS & 1; } }; } // namespace LAMMPS_NS diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 0e91a5f3fb..a6a1b997e3 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -26,21 +25,20 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{MOLECULE,CHARGE,RMASS,IVEC,DVEC,IARRAY,DARRAY}; +enum { MOLECULE, CHARGE, RMASS, IVEC, DVEC, IARRAY, DARRAY }; /* ---------------------------------------------------------------------- */ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - nvalue(0), styles(nullptr), index(nullptr), astyle(nullptr) + Fix(lmp, narg, arg), nvalue(0), styles(nullptr), index(nullptr), astyle(nullptr) { - if (narg < 4) error->all(FLERR,"Illegal fix property/atom command"); + if (narg < 4) error->all(FLERR, "Illegal fix property/atom command"); restart_peratom = 1; wd_section = 1; int iarg = 3; - nvalue = narg-iarg; + nvalue = narg - iarg; styles = new int[nvalue]; cols = new int[nvalue]; index = new int[nvalue]; @@ -53,33 +51,30 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : values_peratom = 0; while (iarg < narg) { - if (strcmp(arg[iarg],"mol") == 0) { + if (strcmp(arg[iarg], "mol") == 0) { if (atom->molecule_flag) - error->all(FLERR,"Fix property/atom mol when atom_style already has molecule attribute"); - if (molecule_flag) - error->all(FLERR,"Fix property/atom cannot specify mol twice"); + error->all(FLERR, "Fix property/atom mol when atom_style already has molecule attribute"); + if (molecule_flag) error->all(FLERR, "Fix property/atom cannot specify mol twice"); styles[nvalue] = MOLECULE; cols[nvalue] = 0; atom->molecule_flag = molecule_flag = 1; values_peratom++; nvalue++; iarg++; - } else if (strcmp(arg[iarg],"q") == 0) { + } 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"); - if (q_flag) - error->all(FLERR,"Fix property/atom cannot specify q twice"); + 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"); styles[nvalue] = CHARGE; cols[nvalue] = 0; atom->q_flag = q_flag = 1; values_peratom++; nvalue++; iarg++; - } else if (strcmp(arg[iarg],"rmass") == 0) { + } 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"); - if (rmass_flag) - error->all(FLERR,"Fix property/atom cannot specify rmass twice"); + 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"); styles[nvalue] = RMASS; cols[nvalue] = 0; atom->rmass_flag = rmass_flag = 1; @@ -87,51 +82,49 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : nvalue++; iarg++; - // custom atom vector + // custom atom vector - } else if (utils::strmatch(arg[iarg],"^i_")) { + } else if (utils::strmatch(arg[iarg], "^i_")) { styles[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"); + 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"); if (ReadData::is_data_section(id)) - error->all(FLERR,"Fix property/atom fix ID must not be a data file section name"); - index[nvalue] = atom->add_custom(&arg[iarg][2],0,0); + error->all(FLERR, "Fix property/atom fix ID must not be a data file section name"); + index[nvalue] = atom->add_custom(&arg[iarg][2], 0, 0); cols[nvalue] = 0; values_peratom++; nvalue++; iarg++; - } else if (utils::strmatch(arg[iarg],"^d_")) { + } else if (utils::strmatch(arg[iarg], "^d_")) { styles[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"); + 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"); if (ReadData::is_data_section(id)) - error->all(FLERR,"Fix property/atom fix ID must not be a data file section name"); - index[nvalue] = atom->add_custom(&arg[iarg][2],1,0); + error->all(FLERR, "Fix property/atom fix ID must not be a data file section name"); + index[nvalue] = atom->add_custom(&arg[iarg][2], 1, 0); cols[nvalue] = 0; values_peratom++; nvalue++; iarg++; - // custom atom array + // custom atom array - } else if (utils::strmatch(arg[iarg],"^[id]2_")) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix property/atom command"); + } 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); + 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]); + error->all(FLERR, "Fix property/atom array name {} already exists", &arg[iarg][3]); if (ReadData::is_data_section(id)) - error->all(FLERR,"Fix property/atom fix ID must not be a data file section name"); + error->all(FLERR, "Fix property/atom fix ID must not be a data file section name"); - ncols = utils::inumeric(FLERR,arg[iarg+1],true,lmp); + ncols = utils::inumeric(FLERR, arg[iarg + 1], true, lmp); if (ncols < 1) - error->all(FLERR,"Invalid array columns number {} in fix property/atom", ncols); + error->all(FLERR, "Invalid array columns number {} in fix property/atom", ncols); if (arg[iarg][0] == 'i') { which = 0; @@ -140,26 +133,28 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : which = 1; styles[nvalue] = DARRAY; } - index[nvalue] = atom->add_custom(&arg[iarg][3],which,ncols); + index[nvalue] = atom->add_custom(&arg[iarg][3], which, ncols); cols[nvalue] = ncols; values_peratom += ncols; nvalue++; iarg += 2; - // no match + // no match - } else break; + } else + break; } // optional args border = 0; while (iarg < narg) { - if (strcmp(arg[iarg],"ghost") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix property/atom command"); - border = utils::logical(FLERR,arg[iarg+1],false,lmp); + if (strcmp(arg[iarg], "ghost") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Illegal fix property/atom command"); + border = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else error->all(FLERR,"Illegal fix property/atom command"); + } else + error->all(FLERR, "Illegal fix property/atom command"); } if (border) comm_border = values_peratom; @@ -169,12 +164,9 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : if (border == 0) { int flag = 0; for (int i = 0; i < nvalue; i++) - if (styles[i] == MOLECULE - || styles[i] == CHARGE - || styles[i] == RMASS) flag = 1; + if (styles[i] == MOLECULE || styles[i] == CHARGE || styles[i] == RMASS) flag = 1; if (flag && comm->me == 0) - error->warning(FLERR,"Fix property/atom mol or charge or rmass " - "w/out ghost communication"); + error->warning(FLERR, "Fix property/atom mol or charge or rmass w/out ghost communication"); } // store current atom style @@ -197,9 +189,9 @@ FixPropertyAtom::~FixPropertyAtom() { // unregister callbacks to this fix from Atom class - atom->delete_callback(id,Atom::GROW); - atom->delete_callback(id,Atom::RESTART); - if (border) atom->delete_callback(id,Atom::BORDER); + atom->delete_callback(id, Atom::GROW); + atom->delete_callback(id, Atom::RESTART); + if (border) atom->delete_callback(id, Atom::BORDER); // deallocate per-atom vectors in Atom class // set ptrs to a null pointer, so they no longer exist for Atom class @@ -218,20 +210,20 @@ FixPropertyAtom::~FixPropertyAtom() memory->destroy(atom->rmass); atom->rmass = nullptr; } else if (styles[nv] == IVEC) { - atom->remove_custom(index[nv],0,cols[nv]); + atom->remove_custom(index[nv], 0, cols[nv]); } else if (styles[nv] == DVEC) { - atom->remove_custom(index[nv],1,cols[nv]); + atom->remove_custom(index[nv], 1, cols[nv]); } else if (styles[nv] == IARRAY) { - atom->remove_custom(index[nv],0,cols[nv]); + atom->remove_custom(index[nv], 0, cols[nv]); } else if (styles[nv] == DARRAY) { - atom->remove_custom(index[nv],1,cols[nv]); + atom->remove_custom(index[nv], 1, cols[nv]); } } - delete [] styles; - delete [] cols; - delete [] index; - delete [] astyle; + delete[] styles; + delete[] cols; + delete[] index; + delete[] astyle; } /* ---------------------------------------------------------------------- */ @@ -249,8 +241,8 @@ void FixPropertyAtom::init() // error if atom style has changed since fix was defined // don't allow this because user could change to style that defines molecule,q - if (strcmp(astyle,atom->atom_style) != 0) - error->all(FLERR,"Atom style was redefined after using fix property/atom"); + if (strcmp(astyle, atom->atom_style) != 0) + error->all(FLERR, "Atom style was redefined after using fix property/atom"); } /* ---------------------------------------------------------------------- @@ -260,7 +252,7 @@ void FixPropertyAtom::init() void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint id_offset) { - int j,k,m,ncol; + int j, k, m, ncol; tagint itag; char *next; @@ -278,18 +270,18 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint tagint map_tag_max = atom->map_tag_max; for (int i = 0; i < n; i++) { - next = strchr(buf,'\n'); + next = strchr(buf, '\n'); *next = '\0'; try { ValueTokenizer values(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()); + 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 @@ -307,17 +299,16 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf, tagint atom->dvector[index[j]][m] = values.next_double(); } else if (styles[j] == IARRAY) { ncol = cols[j]; - for (k = 0; k < ncol; k++) - atom->iarray[index[j]][m][k] = values.next_int(); + for (k = 0; k < ncol; k++) atom->iarray[index[j]][m][k] = values.next_int(); } else if (styles[j] == DARRAY) { ncol = cols[j]; - for (k = 0; k < ncol; k++) - atom->darray[index[j]][m][k] = values.next_double(); + 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; } @@ -357,7 +348,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,k,ncol; + int i, k, ncol; // 1st column = atom tag // rest of columns = per-atom values @@ -393,15 +384,13 @@ void FixPropertyAtom::write_data_section_pack(int /*mth*/, double **buf) int **iarray = atom->iarray[index[nv]]; ncol = cols[nv]; for (i = 0; i < nlocal; i++) - for (k = 0; k < ncol; k++) - buf[i][icol+k] = ubuf(iarray[i][k]).d; + for (k = 0; k < ncol; k++) buf[i][icol + k] = ubuf(iarray[i][k]).d; icol += ncol; } else if (styles[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]; + for (k = 0; k < ncol; k++) buf[i][icol + k] = darray[i][k]; icol += ncol; } } @@ -416,21 +405,30 @@ void FixPropertyAtom::write_data_section_pack(int /*mth*/, double **buf) void FixPropertyAtom::write_data_section_keyword(int /*mth*/, FILE *fp) { - if (nvalue == 1 && styles[0] == MOLECULE) fprintf(fp,"\nMolecules\n\n"); - else if (nvalue == 1 && styles[0] == CHARGE) fprintf(fp,"\nCharges\n\n"); + if (nvalue == 1 && styles[0] == MOLECULE) + fprintf(fp, "\nMolecules\n\n"); + else if (nvalue == 1 && styles[0] == CHARGE) + fprintf(fp, "\nCharges\n\n"); else { - fprintf(fp,"\n%s #",id); + fprintf(fp, "\n%s #", id); // write column hint as comment for (int i = 0; i < nvalue; ++i) { - if (styles[i] == MOLECULE) fputs(" mol",fp); - else if (styles[i] == CHARGE) fputs(" q",fp); - else if (styles[i] == RMASS) fputs(" rmass",fp); - else if (styles[i] == IVEC) fprintf(fp," i_%s", atom->ivname[index[i]]); - else if (styles[i] == DVEC) fprintf(fp, " d_%s", atom->dvname[index[i]]); - else if (styles[i] == IARRAY) fprintf(fp, " i_%s", atom->ianame[index[i]]); - else if (styles[i] == DARRAY) fprintf(fp, " d_%s", atom->daname[index[i]]); + if (styles[i] == MOLECULE) + fputs(" mol", fp); + else if (styles[i] == CHARGE) + fputs(" q", fp); + else if (styles[i] == RMASS) + fputs(" rmass", fp); + else if (styles[i] == IVEC) + fprintf(fp, " i_%s", atom->ivname[index[i]]); + else if (styles[i] == DVEC) + fprintf(fp, " d_%s", atom->dvname[index[i]]); + else if (styles[i] == IARRAY) + fprintf(fp, " i_%s", atom->ianame[index[i]]); + else if (styles[i] == DARRAY) + fprintf(fp, " d_%s", atom->daname[index[i]]); } - fputs("\n\n",fp); + fputs("\n\n", fp); } } @@ -441,39 +439,36 @@ void FixPropertyAtom::write_data_section_keyword(int /*mth*/, FILE *fp) only called by proc 0 ------------------------------------------------------------------------- */ -void FixPropertyAtom::write_data_section(int /*mth*/, FILE *fp, - int n, double **buf, int /*index*/) +void FixPropertyAtom::write_data_section(int /*mth*/, FILE *fp, int n, double **buf, int /*index*/) { - int k,icol,ncol,nv; + int k, icol, ncol, nv; std::string line; for (int i = 0; i < n; i++) { - line = fmt::format("{}",(tagint) ubuf(buf[i][0]).i); + line = fmt::format("{}", (tagint) ubuf(buf[i][0]).i); icol = 1; for (nv = 0; nv < nvalue; nv++) { if (styles[nv] == MOLECULE) - line += fmt::format(" {}",(tagint) ubuf(buf[i][icol++]).i); + line += fmt::format(" {}", (tagint) ubuf(buf[i][icol++]).i); else if (styles[nv] == CHARGE) - line += fmt::format(" {}",buf[i][icol++]); + line += fmt::format(" {}", buf[i][icol++]); else if (styles[nv] == RMASS) - line += fmt::format(" {}",buf[i][icol++]); + line += fmt::format(" {}", buf[i][icol++]); else if (styles[nv] == IVEC) - line += fmt::format(" {}",(int) ubuf(buf[i][icol++]).i); + line += fmt::format(" {}", (int) ubuf(buf[i][icol++]).i); else if (styles[nv] == DVEC) - line += fmt::format(" {}",buf[i][icol++]); + line += fmt::format(" {}", buf[i][icol++]); else if (styles[nv] == IARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - line += fmt::format(" {}",(int) ubuf(buf[i][icol+k]).i); + for (k = 0; k < ncol; k++) line += fmt::format(" {}", (int) ubuf(buf[i][icol + k]).i); icol += ncol; } else if (styles[nv] == DARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - line += fmt::format(" {}",buf[i][icol+k]); + for (k = 0; k < ncol; k++) line += fmt::format(" {}", buf[i][icol + k]); icol += ncol; } } - fmt::print(fp,line+"\n"); + fmt::print(fp, line + "\n"); } } @@ -485,13 +480,20 @@ double FixPropertyAtom::memory_usage() { double bytes = 0.0; for (int m = 0; m < nvalue; m++) { - if (styles[m] == MOLECULE) bytes = atom->nmax * sizeof(tagint); - else if (styles[m] == CHARGE) bytes = atom->nmax * sizeof(double); - else if (styles[m] == RMASS) bytes = atom->nmax * sizeof(double); - else if (styles[m] == IVEC) bytes = atom->nmax * sizeof(int); - else if (styles[m] == DVEC) bytes = atom->nmax * sizeof(double); - else if (styles[m] == IARRAY) bytes = (size_t) atom->nmax * cols[m] * sizeof(int); - else if (styles[m] == DARRAY) bytes = (size_t) atom->nmax * cols[m] * sizeof(double); + if (styles[m] == MOLECULE) + bytes = atom->nmax * sizeof(tagint); + else if (styles[m] == CHARGE) + bytes = atom->nmax * sizeof(double); + else if (styles[m] == RMASS) + bytes = atom->nmax * sizeof(double); + else if (styles[m] == IVEC) + bytes = atom->nmax * sizeof(int); + else if (styles[m] == DVEC) + bytes = atom->nmax * sizeof(double); + else if (styles[m] == IARRAY) + bytes = (size_t) atom->nmax * cols[m] * sizeof(int); + else if (styles[m] == DARRAY) + bytes = (size_t) atom->nmax * cols[m] * sizeof(double); } return bytes; } @@ -507,33 +509,33 @@ void FixPropertyAtom::grow_arrays(int nmax) { for (int nv = 0; nv < nvalue; nv++) { if (styles[nv] == MOLECULE) { - memory->grow(atom->molecule,nmax,"atom:molecule"); - size_t nbytes = (nmax-nmax_old) * sizeof(tagint); - memset(&atom->molecule[nmax_old],0,nbytes); + memory->grow(atom->molecule, nmax, "atom:molecule"); + size_t nbytes = (nmax - nmax_old) * sizeof(tagint); + memset(&atom->molecule[nmax_old], 0, nbytes); } else if (styles[nv] == CHARGE) { - memory->grow(atom->q,nmax,"atom:q"); - size_t nbytes = (nmax-nmax_old) * sizeof(double); - memset(&atom->q[nmax_old],0,nbytes); + memory->grow(atom->q, nmax, "atom:q"); + size_t nbytes = (nmax - nmax_old) * sizeof(double); + memset(&atom->q[nmax_old], 0, nbytes); } else if (styles[nv] == RMASS) { - memory->grow(atom->rmass,nmax,"atom:rmass"); - size_t nbytes = (nmax-nmax_old) * sizeof(double); - memset(&atom->rmass[nmax_old],0,nbytes); + memory->grow(atom->rmass, nmax, "atom:rmass"); + size_t nbytes = (nmax - nmax_old) * sizeof(double); + memset(&atom->rmass[nmax_old], 0, nbytes); } else if (styles[nv] == IVEC) { - memory->grow(atom->ivector[index[nv]],nmax,"atom:ivector"); - size_t nbytes = (nmax-nmax_old) * sizeof(int); - memset(&atom->ivector[index[nv]][nmax_old],0,nbytes); + memory->grow(atom->ivector[index[nv]], nmax, "atom:ivector"); + size_t nbytes = (nmax - nmax_old) * sizeof(int); + memset(&atom->ivector[index[nv]][nmax_old], 0, nbytes); } else if (styles[nv] == DVEC) { - memory->grow(atom->dvector[index[nv]],nmax,"atom:dvector"); - size_t nbytes = (nmax-nmax_old) * sizeof(double); - memset(&atom->dvector[index[nv]][nmax_old],0,nbytes); + memory->grow(atom->dvector[index[nv]], nmax, "atom:dvector"); + size_t nbytes = (nmax - nmax_old) * sizeof(double); + memset(&atom->dvector[index[nv]][nmax_old], 0, nbytes); } else if (styles[nv] == IARRAY) { - memory->grow(atom->iarray[index[nv]],nmax,cols[nv],"atom:iarray"); - size_t nbytes = (size_t) (nmax-nmax_old) * cols[nv] * sizeof(int); - if (nbytes) memset(&atom->iarray[index[nv]][nmax_old][0],0,nbytes); + memory->grow(atom->iarray[index[nv]], nmax, cols[nv], "atom:iarray"); + size_t nbytes = (size_t) (nmax - nmax_old) * cols[nv] * sizeof(int); + if (nbytes) memset(&atom->iarray[index[nv]][nmax_old][0], 0, nbytes); } else if (styles[nv] == DARRAY) { - memory->grow(atom->darray[index[nv]],nmax,cols[nv],"atom:darray"); - size_t nbytes = (size_t) (nmax-nmax_old) * cols[nv] * sizeof(double); - if (nbytes) memset(&atom->darray[index[nv]][nmax_old][0],0,nbytes); + memory->grow(atom->darray[index[nv]], nmax, cols[nv], "atom:darray"); + size_t nbytes = (size_t) (nmax - nmax_old) * cols[nv] * sizeof(double); + if (nbytes) memset(&atom->darray[index[nv]][nmax_old][0], 0, nbytes); } } @@ -546,7 +548,7 @@ void FixPropertyAtom::grow_arrays(int nmax) void FixPropertyAtom::copy_arrays(int i, int j, int /*delflag*/) { - int k,ncol; + int k, ncol; for (int nv = 0; nv < nvalue; nv++) { if (styles[nv] == MOLECULE) @@ -561,12 +563,10 @@ void FixPropertyAtom::copy_arrays(int i, int j, int /*delflag*/) atom->dvector[index[nv]][j] = atom->dvector[index[nv]][i]; else if (styles[nv] == IARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - atom->iarray[index[nv]][j][k] = atom->iarray[index[nv]][i][k]; + for (k = 0; k < ncol; k++) atom->iarray[index[nv]][j][k] = atom->iarray[index[nv]][i][k]; } else if (styles[nv] == DARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - atom->darray[index[nv]][j][k] = atom->darray[index[nv]][i][k]; + for (k = 0; k < ncol; k++) atom->darray[index[nv]][j][k] = atom->darray[index[nv]][i][k]; } } } @@ -577,7 +577,7 @@ void FixPropertyAtom::copy_arrays(int i, int j, int /*delflag*/) int FixPropertyAtom::pack_border(int n, int *list, double *buf) { - int i,j,k,ncol; + int i, j, k, ncol; int m = 0; for (int nv = 0; nv < nvalue; nv++) { @@ -616,16 +616,14 @@ int FixPropertyAtom::pack_border(int n, int *list, double *buf) 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; + for (k = 0; k < ncol; k++) buf[m++] = ubuf(iarray[j][k]).d; } } else if (styles[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]; + for (k = 0; k < ncol; k++) buf[m++] = darray[j][k]; } } } @@ -639,49 +637,42 @@ int FixPropertyAtom::pack_border(int n, int *list, double *buf) int FixPropertyAtom::unpack_border(int n, int first, double *buf) { - int i,k,last,ncol; + int i, k, last, ncol; int m = 0; for (int nv = 0; nv < nvalue; nv++) { if (styles[nv] == MOLECULE) { tagint *molecule = atom->molecule; last = first + n; - for (i = first; i < last; i++) - molecule[i] = (tagint) ubuf(buf[m++]).i; + for (i = first; i < last; i++) molecule[i] = (tagint) ubuf(buf[m++]).i; } else if (styles[nv] == CHARGE) { double *q = atom->q; last = first + n; - for (i = first; i < last; i++) - q[i] = buf[m++]; + for (i = first; i < last; i++) q[i] = buf[m++]; } else if (styles[nv] == RMASS) { double *rmass = atom->rmass; last = first + n; - for (i = first; i < last; i++) - rmass[i] = buf[m++]; + for (i = first; i < last; i++) rmass[i] = buf[m++]; } else if (styles[nv] == IVEC) { int *ivector = atom->ivector[index[nv]]; last = first + n; - for (i = first; i < last; i++) - ivector[i] = (int) ubuf(buf[m++]).i; + for (i = first; i < last; i++) ivector[i] = (int) ubuf(buf[m++]).i; } else if (styles[nv] == DVEC) { double *dvector = atom->dvector[index[nv]]; last = first + n; - for (i = first; i < last; i++) - dvector[i] = buf[m++]; + for (i = first; i < last; i++) dvector[i] = buf[m++]; } else if (styles[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; + for (k = 0; k < ncol; k++) iarray[i][k] = (int) ubuf(buf[m++]).i; } else if (styles[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++]; + for (k = 0; k < ncol; k++) darray[i][k] = buf[m++]; } } @@ -694,23 +685,26 @@ int FixPropertyAtom::unpack_border(int n, int first, double *buf) int FixPropertyAtom::pack_exchange(int i, double *buf) { - int k,ncol; + int k, ncol; int m = 0; for (int nv = 0; nv < nvalue; nv++) { - if (styles[nv] == MOLECULE) buf[m++] = ubuf(atom->molecule[i]).d; - else if (styles[nv] == CHARGE) buf[m++] = atom->q[i]; - else if (styles[nv] == RMASS) buf[m++] = atom->rmass[i]; - else if (styles[nv] == IVEC) buf[m++] = ubuf(atom->ivector[index[nv]][i]).d; - else if (styles[nv] == DVEC) buf[m++] = atom->dvector[index[nv]][i]; + if (styles[nv] == MOLECULE) + buf[m++] = ubuf(atom->molecule[i]).d; + else if (styles[nv] == CHARGE) + buf[m++] = atom->q[i]; + else if (styles[nv] == RMASS) + buf[m++] = atom->rmass[i]; + else if (styles[nv] == IVEC) + buf[m++] = ubuf(atom->ivector[index[nv]][i]).d; + else if (styles[nv] == DVEC) + buf[m++] = atom->dvector[index[nv]][i]; else if (styles[nv] == IARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - buf[m++] = ubuf(atom->iarray[index[nv]][i][k]).d; + for (k = 0; k < ncol; k++) buf[m++] = ubuf(atom->iarray[index[nv]][i][k]).d; } else if (styles[nv] == DARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - buf[m++] = atom->darray[index[nv]][i][k]; + for (k = 0; k < ncol; k++) buf[m++] = atom->darray[index[nv]][i][k]; } } @@ -723,7 +717,7 @@ int FixPropertyAtom::pack_exchange(int i, double *buf) int FixPropertyAtom::unpack_exchange(int nlocal, double *buf) { - int k,ncol; + int k, ncol; int m = 0; for (int nv = 0; nv < nvalue; nv++) { @@ -739,12 +733,10 @@ int FixPropertyAtom::unpack_exchange(int nlocal, double *buf) atom->dvector[index[nv]][nlocal] = buf[m++]; else if (styles[nv] == IARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - atom->iarray[index[nv]][nlocal][k] = (int) ubuf(buf[m++]).i; + for (k = 0; k < ncol; k++) atom->iarray[index[nv]][nlocal][k] = (int) ubuf(buf[m++]).i; } else if (styles[nv] == DARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - atom->darray[index[nv]][nlocal][k] = buf[m++]; + for (k = 0; k < ncol; k++) atom->darray[index[nv]][nlocal][k] = buf[m++]; } } @@ -757,31 +749,34 @@ int FixPropertyAtom::unpack_exchange(int nlocal, double *buf) int FixPropertyAtom::pack_restart(int i, double *buf) { - int k,ncol; + int k, ncol; // pack buf[0] this way because other fixes unpack it - buf[0] = values_peratom+1; + buf[0] = values_peratom + 1; int m = 1; for (int nv = 0; nv < nvalue; nv++) { - if (styles[nv] == MOLECULE) buf[m++] = ubuf(atom->molecule[i]).d; - else if (styles[nv] == CHARGE) buf[m++] = atom->q[i]; - else if (styles[nv] == RMASS) buf[m++] = atom->rmass[i]; - else if (styles[nv] == IVEC) buf[m++] = ubuf(atom->ivector[index[nv]][i]).d; - else if (styles[nv] == DVEC) buf[m++] = atom->dvector[index[nv]][i]; + if (styles[nv] == MOLECULE) + buf[m++] = ubuf(atom->molecule[i]).d; + else if (styles[nv] == CHARGE) + buf[m++] = atom->q[i]; + else if (styles[nv] == RMASS) + buf[m++] = atom->rmass[i]; + else if (styles[nv] == IVEC) + buf[m++] = ubuf(atom->ivector[index[nv]][i]).d; + else if (styles[nv] == DVEC) + buf[m++] = atom->dvector[index[nv]][i]; else if (styles[nv] == IARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - buf[m++] = ubuf(atom->iarray[index[nv]][i][k]).d; + for (k = 0; k < ncol; k++) buf[m++] = ubuf(atom->iarray[index[nv]][i][k]).d; } else if (styles[nv] == DARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - buf[m++] = atom->darray[index[nv]][i][k]; + for (k = 0; k < ncol; k++) buf[m++] = atom->darray[index[nv]][i][k]; } } - return values_peratom+1; + return values_peratom + 1; } /* ---------------------------------------------------------------------- @@ -790,14 +785,14 @@ int FixPropertyAtom::pack_restart(int i, double *buf) void FixPropertyAtom::unpack_restart(int nlocal, int nth) { - int k,ncol; + int k, ncol; double **extra = atom->extra; // skip to Nth set of extra values // unpack the Nth first values this way because other fixes pack them int m = 0; - for (int i = 0; i < nth; i++) m += static_cast (extra[nlocal][m]); + for (int i = 0; i < nth; i++) m += static_cast(extra[nlocal][m]); m++; for (int nv = 0; nv < nvalue; nv++) { @@ -817,8 +812,7 @@ void FixPropertyAtom::unpack_restart(int nlocal, int nth) atom->iarray[index[nv]][nlocal][k] = (int) ubuf(extra[nlocal][m++]).i; } else if (styles[nv] == DARRAY) { ncol = cols[nv]; - for (k = 0; k < ncol; k++) - atom->darray[index[nv]][nlocal][k] = extra[nlocal][m++]; + for (k = 0; k < ncol; k++) atom->darray[index[nv]][nlocal][k] = extra[nlocal][m++]; } } } @@ -829,7 +823,7 @@ void FixPropertyAtom::unpack_restart(int nlocal, int nth) int FixPropertyAtom::maxsize_restart() { - return values_peratom+1; + return values_peratom + 1; } /* ---------------------------------------------------------------------- @@ -838,5 +832,5 @@ int FixPropertyAtom::maxsize_restart() int FixPropertyAtom::size_restart(int /*nlocal*/) { - return values_peratom+1; + return values_peratom + 1; } diff --git a/src/fix_property_atom.h b/src/fix_property_atom.h index 500ad6316c..16b282913f 100644 --- a/src/fix_property_atom.h +++ b/src/fix_property_atom.h @@ -27,6 +27,7 @@ namespace LAMMPS_NS { class FixPropertyAtom : public Fix { public: FixPropertyAtom(class LAMMPS *, int, char **); + ~FixPropertyAtom() override; int setmask() override; void init() override; diff --git a/src/fix_store_local.cpp b/src/fix_store_local.cpp new file mode 100644 index 0000000000..a61e8b58b0 --- /dev/null +++ b/src/fix_store_local.cpp @@ -0,0 +1,125 @@ +/* ---------------------------------------------------------------------- + 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 "fix_store_local.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "memory.h" +#include "update.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +#define DELTA 1024 + +/* ---------------------------------------------------------------------- */ + +FixStoreLocal::FixStoreLocal(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), nvalues(0), vector(nullptr), array(nullptr) +{ + if (narg != 5) error->all(FLERR, "Illegal fix store/local command"); + local_flag = 1; + + nreset = utils::inumeric(FLERR, arg[3], false, lmp); + if (nreset <= 0) error->all(FLERR, "Illegal fix store/local command"); + local_freq = nreset; + + nvalues = utils::inumeric(FLERR, arg[4], false, lmp); + + if (nvalues <= 0) error->all(FLERR, "Illegal fix store/local command"); + if (nvalues == 1) + size_local_cols = 0; + else + size_local_cols = nvalues; + size_local_rows = 0; + + vector = nullptr; + array = nullptr; + nmax = 0; + ncount = 0; +} + +/* ---------------------------------------------------------------------- */ + +FixStoreLocal::~FixStoreLocal() +{ + memory->destroy(vector); + memory->destroy(array); +} + +/* ---------------------------------------------------------------------- */ + +int FixStoreLocal::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixStoreLocal::add_data(double *input_data, int i, int j) +{ + int *mask = atom->mask; + if (!(mask[i] & groupbit)) return; + if (!(mask[j] & groupbit)) return; + + if (ncount >= nmax) reallocate(ncount); + + // fill vector or array with local values + if (nvalues == 1) { + vector[ncount] = input_data[0]; + } else { + for (int n = 0; n < nvalues; n++) array[ncount][n] = input_data[n]; + } + + ncount += 1; +} + +/* ---------------------------------------------------------------------- */ + +void FixStoreLocal::post_force(int /*vflag*/) +{ + if (update->ntimestep % nreset == 0) { + size_local_rows = ncount; + ncount = 0; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixStoreLocal::reallocate(int n) +{ + // grow vector or array + while (nmax <= n) nmax += DELTA; + + if (nvalues == 1) { + memory->grow(vector, nmax, "fix_store_local:vector"); + vector_local = vector; + } else { + memory->grow(array, nmax, nvalues, "fix_store_local:array"); + array_local = array; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local data +------------------------------------------------------------------------- */ + +double FixStoreLocal::memory_usage() +{ + double bytes = (double) nmax * (double) nvalues * sizeof(double); + return bytes; +} diff --git a/src/MISC/fix_pair_tracker.h b/src/fix_store_local.h similarity index 60% rename from src/MISC/fix_pair_tracker.h rename to src/fix_store_local.h index a9743b3b50..dc9d83b9dd 100644 --- a/src/MISC/fix_pair_tracker.h +++ b/src/fix_store_local.h @@ -13,56 +13,37 @@ #ifdef FIX_CLASS // clang-format off -FixStyle(pair/tracker,FixPairTracker); +FixStyle(STORE_LOCAL,FixStoreLocal); // clang-format on #else -#ifndef LMP_FIX_PAIR_TRACKING_H -#define LMP_FIX_PAIR_TRACKING_H +#ifndef LMP_FIX_STORE_LOCAL_H +#define LMP_FIX_STORE_LOCAL_H #include "fix.h" namespace LAMMPS_NS { -class FixPairTracker : public Fix { +class FixStoreLocal : public Fix { public: - FixPairTracker(class LAMMPS *, int, char **); - ~FixPairTracker() override; + FixStoreLocal(class LAMMPS *, int, char **); + ~FixStoreLocal() override; int setmask() override; - void init() override; void post_force(int) override; double memory_usage() override; - void lost_contact(int, int, double, double, double, double); + void add_data(double *, int, int); + int nvalues; private: - int nvalues, nmax; - int index_i, index_j; - double tmin, rmin, rsum, time_initial, nstep_initial; + int nmax; double *vector; double **array; - int **type_filter; int ncount; + int nreset; void reallocate(int); - - typedef void (FixPairTracker::*FnPtrPack)(int); - FnPtrPack *pack_choice; // ptrs to pack functions - - void pack_id1(int); - void pack_id2(int); - - void pack_time_created(int); - void pack_time_broken(int); - void pack_time_total(int); - - void pack_x(int); - void pack_y(int); - void pack_z(int); - - void pack_rmin(int); - void pack_rave(int); }; } // namespace LAMMPS_NS @@ -78,8 +59,13 @@ 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: Invalid keyword in fix pair/tracker command +E: Invalid keyword in fix store/local command Self-explanatory. +E: Unused instance of fix store/local + +Instance of fix store/local is not associated with any other LAMMPS +class such as a bond style, pair style, etc. + */ diff --git a/src/fix_update_special_bonds.cpp b/src/fix_update_special_bonds.cpp new file mode 100644 index 0000000000..c31aefd28d --- /dev/null +++ b/src/fix_update_special_bonds.cpp @@ -0,0 +1,176 @@ +/* ---------------------------------------------------------------------- + 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 "fix_update_special_bonds.h" + +#include "atom.h" +#include "atom_vec.h" +#include "error.h" +#include "force.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "pair.h" + +#include + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixUpdateSpecialBonds::FixUpdateSpecialBonds(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR, "Illegal fix update/special/bonds command"); +} + +/* ---------------------------------------------------------------------- */ + +int FixUpdateSpecialBonds::setmask() +{ + int mask = 0; + mask |= PRE_EXCHANGE; + mask |= PRE_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixUpdateSpecialBonds::setup(int /*vflag*/) +{ + // Require atoms know about all of their bonds and if they break + if (force->newton_bond) error->all(FLERR, "Fix update/special/bonds requires Newton bond off"); + + if (!atom->avec->bonds_allow) error->all(FLERR, "Fix update/special/bonds requires atom bonds"); + + // special lj must be 0 1 1 to censor pair forces between bonded particles + // special coulomb must be 1 1 1 to ensure all pairs are included in the + // neighbor list and 1-3 and 1-4 special bond lists are skipped + if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 || force->special_lj[3] != 1.0) + error->all(FLERR, "Fix update/special/bonds requires special LJ weights = 0,1,1"); + if (force->special_coul[1] != 1.0 || force->special_coul[2] != 1.0 || + force->special_coul[3] != 1.0) + error->all(FLERR, "Fix update/special/bonds requires special Coulomb weights = 1,1,1"); + + new_broken_pairs.clear(); + broken_pairs.clear(); +} + +/* ---------------------------------------------------------------------- + Update special bond list and atom bond arrays, empty broken bond list +------------------------------------------------------------------------- */ + +void FixUpdateSpecialBonds::pre_exchange() +{ + int i, j, m, n1, n3; + tagint tagi, tagj; + int nlocal = atom->nlocal; + + tagint *slist; + int **nspecial = atom->nspecial; + tagint **special = atom->special; + + for (auto const &it : broken_pairs) { + tagi = it.first; + tagj = it.second; + + i = atom->map(tagi); + j = atom->map(tagj); + + // remove i from special bond list for atom j and vice versa + if (i < nlocal) { + slist = special[i]; + n1 = nspecial[i][0]; + for (m = 0; m < n1; m++) + if (slist[m] == tagj) break; + n3 = nspecial[i][2]; + for (; m < n3 - 1; m++) slist[m] = slist[m + 1]; + nspecial[i][0]--; + nspecial[i][1]--; + nspecial[i][2]--; + } + + if (j < nlocal) { + slist = special[j]; + n1 = nspecial[j][0]; + for (m = 0; m < n1; m++) + if (slist[m] == tagi) break; + n3 = nspecial[j][2]; + for (; m < n3 - 1; m++) slist[m] = slist[m + 1]; + nspecial[j][0]--; + nspecial[j][1]--; + nspecial[j][2]--; + } + } + + broken_pairs.clear(); +} + +/* ---------------------------------------------------------------------- + Loop neighbor list and update special bond lists for recently broken bonds +------------------------------------------------------------------------- */ + +void FixUpdateSpecialBonds::pre_force(int /*vflag*/) +{ + int i1, i2, j, jj, jnum; + int *jlist, *numneigh, **firstneigh; + tagint tag1, tag2; + + int nlocal = atom->nlocal; + + tagint *tag = atom->tag; + NeighList *list = force->pair->list; // may need to be generalized to work with pair hybrid* + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // In theory could communicate a list of broken bonds to neighboring processors here + // to remove restriction that users use Newton bond off + + for (auto const &it : new_broken_pairs) { + tag1 = it.first; + tag2 = it.second; + i1 = atom->map(tag1); + i2 = atom->map(tag2); + + // Loop through atoms of owned atoms i j + if (i1 < nlocal) { + jlist = firstneigh[i1]; + jnum = numneigh[i1]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= SPECIALMASK; // Clear special bond bits + if (tag[j] == tag2) jlist[jj] = j; + } + } + + if (i2 < nlocal) { + jlist = firstneigh[i2]; + jnum = numneigh[i2]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= SPECIALMASK; // Clear special bond bits + if (tag[j] == tag1) jlist[jj] = j; + } + } + } + new_broken_pairs.clear(); +} + +/* ---------------------------------------------------------------------- */ + +void FixUpdateSpecialBonds::add_broken_bond(int i, int j) +{ + auto tag_pair = std::make_pair(atom->tag[i], atom->tag[j]); + new_broken_pairs.push_back(tag_pair); + broken_pairs.push_back(tag_pair); +} diff --git a/src/fix_update_special_bonds.h b/src/fix_update_special_bonds.h new file mode 100644 index 0000000000..d6cf2fb837 --- /dev/null +++ b/src/fix_update_special_bonds.h @@ -0,0 +1,73 @@ +/* -*- 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 FIX_CLASS +// clang-format off +FixStyle(UPDATE_SPECIAL_BONDS,FixUpdateSpecialBonds); +// clang-format on +#else + +#ifndef LMP_FIX_UPDATE_SPECIAL_BONDS_H +#define LMP_FIX_UPDATE_SPECIAL_BONDS_H + +#include "fix.h" + +#include +#include + +namespace LAMMPS_NS { + +class FixUpdateSpecialBonds : public Fix { + public: + FixUpdateSpecialBonds(class LAMMPS *, int, char **); + int setmask() override; + void setup(int) override; + void pre_exchange() override; + void pre_force(int) override; + void add_broken_bond(int, int); + + protected: + // Create two arrays to store bonds broken this timestep (new) + // and since the last neighbor list build + std::vector> new_broken_pairs; + std::vector> broken_pairs; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal fix censor/bonded/pairs command + +Self-explanatory. + +E: Fix censor/bonded/pairs requires Newton bond off + +Self-explanatory. + +E: Fix censor/bonded/pairs requires atom bonds + +Self-explanatory. + +E: Fix censor/bonded/pairs must be used without special bonds + +Self-explanatory. Look at the atom modify special command. + +E: Fix censor/bonded/pairs requires special_bonds = 0,0,0 + +Self-explanatory. + +*/ diff --git a/src/lmptype.h b/src/lmptype.h index f46956e7d2..e02cd74734 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -55,11 +55,15 @@ namespace LAMMPS_NS { -// reserve 2 hi bits in molecular system neigh list for special bonds flag -// max local + ghost atoms per processor = 2^30 - 1 +// reserve 2 highest bits in molecular system neigh list for special bonds flag +// reserve 3rd highest bit in neigh list for fix neigh/history flag +// max local + ghost atoms per processor = 2^29 - 1 #define SBBITS 30 -#define NEIGHMASK 0x3FFFFFFF +#define HISTBITS 29 +#define NEIGHMASK 0x1FFFFFFF +#define HISTMASK 0xDFFFFFFF +#define SPECIALMASK 0x3FFFFFFF // default to 32-bit smallint and other ints, 64-bit bigint diff --git a/src/math_extra.cpp b/src/math_extra.cpp index 54f6204182..15d6e472c9 100644 --- a/src/math_extra.cpp +++ b/src/math_extra.cpp @@ -143,6 +143,58 @@ void richardson(double *q, double *m, double *w, double *moments, double dtq) MathExtra::qnormalize(q); } +/* ---------------------------------------------------------------------- + Richardson iteration to update quaternion from angular velocity + return new normalized quaternion q + also returns updated omega at 1/2 step + Assumes spherical particles - no need to rotate to match moments +------------------------------------------------------------------------- */ + +void richardson_sphere(double *q, double *w, double dtq) +{ + // full update from dq/dt = 1/2 w q + + double wq[4]; + MathExtra::vecquat(w,q,wq); + + double qfull[4]; + qfull[0] = q[0] + dtq * wq[0]; + qfull[1] = q[1] + dtq * wq[1]; + qfull[2] = q[2] + dtq * wq[2]; + qfull[3] = q[3] + dtq * wq[3]; + MathExtra::qnormalize(qfull); + + // 1st half update from dq/dt = 1/2 w q + + double qhalf[4]; + qhalf[0] = q[0] + 0.5*dtq * wq[0]; + qhalf[1] = q[1] + 0.5*dtq * wq[1]; + qhalf[2] = q[2] + 0.5*dtq * wq[2]; + qhalf[3] = q[3] + 0.5*dtq * wq[3]; + MathExtra::qnormalize(qhalf); + + // re-compute q at 1/2 step + // recompute wq + + MathExtra::vecquat(w,qhalf,wq); + + // 2nd half update from dq/dt = 1/2 w q + + qhalf[0] += 0.5*dtq * wq[0]; + qhalf[1] += 0.5*dtq * wq[1]; + qhalf[2] += 0.5*dtq * wq[2]; + qhalf[3] += 0.5*dtq * wq[3]; + MathExtra::qnormalize(qhalf); + + // corrected Richardson update + + q[0] = 2.0*qhalf[0] - qfull[0]; + q[1] = 2.0*qhalf[1] - qfull[1]; + q[2] = 2.0*qhalf[2] - qfull[2]; + q[3] = 2.0*qhalf[3] - qfull[3]; + MathExtra::qnormalize(q); +} + /* ---------------------------------------------------------------------- apply evolution operators to quat, quat momentum Miller et al., J Chem Phys. 116, 8649-8659 (2002) diff --git a/src/math_extra.h b/src/math_extra.h index 7c71e4c11b..55d680b0f2 100644 --- a/src/math_extra.h +++ b/src/math_extra.h @@ -76,6 +76,7 @@ void write3(const double mat[3][3]); int mldivide3(const double mat[3][3], const double *vec, double *ans); void rotate(double matrix[3][3], int i, int j, int k, int l, double s, double tau); void richardson(double *q, double *m, double *w, double *moments, double dtq); +void richardson_sphere(double *q, double *w, double dtq); void no_squish_rotate(int k, double *p, double *q, double *inertia, double dt); // shape matrix operations @@ -91,6 +92,7 @@ inline void vecquat(double *a, double *b, double *c); inline void quatvec(double *a, double *b, double *c); inline void quatquat(double *a, double *b, double *c); inline void invquatvec(double *a, double *b, double *c); +inline void quatrotvec(double *a, double *b, double *c); inline void axisangle_to_quat(const double *v, const double angle, double *quat); void angmom_to_omega(double *m, double *ex, double *ey, double *ez, double *idiag, double *w); @@ -651,6 +653,29 @@ inline void MathExtra::invquatvec(double *a, double *b, double *c) c[2] = -a[3] * b[0] + a[2] * b[1] - a[1] * b[2] + a[0] * b[3]; } +/* ---------------------------------------------------------------------- + quaternion rotation of vector: c = a*b*conj(a) + a is a quaternion + b is a three component vector + c is a three component vector +------------------------------------------------------------------------- */ + +inline void MathExtra::quatrotvec(double *a, double *b, double *c) +{ + double temp[4]; + + // temp = a*b + temp[0] = -a[1]*b[0] - a[2]*b[1] - a[3]*b[2]; + temp[1] = a[0]*b[0] + a[2]*b[2] - a[3]*b[1]; + temp[2] = a[0]*b[1] + a[3]*b[0] - a[1]*b[2]; + temp[3] = a[0]*b[2] + a[1]*b[1] - a[2]*b[0]; + + // c = temp*conj(a) + c[0] = -a[1]*temp[0] + a[0]*temp[1] - a[3]*temp[2] + a[2]*temp[3]; + c[1] = -a[2]*temp[0] + a[3]*temp[1] + a[0]*temp[2] - a[1]*temp[3]; + c[2] = -a[3]*temp[0] - a[2]*temp[1] + a[1]*temp[2] + a[0]*temp[3]; +} + /* ---------------------------------------------------------------------- compute quaternion from axis-angle rotation v MUST be a unit vector diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 569bd154fa..2c7ce0004b 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -22,6 +22,7 @@ #include "accelerator_kokkos.h" #include "atom.h" #include "atom_vec.h" +#include "bond.h" #include "citeme.h" #include "comm.h" #include "compute.h" @@ -1468,7 +1469,7 @@ void Neighbor::init_topology() // bonds,etc can only be broken for atom->molecular = Atom::MOLECULAR, not Atom::TEMPLATE // SHAKE sets bonds and angles negative // gcmc sets all bonds, angles, etc negative - // bond_quartic sets bonds to 0 + // partial_flag sets bonds to 0 // delete_bonds sets all interactions negative int bond_off = 0; @@ -1477,7 +1478,9 @@ void Neighbor::init_topology() if (utils::strmatch(modify->fix[i]->style,"^shake") || utils::strmatch(modify->fix[i]->style,"^rattle")) bond_off = angle_off = 1; - if (force->bond && force->bond_match("quartic")) bond_off = 1; + if (force->bond) + if (force->bond->partial_flag) + bond_off = 1; if (atom->avec->bonds_allow && atom->molecular == Atom::MOLECULAR) { for (i = 0; i < atom->nlocal; i++) { diff --git a/src/npair_half_size_bin_newtoff.cpp b/src/npair_half_size_bin_newtoff.cpp index e836503190..de063c1eb9 100644 --- a/src/npair_half_size_bin_newtoff.cpp +++ b/src/npair_half_size_bin_newtoff.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_bin_newtoff.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" @@ -35,7 +38,8 @@ NPairHalfSizeBinNewtoff::NPairHalfSizeBinNewtoff(LAMMPS *lmp) : NPair(lmp) {} void NPairHalfSizeBinNewtoff::build(NeighList *list) { - int i,j,k,n,ibin; + int i,j,jh,k,n,ibin,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -44,17 +48,26 @@ void NPairHalfSizeBinNewtoff::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -68,6 +81,11 @@ void NPairHalfSizeBinNewtoff::build(NeighList *list) ztmp = x[i][2]; radi = radius[i]; ibin = atom2bin[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in surrounding bins in stencil including self // only store pair if i < j @@ -87,10 +105,23 @@ void NPairHalfSizeBinNewtoff::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/npair_half_size_bin_newton.cpp b/src/npair_half_size_bin_newton.cpp index b6a786b0cf..fbf5ce14d4 100644 --- a/src/npair_half_size_bin_newton.cpp +++ b/src/npair_half_size_bin_newton.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_bin_newton.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" @@ -34,7 +37,8 @@ NPairHalfSizeBinNewton::NPairHalfSizeBinNewton(LAMMPS *lmp) : NPair(lmp) {} void NPairHalfSizeBinNewton::build(NeighList *list) { - int i,j,k,n,ibin; + int i,j,jh,k,n,ibin,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -43,17 +47,26 @@ void NPairHalfSizeBinNewton::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -66,6 +79,11 @@ void NPairHalfSizeBinNewton::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over rest of atoms in i's bin, ghosts are at end of linked list // if j is owned atom, store it, since j is beyond i in linked list @@ -90,10 +108,23 @@ void NPairHalfSizeBinNewton::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } @@ -112,10 +143,23 @@ void NPairHalfSizeBinNewton::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/npair_half_size_bin_newton_tri.cpp b/src/npair_half_size_bin_newton_tri.cpp index a86feb6f40..15728a596a 100644 --- a/src/npair_half_size_bin_newton_tri.cpp +++ b/src/npair_half_size_bin_newton_tri.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_bin_newton_tri.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" @@ -35,7 +38,8 @@ NPairHalfSizeBinNewtonTri::NPairHalfSizeBinNewtonTri(LAMMPS *lmp) : void NPairHalfSizeBinNewtonTri::build(NeighList *list) { - int i,j,k,n,ibin; + int i,j,jh,k,n,ibin,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -44,17 +48,26 @@ void NPairHalfSizeBinNewtonTri::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -67,6 +80,11 @@ void NPairHalfSizeBinNewtonTri::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in bins in stencil // pairs for atoms j "below" i are excluded @@ -96,10 +114,23 @@ void NPairHalfSizeBinNewtonTri::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/npair_half_size_multi_newtoff.cpp b/src/npair_half_size_multi_newtoff.cpp index 4c9d9b3f62..ecb70cd6c4 100644 --- a/src/npair_half_size_multi_newtoff.cpp +++ b/src/npair_half_size_multi_newtoff.cpp @@ -15,7 +15,10 @@ es certain rights in this software. This software is distributed under #include "npair_half_size_multi_newtoff.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" @@ -37,7 +40,9 @@ NPairHalfSizeMultiNewtoff::NPairHalfSizeMultiNewtoff(LAMMPS *lmp) : NPair(lmp) { void NPairHalfSizeMultiNewtoff::build(NeighList *list) { - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; + int which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -48,17 +53,26 @@ void NPairHalfSizeMultiNewtoff::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -72,6 +86,11 @@ void NPairHalfSizeMultiNewtoff::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } ibin = atom2bin[i]; @@ -92,27 +111,40 @@ 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) { + jh = j; + if (history && rsq < radsum*radsum) + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; + } + } } } diff --git a/src/npair_half_size_multi_newton.cpp b/src/npair_half_size_multi_newton.cpp index 8af60aa435..ee100596bc 100644 --- a/src/npair_half_size_multi_newton.cpp +++ b/src/npair_half_size_multi_newton.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_newton.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" @@ -36,7 +39,9 @@ NPairHalfSizeMultiNewton::NPairHalfSizeMultiNewton(LAMMPS *lmp) : NPair(lmp) {} void NPairHalfSizeMultiNewton::build(NeighList *list) { - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; + int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; + int which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -46,17 +51,26 @@ void NPairHalfSizeMultiNewton::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -70,6 +84,11 @@ void NPairHalfSizeMultiNewton::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } ibin = atom2bin[i]; @@ -94,33 +113,46 @@ 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) { + jh = j; + if (history && rsq < radsum*radsum) + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; + } } } @@ -129,30 +161,43 @@ 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) { + jh = j; + if (history && rsq < radsum*radsum) + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; + } + } } } diff --git a/src/npair_half_size_multi_newton_tri.cpp b/src/npair_half_size_multi_newton_tri.cpp index 20d4d8b421..9a170948b9 100644 --- a/src/npair_half_size_multi_newton_tri.cpp +++ b/src/npair_half_size_multi_newton_tri.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_newton_tri.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" @@ -36,7 +39,9 @@ NPairHalfSizeMultiNewtonTri::NPairHalfSizeMultiNewtonTri(LAMMPS *lmp) : NPair(lm void NPairHalfSizeMultiNewtonTri::build(NeighList *list) { - int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; + int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns,js; + int which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -46,17 +51,26 @@ void NPairHalfSizeMultiNewtonTri::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -70,6 +84,11 @@ void NPairHalfSizeMultiNewtonTri::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } ibin = atom2bin[i]; @@ -119,10 +138,23 @@ void NPairHalfSizeMultiNewtonTri::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/npair_half_size_multi_old_newtoff.cpp b/src/npair_half_size_multi_old_newtoff.cpp index d98b0a635d..4f8e4a8078 100644 --- a/src/npair_half_size_multi_old_newtoff.cpp +++ b/src/npair_half_size_multi_old_newtoff.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_old_newtoff.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" @@ -36,7 +39,8 @@ NPairHalfSizeMultiOldNewtoff::NPairHalfSizeMultiOldNewtoff(LAMMPS *lmp) : NPair( void NPairHalfSizeMultiOldNewtoff::build(NeighList *list) { - int i,j,k,n,itype,jtype,ibin,ns; + int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -46,17 +50,26 @@ void NPairHalfSizeMultiOldNewtoff::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -70,6 +83,11 @@ void NPairHalfSizeMultiOldNewtoff::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in other bins in stencil including self // only store pair if i < j @@ -98,10 +116,23 @@ void NPairHalfSizeMultiOldNewtoff::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/npair_half_size_multi_old_newton.cpp b/src/npair_half_size_multi_old_newton.cpp index 8ea894db4c..753c8c7d44 100644 --- a/src/npair_half_size_multi_old_newton.cpp +++ b/src/npair_half_size_multi_old_newton.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_old_newton.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" @@ -35,7 +38,8 @@ NPairHalfSizeMultiOldNewton::NPairHalfSizeMultiOldNewton(LAMMPS *lmp) : NPair(lm void NPairHalfSizeMultiOldNewton::build(NeighList *list) { - int i,j,k,n,itype,jtype,ibin,ns; + int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -45,17 +49,26 @@ void NPairHalfSizeMultiOldNewton::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -69,6 +82,11 @@ void NPairHalfSizeMultiOldNewton::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over rest of atoms in i's bin, ghosts are at end of linked list // if j is owned atom, store it, since j is beyond i in linked list @@ -94,10 +112,23 @@ void NPairHalfSizeMultiOldNewton::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } @@ -124,10 +155,22 @@ void NPairHalfSizeMultiOldNewton::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { - if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else + if (history && rsq < radsum*radsum) + j = j ^ mask_history; + + 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_size_multi_old_newton_tri.cpp b/src/npair_half_size_multi_old_newton_tri.cpp index cf7495de1b..ee7a11a36e 100644 --- a/src/npair_half_size_multi_old_newton_tri.cpp +++ b/src/npair_half_size_multi_old_newton_tri.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_multi_old_newton_tri.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "my_page.h" #include "neigh_list.h" @@ -34,7 +37,8 @@ NPairHalfSizeMultiOldNewtonTri::NPairHalfSizeMultiOldNewtonTri(LAMMPS *lmp) : NP void NPairHalfSizeMultiOldNewtonTri::build(NeighList *list) { - int i,j,k,n,itype,jtype,ibin,ns; + int i,j,jh,k,n,itype,jtype,ibin,ns,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; @@ -44,17 +48,26 @@ void NPairHalfSizeMultiOldNewtonTri::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -68,7 +81,11 @@ void NPairHalfSizeMultiOldNewtonTri::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; - + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over all atoms in bins, including self, in stencil // skip if i,j neighbor cutoff is less than bin distance @@ -106,10 +123,23 @@ void NPairHalfSizeMultiOldNewtonTri::build(NeighList *list) cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } } diff --git a/src/npair_half_size_nsq_newtoff.cpp b/src/npair_half_size_nsq_newtoff.cpp index e8eac6f54b..9ace347901 100644 --- a/src/npair_half_size_nsq_newtoff.cpp +++ b/src/npair_half_size_nsq_newtoff.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_nsq_newtoff.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "group.h" #include "my_page.h" #include "neigh_list.h" @@ -35,7 +38,8 @@ NPairHalfSizeNsqNewtoff::NPairHalfSizeNsqNewtoff(LAMMPS *lmp) : NPair(lmp) {} void NPairHalfSizeNsqNewtoff::build(NeighList *list) { - int i,j,n,bitmask; + int i,j,jh,n,bitmask,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -44,7 +48,10 @@ void NPairHalfSizeNsqNewtoff::build(NeighList *list) double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; + tagint *tag = atom->tag; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; if (includegroup) { @@ -52,13 +59,19 @@ void NPairHalfSizeNsqNewtoff::build(NeighList *list) bitmask = group->bitmask[includegroup]; } + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -71,6 +84,11 @@ void NPairHalfSizeNsqNewtoff::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over remaining atoms, owned and ghost @@ -86,10 +104,23 @@ void NPairHalfSizeNsqNewtoff::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } diff --git a/src/npair_half_size_nsq_newton.cpp b/src/npair_half_size_nsq_newton.cpp index 7f90596755..05409a0bab 100644 --- a/src/npair_half_size_nsq_newton.cpp +++ b/src/npair_half_size_nsq_newton.cpp @@ -15,7 +15,10 @@ #include "npair_half_size_nsq_newton.h" #include "atom.h" +#include "atom_vec.h" +#include "domain.h" #include "error.h" +#include "molecule.h" #include "group.h" #include "my_page.h" #include "neigh_list.h" @@ -36,7 +39,8 @@ NPairHalfSizeNsqNewton::NPairHalfSizeNsqNewton(LAMMPS *lmp) : NPair(lmp) {} void NPairHalfSizeNsqNewton::build(NeighList *list) { - int i,j,n,itag,jtag,bitmask; + int i,j,jh,n,itag,jtag,bitmask,which,imol,iatom,moltemplate; + tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr; @@ -47,6 +51,8 @@ void NPairHalfSizeNsqNewton::build(NeighList *list) int *type = atom->type; int *mask = atom->mask; tagint *molecule = atom->molecule; + tagint **special = atom->special; + int **nspecial = atom->nspecial; int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; if (includegroup) { @@ -54,13 +60,19 @@ void NPairHalfSizeNsqNewton::build(NeighList *list) bitmask = group->bitmask[includegroup]; } + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; - int mask_history = 3 << SBBITS; + int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); @@ -74,6 +86,11 @@ void NPairHalfSizeNsqNewton::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } // loop over remaining atoms, owned and ghost @@ -105,10 +122,23 @@ void NPairHalfSizeNsqNewton::build(NeighList *list) cutsq = (radsum+skin) * (radsum+skin); if (rsq <= cutsq) { + jh = j; if (history && rsq < radsum*radsum) - neighptr[n++] = j ^ mask_history; - else - neighptr[n++] = j; + jh = jh ^ mask_history; + + 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++] = jh; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = jh; + else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); + } else neighptr[n++] = jh; } } diff --git a/src/set.cpp b/src/set.cpp index 970155bda3..1abd6c758c 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -303,7 +303,7 @@ void Set::command(int narg, char **arg) else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (utils::strmatch(arg[iarg+4],"^v_")) varparse(arg[iarg+4],4); else wvalue = utils::numeric(FLERR,arg[iarg+4],false,lmp); - if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag) + if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag && !atom->quat_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); set(QUAT); iarg += 5; @@ -311,7 +311,7 @@ void Set::command(int narg, char **arg) } else if (strcmp(arg[iarg],"quat/random") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag) + if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag && !atom->quat_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); @@ -933,31 +933,44 @@ void Set::set(int keyword) sp[i][3] = dvalue; } - // set quaternion orientation of ellipsoid or tri or body particle - // set quaternion orientation of ellipsoid or tri or body particle + // set quaternion orientation of ellipsoid or tri or body particle or sphere/bpm // enforce quat rotation vector in z dir for 2d systems else if (keyword == QUAT) { double *quat = nullptr; + double **quat2 = nullptr; if (avec_ellipsoid && atom->ellipsoid[i] >= 0) quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; else if (avec_tri && atom->tri[i] >= 0) quat = avec_tri->bonus[atom->tri[i]].quat; else if (avec_body && atom->body[i] >= 0) quat = avec_body->bonus[atom->body[i]].quat; + else if (atom->quat_flag) + quat2 = atom->quat; else error->one(FLERR,"Cannot set quaternion for atom that has none"); if (domain->dimension == 2 && (xvalue != 0.0 || yvalue != 0.0)) - error->one(FLERR,"Cannot set quaternion with xy components " - "for 2d system"); + error->one(FLERR,"Cannot set quaternion with xy components for 2d system"); - double theta2 = MY_PI2 * wvalue/180.0; - double sintheta2 = sin(theta2); - quat[0] = cos(theta2); - quat[1] = xvalue * sintheta2; - quat[2] = yvalue * sintheta2; - quat[3] = zvalue * sintheta2; - MathExtra::qnormalize(quat); + const double theta2 = MY_PI2 * wvalue/180.0; + const double sintheta2 = sin(theta2); + double temp[4]; + temp[0] = cos(theta2); + temp[1] = xvalue * sintheta2; + temp[2] = yvalue * sintheta2; + temp[3] = zvalue * sintheta2; + MathExtra::qnormalize(temp); + if (atom->quat_flag) { + quat2[i][0] = temp[0]; + quat2[i][1] = temp[1]; + quat2[i][2] = temp[2]; + quat2[i][3] = temp[3]; + } else { + quat[0] = temp[0]; + quat[1] = temp[1]; + quat[2] = temp[2]; + quat[3] = temp[3]; + } } // set theta of line particle @@ -1218,6 +1231,7 @@ void Set::setrandom(int keyword) } else if (keyword == QUAT_RANDOM) { int nlocal = atom->nlocal; double *quat; + double **quat2; if (domain->dimension == 3) { double s,t1,t2,theta1,theta2; @@ -1229,6 +1243,8 @@ void Set::setrandom(int keyword) quat = avec_tri->bonus[atom->tri[i]].quat; else if (avec_body && atom->body[i] >= 0) quat = avec_body->bonus[atom->body[i]].quat; + else if (atom->quat_flag) + quat2 = atom->quat; else error->one(FLERR,"Cannot set quaternion for atom that has none"); @@ -1238,10 +1254,17 @@ void Set::setrandom(int keyword) t2 = sqrt(s); theta1 = 2.0*MY_PI*ranpark->uniform(); theta2 = 2.0*MY_PI*ranpark->uniform(); - quat[0] = cos(theta2)*t2; - quat[1] = sin(theta1)*t1; - quat[2] = cos(theta1)*t1; - quat[3] = sin(theta2)*t2; + if (atom->quat_flag) { + quat2[i][0] = cos(theta2)*t2; + quat2[i][1] = sin(theta1)*t1; + quat2[i][2] = cos(theta1)*t1; + quat2[i][3] = sin(theta2)*t2; + } else { + quat[0] = cos(theta2)*t2; + quat[1] = sin(theta1)*t1; + quat[2] = cos(theta1)*t1; + quat[3] = sin(theta2)*t2; + } count++; } @@ -1253,15 +1276,24 @@ void Set::setrandom(int keyword) quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; else if (avec_body && atom->body[i] >= 0) quat = avec_body->bonus[atom->body[i]].quat; + else if (atom->quat_flag) + quat2 = atom->quat; else error->one(FLERR,"Cannot set quaternion for atom that has none"); ranpark->reset(seed,x[i]); theta2 = MY_PI*ranpark->uniform(); - quat[0] = cos(theta2); - quat[1] = 0.0; - quat[2] = 0.0; - quat[3] = sin(theta2); + if (atom->quat_flag) { + quat2[i][0] = cos(theta2); + quat2[i][1] = 0.0; + quat2[i][2] = 0.0; + quat2[i][3] = sin(theta2); + } else { + quat[0] = cos(theta2); + quat[1] = 0.0; + quat[2] = 0.0; + quat[3] = sin(theta2); + } count++; } }