diff --git a/.github/workflows/unittest-macos.yml b/.github/workflows/unittest-macos.yml index f9c2a838d6..b0bc4b2727 100644 --- a/.github/workflows/unittest-macos.yml +++ b/.github/workflows/unittest-macos.yml @@ -15,7 +15,7 @@ jobs: build: name: MacOS Unit Test if: ${{ github.repository == 'lammps/lammps' }} - runs-on: macos-latest + runs-on: macos-13 env: CCACHE_DIR: ${{ github.workspace }}/.ccache @@ -43,6 +43,8 @@ jobs: working-directory: build run: | ccache -z + python3 -m venv macosenv + source macosenv/bin/activate python3 -m pip install numpy python3 -m pip install pyyaml cmake -C ../cmake/presets/clang.cmake \ diff --git a/cmake/Modules/OpenCLLoader.cmake b/cmake/Modules/OpenCLLoader.cmake index 4b5c5a1200..411058e0b1 100644 --- a/cmake/Modules/OpenCLLoader.cmake +++ b/cmake/Modules/OpenCLLoader.cmake @@ -1,6 +1,6 @@ message(STATUS "Downloading and building OpenCL loader library") -set(OPENCL_LOADER_URL "${LAMMPS_THIRDPARTY_URL}/opencl-loader-2024.02.09.tar.gz" CACHE STRING "URL for OpenCL loader tarball") -set(OPENCL_LOADER_MD5 "f3573cf9daa3558ba46fd5866517f38f" CACHE STRING "MD5 checksum of OpenCL loader tarball") +set(OPENCL_LOADER_URL "${LAMMPS_THIRDPARTY_URL}/opencl-loader-2024.05.09.tar.gz" CACHE STRING "URL for OpenCL loader tarball") +set(OPENCL_LOADER_MD5 "e7796826b21c059224fabe997e0f2075" CACHE STRING "MD5 checksum of OpenCL loader tarball") mark_as_advanced(OPENCL_LOADER_URL) mark_as_advanced(OPENCL_LOADER_MD5) diff --git a/doc/src/Howto_bpm.rst b/doc/src/Howto_bpm.rst index 0ca4e85fbb..5aa277275d 100644 --- a/doc/src/Howto_bpm.rst +++ b/doc/src/Howto_bpm.rst @@ -15,7 +15,8 @@ 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. +pouring of extended, elastic bodies. See :ref:`(Clemmer) ` +for more general information on the approach and the LAMMPS implementation. ---------- @@ -150,3 +151,9 @@ the following are currently compatible with BPM bond styles: interactions, one will need to switch between different *special_bonds* settings in the input script. An example is found in ``examples/bpm/impact``. + +---------- + +.. _howto-Clemmer: + +**(Clemmer)** Clemmer, Monti, Lechman, Soft Matter, 20, 1702 (2024). diff --git a/doc/src/create_atoms.rst b/doc/src/create_atoms.rst index 7935c676ef..1b7bcecd13 100644 --- a/doc/src/create_atoms.rst +++ b/doc/src/create_atoms.rst @@ -468,12 +468,13 @@ to. The *overlap* keyword only applies to the *random* style. It prevents newly created particles from being created closer than the specified -*Doverlap* distance from any other particle. When the particles being -created are molecules, the radius of the molecule (from its geometric -center) is added to *Doverlap*. If particles have finite size (see -:doc:`atom_style sphere ` for example) *Doverlap* should -be specified large enough to include the particle size in the -non-overlapping criterion. +*Doverlap* distance from any other particle. If particles have finite +size (see :doc:`atom_style sphere ` for example) *Doverlap* +should be specified large enough to include the particle size in the +non-overlapping criterion. If molecules are being randomly inserted, then +an insertion is only accepted if each particle in the molecule meets the +overlap criterion with respect to other particles (not including particles +in the molecule itself). .. note:: diff --git a/doc/src/fix_deform_pressure.rst b/doc/src/fix_deform_pressure.rst index 8e848b3969..1490390988 100644 --- a/doc/src/fix_deform_pressure.rst +++ b/doc/src/fix_deform_pressure.rst @@ -29,10 +29,12 @@ Syntax NOTE: All other styles are documented by the :doc:`fix deform ` command *xy*, *xz*, *yz* args = style value - style = *final* or *delta* or *vel* or *erate* or *trate* or *wiggle* or *variable* or *pressure* + style = *final* or *delta* or *vel* or *erate* or *trate* or *wiggle* or *variable* or *pressure* or *erate/rescale* *pressure* values = target gain target = target pressure (pressure units) gain = proportional gain constant (1/(time * pressure) or 1/time units) + *erate/rescale* value = R + R = engineering shear strain rate (1/time units) NOTE: All other styles are documented by the :doc:`fix deform ` command *box* = style value @@ -159,6 +161,21 @@ details of a simulation and testing different values is recommended. One can also apply a maximum limit to the magnitude of the applied strain using the :ref:`max/rate ` option. +The *erate/rescale* style operates similarly to the *erate* style with +a specified strain rate in units of 1/time. The difference is that +the change in the tilt factor will depend on the current length of +the box perpendicular to the shear direction, L, instead of the +original length, L0. The tilt factor T as a function of time will +change as + +.. parsed-literal:: + + T(t) = T(t-1) + L\*erate\* \Delta t + +where T(t-1) is the tilt factor on the previous timestep and :math:`\Delta t` +is the timestep size. This option may be useful in scenarios where +L changes in time. + ---------- The *box* parameter provides an additional control over the *x*, *y*, diff --git a/doc/src/fix_nonaffine_displacement.rst b/doc/src/fix_nonaffine_displacement.rst index 0a271ebc32..fd9830cc48 100644 --- a/doc/src/fix_nonaffine_displacement.rst +++ b/doc/src/fix_nonaffine_displacement.rst @@ -8,7 +8,7 @@ Syntax .. parsed-literal:: - fix ID group nonaffine/displacement style args reference/style nstep + fix ID group nonaffine/displacement style args reference/style nstep keyword values * ID, group are documented in :doc:`fix ` command * nonaffine/displacement = style name of this fix command @@ -32,6 +32,13 @@ Syntax *update* = update the reference frame every *nstep* timesteps *offset* = update the reference frame *nstep* timesteps before calculating the nonaffine displacement +* zero or more keyword/value pairs may be appended + + .. parsed-literal:: + + *z/min* values = zmin + zmin = minimum coordination number to calculate D2min + Examples """""""" @@ -76,6 +83,12 @@ is the identity tensor. This calculation is only performed on timesteps that are a multiple of *nevery* (including timestep zero). Data accessed before this occurs will simply be zeroed. +For particles with low coordination numbers, calculations of :math:`D^2_\mathrm{min}` +may not be accurate. An optional minimum coordination number can be defined using +the *z/min* keyword. If any particle has fewer than the specified number of particles +in the cutoff distance or in contact, the above calculations will be skipped and the +corresponding peratom array entries will be zero. + The *integrated* style simply integrates the velocity of particles every timestep to calculate a displacement. This style only works if used in conjunction with another fix that deforms the box and displaces diff --git a/doc/src/fix_reaxff_species.rst b/doc/src/fix_reaxff_species.rst index 9bf1a82933..a6da15b161 100644 --- a/doc/src/fix_reaxff_species.rst +++ b/doc/src/fix_reaxff_species.rst @@ -20,7 +20,7 @@ Syntax * Nfreq = calculate average bond-order every this many timesteps * filename = name of output file * zero or more keyword/value pairs may be appended -* keyword = *cutoff* or *element* or *position* or *delete* +* keyword = *cutoff* or *element* or *position* or *delete* or *delete_rate_limit* .. parsed-literal:: @@ -110,10 +110,10 @@ all types from 1 to :math:`N`. A leading asterisk means all types from The optional keyword *element* can be used to specify the chemical symbol printed for each LAMMPS atom type. The number of symbols must match the number of LAMMPS atom types and each symbol must consist of -1 or 2 alphanumeric characters. Normally, these symbols should be -chosen to match the chemical identity of each LAMMPS atom type, as -specified using the :doc:`reaxff pair_coeff ` command and -the ReaxFF force field file. +1 or 2 alphanumeric characters. By default, these symbols are the same +as the chemical identity of each LAMMPS atom type, as specified by the +:doc:`ReaxFF pair_coeff ` command and the ReaxFF force +field file. The optional keyword *position* writes center-of-mass positions of each identified molecules to file *filepos* every *posfreq* timesteps. @@ -233,5 +233,5 @@ Default """"""" The default values for bond-order cutoffs are 0.3 for all I-J pairs. -The default element symbols are C, H, O, N. +The default element symbols are taken from the ReaxFF pair_coeff command. Position files are not written by default. diff --git a/doc/src/replicate.rst b/doc/src/replicate.rst index 6bfbeab891..eb62fbfa21 100644 --- a/doc/src/replicate.rst +++ b/doc/src/replicate.rst @@ -8,56 +8,118 @@ Syntax .. code-block:: LAMMPS - replicate nx ny nz *keyword* + replicate nx ny nz keyword ... nx,ny,nz = replication factors in each dimension -* optional *keyword* = *bbox* +* zero or more keywords may be appended +* keyword = *bbox* or *bond/periodic* .. parsed-literal:: - *bbox* = only check atoms in replicas that overlap with a processor's subdomain + *bbox* = use a bounding-box algorithm which is faster for large proc counts + *bond/periodic* = use an algorithm that correctly replicates periodic bond loops Examples """""""" +For examples of replicating simple linear polymer chains (periodic or +non-periodic) or periodic carbon nanotubes, see examples/replicate. + .. code-block:: LAMMPS replicate 2 3 2 + replicate 2 3 2 bbox + replicate 2 3 2 bond/periodic Description """"""""""" -Replicate the current simulation one or more times in each dimension. -For example, replication factors of 2,2,2 will create a simulation -with 8x as many atoms by doubling the simulation domain in each -dimension. A replication factor of 1 in a dimension leaves the -simulation domain unchanged. When the new simulation box is created -it is also partitioned into a regular 3d grid of rectangular bricks, -one per processor, based on the number of processors being used and -the settings of the :doc:`processors ` command. The -partitioning can later be changed by the :doc:`balance ` or -:doc:`fix balance ` commands. +Replicate the current system one or more times in each dimension. For +example, replication factors of 2,2,2 will create a simulation with 8x +as many atoms by doubling the size of the simulation box in each +dimension. A replication factor of 1 leaves the simulation domain +unchanged in that dimension. -All properties of the atoms are replicated, including their -velocities, which may or may not be desirable. New atom IDs are -assigned to new atoms, as are molecule IDs. Bonds and other topology -interactions are created between pairs of new atoms as well as between -old and new atoms. This is done by using the image flag for each atom -to "unwrap" it out of the periodic box before replicating it. +When the new simulation box is created it is partitioned into a +regular 3d grid of rectangular bricks, one per processor, based on the +number of processors being used and the settings of the +:doc:`processors ` command. The partitioning can be +changed by subsequent :doc:`balance ` or :doc:`fix balance +` commands. -This means that any molecular bond you specify in the original data -file that crosses a periodic boundary should be between two atoms with -image flags that differ by 1. This will allow the bond to be -unwrapped appropriately. +All properties of each atom are replicated (except per-atom fix data, +see the Restrictions section below). This includes their velocities, +which may or may not be desirable. New atom IDs are assigned to new +atoms, as are new molecule IDs. Bonds and other topology interactions +are created between pairs of new atoms as well as between old and new +atoms. -The optional keyword *bbox* uses a bounding box to only check atoms in -replicas that overlap with a processor's subdomain when assigning -atoms to processors. It typically results in a substantial speedup -when using the replicate command on a large number of processors. It -does require temporary use of more memory, specifically that each -processor can store all atoms in the entire system before it is -replicated. +.. note:: + + The bond discussion which follows only refers to models with + permanent covalent bonds typically defined in LAMMPS via a data + file. It is not relevant to sytems modeled with many-body + potentials which can define bonds on-the-fly, based on the current + positions of nearby atoms, e.g. models using the :doc:`AIREBO + ` or :doc:`ReaxFF ` potentials. + +If the *bond/periodic* keyword is not specified, bond replication is +done by using the image flag for each atom to "unwrap" it out of the +periodic box before replicating it. After replication is performed, +atoms outside the new periodic box are wrapped back into it. This +assigns correct images flags to all atoms in the system. For this to +work, all original atoms in the original simulation box must have +consistent image flags. This means that if two atoms have a bond +between them which crosses a periodic boundary, their respective image +flags will differ by 1 in that dimension. + +Image flag consistency is not possible if a system has a periodic bond +loop, meaning there is a chain of bonds which crosses an entire +dimension and re-connects to itself across a periodic boundary. In +this case you MUST use the *bond/periodic* keyword to correctly +replicate the system. This option zeroes the image flags for all +atoms and uses a different algorithm to find new (nearby) bond +neighbors in the replicated system. In the final replicated system +all image flags are zero (in each dimension). + +.. note:: + + LAMMPS does not check for image flag consistency before performing + the replication (it does issue a warning about this before a + simulation is run). If the original image flags are inconsistent, + the replicated system will also have inconsistent image flags, but + will otherwise be correctly replicated. This is NOT the case if + there is a periodic bond loop. See the next note. + +.. note:: + + LAMMPS does not check for periodic bond loops. If you use the + *bond/periodic* keyword for a system without periodic bond loops, + the system will be correctly replicated, but image flag information + will be lost (which may or may not be important to your model). If + you do not use the *bond/periodic* keyword for a system with + periodic bond loops, the replicated system will have invalid bonds + (typically very long), resulting in bad dynamics. + +If possible, the *bbox* keyword should be used when running on a large +number of processors, as it can result in a substantial speed-up for +the replication operation. It uses a bounding box to only check atoms +in replicas that overlap with each processor's new subdomain when +assigning atoms to processors. It also preserves image flag +information. The only drawback to the *bbox* option is that it +requires a temporary use of more memory. Each processor must be able +to store all atoms (and their per-atom data) in the original system, +before it is replicated. + +.. note:: + + The algorithm used by the *bond/periodic* keyword builds on the + algorithm used by the *bbox* keyword and thus has the same memory + requirements. If you specify only the *bond/peridoic* keyword it + will internally set the *bbox* keyword as well. + +---------- Restrictions """""""""""" @@ -65,49 +127,30 @@ Restrictions A 2d simulation cannot be replicated in the z dimension. If a simulation is non-periodic in a dimension, care should be used -when replicating it in that dimension, as it may put atoms nearly on -top of each other. - -.. note:: - - You cannot use the replicate command on a system which has a - molecule that spans the box and is bonded to itself across a periodic - boundary, so that the molecule is effectively a loop. A simple - example would be a linear polymer chain that spans the simulation box - and bonds back to itself across the periodic boundary. More realistic - examples would be a CNT (meant to be an infinitely long CNT) or a - graphene sheet or a bulk periodic crystal where there are explicit - bonds specified between near neighbors. (Note that this only applies - to systems that have permanent bonds as specified in the data file. A - CNT that is just atoms modeled with the :doc:`AIREBO potential ` has no such permanent bonds, so it can be - replicated.) The reason replication does not work with those systems - is that the image flag settings described above cannot be made - consistent. I.e. it is not possible to define images flags so that - when every pair of bonded atoms is unwrapped (using the image flags), - they will be close to each other. The only way the replicate command - could work in this scenario is for it to break a bond, insert more - atoms, and re-connect the loop for the larger simulation box. But it - is not clever enough to do this. So you will have to construct a - larger version of your molecule as a pre-processing step and input a - new data file to LAMMPS. +when replicating it in that dimension, as it may generate atoms nearly +on top of each other. If the current simulation was read in from a restart file (before a -run is performed), there must not be any fix information stored in -the file for individual atoms. Similarly, no fixes can be defined at -the time the replicate command is used that require vectors of atom +run is performed), there must not be any fix information stored in the +file for individual atoms. Similarly, no fixes can be defined at the +time the replicate command is used that require vectors of atom information to be stored. This is because the replicate command does not know how to replicate that information for new atoms it creates. -To work around this restriction, restart files may be converted into -data files and fixes may be undefined via the :doc:`unfix ` -command before and redefined after the replicate command. + +To work around this restriction two options are possible. (1) Fixes +which use the stored data in the restart file can be defined before +replication and then deleted via the :doc:`unfix ` command and +re-defined after it. Or (2) the restart file can be converted to a +data file (which deletes the stored fix infomation) and fixes defined +after the replicate command. In both these scenarios, the per-atom +fix information in the restart file is lost. Related commands """""""""""""""" none - Default """"""" -none +No settings for using the *bbox* or *bond/periodic* algorithms. diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 20e0bd1f12..5dfbe48ffa 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -4162,6 +4162,7 @@ zenodo Zepeda zflag Zhang +Zhao Zhen zhi Zhigilei diff --git a/examples/README b/examples/README index 86d14e7078..90831b49f0 100644 --- a/examples/README +++ b/examples/README @@ -104,6 +104,7 @@ prd: parallel replica dynamics of vacancy diffusion in bulk Si python: use of PYTHON package to invoke Python code from input script qeq: use of QEQ package for charge equilibration reaxff: RDX and TATB and several other models using ReaxFF +replicate: use of replicate command rerun: use of rerun and read_dump commands rigid: rigid bodies modeled as independent or coupled shear: sideways shear applied to 2d solid, with and without a void diff --git a/examples/replicate/README b/examples/replicate/README new file mode 100644 index 0000000000..e33739672c --- /dev/null +++ b/examples/replicate/README @@ -0,0 +1,32 @@ +This directory has input scripts which demonstrate how to use the +replicate command both for systems with and without periodic bond +loops. A periodic bond loop is where a chain of bonds spans a +periodic dimension of the box and includes one or more bonds which +cross the periodic boundary to close the loop. + +To run these scripts, LAMMPS should be built with the MOLECULE and +CLASS2 packages. The latter is only needed for the CNT example. + +-------- + +These scripts are tiny examples which illustrate both kinds of +systems. Each produces a series of images which can be visualized. +If the 3 lines for a dump movie command are uncommented, a MPG movie +is produced, assuming LAMMPS is build with FFMPEG support. + +in.replicate.bond.x # linear chains in x direction, bond loop in x +in.replcate.bond.x.y # 2d grid of bonded atoms, bond loops in x and y +in.replicate.bond.xy # linear chains in diagonal direction, bond loop in x and y +in.replicate.bond.noloop # linear chains in x direction, no bond loop + +If you do not use the bond/periodic keyword with the replicate command +in the first 3 of these scripts (which have periodic bond loops), and +visualize the dynamics of hee simulation, you will see how the +replication creates a bogus system. + +-------- + +This script is for a complex system of 3 orthogonal CNTs which has +periodic bond loops in all 3 dimensions xyz. + +in.replicate.cnt diff --git a/examples/replicate/data.bond.x b/examples/replicate/data.bond.x new file mode 100644 index 0000000000..b5f4d49f2d --- /dev/null +++ b/examples/replicate/data.bond.x @@ -0,0 +1,22 @@ +# system with periodic bonds in x + +3 atoms +3 bonds + +1 atom types +1 bond types + +0 3 xlo xhi +0 1 ylo yhi + +Atoms + +1 1 1 0.5 0.5 0 +2 1 1 1.5 0.5 0 +3 1 1 2.5 0.5 0 + +Bonds + +1 1 1 2 +2 1 2 3 +3 1 3 1 diff --git a/examples/replicate/data.bond.x.noloop b/examples/replicate/data.bond.x.noloop new file mode 100644 index 0000000000..4c096724be --- /dev/null +++ b/examples/replicate/data.bond.x.noloop @@ -0,0 +1,21 @@ +# system with non-periodic bonds in x + +3 atoms +2 bonds + +1 atom types +1 bond types + +0 3 xlo xhi +0 1 ylo yhi + +Atoms + +1 1 1 0.5 0.5 0 0 0 0 +2 1 1 1.5 0.5 0 0 0 0 +3 1 1 2.5 0.5 0 -1 0 0 + +Bonds + +1 1 1 2 +2 1 3 1 diff --git a/examples/replicate/data.bond.x.y b/examples/replicate/data.bond.x.y new file mode 100644 index 0000000000..7eaf19a2ae --- /dev/null +++ b/examples/replicate/data.bond.x.y @@ -0,0 +1,43 @@ +# system with periodic bonds in both x and y + +9 atoms +18 bonds + +1 atom types +1 bond types + +0 3 xlo xhi +0 3 ylo yhi + +Atoms + +1 1 1 0.5 0.5 0 +2 1 1 1.5 0.5 0 +3 1 1 2.5 0.5 0 +4 1 1 0.5 1.5 0 +5 1 1 1.5 1.5 0 +6 1 1 2.5 1.5 0 +7 1 1 0.5 2.5 0 +8 1 1 1.5 2.5 0 +9 1 1 2.5 2.5 0 + +Bonds + +1 1 1 2 +2 1 2 3 +3 1 3 1 +4 1 4 5 +5 1 5 6 +6 1 6 4 +7 1 7 8 +8 1 8 9 +9 1 9 7 +10 1 1 4 +11 1 4 7 +12 1 7 1 +13 1 2 5 +14 1 5 8 +15 1 8 2 +16 1 3 6 +17 1 6 9 +18 1 9 3 diff --git a/examples/replicate/data.bond.xy b/examples/replicate/data.bond.xy new file mode 100644 index 0000000000..31e9d8785a --- /dev/null +++ b/examples/replicate/data.bond.xy @@ -0,0 +1,22 @@ +# system with periodic bonds in xy direction + +3 atoms +3 bonds + +1 atom types +1 bond types + +0 3 xlo xhi +0 3 ylo yhi + +Atoms + +1 1 1 0.5 0.5 0 +2 1 1 1.5 1.5 0 +3 1 1 2.5 2.5 0 + +Bonds + +1 1 1 2 +2 1 2 3 +3 1 3 1 diff --git a/examples/replicate/in.replicate.bond.x b/examples/replicate/in.replicate.bond.x new file mode 100644 index 0000000000..868e05f177 --- /dev/null +++ b/examples/replicate/in.replicate.bond.x @@ -0,0 +1,34 @@ +# test of replicating system with periodic bonds in x + +dimension 2 +atom_style molecular + +read_data data.bond.x + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene + +fix 1 all nve + +write_data tmp.data.x + +dump 1 all image 100 tmp.image.x.*.ppm type type & + adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.mpg type type & +# adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 diff --git a/examples/replicate/in.replicate.bond.x.noloop b/examples/replicate/in.replicate.bond.x.noloop new file mode 100644 index 0000000000..b9862f844d --- /dev/null +++ b/examples/replicate/in.replicate.bond.x.noloop @@ -0,0 +1,34 @@ +# test of replicating system with periodic bonds in x + +dimension 2 +atom_style molecular + +read_data data.bond.x.noloop + +replicate 3 3 1 +#replicate 3 3 1 bond/periodic + +mass 1 1.0 +velocity all create 0.001 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene + +fix 1 all nve + +write_data tmp.data.x.non + +dump 1 all image 100 tmp.image.x.non.*.ppm type type & + adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.non.mpg type type & +# adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 diff --git a/examples/replicate/in.replicate.bond.x.y b/examples/replicate/in.replicate.bond.x.y new file mode 100644 index 0000000000..100350dc18 --- /dev/null +++ b/examples/replicate/in.replicate.bond.x.y @@ -0,0 +1,34 @@ +# test of replicating system with periodic bonds in both x and y + +dimension 2 +atom_style molecular + +read_data data.bond.x.y + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene + +fix 1 all nve + +write_data tmp.data.x.y + +dump 1 all image 100 tmp.image.x.y.*.ppm type type & + adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.y.mpg type type & +# adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 diff --git a/examples/replicate/in.replicate.bond.xy b/examples/replicate/in.replicate.bond.xy new file mode 100644 index 0000000000..52ca79ace7 --- /dev/null +++ b/examples/replicate/in.replicate.bond.xy @@ -0,0 +1,34 @@ +# test of replicating system with periodic bonds in xy diagonal direction + +dimension 2 +atom_style molecular + +read_data data.bond.xy + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.5 + +bond_style harmonic +bond_coeff 1 50.0 1.414 + +special_bonds fene + +fix 1 all nve + +write_data tmp.data.xy + +dump 1 all image 100 tmp.image.xy.*.ppm type type & + adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.xy.mpg type type & +# adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 diff --git a/examples/replicate/in.replicate.cnt b/examples/replicate/in.replicate.cnt new file mode 100644 index 0000000000..0b8b384bbb --- /dev/null +++ b/examples/replicate/in.replicate.cnt @@ -0,0 +1,32 @@ +# three orthogonal periodic CNTs +# demo for replicating triply looped system +# infinite loops in x, y, z +# includes bonded interactions across box corners +# includes bonds, angles, dihedrals, impropers (class2) + +units real + +boundary p p p + +atom_style full + +pair_style lj/class2 10 + +angle_style class2 + +bond_style class2 + +dihedral_style class2 + +improper_style class2 + +read_data three_periodic_CNTs.data.gz + +replicate 2 2 2 bond/periodic + +fix 1 all nve + +run 100 + +# write_restart replicate.restart +# write_data replicate.data diff --git a/examples/replicate/log.6May24.replicate.bond.x.g++.1 b/examples/replicate/log.6May24.replicate.bond.x.g++.1 new file mode 100644 index 0000000000..3f65d11c15 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.x.g++.1 @@ -0,0 +1,125 @@ +LAMMPS (17 Apr 2024) +# test of replicating system with periodic bonds in x + +dimension 2 +atom_style molecular + +read_data data.bond.x +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 3 atoms + scanning bonds ... + 1 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 1 by 1 by 1 MPI processor grid + reading bonds ... + 3 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.004 seconds + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 3 0.5) + 1 by 1 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 0.00 MB + average # of replicas added to proc = 9.00 out of 9 (100.00%) + 27 atoms + 27 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.001 seconds + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 2 = max # of 1-2 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.x +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 3 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.x.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 6.302 | 6.302 | 6.302 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.02 -1.1250229 0 -1.1057636 9.028122 + 5000 0.54111971 -1.9054641 0.29066874 -1.0937172 3.4346743 +Loop time of 0.0764878 on 1 procs for 5000 steps with 27 atoms + +Performance: 28239805.842 tau/day, 65369.921 timesteps/s, 1.765 Matom-step/s +66.5% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0048837 | 0.0048837 | 0.0048837 | 0.0 | 6.38 +Bond | 0.00065879 | 0.00065879 | 0.00065879 | 0.0 | 0.86 +Neigh | 0.0019897 | 0.0019897 | 0.0019897 | 0.0 | 2.60 +Comm | 0.0012815 | 0.0012815 | 0.0012815 | 0.0 | 1.68 +Output | 0.066351 | 0.066351 | 0.066351 | 0.0 | 86.75 +Modify | 0.00069789 | 0.00069789 | 0.00069789 | 0.0 | 0.91 +Other | | 0.0006247 | | | 0.82 + +Nlocal: 27 ave 27 max 27 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 108 ave 108 max 108 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 284 ave 284 max 284 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 284 +Ave neighs/atom = 10.518519 +Ave special neighs/atom = 2 +Neighbor list builds = 287 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.x.g++.4 b/examples/replicate/log.6May24.replicate.bond.x.g++.4 new file mode 100644 index 0000000000..9e4423d5f6 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.x.g++.4 @@ -0,0 +1,126 @@ +LAMMPS (17 Apr 2024) +WARNING: Using I/O redirection is unreliable with parallel runs. Better to use the -in switch to read input files. (../lammps.cpp:551) +# test of replicating system with periodic bonds in x + +dimension 2 +atom_style molecular + +read_data data.bond.x +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 4 by 1 by 1 MPI processor grid + reading atoms ... + 3 atoms + scanning bonds ... + 1 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 4 by 1 by 1 MPI processor grid + reading bonds ... + 3 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.003 seconds + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 3 0.5) + 4 by 1 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 0.00 MB + average # of replicas added to proc = 5.25 out of 9 (58.33%) + 27 atoms + 27 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.002 seconds + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 2 = max # of 1-2 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.x +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 3 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.x.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 6.309 | 6.309 | 6.309 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.02 -1.1250229 0 -1.1057636 9.028122 + 5000 0.50911963 -1.7968226 0.21209852 -1.0944607 4.1676488 +Loop time of 0.21682 on 4 procs for 5000 steps with 27 atoms + +Performance: 9962160.612 tau/day, 23060.557 timesteps/s, 622.635 katom-step/s +93.9% 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.001787 | 0.0021247 | 0.0028772 | 1.0 | 0.98 +Bond | 0.00039682 | 0.00045617 | 0.00059887 | 0.0 | 0.21 +Neigh | 0.0013626 | 0.0014006 | 0.0014798 | 0.1 | 0.65 +Comm | 0.017009 | 0.01791 | 0.018656 | 0.5 | 8.26 +Output | 0.06892 | 0.12188 | 0.18918 | 13.7 | 56.21 +Modify | 0.00060336 | 0.00072159 | 0.00088047 | 0.0 | 0.33 +Other | | 0.07233 | | | 33.36 + +Nlocal: 6.75 ave 7 max 6 min +Histogram: 1 0 0 0 0 0 0 0 0 3 +Nghost: 64.5 ave 65 max 63 min +Histogram: 1 0 0 0 0 0 0 0 0 3 +Neighs: 70.25 ave 77 max 60 min +Histogram: 1 0 0 0 0 1 0 0 1 1 + +Total # of neighbors = 281 +Ave neighs/atom = 10.407407 +Ave special neighs/atom = 2 +Neighbor list builds = 287 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.x.noloop.g++.1 b/examples/replicate/log.6May24.replicate.bond.x.noloop.g++.1 new file mode 100644 index 0000000000..54893b449a --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.x.noloop.g++.1 @@ -0,0 +1,121 @@ +LAMMPS (17 Apr 2024) +# test of replicating system with periodic bonds in x + +dimension 2 +atom_style molecular + +read_data data.bond.x.non +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 3 atoms + scanning bonds ... + 1 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 1 by 1 by 1 MPI processor grid + reading bonds ... + 2 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.004 seconds + +replicate 3 3 1 +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 3 0.5) + 1 by 1 by 1 MPI processor grid + 27 atoms + 18 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.001 seconds +#replicate 3 3 1 bond/periodic + +mass 1 1.0 +velocity all create 0.001 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 2 = max # of 1-2 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.x.non +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 3 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.x.non.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.non.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Per MPI rank memory allocation (min/avg/max) = 6.052 | 6.052 | 6.052 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.001 -1.1250229 0 -1.1240599 13.009826 + 5000 0.62003692 -2.0147214 0.30861545 -1.1090334 8.0279226 +Loop time of 0.0734456 on 1 procs for 5000 steps with 27 atoms + +Performance: 29409520.548 tau/day, 68077.594 timesteps/s, 1.838 Matom-step/s +94.4% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0051444 | 0.0051444 | 0.0051444 | 0.0 | 7.00 +Bond | 0.00048789 | 0.00048789 | 0.00048789 | 0.0 | 0.66 +Neigh | 0.0019333 | 0.0019333 | 0.0019333 | 0.0 | 2.63 +Comm | 0.001332 | 0.001332 | 0.001332 | 0.0 | 1.81 +Output | 0.063139 | 0.063139 | 0.063139 | 0.0 | 85.97 +Modify | 0.00077014 | 0.00077014 | 0.00077014 | 0.0 | 1.05 +Other | | 0.0006387 | | | 0.87 + +Nlocal: 27 ave 27 max 27 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 101 ave 101 max 101 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 288 ave 288 max 288 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 288 +Ave neighs/atom = 10.666667 +Ave special neighs/atom = 1.3333333 +Neighbor list builds = 322 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.x.noloop.g++.4 b/examples/replicate/log.6May24.replicate.bond.x.noloop.g++.4 new file mode 100644 index 0000000000..54d9741781 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.x.noloop.g++.4 @@ -0,0 +1,122 @@ +LAMMPS (17 Apr 2024) +WARNING: Using I/O redirection is unreliable with parallel runs. Better to use the -in switch to read input files. (../lammps.cpp:551) +# test of replicating system with periodic bonds in x + +dimension 2 +atom_style molecular + +read_data data.bond.x.non +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 4 by 1 by 1 MPI processor grid + reading atoms ... + 3 atoms + scanning bonds ... + 1 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 1 0.5) + 4 by 1 by 1 MPI processor grid + reading bonds ... + 2 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.004 seconds + +replicate 3 3 1 +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 3 0.5) + 4 by 1 by 1 MPI processor grid + 27 atoms + 18 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.002 seconds +#replicate 3 3 1 bond/periodic + +mass 1 1.0 +velocity all create 0.001 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 2 = max # of 1-2 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.x.non +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 3 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.x.non.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.non.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Per MPI rank memory allocation (min/avg/max) = 6.059 | 6.059 | 6.059 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.001 -1.1250229 0 -1.1240599 13.009826 + 5000 0.74931971 -2.233724 0.40158766 -1.1105692 5.6354701 +Loop time of 0.197835 on 4 procs for 5000 steps with 27 atoms + +Performance: 10918214.594 tau/day, 25273.645 timesteps/s, 682.388 katom-step/s +88.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.0018771 | 0.0021131 | 0.0027188 | 0.8 | 1.07 +Bond | 0.00032659 | 0.00038248 | 0.00049555 | 0.0 | 0.19 +Neigh | 0.001385 | 0.0014211 | 0.0014704 | 0.1 | 0.72 +Comm | 0.017163 | 0.017405 | 0.017805 | 0.2 | 8.80 +Output | 0.070971 | 0.11052 | 0.17112 | 12.1 | 55.87 +Modify | 0.00058993 | 0.00067708 | 0.00075608 | 0.0 | 0.34 +Other | | 0.06532 | | | 33.02 + +Nlocal: 6.75 ave 7 max 6 min +Histogram: 1 0 0 0 0 0 0 0 0 3 +Nghost: 59.75 ave 60 max 59 min +Histogram: 1 0 0 0 0 0 0 0 0 3 +Neighs: 72 ave 79 max 63 min +Histogram: 1 0 0 0 0 0 2 0 0 1 + +Total # of neighbors = 288 +Ave neighs/atom = 10.666667 +Ave special neighs/atom = 1.3333333 +Neighbor list builds = 323 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.x.y.g++.1 b/examples/replicate/log.6May24.replicate.bond.x.y.g++.1 new file mode 100644 index 0000000000..45308d9a90 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.x.y.g++.1 @@ -0,0 +1,125 @@ +LAMMPS (17 Apr 2024) +# test of replicating system with periodic bonds in both x and y + +dimension 2 +atom_style molecular + +read_data data.bond.x.y +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 9 atoms + scanning bonds ... + 2 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 1 by 1 by 1 MPI processor grid + reading bonds ... + 18 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 4 = max # of 1-2 neighbors + 12 = max # of 1-3 neighbors + 48 = max # of 1-4 neighbors + 8 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.004 seconds + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 9 0.5) + 1 by 1 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 0.00 MB + average # of replicas added to proc = 9.00 out of 9 (100.00%) + 81 atoms + 162 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 4 = max # of 1-2 neighbors + 12 = max # of 1-3 neighbors + 48 = max # of 1-4 neighbors + 24 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.001 seconds + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 4 = max # of 1-2 neighbors + 24 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.x.y +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 7 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.x.y.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.y.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 7.555 | 7.555 | 7.555 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.02 -1.1250229 0 -1.1052698 -2.9713842 + 5000 0.046175679 -1.2280388 0.080003864 -1.1024293 -4.1097897 +Loop time of 0.212344 on 1 procs for 5000 steps with 81 atoms + +Performance: 10172161.526 tau/day, 23546.670 timesteps/s, 1.907 Matom-step/s +93.0% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.01283 | 0.01283 | 0.01283 | 0.0 | 6.04 +Bond | 0.0032785 | 0.0032785 | 0.0032785 | 0.0 | 1.54 +Neigh | 0.0018379 | 0.0018379 | 0.0018379 | 0.0 | 0.87 +Comm | 0.0016247 | 0.0016247 | 0.0016247 | 0.0 | 0.77 +Output | 0.18991 | 0.18991 | 0.18991 | 0.0 | 89.44 +Modify | 0.0018198 | 0.0018198 | 0.0018198 | 0.0 | 0.86 +Other | | 0.001039 | | | 0.49 + +Nlocal: 81 ave 81 max 81 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 144 ave 144 max 144 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 714 ave 714 max 714 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 714 +Ave neighs/atom = 8.8148148 +Ave special neighs/atom = 4 +Neighbor list builds = 72 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.x.y.g++.4 b/examples/replicate/log.6May24.replicate.bond.x.y.g++.4 new file mode 100644 index 0000000000..f232a4e428 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.x.y.g++.4 @@ -0,0 +1,126 @@ +LAMMPS (17 Apr 2024) +WARNING: Using I/O redirection is unreliable with parallel runs. Better to use the -in switch to read input files. (../lammps.cpp:551) +# test of replicating system with periodic bonds in both x and y + +dimension 2 +atom_style molecular + +read_data data.bond.x.y +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 9 atoms + scanning bonds ... + 2 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 2 by 2 by 1 MPI processor grid + reading bonds ... + 18 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 4 = max # of 1-2 neighbors + 12 = max # of 1-3 neighbors + 48 = max # of 1-4 neighbors + 8 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.003 seconds + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 9 0.5) + 2 by 2 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 0.00 MB + average # of replicas added to proc = 6.25 out of 9 (69.44%) + 81 atoms + 162 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 4 = max # of 1-2 neighbors + 12 = max # of 1-3 neighbors + 48 = max # of 1-4 neighbors + 24 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.001 seconds + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 + +bond_style harmonic +bond_coeff 1 50.0 1.0 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 4 = max # of 1-2 neighbors + 24 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.x.y +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 7 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.x.y.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.x.y.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 7.552 | 7.552 | 7.552 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.02 -1.1250229 0 -1.1052698 -2.9713842 + 5000 0.046175679 -1.2280388 0.080003864 -1.1024293 -4.1097897 +Loop time of 0.273847 on 4 procs for 5000 steps with 81 atoms + +Performance: 7887622.810 tau/day, 18258.386 timesteps/s, 1.479 Matom-step/s +92.4% 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.0039465 | 0.0042593 | 0.0046129 | 0.4 | 1.56 +Bond | 0.0011489 | 0.001207 | 0.0012757 | 0.2 | 0.44 +Neigh | 0.00079819 | 0.0008044 | 0.00081324 | 0.0 | 0.29 +Comm | 0.024107 | 0.024703 | 0.025269 | 0.3 | 9.02 +Output | 0.14406 | 0.18123 | 0.23779 | 8.7 | 66.18 +Modify | 0.00089401 | 0.00095321 | 0.0010422 | 0.0 | 0.35 +Other | | 0.06069 | | | 22.16 + +Nlocal: 20.25 ave 22 max 19 min +Histogram: 2 0 0 0 0 0 1 0 0 1 +Nghost: 81.5 ave 82 max 80 min +Histogram: 1 0 0 0 0 0 0 0 0 3 +Neighs: 178.5 ave 195 max 165 min +Histogram: 2 0 0 0 0 0 0 1 0 1 + +Total # of neighbors = 714 +Ave neighs/atom = 8.8148148 +Ave special neighs/atom = 4 +Neighbor list builds = 72 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.xy.g++.1 b/examples/replicate/log.6May24.replicate.bond.xy.g++.1 new file mode 100644 index 0000000000..207b65ef9b --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.xy.g++.1 @@ -0,0 +1,125 @@ +LAMMPS (17 Apr 2024) +# test of replicating system with periodic bonds in xy diagonal direction + +dimension 2 +atom_style molecular + +read_data data.bond.xy +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 3 atoms + scanning bonds ... + 1 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 1 by 1 by 1 MPI processor grid + reading bonds ... + 3 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.004 seconds + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 9 0.5) + 1 by 1 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 0.00 MB + average # of replicas added to proc = 9.00 out of 9 (100.00%) + 27 atoms + 27 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.001 seconds + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.5 + +bond_style harmonic +bond_coeff 1 50.0 1.414 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 2 = max # of 1-2 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.xy +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 7 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.xy.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.xy.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 6.302 | 6.302 | 6.302 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.02 -0.66256987 2.2804444e-06 -0.64330834 -0.59475371 + 5000 0.43110862 -1.1484506 0.16888799 -0.56442095 -0.3683968 +Loop time of 0.124095 on 1 procs for 5000 steps with 27 atoms + +Performance: 17406010.885 tau/day, 40291.692 timesteps/s, 1.088 Matom-step/s +82.3% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0013734 | 0.0013734 | 0.0013734 | 0.0 | 1.11 +Bond | 0.00064058 | 0.00064058 | 0.00064058 | 0.0 | 0.52 +Neigh | 0.00090424 | 0.00090424 | 0.00090424 | 0.0 | 0.73 +Comm | 0.00081732 | 0.00081732 | 0.00081732 | 0.0 | 0.66 +Output | 0.11905 | 0.11905 | 0.11905 | 0.0 | 95.93 +Modify | 0.0007252 | 0.0007252 | 0.0007252 | 0.0 | 0.58 +Other | | 0.0005888 | | | 0.47 + +Nlocal: 27 ave 27 max 27 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 45 ave 45 max 45 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 66 ave 66 max 66 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 66 +Ave neighs/atom = 2.4444444 +Ave special neighs/atom = 2 +Neighbor list builds = 244 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.bond.xy.g++.4 b/examples/replicate/log.6May24.replicate.bond.xy.g++.4 new file mode 100644 index 0000000000..a8ef944ec7 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.bond.xy.g++.4 @@ -0,0 +1,126 @@ +LAMMPS (17 Apr 2024) +WARNING: Using I/O redirection is unreliable with parallel runs. Better to use the -in switch to read input files. (../lammps.cpp:551) +# test of replicating system with periodic bonds in xy diagonal direction + +dimension 2 +atom_style molecular + +read_data data.bond.xy +Reading data file ... + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 3 atoms + scanning bonds ... + 1 = max bonds/atom + orthogonal box = (0 0 -0.5) to (3 3 0.5) + 2 by 2 by 1 MPI processor grid + reading bonds ... + 3 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.000 seconds + read_data CPU = 0.003 seconds + +#replicate 3 3 1 +replicate 3 3 1 bond/periodic +Replication is creating a 3x3x1 = 9 times larger system... + orthogonal box = (0 0 -0.5) to (9 9 0.5) + 2 by 2 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 0.00 MB + average # of replicas added to proc = 6.25 out of 9 (69.44%) + 27 atoms + 27 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + replicate CPU = 0.001 seconds + +mass 1 1.0 +velocity all create 0.02 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.5 + +bond_style harmonic +bond_coeff 1 50.0 1.414 + +special_bonds fene +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 1 1 + special bond factors coul: 0 1 1 + 2 = max # of 1-2 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.000 seconds + +fix 1 all nve + +write_data tmp.data.xy +System init for write_data ... +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 7 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/2d + bin: standard + +dump 1 all image 100 tmp.image.xy.*.ppm type type adiam 0.2 bond type 0.1 zoom 1.6 +dump_modify 1 pad 5 + +#dump 2 all movie 100 tmp.movie.xy.mpg type type # adiam 0.2 bond type 0.1 zoom 1.6 +#dump_modify 2 pad 5 + +run 5000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 6.301 | 6.301 | 6.301 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0.02 -0.66256988 2.2804444e-06 -0.64330834 -0.59475371 + 5000 0.43110877 -1.1484507 0.168888 -0.56442093 -0.36839692 +Loop time of 0.286423 on 4 procs for 5000 steps with 27 atoms + +Performance: 7541285.935 tau/day, 17456.680 timesteps/s, 471.330 katom-step/s +92.9% 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.00054941 | 0.00084836 | 0.0013689 | 0.0 | 0.30 +Bond | 0.00034068 | 0.00045816 | 0.00068461 | 0.0 | 0.16 +Neigh | 0.00092076 | 0.00098494 | 0.0010463 | 0.0 | 0.34 +Comm | 0.018151 | 0.018737 | 0.019531 | 0.4 | 6.54 +Output | 0.13261 | 0.19363 | 0.2596 | 10.7 | 67.60 +Modify | 0.00053153 | 0.00071381 | 0.0010268 | 0.0 | 0.25 +Other | | 0.07105 | | | 24.81 + +Nlocal: 6.75 ave 9 max 5 min +Histogram: 2 0 0 0 0 0 0 1 0 1 +Nghost: 26.25 ave 28 max 25 min +Histogram: 2 0 0 0 0 0 1 0 0 1 +Neighs: 16.5 ave 23 max 10 min +Histogram: 1 1 0 0 0 0 0 0 1 1 + +Total # of neighbors = 66 +Ave neighs/atom = 2.4444444 +Ave special neighs/atom = 2 +Neighbor list builds = 244 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/replicate/log.6May24.replicate.cnt.g++.1 b/examples/replicate/log.6May24.replicate.cnt.g++.1 new file mode 100644 index 0000000000..f44032e723 --- /dev/null +++ b/examples/replicate/log.6May24.replicate.cnt.g++.1 @@ -0,0 +1,134 @@ +LAMMPS (17 Apr 2024) +# three orthogonal periodic CNTs +# demo for replicating triply looped system +# infinite loops in x, y, z +# includes bonded interactions across box corners +# includes bonds, angles, dihedrals, impropers (class2) + +units real + +boundary p p p + +atom_style full + +pair_style lj/class2 10 + +angle_style class2 + +bond_style class2 + +dihedral_style class2 + +improper_style class2 + +read_data three_periodic_CNTs.data.gz +Reading data file ... + orthogonal box = (0 0 0) to (80.96 80.96 80.96) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 3168 atoms + reading velocities ... + 3168 velocities + scanning bonds ... + 3 = max bonds/atom + scanning angles ... + 3 = max angles/atom + scanning dihedrals ... + 12 = max dihedrals/atom + scanning impropers ... + 1 = max impropers/atom + orthogonal box = (0 0 0) to (80.96 80.96 80.96) + 1 by 1 by 1 MPI processor grid + reading bonds ... + 4752 bonds + reading angles ... + 9504 angles + reading dihedrals ... + 19008 dihedrals + reading impropers ... + 3168 impropers +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 3 = max # of 1-2 neighbors + 6 = max # of 1-3 neighbors + 18 = max # of 1-4 neighbors + 18 = max # of special neighbors + special bonds CPU = 0.002 seconds + read_data CPU = 0.056 seconds + +replicate 2 2 2 bond/periodic +Replication is creating a 2x2x2 = 8 times larger system... + orthogonal box = (0 0 0) to (161.92 161.92 161.92) + 1 by 1 by 1 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 1.62 MB + average # of replicas added to proc = 8.00 out of 8 (100.00%) + 25344 atoms + 38016 bonds + 76032 angles + 152064 dihedrals + 25344 impropers +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 3 = max # of 1-2 neighbors + 6 = max # of 1-3 neighbors + 18 = max # of 1-4 neighbors + 18 = max # of special neighbors + special bonds CPU = 0.012 seconds + replicate CPU = 0.027 seconds + +fix 1 all nve + +run 100 +Generated 0 of 0 mixed pair_coeff terms from sixthpower/geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 27 27 27 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/class2, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 51.87 | 51.87 | 51.87 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0 -14266.189 1466925.5 1452659.3 -29908.753 + 100 2155.9128 -17224.188 1306769.8 1452409 1985.2082 +Loop time of 5.0155 on 1 procs for 100 steps with 25344 atoms + +Performance: 1.723 ns/day, 13.932 hours/ns, 19.938 timesteps/s, 505.314 katom-step/s +100.0% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.6557 | 1.6557 | 1.6557 | 0.0 | 33.01 +Bond | 3.2813 | 3.2813 | 3.2813 | 0.0 | 65.42 +Neigh | 0.047025 | 0.047025 | 0.047025 | 0.0 | 0.94 +Comm | 0.0085317 | 0.0085317 | 0.0085317 | 0.0 | 0.17 +Output | 7.8551e-05 | 7.8551e-05 | 7.8551e-05 | 0.0 | 0.00 +Modify | 0.014635 | 0.014635 | 0.014635 | 0.0 | 0.29 +Other | | 0.008159 | | | 0.16 + +Nlocal: 25344 ave 25344 max 25344 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 22737 ave 22737 max 22737 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 2.89358e+06 ave 2.89358e+06 max 2.89358e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2893576 +Ave neighs/atom = 114.17203 +Ave special neighs/atom = 18 +Neighbor list builds = 1 +Dangerous builds = 0 + +# write_restart replicate.restart +# write_data replicate.data +Total wall time: 0:00:05 diff --git a/examples/replicate/log.6May24.replicate.cnt.g++.4 b/examples/replicate/log.6May24.replicate.cnt.g++.4 new file mode 100644 index 0000000000..57abdf767d --- /dev/null +++ b/examples/replicate/log.6May24.replicate.cnt.g++.4 @@ -0,0 +1,135 @@ +LAMMPS (17 Apr 2024) +WARNING: Using I/O redirection is unreliable with parallel runs. Better to use the -in switch to read input files. (../lammps.cpp:551) +# three orthogonal periodic CNTs +# demo for replicating triply looped system +# infinite loops in x, y, z +# includes bonded interactions across box corners +# includes bonds, angles, dihedrals, impropers (class2) + +units real + +boundary p p p + +atom_style full + +pair_style lj/class2 10 + +angle_style class2 + +bond_style class2 + +dihedral_style class2 + +improper_style class2 + +read_data three_periodic_CNTs.data.gz +Reading data file ... + orthogonal box = (0 0 0) to (80.96 80.96 80.96) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 3168 atoms + reading velocities ... + 3168 velocities + scanning bonds ... + 3 = max bonds/atom + scanning angles ... + 3 = max angles/atom + scanning dihedrals ... + 12 = max dihedrals/atom + scanning impropers ... + 1 = max impropers/atom + orthogonal box = (0 0 0) to (80.96 80.96 80.96) + 1 by 2 by 2 MPI processor grid + reading bonds ... + 4752 bonds + reading angles ... + 9504 angles + reading dihedrals ... + 19008 dihedrals + reading impropers ... + 3168 impropers +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 3 = max # of 1-2 neighbors + 6 = max # of 1-3 neighbors + 18 = max # of 1-4 neighbors + 18 = max # of special neighbors + special bonds CPU = 0.001 seconds + read_data CPU = 0.064 seconds + +replicate 2 2 2 bond/periodic +Replication is creating a 2x2x2 = 8 times larger system... + orthogonal box = (0 0 0) to (161.92 161.92 161.92) + 1 by 2 by 2 MPI processor grid + bounding box image = (0 0 0) to (0 0 0) + bounding box extra memory = 1.62 MB + average # of replicas added to proc = 4.50 out of 8 (56.25%) + 25344 atoms + 38016 bonds + 76032 angles + 152064 dihedrals + 25344 impropers +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 3 = max # of 1-2 neighbors + 6 = max # of 1-3 neighbors + 18 = max # of 1-4 neighbors + 18 = max # of special neighbors + special bonds CPU = 0.004 seconds + replicate CPU = 0.012 seconds + +fix 1 all nve + +run 100 +Generated 0 of 0 mixed pair_coeff terms from sixthpower/geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 27 27 27 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/class2, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +WARNING: Inconsistent image flags (../domain.cpp:1051) +Per MPI rank memory allocation (min/avg/max) = 28.69 | 28.69 | 28.69 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 0 -14266.189 1466925.5 1452659.3 -29908.753 + 100 2155.9128 -17224.188 1306769.8 1452409 1985.2082 +Loop time of 1.3667 on 4 procs for 100 steps with 25344 atoms + +Performance: 6.322 ns/day, 3.796 hours/ns, 73.169 timesteps/s, 1.854 Matom-step/s +99.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.43424 | 0.43539 | 0.43741 | 0.2 | 31.86 +Bond | 0.88613 | 0.89013 | 0.90094 | 0.7 | 65.13 +Neigh | 0.013198 | 0.013199 | 0.013201 | 0.0 | 0.97 +Comm | 0.010742 | 0.020522 | 0.02546 | 4.1 | 1.50 +Output | 3.2788e-05 | 3.6302e-05 | 4.4556e-05 | 0.0 | 0.00 +Modify | 0.0042029 | 0.0042366 | 0.004267 | 0.0 | 0.31 +Other | | 0.003188 | | | 0.23 + +Nlocal: 6336 ave 6336 max 6336 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Nghost: 10558 ave 10558 max 10558 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Neighs: 723394 ave 723394 max 723394 min +Histogram: 4 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2893576 +Ave neighs/atom = 114.17203 +Ave special neighs/atom = 18 +Neighbor list builds = 1 +Dangerous builds = 0 + +# write_restart replicate.restart +# write_data replicate.data +Total wall time: 0:00:01 diff --git a/examples/replicate/three_periodic_CNTs.data.gz b/examples/replicate/three_periodic_CNTs.data.gz new file mode 100644 index 0000000000..718c91896a Binary files /dev/null and b/examples/replicate/three_periodic_CNTs.data.gz differ diff --git a/src/BPM/bond_bpm.cpp b/src/BPM/bond_bpm.cpp index f1482d4203..9c2c680cc5 100644 --- a/src/BPM/bond_bpm.cpp +++ b/src/BPM/bond_bpm.cpp @@ -14,6 +14,7 @@ #include "bond_bpm.h" #include "atom.h" +#include "citeme.h" #include "comm.h" #include "domain.h" #include "error.h" @@ -30,6 +31,19 @@ using namespace LAMMPS_NS; +static const char cite_bpm[] = + "BPM bond style: doi:10.1039/D3SM01373A\n\n" + "@Article{Clemmer2024,\n" + " author = {Clemmer, Joel T. and Monti, Joseph M. and Lechman, Jeremy B.},\n" + " title = {A soft departure from jamming: the compaction of deformable\n" + " granular matter under high pressures},\n" + " journal = {Soft Matter},\n" + " year = 2024,\n" + " volume = 20,\n" + " number = 8,\n" + " pages = {1702--1718}\n" + "}\n\n"; + /* ---------------------------------------------------------------------- */ BondBPM::BondBPM(LAMMPS *_lmp) : @@ -55,6 +69,8 @@ BondBPM::BondBPM(LAMMPS *_lmp) : id_fix_dummy2 = utils::strdup("BPM_DUMMY2"); modify->add_fix(fmt::format("{} all DUMMY ", id_fix_dummy2)); + + if (lmp->citeme) lmp->citeme->add(cite_bpm); } /* ---------------------------------------------------------------------- */ diff --git a/src/EXTRA-FIX/fix_deform_pressure.cpp b/src/EXTRA-FIX/fix_deform_pressure.cpp index 51ea75cfed..e2bcdd7f4e 100644 --- a/src/EXTRA-FIX/fix_deform_pressure.cpp +++ b/src/EXTRA-FIX/fix_deform_pressure.cpp @@ -110,6 +110,12 @@ FixDeformPressure::FixDeformPressure(LAMMPS *lmp, int narg, char **arg) : } set_extra[index].pgain = utils::numeric(FLERR, arg[iarg + 3], false, lmp); i += 4; + } else if (strcmp(arg[iarg + 1], "erate/rescale") == 0) { + if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix deform/pressure erate/rescale", error); + set[index].style = ERATERS; + set[index].rate = utils::numeric(FLERR, arg[iarg + 2], false, lmp); + iarg += 3; + i += 3; } else error->all(FLERR, "Illegal fix deform/pressure command: {}", arg[iarg + 1]); } else if (strcmp(arg[iarg], "box") == 0) { @@ -424,16 +430,31 @@ void FixDeformPressure::init() if (!pressure) error->all(FLERR, "Pressure ID {} for fix deform/pressure does not exist", id_press); } + + // if yz [3] changes and will cause box flip, then xy [5] cannot be changing + // this is b/c the flips would induce continuous changes in xz + // in order to keep the edge vectors of the flipped shape matrix + // an integer combination of the edge vectors of the unflipped shape matrix + // error if style PRESSURE/ERATEER for yz, can't calculate if box flip occurs + + if (set[3].style && set[5].style) { + int flag = 0; + double lo,hi; + if (flipflag && set[3].style == PRESSURE) + error->all(FLERR, "Fix {} cannot use yz pressure with xy", style); + if (flipflag && set[3].style == ERATERS) + error->all(FLERR, "Fix {} cannot use yz erate/rescale with xy", style); + } } /* ---------------------------------------------------------------------- - compute T,P if needed before integrator starts + compute T,P before integrator starts ------------------------------------------------------------------------- */ void FixDeformPressure::setup(int /*vflag*/) { - // trigger virial computation on next timestep - if (pressure_flag) pressure->addstep(update->ntimestep+1); + // trigger virial computation, if needed, on next timestep + if (pressure_flag) pressure->addstep(update->ntimestep + 1); } /* ---------------------------------------------------------------------- */ @@ -446,7 +467,20 @@ void FixDeformPressure::end_of_step() // set new box size for strain-based dims - if (strain_flag) FixDeform::apply_strain(); + if (strain_flag) { + FixDeform::apply_strain(); + + for (int i = 3; i < 6; i++) { + if (set[i].style == ERATERS) { + double L = domain->zprd; + if (i == 5) L = domain->yprd; + + h_rate[i] = set[i].rate * L; + set_extra[i].cumulative_shift += update->dt * h_rate[i]; + set[i].tilt_target = set[i].tilt_start + set_extra[i].cumulative_shift; + } + } + } // set new box size for pressure-based dims @@ -479,12 +513,33 @@ void FixDeformPressure::end_of_step() for (int i = 0; i < 3; i++) { set_extra[i].prior_pressure = pressure->vector[i]; set_extra[i].prior_rate = ((set[i].hi_target - set[i].lo_target) / - (domain->boxhi[i] - domain->boxlo[i]) - 1.0) / update->dt; + domain->prd[i] - 1.0) / update->dt; } } if (varflag) modify->addstep_compute(update->ntimestep + nevery); + // If tilting while evolving linear dimension, sum remapping effects + // otherwise, update_domain() will inaccurately use the current + // linear dimension to apply prior remappings + + for (int i = 3; i < 6; i++) { + int idenom = 0; + if (i == 3) idenom = 1; + if (set[i].style && (set_box.style || set[idenom].style) && domain->periodicity[idenom]) { + // Add prior remappings. If the box remaps this timestep, don't + // add it yet so update_domain() will first detect the remapping + set[i].tilt_target += set_extra[i].cumulative_remap; + + // Update remapping for next timestep + double prd = set[idenom].hi_target - set[idenom].lo_target; + double prdinv = 1.0 / prd; + if (set[i].tilt_target * prdinv < -0.5) + set_extra[i].cumulative_remap += prd; + if (set[i].tilt_target * prdinv > 0.5) + set_extra[i].cumulative_remap -= prd; + } + } FixDeform::update_domain(); @@ -502,7 +557,7 @@ void FixDeformPressure::apply_pressure() { // If variable pressure, calculate current target for (int i = 0; i < 6; i++) - if (set[i].style == PRESSURE) + if (set[i].style == PRESSURE || set[i].style == PMEAN) if (set_extra[i].pvar_flag) set_extra[i].ptarget = input->variable->compute_equal(set_extra[i].pvar); @@ -556,26 +611,24 @@ void FixDeformPressure::apply_pressure() h_ratelo[i] = -0.5 * h_rate[i]; - double offset = 0.5 * (domain->boxhi[i] - domain->boxlo[i]) * (1.0 + update->dt * h_rate[i]); - set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - offset; - set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + offset; + double shift = domain->prd[i] * update->dt * h_rate[i]; + set_extra[i].cumulative_shift += shift; + set[i].lo_target = set[i].lo_start - 0.5 * set_extra[i].cumulative_shift; + set[i].hi_target = set[i].hi_start + 0.5 * set_extra[i].cumulative_shift; } for (int i = 3; i < 6; i++) { if (set[i].style != PRESSURE) continue; - double L, tilt, pcurrent; + double L, pcurrent; if (i == 3) { L = domain->zprd; - tilt = domain->yz; pcurrent = tensor[5]; } else if (i == 4) { L = domain->zprd; - tilt = domain->xz + update->dt; pcurrent = tensor[4]; } else { L = domain->yprd; - tilt = domain->xy; pcurrent = tensor[3]; } @@ -592,7 +645,8 @@ void FixDeformPressure::apply_pressure() if (fabs(h_rate[i]) > max_h_rate) h_rate[i] = max_h_rate * h_rate[i] / fabs(h_rate[i]); - set[i].tilt_target = tilt + update->dt * h_rate[i]; + set_extra[i].cumulative_shift += update->dt * h_rate[i]; + set[i].tilt_target = set[i].tilt_start + set_extra[i].cumulative_shift; } } @@ -629,9 +683,9 @@ void FixDeformPressure::apply_volume() double dt = update->dt; double e1i = set_extra[i].prior_rate; double e2i = set_extra[fixed].prior_rate; - double L1i = domain->boxhi[i] - domain->boxlo[i]; - double L2i = domain->boxhi[fixed] - domain->boxlo[fixed]; - double L3i = domain->boxhi[dynamic1] - domain->boxlo[dynamic1]; + double L1i = domain->prd[i]; + double L2i = domain->prd[fixed]; + double L3i = domain->prd[dynamic1]; double L3 = (set[dynamic1].hi_target - set[dynamic1].lo_target); double Vi = L1i * L2i * L3i; double V = L3 * L1i * L2i; @@ -680,7 +734,7 @@ void FixDeformPressure::apply_volume() } } - h_rate[i] = (2.0 * shift / (domain->boxhi[i] - domain->boxlo[i]) - 1.0) / update->dt; + h_rate[i] = (2.0 * shift / domain->prd[i] - 1.0) / update->dt; h_ratelo[i] = -0.5 * h_rate[i]; set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - shift; @@ -742,7 +796,7 @@ void FixDeformPressure::apply_box() set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + shift; // Recalculate h_rate - h_rate[i] = (set[i].hi_target - set[i].lo_target) / (domain->boxhi[i] - domain->boxlo[i]) - 1.0; + h_rate[i] = (set[i].hi_target - set[i].lo_target) / domain->prd[i] - 1.0; h_rate[i] /= update->dt; h_ratelo[i] = -0.5 * h_rate[i]; } @@ -767,14 +821,21 @@ void FixDeformPressure::apply_box() if (fabs(v_rate) > max_h_rate) v_rate = max_h_rate * v_rate / fabs(v_rate); - scale = (1.0 + update->dt * v_rate); for (i = 0; i < 3; i++) { - shift = 0.5 * (set[i].hi_target - set[i].lo_target) * scale; - set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - shift; - set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + shift; + shift = (set[i].hi_target - set[i].lo_target) * update->dt * v_rate; + set_extra[6].cumulative_vshift[i] += shift; + + if (set[i].style == NONE) { + // Overwrite default targets of current length + set[i].lo_target = set[i].lo_start; + set[i].hi_target = set[i].hi_start; + } + + set[i].lo_target -= 0.5 * set_extra[6].cumulative_vshift[i]; + set[i].hi_target += 0.5 * set_extra[6].cumulative_vshift[i]; // Recalculate h_rate - h_rate[i] = (set[i].hi_target - set[i].lo_target) / (domain->boxhi[i] - domain->boxlo[i]) - 1.0; + h_rate[i] = (set[i].hi_target - set[i].lo_target) / domain->prd[i] - 1.0; h_rate[i] /= update->dt; h_ratelo[i] = -0.5 * h_rate[i]; } @@ -788,7 +849,7 @@ void FixDeformPressure::apply_box() void FixDeformPressure::write_restart(FILE *fp) { if (comm->me == 0) { - int size = 9 * sizeof(double) + 7 * sizeof(Set) + 7 * sizeof(SetExtra); + int size = 7 * sizeof(Set) + 7 * sizeof(SetExtra); fwrite(&size, sizeof(int), 1, fp); fwrite(set, sizeof(Set), 6, fp); fwrite(&set_box, sizeof(Set), 1, fp); @@ -803,22 +864,16 @@ void FixDeformPressure::write_restart(FILE *fp) void FixDeformPressure::restart(char *buf) { int n = 0; - auto list = (double *) buf; - for (int i = 0; i < 6; i++) - h_rate[i] = list[n++]; - for (int i = 0; i < 3; i++) - h_ratelo[i] = list[n++]; - - n = n * sizeof(double); int samestyle = 1; - Set *set_restart = (Set *) &buf[n]; + Set *set_restart = (Set *) buf; for (int i = 0; i < 6; ++i) { // restore data from initial state set[i].lo_initial = set_restart[i].lo_initial; set[i].hi_initial = set_restart[i].hi_initial; set[i].vol_initial = set_restart[i].vol_initial; set[i].tilt_initial = set_restart[i].tilt_initial; - // check if style settings are consistent (should do the whole set?) + + // check if style settings are consistent if (set[i].style != set_restart[i].style) samestyle = 0; if (set[i].substyle != set_restart[i].substyle) diff --git a/src/EXTRA-FIX/fix_deform_pressure.h b/src/EXTRA-FIX/fix_deform_pressure.h index 10af1e5ba3..7ce69b9bc5 100644 --- a/src/EXTRA-FIX/fix_deform_pressure.h +++ b/src/EXTRA-FIX/fix_deform_pressure.h @@ -51,6 +51,9 @@ class FixDeformPressure : public FixDeform { struct SetExtra { double ptarget, pgain; double prior_pressure, prior_rate; + double cumulative_shift; + double cumulative_vshift[3]; + double cumulative_remap; int saved; char *pstr; int pvar, pvar_flag; diff --git a/src/EXTRA-FIX/fix_nonaffine_displacement.cpp b/src/EXTRA-FIX/fix_nonaffine_displacement.cpp index eaf45f4e59..b651d5dc5e 100644 --- a/src/EXTRA-FIX/fix_nonaffine_displacement.cpp +++ b/src/EXTRA-FIX/fix_nonaffine_displacement.cpp @@ -46,6 +46,8 @@ enum { TYPE, RADIUS, CUSTOM }; enum { INTEGRATED, D2MIN }; enum { FIXED, OFFSET, UPDATE }; +static constexpr double EPSILON = 1.0e-15; + static const char cite_nonaffine_d2min[] = "@article{PhysRevE.57.7192,\n" " title = {Dynamics of viscoplastic deformation in amorphous solids},\n" @@ -66,7 +68,7 @@ static const char cite_nonaffine_d2min[] = FixNonaffineDisplacement::FixNonaffineDisplacement(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), id_fix(nullptr), fix(nullptr), D2min(nullptr), X(nullptr), Y(nullptr), - F(nullptr), norm(nullptr) + F(nullptr), norm(nullptr), singular(nullptr) { if (narg < 4) utils::missing_cmd_args(FLERR,"fix nonaffine/displacement", error); @@ -74,6 +76,8 @@ FixNonaffineDisplacement::FixNonaffineDisplacement(LAMMPS *lmp, int narg, char * if (nevery <= 0) error->all(FLERR,"Illegal nevery value {} in fix nonaffine/displacement", nevery); reference_timestep = update_timestep = offset_timestep = -1; + z_min = 0; + int iarg = 4; if (strcmp(arg[iarg], "integrated") == 0) { nad_style = INTEGRATED; @@ -117,6 +121,16 @@ FixNonaffineDisplacement::FixNonaffineDisplacement(LAMMPS *lmp, int narg, char * if ((offset_timestep <= 0) || (offset_timestep > nevery)) error->all(FLERR, "Illegal offset timestep {} in fix nonaffine/displacement", arg[iarg + 1]); } else error->all(FLERR,"Illegal reference style {} in fix nonaffine/displacement", arg[iarg]); + iarg += 2; + + while (iarg < narg) { + if (strcmp(arg[iarg], "z/min") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR,"fix nonaffine/displacement", error); + z_min = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + if (z_min < 0) error->all(FLERR, "Minimum coordination must be positive"); + iarg += 2; + } else error->all(FLERR,"Illegal keyword {} in fix nonaffine/displacement", arg[iarg]); + } if (nad_style == D2MIN) if (cut_style == RADIUS && (!atom->radius_flag)) @@ -151,6 +165,7 @@ FixNonaffineDisplacement::~FixNonaffineDisplacement() memory->destroy(Y); memory->destroy(F); memory->destroy(norm); + memory->destroy(singular); memory->destroy(D2min); } @@ -395,6 +410,7 @@ void FixNonaffineDisplacement::calculate_D2Min() } } norm[i] = 0; + singular[i] = 0; D2min[i] = 0; } @@ -471,14 +487,29 @@ void FixNonaffineDisplacement::calculate_D2Min() } if (dim == 3) { - invert3(Y_tmp, Y_inv); + denom = det3(Y_tmp); + if (fabs(denom) < EPSILON) { + singular[i] = 1; + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + Y_inv[j][k] = 0.0; + } else { + invert3(Y_tmp, Y_inv); + } } else { denom = Y_tmp[0][0] * Y_tmp[1][1] - Y_tmp[0][1] * Y_tmp[1][0]; - if (denom != 0.0) denom = 1.0 / denom; - Y_inv[0][0] = Y_tmp[1][1] * denom; - Y_inv[0][1] = -Y_tmp[0][1] * denom; - Y_inv[1][0] = -Y_tmp[1][0] * denom; - Y_inv[1][1] = Y_tmp[0][0] * denom; + if (fabs(denom) < EPSILON) { + singular[i] = 1; + for (j = 0; j < 2; j++) + for (k = 0; k < 2; k++) + Y_inv[j][k] = 0.0; + } else { + denom = 1.0 / denom; + Y_inv[0][0] = Y_tmp[1][1] * denom; + Y_inv[0][1] = -Y_tmp[0][1] * denom; + Y_inv[1][0] = -Y_tmp[1][0] * denom; + Y_inv[1][1] = Y_tmp[0][0] * denom; + } } times3(X_tmp, Y_inv, F_tmp); @@ -559,10 +590,16 @@ void FixNonaffineDisplacement::calculate_D2Min() for (i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; - if (norm[i] != 0) - D2min[i] /= norm[i]; - else - D2min[i] = 0.0; + if (norm[i] < z_min || singular[i] == 1) { + if (norm[i] >= z_min) + error->warning(FLERR, "Singular matrix detected for atom {}, defaulting output to zero", atom->tag[i]); + array_atom[i][0] = 0.0; + array_atom[i][1] = 0.0; + array_atom[i][2] = 0.0; + continue; + } + + D2min[i] /= norm[i]; for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) @@ -743,10 +780,12 @@ void FixNonaffineDisplacement::grow_arrays(int nmax_new) memory->destroy(F); memory->destroy(D2min); memory->destroy(norm); + memory->destroy(singular); memory->create(X, nmax, 3, 3, "fix_nonaffine_displacement:X"); memory->create(Y, nmax, 3, 3, "fix_nonaffine_displacement:Y"); memory->create(F, nmax, 3, 3, "fix_nonaffine_displacement:F"); memory->create(D2min, nmax, "fix_nonaffine_displacement:D2min"); memory->create(norm, nmax, "fix_nonaffine_displacement:norm"); + memory->create(singular, nmax, "fix_nonaffine_displacement:singular"); } } diff --git a/src/EXTRA-FIX/fix_nonaffine_displacement.h b/src/EXTRA-FIX/fix_nonaffine_displacement.h index c7177bd3d9..b0e9c464ca 100644 --- a/src/EXTRA-FIX/fix_nonaffine_displacement.h +++ b/src/EXTRA-FIX/fix_nonaffine_displacement.h @@ -48,12 +48,12 @@ class FixNonaffineDisplacement : public Fix { int nmax, comm_flag; int nad_style, cut_style; int reference_style, offset_timestep, reference_timestep, update_timestep; - int reference_saved; + int reference_saved, z_min; double cutoff_custom, cutsq_custom, mycutneigh; double xprd0, yprd0, zprd0, xprd0_half, yprd0_half, zprd0_half, xy0, xz0, yz0; double *D2min, ***X, ***Y, ***F; - int *norm; + int *norm, *singular; class NeighList *list; // half neighbor list diff --git a/src/GRANULAR/fix_heat_flow.cpp b/src/GRANULAR/fix_heat_flow.cpp index b7643c2c24..be8d93839f 100644 --- a/src/GRANULAR/fix_heat_flow.cpp +++ b/src/GRANULAR/fix_heat_flow.cpp @@ -16,6 +16,7 @@ #include "atom.h" #include "comm.h" #include "error.h" +#include "force.h" #include "memory.h" #include "modify.h" #include "update.h" @@ -127,7 +128,7 @@ void FixHeatFlow::final_integrate() if (igroup == atom->firstgroup) nlocal = atom->nfirst; // add ghost contributions to heatflow if first instance of fix - if (first_flag) comm->reverse_comm(this); + if (force->newton_pair && first_flag) comm->reverse_comm(this); if (rmass) { for (int i = 0; i < nlocal; i++) diff --git a/src/GRANULAR/granular_model.cpp b/src/GRANULAR/granular_model.cpp index 14431f41b4..9764ec42e9 100644 --- a/src/GRANULAR/granular_model.cpp +++ b/src/GRANULAR/granular_model.cpp @@ -216,9 +216,15 @@ int GranularModel::define_classic_model(char **arg, int iarg, int narg) // manually parse coeffs normal_model->coeffs[0] = kn; normal_model->coeffs[1] = gamman; - tangential_model->coeffs[0] = kt; - tangential_model->coeffs[1] = gammat / gamman; - tangential_model->coeffs[2] = xmu; + + if (tangential_model->num_coeffs == 2) { + tangential_model->coeffs[0] = gammat / gamman; + tangential_model->coeffs[1] = xmu; + } else { + tangential_model->coeffs[0] = kt; + tangential_model->coeffs[1] = gammat / gamman; + tangential_model->coeffs[2] = xmu; + } normal_model->coeffs_to_local(); tangential_model->coeffs_to_local(); diff --git a/src/KOKKOS/pair_meam_kokkos.h b/src/KOKKOS/pair_meam_kokkos.h index 66b5700a72..82f48aa997 100644 --- a/src/KOKKOS/pair_meam_kokkos.h +++ b/src/KOKKOS/pair_meam_kokkos.h @@ -13,9 +13,6 @@ #ifdef PAIR_CLASS // clang-format off -PairStyle(meam/c/kk,PairMEAMKokkos); -PairStyle(meam/c/kk/device,PairMEAMKokkos); -PairStyle(meam/c/kk/host,PairMEAMKokkos); PairStyle(meam/kk,PairMEAMKokkos); PairStyle(meam/kk/device,PairMEAMKokkos); PairStyle(meam/kk/host,PairMEAMKokkos); diff --git a/src/MEAM/pair_meam.h b/src/MEAM/pair_meam.h index a89714bfa9..3d50ca9368 100644 --- a/src/MEAM/pair_meam.h +++ b/src/MEAM/pair_meam.h @@ -14,7 +14,6 @@ #ifdef PAIR_CLASS // clang-format off PairStyle(meam,PairMEAM); -PairStyle(meam/c,PairMEAM); // clang-format on #else diff --git a/src/QEQ/fix_qeq.cpp b/src/QEQ/fix_qeq.cpp index 411bdfb60b..47ad3d260f 100644 --- a/src/QEQ/fix_qeq.cpp +++ b/src/QEQ/fix_qeq.cpp @@ -74,6 +74,9 @@ FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) : if ((nevery <= 0) || (cutoff <= 0.0) || (tolerance <= 0.0) || (maxiter <= 0)) error->all(FLERR,"Illegal fix qeq command"); + // must have charges + if (!atom->q_flag) error->all(FLERR, "Fix {} requires atom attribute q", style); + alpha = 0.20; swa = 0.0; swb = cutoff; diff --git a/src/REAXFF/fix_reaxff_species.cpp b/src/REAXFF/fix_reaxff_species.cpp index 8fa06cafb3..2c0775b9d9 100644 --- a/src/REAXFF/fix_reaxff_species.cpp +++ b/src/REAXFF/fix_reaxff_species.cpp @@ -65,7 +65,7 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), Name(nullptr), MolName(nullptr), NMol(nullptr), nd(nullptr), MolType(nullptr), molmap(nullptr), mark(nullptr), Mol2Spec(nullptr), clusterID(nullptr), x0(nullptr), BOCut(nullptr), fp(nullptr), pos(nullptr), fdel(nullptr), delete_Tcount(nullptr), - ele(nullptr), eletype(nullptr), filepos(nullptr), filedel(nullptr) + filepos(nullptr), filedel(nullptr) { if (narg < 7) utils::missing_cmd_args(FLERR, "fix reaxff/species", error); @@ -84,6 +84,9 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : nvalid = -1; ntypes = atom->ntypes; + eletype.resize(ntypes); + ueletype.resize(ntypes); + ele2uele.resize(ntypes); nevery = utils::inumeric(FLERR, arg[3], false, lmp); nrepeat = utils::inumeric(FLERR, arg[4], false, lmp); @@ -156,8 +159,7 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : for (int j = 1; j < np1; j++) BOCut[i][j] = bo_cut; // optional args - eletype = nullptr; - ele = filepos = filedel = nullptr; + filepos = filedel = nullptr; eleflag = posflag = padflag = 0; delflag = specieslistflag = masslimitflag = 0; delete_Nlimit = delete_Nsteps = 0; @@ -191,14 +193,9 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : if (iarg + ntypes + 1 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species element", error); - eletype = (char **) malloc(ntypes * sizeof(char *)); - int len; - for (int i = 0; i < ntypes; i++) { - len = strlen(arg[iarg + 1 + i]) + 1; - eletype[i] = (char *) malloc(len * sizeof(char)); - strcpy(eletype[i], arg[iarg + 1 + i]); - } - eleflag = 1; + for (int i = 0; i < ntypes; i++) + eletype[i] = arg[iarg + 1 + i]; + GetUniqueElements(); iarg += ntypes + 1; // delete species @@ -285,14 +282,6 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR, "Unknown fix reaxff/species keyword: {}", arg[iarg]); } - if (!eleflag) { - memory->create(ele, ntypes + 1, "reaxff/species:ele"); - ele[0] = 'C'; - if (ntypes > 1) ele[1] = 'H'; - if (ntypes > 2) ele[2] = 'O'; - if (ntypes > 3) ele[3] = 'N'; - } - if (delflag && specieslistflag && masslimitflag) error->all(FLERR, "Incompatible combination fix reaxff/species command options"); @@ -312,7 +301,6 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : FixReaxFFSpecies::~FixReaxFFSpecies() { - memory->destroy(ele); memory->destroy(BOCut); memory->destroy(clusterID); memory->destroy(x0); @@ -358,7 +346,13 @@ int FixReaxFFSpecies::setmask() void FixReaxFFSpecies::setup(int /*vflag*/) { ntotal = static_cast(atom->natoms); - if (Name == nullptr) memory->create(Name, ntypes, "reaxff/species:Name"); + if (Name == nullptr) memory->create(Name, nutypes, "reaxff/species:Name"); + + if (!eleflag) { + for (int i = 0; i < ntypes; i++) + eletype[i] = reaxff->eletype[i+1]; + GetUniqueElements(); + } post_integrate(); } @@ -648,14 +642,14 @@ void FixReaxFFSpecies::FindSpecies(int Nmole, int &Nspec) memory->destroy(MolName); MolName = nullptr; - memory->create(MolName, Nmole * (ntypes + 1), "reaxff/species:MolName"); + memory->create(MolName, Nmole * (nutypes + 1), "reaxff/species:MolName"); memory->destroy(NMol); NMol = nullptr; memory->create(NMol, Nmole, "reaxff/species:NMol"); for (m = 0; m < Nmole; m++) NMol[m] = 1; - memory->create(Nameall, ntypes, "reaxff/species:Nameall"); + memory->create(Nameall, nutypes, "reaxff/species:Nameall"); memory->create(NMolall, Nmole, "reaxff/species:NMolall"); memory->destroy(Mol2Spec); @@ -664,12 +658,12 @@ void FixReaxFFSpecies::FindSpecies(int Nmole, int &Nspec) for (m = 0; m < Nmole; m++) Mol2Spec[m] = -1; for (m = 1, Nspec = 0; m <= Nmole; m++) { - for (n = 0; n < ntypes; n++) Name[n] = 0; + for (n = 0; n < nutypes; n++) Name[n] = 0; for (n = 0, flag_mol = 0; n < nlocal; n++) { if (!(mask[n] & groupbit)) continue; cid = nint(clusterID[n]); if (cid == m) { - itype = atom->type[n] - 1; + itype = ele2uele[atom->type[n] - 1]; Name[itype]++; flag_mol = 1; } @@ -677,15 +671,15 @@ void FixReaxFFSpecies::FindSpecies(int Nmole, int &Nspec) MPI_Allreduce(&flag_mol, &flag_tmp, 1, MPI_INT, MPI_MAX, world); flag_mol = flag_tmp; - MPI_Allreduce(Name, Nameall, ntypes, MPI_INT, MPI_SUM, world); - for (n = 0; n < ntypes; n++) Name[n] = Nameall[n]; + MPI_Allreduce(Name, Nameall, nutypes, MPI_INT, MPI_SUM, world); + for (n = 0; n < nutypes; n++) Name[n] = Nameall[n]; if (flag_mol == 1) { flag_identity = 1; for (k = 0; k < Nspec; k++) { flag_spec = 0; - for (l = 0; l < ntypes; l++) - if (MolName[ntypes * k + l] != Name[l]) flag_spec = 1; + for (l = 0; l < nutypes; l++) + if (MolName[nutypes * k + l] != Name[l]) flag_spec = 1; if (flag_spec == 0) { NMol[k]++; Mol2Spec[m - 1] = k; @@ -693,7 +687,7 @@ void FixReaxFFSpecies::FindSpecies(int Nmole, int &Nspec) flag_identity *= flag_spec; } if (Nspec == 0 || flag_identity == 1) { - for (l = 0; l < ntypes; l++) MolName[ntypes * Nspec + l] = Name[l]; + for (l = 0; l < nutypes; l++) MolName[nutypes * Nspec + l] = Name[l]; Mol2Spec[m - 1] = Nspec; Nspec++; } @@ -708,24 +702,24 @@ void FixReaxFFSpecies::FindSpecies(int Nmole, int &Nspec) memory->destroy(MolType); MolType = nullptr; - memory->create(MolType, Nspec * (ntypes + 2), "reaxff/species:MolType"); + memory->create(MolType, Nspec * (nutypes + 2), "reaxff/species:MolType"); } /* ---------------------------------------------------------------------- */ -int FixReaxFFSpecies::CheckExistence(int id, int ntypes) +int FixReaxFFSpecies::CheckExistence(int id, int nutypes) { int i, j, molid, flag; for (i = 0; i < Nmoltype; i++) { flag = 0; - for (j = 0; j < ntypes; j++) { - molid = MolType[ntypes * i + j]; - if (molid != MolName[ntypes * id + j]) flag = 1; + for (j = 0; j < nutypes; j++) { + molid = MolType[nutypes * i + j]; + if (molid != MolName[nutypes * id + j]) flag = 1; } if (flag == 0) return i; } - for (i = 0; i < ntypes; i++) MolType[ntypes * Nmoltype + i] = MolName[ntypes * id + i]; + for (i = 0; i < nutypes; i++) MolType[nutypes * Nmoltype + i] = MolName[nutypes * id + i]; Nmoltype++; return Nmoltype - 1; @@ -733,6 +727,50 @@ int FixReaxFFSpecies::CheckExistence(int id, int ntypes) /* ---------------------------------------------------------------------- */ +void FixReaxFFSpecies::GetUniqueElements() +{ + eleflag = 1; + + // get unique 'element' labels + + nutypes = 0; + int skipflag; + for (int i = 0; i < ntypes; i++) { + skipflag = 0; + for (int j = 0; j < nutypes; j++) + if (eletype[i] == ueletype[j]) { + skipflag = 1; + break; + } + if (skipflag) continue; + ueletype[nutypes++] = eletype[i]; + } + + // reorder CHON, if necessary + + int incr = 0; + std::vector CHON = {"C", "H", "O", "N"}; + for (auto it = CHON.begin(); it != CHON.end(); ++it) + for (int j = incr; j < nutypes; j++) { + if (ueletype[j] == *it) { + ueletype.erase(ueletype.begin() + j); + ueletype.insert(ueletype.begin() + incr++, *it); + break; + } + } + + // map user input to unique list + + for (int i = 0; i < ntypes; i++) + for (int j = 0; j < nutypes; j++) + if (eletype[i] == ueletype[j]) { + ele2uele[i] = j; + break; + } +} + +/* ---------------------------------------------------------------------- */ + void FixReaxFFSpecies::WriteFormulas(int Nmole, int Nspec) { int i, j, itemp; @@ -742,17 +780,14 @@ void FixReaxFFSpecies::WriteFormulas(int Nmole, int Nspec) Nmoltype = 0; - for (i = 0; i < Nspec; i++) nd[i] = CheckExistence(i, ntypes); + for (i = 0; i < Nspec; i++) nd[i] = CheckExistence(i, nutypes); for (i = 0; i < Nmoltype; i++) { std::string molname; - for (j = 0; j < ntypes; j++) { - itemp = MolType[ntypes * i + j]; + for (j = 0; j < nutypes; j++) { + itemp = MolType[nutypes * i + j]; if (itemp != 0) { - if (eletype) - molname += eletype[j]; - else - molname += ele[j]; + molname += ueletype[j]; if (itemp != 1) molname += std::to_string(itemp); } } @@ -810,20 +845,20 @@ void FixReaxFFSpecies::WritePos(int Nmole, int Nspec) } Nameall = nullptr; - memory->create(Nameall, ntypes, "reaxff/species:Nameall"); + memory->create(Nameall, nutypes, "reaxff/species:Nameall"); for (m = 1; m <= Nmole; m++) { count = 0; avq = 0.0; for (n = 0; n < 3; n++) avx[n] = 0.0; - for (n = 0; n < ntypes; n++) Name[n] = 0; + for (n = 0; n < nutypes; n++) Name[n] = 0; for (i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; cid = nint(clusterID[i]); if (cid == m) { - itype = atom->type[i] - 1; + itype = ele2uele[atom->type[i] - 1]; Name[itype]++; count++; avq += spec_atom[i][0]; @@ -850,17 +885,14 @@ void FixReaxFFSpecies::WritePos(int Nmole, int Nspec) MPI_Reduce(&count, &count_tmp, 1, MPI_INT, MPI_SUM, 0, world); count = count_tmp; - MPI_Reduce(Name, Nameall, ntypes, MPI_INT, MPI_SUM, 0, world); - for (n = 0; n < ntypes; n++) Name[n] = Nameall[n]; + MPI_Reduce(Name, Nameall, nutypes, MPI_INT, MPI_SUM, 0, world); + for (n = 0; n < nutypes; n++) Name[n] = Nameall[n]; if (comm->me == 0) { fprintf(pos, "%d\t%d\t", m, count); - for (n = 0; n < ntypes; n++) { + for (n = 0; n < nutypes; n++) { if (Name[n] != 0) { - if (eletype) - fprintf(pos, "%s", eletype[n]); - else - fprintf(pos, "%c", ele[n]); + fprintf(pos, "%s", ueletype[n].c_str()); if (Name[n] != 1) fprintf(pos, "%d", Name[n]); } } @@ -912,7 +944,7 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) for (i = 0; i < nlocal; i++) mark[i] = 0; Nameall = nullptr; - memory->create(Nameall, ntypes, "reaxff/species:Nameall"); + memory->create(Nameall, nutypes, "reaxff/species:Nameall"); int ndelcomm; if (masslimitflag) @@ -944,13 +976,13 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) if (this_delete_Tcount == headroom) break; m = molrange[mm]; localmass = totalmass = count = nmarklist = 0; - for (n = 0; n < ntypes; n++) Name[n] = 0; + for (n = 0; n < nutypes; n++) Name[n] = 0; for (i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; cid = nint(clusterID[i]); if (cid == m) { - itype = atom->type[i] - 1; + itype = ele2uele[atom->type[i] - 1]; Name[itype]++; count++; marklist[nmarklist++] = i; @@ -961,18 +993,15 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) MPI_Allreduce(&count, &count_tmp, 1, MPI_INT, MPI_SUM, world); count = count_tmp; - MPI_Allreduce(Name, Nameall, ntypes, MPI_INT, MPI_SUM, world); - for (n = 0; n < ntypes; n++) Name[n] = Nameall[n]; + MPI_Allreduce(Name, Nameall, nutypes, MPI_INT, MPI_SUM, world); + for (n = 0; n < nutypes; n++) Name[n] = Nameall[n]; MPI_Allreduce(&localmass, &totalmass, 1, MPI_DOUBLE, MPI_SUM, world); species_str = ""; - for (j = 0; j < ntypes; j++) { + for (j = 0; j < nutypes; j++) { if (Name[j] != 0) { - if (eletype) - species_str += eletype[j]; - else - species_str += ele[j]; + species_str += ueletype[j]; if (Name[j] != 1) species_str += fmt::format("{}", Name[j]); } } @@ -1034,13 +1063,10 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) printflag = 1; } fprintf(fdel, " %g ", deletecount[m]); - for (j = 0; j < ntypes; j++) { - int itemp = MolName[ntypes * m + j]; + for (j = 0; j < nutypes; j++) { + int itemp = MolName[nutypes * m + j]; if (itemp != 0) { - if (eletype) - fprintf(fdel, "%s", eletype[j]); - else - fprintf(fdel, "%c", ele[j]); + fprintf(fdel, "%s", ueletype[j].c_str()); if (itemp != 1) fprintf(fdel, "%d", itemp); } } diff --git a/src/REAXFF/fix_reaxff_species.h b/src/REAXFF/fix_reaxff_species.h index 8fcbb131a9..b9afc5466a 100644 --- a/src/REAXFF/fix_reaxff_species.h +++ b/src/REAXFF/fix_reaxff_species.h @@ -43,7 +43,7 @@ class FixReaxFFSpecies : public Fix { double compute_vector(int) override; protected: - int nmax, nlocal, ntypes, ntotal; + int nmax, nlocal, ntypes, nutypes, ntotal; int nrepeat, nfreq, posfreq, compressed, ndelspec; int Nmoltype, vector_nmole, vector_nspec; int *Name, *MolName, *NMol, *nd, *MolType, *molmap, *mark; @@ -62,7 +62,10 @@ class FixReaxFFSpecies : public Fix { int delete_Nsteps, *delete_Tcount; double massmin, massmax; int singlepos_opened, multipos_opened, del_opened; - char *ele, **eletype, *filepos, *filedel; + char *filepos, *filedel; + std::vector ele2uele; // for element eletype[i], ele2uele[i] stores index of unique element + std::vector eletype; // list of ReaxFF elements of length ntypes + std::vector ueletype; // list of unique elements, of quantity nutypes void Output_ReaxFF_Bonds(bigint, FILE *); AtomCoord chAnchor(AtomCoord, AtomCoord); @@ -72,6 +75,7 @@ class FixReaxFFSpecies : public Fix { void WriteFormulas(int, int); void DeleteSpecies(int, int); int CheckExistence(int, int); + void GetUniqueElements(); int nint(const double &); int pack_forward_comm(int, int *, double *, int, int *) override; diff --git a/src/REAXFF/pair_reaxff.cpp b/src/REAXFF/pair_reaxff.cpp index 1867aec81b..99f7510a49 100644 --- a/src/REAXFF/pair_reaxff.cpp +++ b/src/REAXFF/pair_reaxff.cpp @@ -297,14 +297,17 @@ void PairReaxFF::coeff(int nargs, char **args) } int n = atom->ntypes; + eletype.resize(n+1); // pair_coeff element map - for (int i = 3; i < nargs; i++) + for (int i = 3; i < nargs; i++) { + eletype[i-2] = args[i]; for (int j = 0; j < nreax_types; j++) if (utils::lowercase(args[i]) == utils::lowercase(api->system->reax_param.sbp[j].name)) { map[i-2] = j; itmp ++; } + } // error check if (itmp != n) diff --git a/src/REAXFF/pair_reaxff.h b/src/REAXFF/pair_reaxff.h index 594e7e502d..7bd2c6efe1 100644 --- a/src/REAXFF/pair_reaxff.h +++ b/src/REAXFF/pair_reaxff.h @@ -53,6 +53,7 @@ class PairReaxFF : public Pair { int fixbond_flag, fixspecies_flag; int **tmpid; double **tmpbo, **tmpr; + std::vector eletype; ReaxFF::API *api; typedef double rvec[3]; diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp index fd1d535792..2912701159 100644 --- a/src/create_atoms.cpp +++ b/src/create_atoms.cpp @@ -316,6 +316,7 @@ void CreateAtoms::command(int narg, char **arg) onemol->compute_center(); ranmol = new RanMars(lmp, molseed + comm->me); + memory->create(xmol, onemol->natoms, 3, "create_atoms:xmol"); } if (style == MESH) { @@ -651,6 +652,7 @@ void CreateAtoms::command(int narg, char **arg) delete[] xstr; delete[] ystr; delete[] zstr; + if (mode == MOLECULE) memory->destroy(xmol); // for MOLECULE mode: // create special bond lists for molecular systems, @@ -714,7 +716,8 @@ void CreateAtoms::add_single() if (mode == ATOM) { atom->avec->create_atom(ntype, xone); } else { - add_molecule(xone); + get_xmol(xone); + add_molecule(); } } } @@ -732,7 +735,6 @@ void CreateAtoms::add_random() if (overlapflag) { double odist = overlap; - if (mode == MOLECULE) odist += onemol->molradius; odistsq = odist * odist; } @@ -813,25 +815,43 @@ void CreateAtoms::add_random() // check for overlap of new atom/mol with all other atoms // including prior insertions // minimum_image() needed to account for distances across PBC - // new molecule only checks its center pt against others - // odistsq is expanded for mode=MOLECULE to account for molecule size if (overlapflag) { double **x = atom->x; int nlocal = atom->nlocal; int reject = 0; - for (int i = 0; i < nlocal; i++) { - delx = xone[0] - x[i][0]; - dely = xone[1] - x[i][1]; - delz = xone[2] - x[i][2]; - domain->minimum_image(delx, dely, delz); - distsq = delx * delx + dely * dely + delz * delz; - if (distsq < odistsq) { - reject = 1; - break; + if (mode == ATOM) { + for (int i = 0; i < nlocal; i++) { + delx = xone[0] - x[i][0]; + dely = xone[1] - x[i][1]; + delz = xone[2] - x[i][2]; + domain->minimum_image(delx, dely, delz); + distsq = delx * delx + dely * dely + delz * delz; + if (distsq < odistsq) { + reject = 1; + break; + } + } + } else { + if (comm->me == 0) get_xmol(xone); + MPI_Bcast(&xmol[0][0], onemol->natoms*3, MPI_DOUBLE, 0, world); + + for (int i = 0; i < nlocal; i++) { + for (int j = 0; j < onemol->natoms; j++) { + delx = xmol[j][0] - x[i][0]; + dely = xmol[j][1] - x[i][1]; + delz = xmol[j][2] - x[i][2]; + domain->minimum_image(delx, dely, delz); + distsq = delx * delx + dely * dely + delz * delz; + if (distsq < odistsq) { + reject = 1; + break; + } + } } } + int reject_any; MPI_Allreduce(&reject, &reject_any, 1, MPI_INT, MPI_MAX, world); if (reject_any) continue; @@ -858,7 +878,11 @@ void CreateAtoms::add_random() if (mode == ATOM) { atom->avec->create_atom(ntype, xone); } else { - add_molecule(xone); + + // atomic coordinates calculated above for overlap check + + if (!overlapflag) get_xmol(xone); + add_molecule(); } } } @@ -1429,7 +1453,8 @@ void CreateAtoms::loop_lattice(int action) if (mode == ATOM) { atom->avec->create_atom(basistype[m], x); } else { - add_molecule(x); + get_xmol(x); + add_molecule(); } } else if (action == COUNT) { if (nlatt == MAXSMALLINT) nlatt_overflow = 1; @@ -1437,7 +1462,8 @@ void CreateAtoms::loop_lattice(int action) if (mode == ATOM) { atom->avec->create_atom(basistype[m], x); } else { - add_molecule(x); + get_xmol(x); + add_molecule(); } } @@ -1452,7 +1478,7 @@ void CreateAtoms::loop_lattice(int action) add a molecule with its center at center ------------------------------------------------------------------------- */ -void CreateAtoms::add_molecule(double *center) +void CreateAtoms::get_xmol(double *center) { double r[3], rotmat[3][3]; @@ -1475,10 +1501,6 @@ void CreateAtoms::add_molecule(double *center) MathExtra::quat_to_mat(quatone, rotmat); - // create atoms in molecule with atom ID = 0 and mol ID = 0 - // IDs are reset in caller after all molecules created by all procs - // pass add_molecule_atom an offset of 0 since don't know - // max tag of atoms in previous molecules at this point // onemol->quat_external is used by atom->add_moleclue_atom() onemol->quat_external = quatone; @@ -1488,9 +1510,25 @@ void CreateAtoms::add_molecule(double *center) for (int m = 0; m < natoms; m++) { MathExtra::matvec(rotmat, onemol->dx[m], xnew); MathExtra::add3(xnew, center, xnew); - atom->avec->create_atom(ntype + onemol->type[m], xnew); - n = atom->nlocal - 1; - atom->add_molecule_atom(onemol, m, n, 0); + for (int i = 0; i < 3; i++) + xmol[m][i] = xnew[i]; + } +} + +/* ---------------------------------------------------------------------- + add a molecule with atom coordinates from xmol +------------------------------------------------------------------------- */ + +void CreateAtoms::add_molecule() +{ + // create atoms in molecule with atom ID = 0 and mol ID = 0 + // IDs are reset in caller after all molecules created by all procs + // pass add_molecule_atom an offset of 0 since don't know + // max tag of atoms in previous molecules at this point + + for (int m = 0; m < onemol->natoms; m++) { + atom->avec->create_atom(ntype + onemol->type[m], xmol[m]); + atom->add_molecule_atom(onemol, m, atom->nlocal - 1, 0); } } diff --git a/src/create_atoms.h b/src/create_atoms.h index ae6f1b9d33..f839e3f0df 100644 --- a/src/create_atoms.h +++ b/src/create_atoms.h @@ -40,7 +40,7 @@ class CreateAtoms : public Command { bigint nsubset; double subsetfrac; int *basistype; - double xone[3], quatone[4]; + double xone[3], quatone[4], **xmol; double radthresh, radscale, mesh_density; int varflag, vvar, xvar, yvar, zvar; @@ -71,7 +71,8 @@ class CreateAtoms : public Command { int add_quasirandom(const double[3][3], tagint); void add_lattice(); void loop_lattice(int); - void add_molecule(double *); + void get_xmol(double *); + void add_molecule(); int vartest(double *); // evaluate a variable with new atom position }; diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp index 293ade6229..dfacf8f2da 100644 --- a/src/dump_atom.cpp +++ b/src/dump_atom.cpp @@ -166,11 +166,12 @@ int DumpAtom::modify_param(int narg, char **arg) } if (strcmp(arg[0],"triclinic/general") == 0) { - triclinic_general = 1; + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); + triclinic_general = utils::logical(FLERR,arg[1],false,lmp); if (triclinic_general && !domain->triclinic_general) error->all(FLERR,"Dump_modify triclinic/general cannot be used " "if simulation box is not general triclinic"); - return 1; + return 2; } return 0; diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index fb07efd561..431dd62fb7 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -1766,7 +1766,8 @@ int DumpCustom::modify_param(int narg, char **arg) if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); triclinic_general = utils::logical(FLERR,arg[1],false,lmp); if (triclinic_general && !domain->triclinic_general) - error->all(FLERR,"Dump_modify triclinic/general invalid b/c simulation box is not"); + error->all(FLERR,"Dump_modify triclinic/general cannot be used " + "if simulation box is not general triclinic"); return 2; } diff --git a/src/fix.cpp b/src/fix.cpp index 754948fdd1..a93d4b954a 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -119,8 +119,8 @@ Fix::~Fix() { if (copymode) return; - delete [] id; - delete [] style; + delete[] id; + delete[] style; memory->destroy(eatom); memory->destroy(vatom); memory->destroy(cvatom); @@ -133,36 +133,37 @@ Fix::~Fix() void Fix::modify_params(int narg, char **arg) { - if (narg == 0) error->all(FLERR,"Illegal fix_modify command"); + if (narg == 0) utils::missing_cmd_args(FLERR, "fix_modify", error); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"dynamic/dof") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix_modify dynamic/dof", error); dynamic = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"energy") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix_modify energy", error); thermo_energy = utils::logical(FLERR,arg[iarg+1],false,lmp); if (thermo_energy && !energy_global_flag && !energy_peratom_flag) error->all(FLERR,"Fix {} {} does not support fix_modify energy command", id, style); iarg += 2; } else if (strcmp(arg[iarg],"virial") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix_modify virial", error); thermo_virial = utils::logical(FLERR,arg[iarg+1],false,lmp); if (thermo_virial && !virial_global_flag && !virial_peratom_flag) error->all(FLERR,"Fix {} {} does not support fix_modify virial command", id, style); iarg += 2; } else if (strcmp(arg[iarg],"respa") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); - if (!respa_level_support) error->all(FLERR,"Illegal fix_modify command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix_modify respa", error); + if (!respa_level_support) error->all(FLERR,"Illegal fix_modify respa command"); int lvl = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (lvl < 0) error->all(FLERR,"Illegal fix_modify command"); + if (lvl < 0) error->all(FLERR,"Illegal fix_modify respa command"); respa_level = lvl-1; iarg += 2; } else { int n = modify_param(narg-iarg,&arg[iarg]); - if (n == 0) error->all(FLERR,"Illegal fix_modify command"); + if (n == 0) + error->all(FLERR,"Fix {} {} does not support fix_modify {} command", id, style, arg[iarg]); iarg += n; } } diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp index bb27faeaa8..135d7176e6 100644 --- a/src/fix_deform.cpp +++ b/src/fix_deform.cpp @@ -63,7 +63,7 @@ irregular(nullptr), set(nullptr) int nskip; if (utils::strmatch(style, "^deform/pressure")) { child_parameters.insert("box"); - child_styles.insert({{"pressure", 4}, {"pressure/mean", 4}, {"volume", 2}}); + child_styles.insert({{"pressure", 4}, {"pressure/mean", 4}, {"erate/rescale", 3}, {"volume", 2}}); } // set defaults diff --git a/src/fix_deform.h b/src/fix_deform.h index b133729444..c524c2fe6c 100644 --- a/src/fix_deform.h +++ b/src/fix_deform.h @@ -29,7 +29,7 @@ class FixDeform : public Fix { int remapflag; // whether x,v are remapped across PBC int dimflag[6]; // which dims are deformed - enum { NONE, FINAL, DELTA, SCALE, VEL, ERATE, TRATE, VOLUME, WIGGLE, VARIABLE, PRESSURE, PMEAN }; + enum { NONE, FINAL, DELTA, SCALE, VEL, ERATE, TRATE, VOLUME, WIGGLE, VARIABLE, PRESSURE, PMEAN, ERATERS }; enum { ONE_FROM_ONE, ONE_FROM_TWO, TWO_FROM_ONE }; FixDeform(class LAMMPS *, int, char **); diff --git a/src/pair_deprecated.cpp b/src/pair_deprecated.cpp index 298fc26fd0..2c86b252ea 100644 --- a/src/pair_deprecated.cpp +++ b/src/pair_deprecated.cpp @@ -56,6 +56,9 @@ void PairDeprecated::settings(int, char **) utils::logmesg(lmp, "\nPair style 'mesont/tpm' has been removed from LAMMPS. " "Please use pair style 'mesocnt' instead\n\n"); + } else if (utils::strmatch(my_style, "^meam/c")) { + if (lmp->comm->me == 0) + utils::logmesg(lmp, "\nPair style 'meam/c' has been renamed to 'meam'\n\n"); } error->all(FLERR, "This pair style is no longer available"); } diff --git a/src/pair_deprecated.h b/src/pair_deprecated.h index 1a705c9051..8db8b3541d 100644 --- a/src/pair_deprecated.h +++ b/src/pair_deprecated.h @@ -14,6 +14,7 @@ #ifdef PAIR_CLASS // clang-format off PairStyle(DEPRECATED,PairDeprecated); +PairStyle(meam/c,PairDeprecated); PairStyle(reax,PairDeprecated); PairStyle(reax/c,PairDeprecated); PairStyle(mesont/tpm,PairDeprecated); diff --git a/src/replicate.cpp b/src/replicate.cpp index b27304a2a0..e07c7d9a26 100644 --- a/src/replicate.cpp +++ b/src/replicate.cpp @@ -12,6 +12,12 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing authors: + Chris Knight (ANL) for bbox option + Jake Gissinger (Stevens Institute of Technology) for bond/periodic option +------------------------------------------------------------------------- */ + #include "replicate.h" #include "accelerator_kokkos.h" @@ -63,13 +69,30 @@ void Replicate::command(int narg, char **arg) "Please use replicate multiple times", nx, ny, nz, nrepbig); int nrep = (int) nrepbig; + allnrep[0] = nx; + allnrep[1] = ny; + allnrep[2] = nz; if (me == 0) utils::logmesg(lmp, "Replication is creating a {}x{}x{} = {} times larger system...\n", nx, ny, nz, nrep); - int bbox_flag = 0; - if (narg == 4) - if (strcmp(arg[3],"bbox") == 0) bbox_flag = 1; + // optional keywords + + bbox_flag = 0; + bond_flag = 0; + + int iarg = 3; + while (iarg < narg) { + if (strcmp(arg[iarg],"bbox") == 0) { + bbox_flag = 1; + iarg++; + } else if (strcmp(arg[iarg],"bond/periodic") == 0) { + bond_flag = 1; + iarg++; + } else error->all(FLERR,"Illegal replicate command"); + } + + if (bond_flag) bbox_flag = 1; // error and warning checks @@ -85,16 +108,16 @@ void Replicate::command(int narg, char **arg) } if (atom->nextra_grow || atom->nextra_restart || atom->nextra_store) - error->all(FLERR,"Cannot replicate with fixes that store atom quantities"); + error->all(FLERR,"Cannot replicate with fixes that store per-atom quantities"); // record wall time for atom replication MPI_Barrier(world); double time1 = platform::walltime(); - // maxtag = largest atom tag across all existing atoms + // maxtag = original largest atom tag across all existing atoms - tagint maxtag = 0; + maxtag = 0; if (atom->tag_enable) { for (i = 0; i < atom->nlocal; i++) maxtag = MAX(atom->tag[i],maxtag); tagint maxtag_all; @@ -104,7 +127,7 @@ void Replicate::command(int narg, char **arg) // maxmol = largest molecule tag across all existing atoms - tagint maxmol = 0; + maxmol = 0; if (atom->molecule_flag) { for (i = 0; i < atom->nlocal; i++) maxmol = MAX(atom->molecule[i],maxmol); tagint maxmol_all; @@ -112,10 +135,16 @@ void Replicate::command(int narg, char **arg) maxmol = maxmol_all; } - // check image flags maximum extent + // reset image flags to zero for bond/periodic option + + if (bond_flag) + for (i=0; inlocal; ++i) + atom->image[i] = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + + // _imagelo/hi = maximum extent of image flags in each dimension // only efficient small image flags compared to new system - int _imagelo[3], _imagehi[3]; _imagelo[0] = 0; _imagelo[1] = 0; _imagelo[2] = 0; @@ -123,7 +152,7 @@ void Replicate::command(int narg, char **arg) _imagehi[1] = 0; _imagehi[2] = 0; - if (bbox_flag) { + if (bbox_flag || bond_flag) { for (i=0; inlocal; ++i) { imageint image = atom->image[i]; @@ -145,14 +174,14 @@ void Replicate::command(int narg, char **arg) } // unmap existing atoms via image flags + // no-op for bond/periodic option for (i = 0; i < atom->nlocal; i++) domain->unmap(atom->x[i],atom->image[i]); // communication buffer for all my atom's info // max_size = largest buffer needed by any proc - // must do before new Atom class created, - // since size_restart() uses atom->nlocal + // must do before new Atom class created, since size_restart() uses atom->nlocal int max_size; int send_size = atom->avec->size_restart(); @@ -165,7 +194,7 @@ void Replicate::command(int narg, char **arg) // atom = new replicated atom class // also set atomKK for Kokkos version of Atom class - Atom *old = atom; + old = atom; atomKK = nullptr; if (lmp->kokkos) atom = atomKK = new AtomKokkos(lmp); else atom = new Atom(lmp); @@ -204,7 +233,7 @@ void Replicate::command(int narg, char **arg) nrep*old->nimpropers < 0 || nrep*old->nimpropers >= MAXBIGINT) error->all(FLERR,"Replicated system is too big"); - // assign atom and topology counts in new class from old one + // assign atom and topology counts in new Atom class from old Atom class atom->natoms = old->natoms * nrep; atom->nbonds = old->nbonds * nrep; @@ -246,14 +275,18 @@ void Replicate::command(int narg, char **arg) // store old simulation box int triclinic = domain->triclinic; - double old_xprd = domain->xprd; - double old_yprd = domain->yprd; - double old_zprd = domain->zprd; - double old_xy = domain->xy; - double old_xz = domain->xz; - double old_yz = domain->yz; + old_xprd = domain->xprd; + old_yprd = domain->yprd; + old_zprd = domain->zprd; + for (i = 0; i < 3; i++) { + old_prd_half[i] = domain->prd_half[i]; + old_center[i] = 0.5*(domain->boxlo[i]+domain->boxhi[i]); + } + old_xy = domain->xy; + old_xz = domain->xz; + old_yz = domain->yz; - // setup new simulation box + // define new simulation box domain->boxhi[0] = domain->boxlo[0] + nx*old_xprd; domain->boxhi[1] = domain->boxlo[1] + ny*old_yprd; @@ -264,15 +297,14 @@ void Replicate::command(int narg, char **arg) domain->yz *= nz; } - // new problem setup using new box boundaries + // setup of new system using new atom counts and new box boundaries + // allocate atom arrays to size N, rounded up by AtomVec->DELTA if (nprocs == 1) n = static_cast (atom->natoms); else n = static_cast (LB_FACTOR * atom->natoms / nprocs); atom->allocate_type_arrays(); - // allocate atom arrays to size N, rounded up by AtomVec->DELTA - bigint nbig = n; nbig = atom->avec->roundup(nbig); n = static_cast (nbig); @@ -346,420 +378,13 @@ void Replicate::command(int narg, char **arg) } } - // loop over all procs - // if this iteration of loop is me: - // pack my unmapped atom data into buf - // bcast it to all other procs - // performs 3d replicate loop with while loop over atoms in buf - // x = new replicated position, remapped into simulation box - // unpack atom into new atom class from buf if I own it - // adjust tag, mol #, coord, topology info as needed + // use one of two algorithms for replication - AtomVec *old_avec = old->avec; - AtomVec *avec = atom->avec; - - int ix,iy,iz; - tagint atom_offset,mol_offset; - imageint image; - double x[3],lamda[3]; - double *coord; - int tag_enable = atom->tag_enable; - - if (bbox_flag) { - - // allgather size of buf on each proc - - n = 0; - for (i = 0; i < old->nlocal; i++) n += old_avec->pack_restart(i,&buf[n]); - - int * size_buf_rnk; - memory->create(size_buf_rnk, nprocs, "replicate:size_buf_rnk"); - - MPI_Allgather(&n, 1, MPI_INT, size_buf_rnk, 1, MPI_INT, world); - - // size of buf_all - - int size_buf_all = 0; - MPI_Allreduce(&n, &size_buf_all, 1, MPI_INT, MPI_SUM, world); - - if (me == 0) { - auto mesg = fmt::format(" bounding box image = ({} {} {}) " - "to ({} {} {})\n", - _imagelo[0],_imagelo[1],_imagelo[2], - _imagehi[0],_imagehi[1],_imagehi[2]); - mesg += fmt::format(" bounding box extra memory = {:.2f} MB\n", - (double)size_buf_all*sizeof(double)/1024/1024); - utils::logmesg(lmp,mesg); - } - - // rnk offsets - - int *disp_buf_rnk; - memory->create(disp_buf_rnk, nprocs, "replicate:disp_buf_rnk"); - disp_buf_rnk[0] = 0; - for (i = 1; i < nprocs; i++) - disp_buf_rnk[i] = disp_buf_rnk[i-1] + size_buf_rnk[i-1]; - - // allgather buf_all - - double * buf_all; - memory->create(buf_all, size_buf_all, "replicate:buf_all"); - - MPI_Allgatherv(buf,n,MPI_DOUBLE,buf_all,size_buf_rnk,disp_buf_rnk, - MPI_DOUBLE,world); - - // bounding box of original unwrapped system - - double _orig_lo[3], _orig_hi[3]; - if (triclinic) { - _orig_lo[0] = domain->boxlo[0] + - _imagelo[0] * old_xprd + _imagelo[1] * old_xy + _imagelo[2] * old_xz; - _orig_lo[1] = domain->boxlo[1] + - _imagelo[1] * old_yprd + _imagelo[2] * old_yz; - _orig_lo[2] = domain->boxlo[2] + _imagelo[2] * old_zprd; - - _orig_hi[0] = domain->boxlo[0] + - (_imagehi[0]+1) * old_xprd + - (_imagehi[1]+1) * old_xy + (_imagehi[2]+1) * old_xz; - _orig_hi[1] = domain->boxlo[1] + - (_imagehi[1]+1) * old_yprd + (_imagehi[2]+1) * old_yz; - _orig_hi[2] = domain->boxlo[2] + (_imagehi[2]+1) * old_zprd; - } else { - _orig_lo[0] = domain->boxlo[0] + _imagelo[0] * old_xprd; - _orig_lo[1] = domain->boxlo[1] + _imagelo[1] * old_yprd; - _orig_lo[2] = domain->boxlo[2] + _imagelo[2] * old_zprd; - - _orig_hi[0] = domain->boxlo[0] + (_imagehi[0]+1) * old_xprd; - _orig_hi[1] = domain->boxlo[1] + (_imagehi[1]+1) * old_yprd; - _orig_hi[2] = domain->boxlo[2] + (_imagehi[2]+1) * old_zprd; - } - - double _lo[3], _hi[3]; - - int num_replicas_added = 0; - - for (ix = 0; ix < nx; ix++) { - for (iy = 0; iy < ny; iy++) { - for (iz = 0; iz < nz; iz++) { - - // domain->remap() overwrites coordinates, so always recompute here - - if (triclinic) { - _lo[0] = _orig_lo[0] + ix * old_xprd + iy * old_xy + iz * old_xz; - _hi[0] = _orig_hi[0] + ix * old_xprd + iy * old_xy + iz * old_xz; - - _lo[1] = _orig_lo[1] + iy * old_yprd + iz * old_yz; - _hi[1] = _orig_hi[1] + iy * old_yprd + iz * old_yz; - - _lo[2] = _orig_lo[2] + iz * old_zprd; - _hi[2] = _orig_hi[2] + iz * old_zprd; - } else { - _lo[0] = _orig_lo[0] + ix * old_xprd; - _hi[0] = _orig_hi[0] + ix * old_xprd; - - _lo[1] = _orig_lo[1] + iy * old_yprd; - _hi[1] = _orig_hi[1] + iy * old_yprd; - - _lo[2] = _orig_lo[2] + iz * old_zprd; - _hi[2] = _orig_hi[2] + iz * old_zprd; - } - - // test if bounding box of shifted replica overlaps sub-domain of proc - // if not, then skip testing atoms - - int xoverlap = 1; - int yoverlap = 1; - int zoverlap = 1; - if (triclinic) { - double _llo[3]; - domain->x2lamda(_lo,_llo); - double _lhi[3]; - domain->x2lamda(_hi,_lhi); - - if (_llo[0] > (subhi[0] - EPSILON) - || _lhi[0] < (sublo[0] + EPSILON) ) xoverlap = 0; - if (_llo[1] > (subhi[1] - EPSILON) - || _lhi[1] < (sublo[1] + EPSILON) ) yoverlap = 0; - if (_llo[2] > (subhi[2] - EPSILON) - || _lhi[2] < (sublo[2] + EPSILON) ) zoverlap = 0; - } else { - if (_lo[0] > (subhi[0] - EPSILON) - || _hi[0] < (sublo[0] + EPSILON) ) xoverlap = 0; - if (_lo[1] > (subhi[1] - EPSILON) - || _hi[1] < (sublo[1] + EPSILON) ) yoverlap = 0; - if (_lo[2] > (subhi[2] - EPSILON) - || _hi[2] < (sublo[2] + EPSILON) ) zoverlap = 0; - } - - int overlap = 0; - if (xoverlap && yoverlap && zoverlap) overlap = 1; - - // if no overlap, test if bounding box wrapped back into new system - - if (!overlap) { - - // wrap back into cell - - imageint imagelo = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) IMGMAX << IMGBITS) | IMGMAX; - domain->remap(&(_lo[0]), imagelo); - int xboxlo = (imagelo & IMGMASK) - IMGMAX; - int yboxlo = (imagelo >> IMGBITS & IMGMASK) - IMGMAX; - int zboxlo = (imagelo >> IMG2BITS) - IMGMAX; - - imageint imagehi = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) IMGMAX << IMGBITS) | IMGMAX; - domain->remap(&(_hi[0]), imagehi); - int xboxhi = (imagehi & IMGMASK) - IMGMAX; - int yboxhi = (imagehi >> IMGBITS & IMGMASK) - IMGMAX; - int zboxhi = (imagehi >> IMG2BITS) - IMGMAX; - - if (triclinic) { - double _llo[3]; - _llo[0] = _lo[0]; _llo[1] = _lo[1]; _llo[2] = _lo[2]; - domain->x2lamda(_llo,_lo); - - double _lhi[3]; - _lhi[0] = _hi[0]; _lhi[1] = _hi[1]; _lhi[2] = _hi[2]; - domain->x2lamda(_lhi,_hi); - } - - // test all fragments for any overlap; ok to include false positives - - int _xoverlap1 = 0; - int _xoverlap2 = 0; - if (!xoverlap) { - if (xboxlo < 0) { - _xoverlap1 = 1; - if (_lo[0] > (subhi[0] - EPSILON)) _xoverlap1 = 0; - } - - if (xboxhi > 0) { - _xoverlap2 = 1; - if (_hi[0] < (sublo[0] + EPSILON)) _xoverlap2 = 0; - } - - if (_xoverlap1 || _xoverlap2) xoverlap = 1; - } - - int _yoverlap1 = 0; - int _yoverlap2 = 0; - if (!yoverlap) { - if (yboxlo < 0) { - _yoverlap1 = 1; - if (_lo[1] > (subhi[1] - EPSILON)) _yoverlap1 = 0; - } - - if (yboxhi > 0) { - _yoverlap2 = 1; - if (_hi[1] < (sublo[1] + EPSILON)) _yoverlap2 = 0; - } - - if (_yoverlap1 || _yoverlap2) yoverlap = 1; - } - - - int _zoverlap1 = 0; - int _zoverlap2 = 0; - if (!zoverlap) { - if (zboxlo < 0) { - _zoverlap1 = 1; - if (_lo[2] > (subhi[2] - EPSILON)) _zoverlap1 = 0; - } - - if (zboxhi > 0) { - _zoverlap2 = 1; - if (_hi[2] < (sublo[2] + EPSILON)) _zoverlap2 = 0; - } - - if (_zoverlap1 || _zoverlap2) zoverlap = 1; - } - - // does either fragment overlap w/ sub-domain - - if (xoverlap && yoverlap && zoverlap) overlap = 1; - } - - // while loop over one proc's atom list - - if (overlap) { - num_replicas_added++; - - m = 0; - while (m < size_buf_all) { - image = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) IMGMAX << IMGBITS) | IMGMAX; - if (triclinic == 0) { - x[0] = buf_all[m+1] + ix*old_xprd; - x[1] = buf_all[m+2] + iy*old_yprd; - x[2] = buf_all[m+3] + iz*old_zprd; - } else { - x[0] = buf_all[m+1] + ix*old_xprd + iy*old_xy + iz*old_xz; - x[1] = buf_all[m+2] + iy*old_yprd + iz*old_yz; - x[2] = buf_all[m+3] + iz*old_zprd; - } - domain->remap(x,image); - if (triclinic) { - domain->x2lamda(x,lamda); - coord = lamda; - } else coord = x; - - if (coord[0] >= sublo[0] && coord[0] < subhi[0] && - coord[1] >= sublo[1] && coord[1] < subhi[1] && - coord[2] >= sublo[2] && coord[2] < subhi[2]) { - - m += avec->unpack_restart(&buf_all[m]); - - i = atom->nlocal - 1; - if (tag_enable) - atom_offset = iz*ny*nx*maxtag + iy*nx*maxtag + ix*maxtag; - else atom_offset = 0; - mol_offset = iz*ny*nx*maxmol + iy*nx*maxmol + ix*maxmol; - - atom->x[i][0] = x[0]; - atom->x[i][1] = x[1]; - atom->x[i][2] = x[2]; - - atom->tag[i] += atom_offset; - atom->image[i] = image; - - if (atom->molecular != Atom::ATOMIC) { - if (atom->molecule[i] > 0) - atom->molecule[i] += mol_offset; - if (atom->molecular == Atom::MOLECULAR) { - if (atom->avec->bonds_allow) - for (j = 0; j < atom->num_bond[i]; j++) - atom->bond_atom[i][j] += atom_offset; - if (atom->avec->angles_allow) - for (j = 0; j < atom->num_angle[i]; j++) { - atom->angle_atom1[i][j] += atom_offset; - atom->angle_atom2[i][j] += atom_offset; - atom->angle_atom3[i][j] += atom_offset; - } - if (atom->avec->dihedrals_allow) - for (j = 0; j < atom->num_dihedral[i]; j++) { - atom->dihedral_atom1[i][j] += atom_offset; - atom->dihedral_atom2[i][j] += atom_offset; - atom->dihedral_atom3[i][j] += atom_offset; - atom->dihedral_atom4[i][j] += atom_offset; - } - if (atom->avec->impropers_allow) - for (j = 0; j < atom->num_improper[i]; j++) { - atom->improper_atom1[i][j] += atom_offset; - atom->improper_atom2[i][j] += atom_offset; - atom->improper_atom3[i][j] += atom_offset; - atom->improper_atom4[i][j] += atom_offset; - } - } - } - } else m += static_cast (buf_all[m]); - } - } // if (overlap) - - } - } - } - - memory->destroy(size_buf_rnk); - memory->destroy(disp_buf_rnk); - memory->destroy(buf_all); - - int sum = 0; - MPI_Reduce(&num_replicas_added, &sum, 1, MPI_INT, MPI_SUM, 0, world); - double avg = (double) sum / nprocs; - if (me == 0) - utils::logmesg(lmp," average # of replicas added to proc = {:.2f} out " - "of {} ({:.2f}%)\n",avg,nx*ny*nz,avg/(nx*ny*nz)*100.0); + if (!bbox_flag) { + replicate_by_proc(nx,ny,nz,sublo,subhi,buf); } else { - - for (int iproc = 0; iproc < nprocs; iproc++) { - if (me == iproc) { - n = 0; - for (i = 0; i < old->nlocal; i++) n += old_avec->pack_restart(i,&buf[n]); - } - MPI_Bcast(&n,1,MPI_INT,iproc,world); - MPI_Bcast(buf,n,MPI_DOUBLE,iproc,world); - - for (ix = 0; ix < nx; ix++) { - for (iy = 0; iy < ny; iy++) { - for (iz = 0; iz < nz; iz++) { - - // while loop over one proc's atom list - - m = 0; - while (m < n) { - image = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) IMGMAX << IMGBITS) | IMGMAX; - if (triclinic == 0) { - x[0] = buf[m+1] + ix*old_xprd; - x[1] = buf[m+2] + iy*old_yprd; - x[2] = buf[m+3] + iz*old_zprd; - } else { - x[0] = buf[m+1] + ix*old_xprd + iy*old_xy + iz*old_xz; - x[1] = buf[m+2] + iy*old_yprd + iz*old_yz; - x[2] = buf[m+3] + iz*old_zprd; - } - domain->remap(x,image); - if (triclinic) { - domain->x2lamda(x,lamda); - coord = lamda; - } else coord = x; - - if (coord[0] >= sublo[0] && coord[0] < subhi[0] && - coord[1] >= sublo[1] && coord[1] < subhi[1] && - coord[2] >= sublo[2] && coord[2] < subhi[2]) { - - m += avec->unpack_restart(&buf[m]); - - i = atom->nlocal - 1; - if (tag_enable) - atom_offset = iz*ny*nx*maxtag + iy*nx*maxtag + ix*maxtag; - else atom_offset = 0; - mol_offset = iz*ny*nx*maxmol + iy*nx*maxmol + ix*maxmol; - - atom->x[i][0] = x[0]; - atom->x[i][1] = x[1]; - atom->x[i][2] = x[2]; - - atom->tag[i] += atom_offset; - atom->image[i] = image; - - if (atom->molecular != Atom::ATOMIC) { - if (atom->molecule[i] > 0) - atom->molecule[i] += mol_offset; - if (atom->molecular == Atom::MOLECULAR) { - if (atom->avec->bonds_allow) - for (j = 0; j < atom->num_bond[i]; j++) - atom->bond_atom[i][j] += atom_offset; - if (atom->avec->angles_allow) - for (j = 0; j < atom->num_angle[i]; j++) { - atom->angle_atom1[i][j] += atom_offset; - atom->angle_atom2[i][j] += atom_offset; - atom->angle_atom3[i][j] += atom_offset; - } - if (atom->avec->dihedrals_allow) - for (j = 0; j < atom->num_dihedral[i]; j++) { - atom->dihedral_atom1[i][j] += atom_offset; - atom->dihedral_atom2[i][j] += atom_offset; - atom->dihedral_atom3[i][j] += atom_offset; - atom->dihedral_atom4[i][j] += atom_offset; - } - if (atom->avec->impropers_allow) - for (j = 0; j < atom->num_improper[i]; j++) { - atom->improper_atom1[i][j] += atom_offset; - atom->improper_atom2[i][j] += atom_offset; - atom->improper_atom3[i][j] += atom_offset; - atom->improper_atom4[i][j] += atom_offset; - } - } - } - } else m += static_cast (buf[m]); - } - } - } - } - } - } // if (bbox_flag) + replicate_by_bbox(nx,ny,nz,sublo,subhi,buf); + } // free communication buffer and old atom class @@ -821,3 +446,533 @@ void Replicate::command(int narg, char **arg) if (me == 0) utils::logmesg(lmp," replicate CPU = {:.3f} seconds\n",platform::walltime()-time1); } + +/* ---------------------------------------------------------------------- + simple replication algorithm, suitable for small proc count + loop over procs, then over replication factors + check each atom to see if in my subdomain +------------------------------------------------------------------------- */ + +void Replicate::replicate_by_proc(int nx, int ny, int nz, + double *sublo, double *subhi, double *buf) +{ + int i,j,m,n; + int ix,iy,iz; + + int me = comm->me; + int nprocs = comm->nprocs; + int triclinic = domain->triclinic; + int tag_enable = atom->tag_enable; + + AtomVec *old_avec = old->avec; + AtomVec *avec = atom->avec; + + tagint atom_offset,mol_offset; + imageint image; + double x[3],lamda[3]; + double *coord; + + // loop over all procs + // if this iteration of loop is me: + // pack my unmapped atom data into buf + // bcast it to all other procs + + for (int iproc = 0; iproc < nprocs; iproc++) { + if (me == iproc) { + n = 0; + for (i = 0; i < old->nlocal; i++) n += old_avec->pack_restart(i,&buf[n]); + } + MPI_Bcast(&n,1,MPI_INT,iproc,world); + MPI_Bcast(buf,n,MPI_DOUBLE,iproc,world); + + for (ix = 0; ix < nx; ix++) { + for (iy = 0; iy < ny; iy++) { + for (iz = 0; iz < nz; iz++) { + + // while loop over one proc's atom list + // x = new replicated position, remapped into new simulation box + // if atom is within my new subdomain, unpack it into new atom class + // adjust tag, mol #, coord, topology info as needed + + m = 0; + while (m < n) { + image = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + if (triclinic == 0) { + x[0] = buf[m+1] + ix*old_xprd; + x[1] = buf[m+2] + iy*old_yprd; + x[2] = buf[m+3] + iz*old_zprd; + } else { + x[0] = buf[m+1] + ix*old_xprd + iy*old_xy + iz*old_xz; + x[1] = buf[m+2] + iy*old_yprd + iz*old_yz; + x[2] = buf[m+3] + iz*old_zprd; + } + domain->remap(x,image); + if (triclinic) { + domain->x2lamda(x,lamda); + coord = lamda; + } else coord = x; + + if (coord[0] >= sublo[0] && coord[0] < subhi[0] && + coord[1] >= sublo[1] && coord[1] < subhi[1] && + coord[2] >= sublo[2] && coord[2] < subhi[2]) { + + m += avec->unpack_restart(&buf[m]); + + i = atom->nlocal - 1; + if (tag_enable) atom_offset = iz*ny*nx*maxtag + iy*nx*maxtag + ix*maxtag; + else atom_offset = 0; + mol_offset = iz*ny*nx*maxmol + iy*nx*maxmol + ix*maxmol; + + atom->x[i][0] = x[0]; + atom->x[i][1] = x[1]; + atom->x[i][2] = x[2]; + + atom->tag[i] += atom_offset; + atom->image[i] = image; + + if (atom->molecular != Atom::ATOMIC) { + if (atom->molecule[i] > 0) + atom->molecule[i] += mol_offset; + if (atom->molecular == Atom::MOLECULAR) { + if (atom->avec->bonds_allow) + for (j = 0; j < atom->num_bond[i]; j++) + atom->bond_atom[i][j] += atom_offset; + if (atom->avec->angles_allow) + for (j = 0; j < atom->num_angle[i]; j++) { + atom->angle_atom1[i][j] += atom_offset; + atom->angle_atom2[i][j] += atom_offset; + atom->angle_atom3[i][j] += atom_offset; + } + if (atom->avec->dihedrals_allow) + for (j = 0; j < atom->num_dihedral[i]; j++) { + atom->dihedral_atom1[i][j] += atom_offset; + atom->dihedral_atom2[i][j] += atom_offset; + atom->dihedral_atom3[i][j] += atom_offset; + atom->dihedral_atom4[i][j] += atom_offset; + } + if (atom->avec->impropers_allow) + for (j = 0; j < atom->num_improper[i]; j++) { + atom->improper_atom1[i][j] += atom_offset; + atom->improper_atom2[i][j] += atom_offset; + atom->improper_atom3[i][j] += atom_offset; + atom->improper_atom4[i][j] += atom_offset; + } + } + } + } else m += static_cast (buf[m]); + } + } + } + } + } +} + +/* ---------------------------------------------------------------------- + more complex replication algorithm + uses bounding box of each proc's subdomain to avoid checking individual atoms + faster for large processor counts + required for bond/periodic option +------------------------------------------------------------------------- */ + +void Replicate::replicate_by_bbox(int nx, int ny, int nz, + double *sublo, double *subhi, double *buf) +{ + int i,j,m,n; + int ix,iy,iz; + + int me = comm->me; + int nprocs = comm->nprocs; + int triclinic = domain->triclinic; + int tag_enable = atom->tag_enable; + + AtomVec *old_avec = old->avec; + AtomVec *avec = atom->avec; + + tagint atom_offset,mol_offset,atom0tag; + imageint image; + double x[3],lamda[3]; + double *coord; + + // allgather size of buf on each proc + + n = 0; + for (i = 0; i < old->nlocal; i++) n += old_avec->pack_restart(i,&buf[n]); + + int * size_buf_rnk; + memory->create(size_buf_rnk, nprocs, "replicate:size_buf_rnk"); + + MPI_Allgather(&n, 1, MPI_INT, size_buf_rnk, 1, MPI_INT, world); + + // size of buf_all + + int size_buf_all = 0; + MPI_Allreduce(&n, &size_buf_all, 1, MPI_INT, MPI_SUM, world); + + if (me == 0) { + auto mesg = fmt::format(" bounding box image = ({} {} {}) " + "to ({} {} {})\n", + _imagelo[0],_imagelo[1],_imagelo[2], + _imagehi[0],_imagehi[1],_imagehi[2]); + mesg += fmt::format(" bounding box extra memory = {:.2f} MB\n", + (double)size_buf_all*sizeof(double)/1024/1024); + utils::logmesg(lmp,mesg); + } + + // rnk offsets + + int *disp_buf_rnk; + memory->create(disp_buf_rnk, nprocs, "replicate:disp_buf_rnk"); + disp_buf_rnk[0] = 0; + for (i = 1; i < nprocs; i++) + disp_buf_rnk[i] = disp_buf_rnk[i-1] + size_buf_rnk[i-1]; + + // allgather buf_all + + double *buf_all; + memory->create(buf_all, size_buf_all, "replicate:buf_all"); + + MPI_Allgatherv(buf,n,MPI_DOUBLE,buf_all,size_buf_rnk,disp_buf_rnk, + MPI_DOUBLE,world); + + // bounding box of original unwrapped system + + double _orig_lo[3], _orig_hi[3]; + if (triclinic) { + _orig_lo[0] = domain->boxlo[0] + + _imagelo[0] * old_xprd + _imagelo[1] * old_xy + _imagelo[2] * old_xz; + _orig_lo[1] = domain->boxlo[1] + + _imagelo[1] * old_yprd + _imagelo[2] * old_yz; + _orig_lo[2] = domain->boxlo[2] + _imagelo[2] * old_zprd; + + _orig_hi[0] = domain->boxlo[0] + + (_imagehi[0]+1) * old_xprd + + (_imagehi[1]+1) * old_xy + (_imagehi[2]+1) * old_xz; + _orig_hi[1] = domain->boxlo[1] + + (_imagehi[1]+1) * old_yprd + (_imagehi[2]+1) * old_yz; + _orig_hi[2] = domain->boxlo[2] + (_imagehi[2]+1) * old_zprd; + } else { + _orig_lo[0] = domain->boxlo[0] + _imagelo[0] * old_xprd; + _orig_lo[1] = domain->boxlo[1] + _imagelo[1] * old_yprd; + _orig_lo[2] = domain->boxlo[2] + _imagelo[2] * old_zprd; + + _orig_hi[0] = domain->boxlo[0] + (_imagehi[0]+1) * old_xprd; + _orig_hi[1] = domain->boxlo[1] + (_imagehi[1]+1) * old_yprd; + _orig_hi[2] = domain->boxlo[2] + (_imagehi[2]+1) * old_zprd; + } + + double _lo[3], _hi[3]; + + int num_replicas_added = 0; + + // if bond/periodic option + // store old_x and old_tag for the entire original system + + if (bond_flag) { + memory->create(old_x,old->natoms,3,"replicate:old_x"); + memory->create(old_tag,old->natoms,"replicate:old_tag"); + + i = m = 0; + while (m < size_buf_all) { + old_x[i][0] = buf_all[m+1]; + old_x[i][1] = buf_all[m+2]; + old_x[i][2] = buf_all[m+3]; + old_tag[i] = (tagint) ubuf(buf_all[m+4]).i; + old_map.insert({old_tag[i],i}); + m += static_cast (buf_all[m]); + i++; + } + } + + // replication loop + + for (ix = 0; ix < nx; ix++) { + for (iy = 0; iy < ny; iy++) { + for (iz = 0; iz < nz; iz++) { + + thisrep[0] = ix; + thisrep[1] = iy; + thisrep[2] = iz; + + // domain->remap() overwrites coordinates, so always recompute here + + if (triclinic) { + _lo[0] = _orig_lo[0] + ix * old_xprd + iy * old_xy + iz * old_xz; + _hi[0] = _orig_hi[0] + ix * old_xprd + iy * old_xy + iz * old_xz; + + _lo[1] = _orig_lo[1] + iy * old_yprd + iz * old_yz; + _hi[1] = _orig_hi[1] + iy * old_yprd + iz * old_yz; + + _lo[2] = _orig_lo[2] + iz * old_zprd; + _hi[2] = _orig_hi[2] + iz * old_zprd; + } else { + _lo[0] = _orig_lo[0] + ix * old_xprd; + _hi[0] = _orig_hi[0] + ix * old_xprd; + + _lo[1] = _orig_lo[1] + iy * old_yprd; + _hi[1] = _orig_hi[1] + iy * old_yprd; + + _lo[2] = _orig_lo[2] + iz * old_zprd; + _hi[2] = _orig_hi[2] + iz * old_zprd; + } + + // test if bounding box of shifted replica overlaps sub-domain of proc + // if not, then can skip testing of any individual atoms + + int xoverlap = 1; + int yoverlap = 1; + int zoverlap = 1; + if (triclinic) { + double _llo[3]; + domain->x2lamda(_lo,_llo); + double _lhi[3]; + domain->x2lamda(_hi,_lhi); + + if (_llo[0] > (subhi[0] - EPSILON) + || _lhi[0] < (sublo[0] + EPSILON) ) xoverlap = 0; + if (_llo[1] > (subhi[1] - EPSILON) + || _lhi[1] < (sublo[1] + EPSILON) ) yoverlap = 0; + if (_llo[2] > (subhi[2] - EPSILON) + || _lhi[2] < (sublo[2] + EPSILON) ) zoverlap = 0; + } else { + if (_lo[0] > (subhi[0] - EPSILON) + || _hi[0] < (sublo[0] + EPSILON) ) xoverlap = 0; + if (_lo[1] > (subhi[1] - EPSILON) + || _hi[1] < (sublo[1] + EPSILON) ) yoverlap = 0; + if (_lo[2] > (subhi[2] - EPSILON) + || _hi[2] < (sublo[2] + EPSILON) ) zoverlap = 0; + } + + int overlap = 0; + if (xoverlap && yoverlap && zoverlap) overlap = 1; + + // if no overlap, test if bounding box wrapped back into new system + + if (!overlap) { + + // wrap back into cell + + imageint imagelo = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + domain->remap(&(_lo[0]), imagelo); + int xboxlo = (imagelo & IMGMASK) - IMGMAX; + int yboxlo = (imagelo >> IMGBITS & IMGMASK) - IMGMAX; + int zboxlo = (imagelo >> IMG2BITS) - IMGMAX; + + imageint imagehi = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + domain->remap(&(_hi[0]), imagehi); + int xboxhi = (imagehi & IMGMASK) - IMGMAX; + int yboxhi = (imagehi >> IMGBITS & IMGMASK) - IMGMAX; + int zboxhi = (imagehi >> IMG2BITS) - IMGMAX; + + if (triclinic) { + double _llo[3]; + _llo[0] = _lo[0]; _llo[1] = _lo[1]; _llo[2] = _lo[2]; + domain->x2lamda(_llo,_lo); + + double _lhi[3]; + _lhi[0] = _hi[0]; _lhi[1] = _hi[1]; _lhi[2] = _hi[2]; + domain->x2lamda(_lhi,_hi); + } + + // test all fragments for any overlap; ok to include false positives + + int _xoverlap1 = 0; + int _xoverlap2 = 0; + if (!xoverlap) { + if (xboxlo < 0) { + _xoverlap1 = 1; + if (_lo[0] > (subhi[0] - EPSILON)) _xoverlap1 = 0; + } + + if (xboxhi > 0) { + _xoverlap2 = 1; + if (_hi[0] < (sublo[0] + EPSILON)) _xoverlap2 = 0; + } + + if (_xoverlap1 || _xoverlap2) xoverlap = 1; + } + + int _yoverlap1 = 0; + int _yoverlap2 = 0; + if (!yoverlap) { + if (yboxlo < 0) { + _yoverlap1 = 1; + if (_lo[1] > (subhi[1] - EPSILON)) _yoverlap1 = 0; + } + + if (yboxhi > 0) { + _yoverlap2 = 1; + if (_hi[1] < (sublo[1] + EPSILON)) _yoverlap2 = 0; + } + + if (_yoverlap1 || _yoverlap2) yoverlap = 1; + } + + + int _zoverlap1 = 0; + int _zoverlap2 = 0; + if (!zoverlap) { + if (zboxlo < 0) { + _zoverlap1 = 1; + if (_lo[2] > (subhi[2] - EPSILON)) _zoverlap1 = 0; + } + + if (zboxhi > 0) { + _zoverlap2 = 1; + if (_hi[2] < (sublo[2] + EPSILON)) _zoverlap2 = 0; + } + + if (_zoverlap1 || _zoverlap2) zoverlap = 1; + } + + // does either fragment overlap w/ sub-domain + + if (xoverlap && yoverlap && zoverlap) overlap = 1; + } + + // while loop over one proc's atom list + + if (overlap) { + num_replicas_added++; + + m = 0; + while (m < size_buf_all) { + image = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + if (triclinic == 0) { + x[0] = buf_all[m+1] + ix*old_xprd; + x[1] = buf_all[m+2] + iy*old_yprd; + x[2] = buf_all[m+3] + iz*old_zprd; + } else { + x[0] = buf_all[m+1] + ix*old_xprd + iy*old_xy + iz*old_xz; + x[1] = buf_all[m+2] + iy*old_yprd + iz*old_yz; + x[2] = buf_all[m+3] + iz*old_zprd; + } + domain->remap(x,image); + if (triclinic) { + domain->x2lamda(x,lamda); + coord = lamda; + } else coord = x; + + if (coord[0] >= sublo[0] && coord[0] < subhi[0] && + coord[1] >= sublo[1] && coord[1] < subhi[1] && + coord[2] >= sublo[2] && coord[2] < subhi[2]) { + + m += avec->unpack_restart(&buf_all[m]); + + i = atom->nlocal - 1; + if (tag_enable) + atom_offset = iz*ny*nx*maxtag + iy*nx*maxtag + ix*maxtag; + else atom_offset = 0; + mol_offset = iz*ny*nx*maxmol + iy*nx*maxmol + ix*maxmol; + + atom->x[i][0] = x[0]; + atom->x[i][1] = x[1]; + atom->x[i][2] = x[2]; + + atom0tag = atom->tag[i]; + atom->tag[i] += atom_offset; + atom->image[i] = image; + + if (atom->molecular != Atom::ATOMIC) { + if (atom->molecule[i] > 0) + atom->molecule[i] += mol_offset; + if (atom->molecular == Atom::MOLECULAR) { + if (atom->avec->bonds_allow) + for (j = 0; j < atom->num_bond[i]; j++) { + if (bond_flag) + newtag(atom0tag,atom->bond_atom[i][j]); + else atom->bond_atom[i][j] += atom_offset; + } + if (atom->avec->angles_allow) + for (j = 0; j < atom->num_angle[i]; j++) { + if (bond_flag) { + newtag(atom0tag,atom->angle_atom1[i][j]); + newtag(atom0tag,atom->angle_atom2[i][j]); + newtag(atom0tag,atom->angle_atom3[i][j]); + } else { + atom->angle_atom1[i][j] += atom_offset; + atom->angle_atom2[i][j] += atom_offset; + atom->angle_atom3[i][j] += atom_offset; + } + } + if (atom->avec->dihedrals_allow) + for (j = 0; j < atom->num_dihedral[i]; j++) { + if (bond_flag) { + newtag(atom0tag,atom->dihedral_atom1[i][j]); + newtag(atom0tag,atom->dihedral_atom2[i][j]); + newtag(atom0tag,atom->dihedral_atom3[i][j]); + newtag(atom0tag,atom->dihedral_atom4[i][j]); + } else { + atom->dihedral_atom1[i][j] += atom_offset; + atom->dihedral_atom2[i][j] += atom_offset; + atom->dihedral_atom3[i][j] += atom_offset; + atom->dihedral_atom4[i][j] += atom_offset; + } + } + if (atom->avec->impropers_allow) + for (j = 0; j < atom->num_improper[i]; j++) { + if (bond_flag) { + newtag(atom0tag,atom->improper_atom1[i][j]); + newtag(atom0tag,atom->improper_atom2[i][j]); + newtag(atom0tag,atom->improper_atom3[i][j]); + newtag(atom0tag,atom->improper_atom4[i][j]); + } else { + atom->improper_atom1[i][j] += atom_offset; + atom->improper_atom2[i][j] += atom_offset; + atom->improper_atom3[i][j] += atom_offset; + atom->improper_atom4[i][j] += atom_offset; + } + } + } + } + } else m += static_cast (buf_all[m]); + } + } + } + } + } + + memory->destroy(size_buf_rnk); + memory->destroy(disp_buf_rnk); + memory->destroy(buf_all); + if (bond_flag) { + memory->destroy(old_x); + memory->destroy(old_tag); + } + + int sum = 0; + MPI_Reduce(&num_replicas_added, &sum, 1, MPI_INT, MPI_SUM, 0, world); + double avg = (double) sum / nprocs; + if (me == 0) + utils::logmesg(lmp," average # of replicas added to proc = {:.2f} out " + "of {} ({:.2f}%)\n",avg,nx*ny*nz,avg/(nx*ny*nz)*100.0); +} + +/* ---------------------------------------------------------------------- + find new tag for atom 'atom2bond' bonded to atom 'atom0' + for bond/periodic option + useful for periodic loops or inconsistent image flags + reassign bond if > old boxlength / 2 +------------------------------------------------------------------------- */ + +void Replicate::newtag(tagint atom0tag, tagint &tag2bond) { + double del; + int repshift,rep2bond[3]; + int atom0 = old_map.find(atom0tag)->second; + int atom2bond = old_map.find(tag2bond)->second; + for (int i = 0; i < 3; i++) { + del = fabs(old_x[atom0][i] - old_x[atom2bond][i]); + if (del > old_prd_half[i]) { + if (old_x[atom0][i] > old_center[i]) repshift = 1; + else repshift = -1; + } else repshift = 0; + rep2bond[i] = thisrep[i] + repshift; + if (rep2bond[i] >= allnrep[i]) rep2bond[i] = 0; + if (rep2bond[i] < 0) rep2bond[i] = allnrep[i]-1; + } + tag2bond = (tag2bond + rep2bond[2]*allnrep[1]*allnrep[0]*maxtag + + rep2bond[1]*allnrep[0]*maxtag + rep2bond[0]*maxtag); +} diff --git a/src/replicate.h b/src/replicate.h index 8d71ba6584..defb35d1c6 100644 --- a/src/replicate.h +++ b/src/replicate.h @@ -22,12 +22,37 @@ CommandStyle(replicate,Replicate); #include "command.h" +#include + namespace LAMMPS_NS { class Replicate : public Command { public: Replicate(class LAMMPS *); void command(int, char **) override; + +private: + int bbox_flag, bond_flag; + + class Atom *old; + + double old_xprd, old_yprd, old_zprd; + double old_xy, old_xz, old_yz; + + int _imagelo[3], _imagehi[3]; + + double **old_x; + double old_prd_half[3], old_center[3]; + tagint *old_tag; + tagint maxtag, maxmol; + int thisrep[3], allnrep[3]; + + std::unordered_map old_map; + + void replicate_by_proc(int, int, int, double *, double *, double *); + void replicate_by_bbox(int, int, int, double *, double *, double *); + + void newtag(tagint, tagint &); }; } // namespace LAMMPS_NS diff --git a/src/version.h b/src/version.h index 37c44b49f2..64d5210270 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1,2 @@ #define LAMMPS_VERSION "17 Apr 2024" +#define LAMMPS_UPDATE "Development" diff --git a/unittest/cplusplus/test_advanced_utils.cpp b/unittest/cplusplus/test_advanced_utils.cpp index 0453ef0143..43ac5dc9cf 100644 --- a/unittest/cplusplus/test_advanced_utils.cpp +++ b/unittest/cplusplus/test_advanced_utils.cpp @@ -110,16 +110,31 @@ TEST_F(Advanced_utils, expand_args) { atomic_system(); BEGIN_CAPTURE_OUTPUT(); - command("compute temp all temp"); - command("variable temp vector c_temp"); - command("variable step equal step"); - command("variable pe equal pe"); - command("variable pe equal pe"); - command("variable epair equal epair"); - command("compute gofr all rdf 20 1 1 1 2"); - command("fix 1 all ave/time 1 1 1 v_step v_pe v_epair"); - command("fix 2 all nve"); - command("run 1 post no"); + try { + command("compute temp all temp"); + command("variable temp vector c_temp"); + command("variable step equal step"); + command("variable pe equal pe"); + command("variable pe equal pe"); + command("variable epair equal epair"); + command("compute gofr all rdf 20 1 1 1 2"); + command("fix 1 all ave/time 1 1 1 v_step v_pe v_epair"); + command("fix 2 all nve"); + command("run 1 post no"); + } catch (LAMMPSAbortException &ae) { + fprintf(stderr, "LAMMPS Error: %s\n", ae.what()); + exit(2); + } catch (LAMMPSException &e) { + fprintf(stderr, "LAMMPS Error: %s\n", e.what()); + exit(3); + } catch (fmt::format_error &fe) { + fprintf(stderr, "fmt::format_error: %s\n", fe.what()); + exit(4); + } catch (std::exception &e) { + fprintf(stderr, "General exception: %s\n", e.what()); + exit(5); + } + auto output = END_CAPTURE_OUTPUT(); char **args, **earg;