diff --git a/doc/src/Commands_compute.rst b/doc/src/Commands_compute.rst index 91910ccdaa..590b3d2ea8 100644 --- a/doc/src/Commands_compute.rst +++ b/doc/src/Commands_compute.rst @@ -100,7 +100,6 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`pe/tally ` * :doc:`plasticity/atom ` * :doc:`pressure ` - * :doc:`pressure/cylinder ` * :doc:`pressure/uef ` * :doc:`property/atom ` * :doc:`property/chunk ` @@ -143,8 +142,11 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`sph/t/atom ` * :doc:`spin ` * :doc:`stress/atom ` + * :doc:`stress/cartesian ` + * :doc:`stress/cylinder ` * :doc:`stress/mop ` * :doc:`stress/mop/profile ` + * :doc:`stress/spherical ` * :doc:`stress/tally ` * :doc:`tdpd/cc/atom ` * :doc:`temp (k) ` diff --git a/doc/src/compute.rst b/doc/src/compute.rst index 9edd7e8474..6973559d16 100644 --- a/doc/src/compute.rst +++ b/doc/src/compute.rst @@ -246,7 +246,6 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`pe/tally ` - potential energy between two groups of atoms via the tally callback mechanism * :doc:`plasticity/atom ` - Peridynamic plasticity for each atom * :doc:`pressure ` - total pressure and pressure tensor -* :doc:`pressure/cylinder ` - pressure tensor in cylindrical coordinates * :doc:`pressure/uef ` - pressure tensor in the reference frame of an applied flow field * :doc:`property/atom ` - convert atom attributes to per-atom vectors/arrays * :doc:`property/chunk ` - extract various per-chunk attributes @@ -289,8 +288,11 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`sph/t/atom ` - per-atom internal temperature of Smooth-Particle Hydrodynamics atoms * :doc:`spin ` - magnetic quantities for a system of atoms having spins * :doc:`stress/atom ` - stress tensor for each atom +* :doc:`stress/cartesian ` - stress tensor in cartesian coordinates +* :doc:`stress/cylinder ` - stress tensor in cylindrical coordinates * :doc:`stress/mop ` - normal components of the local stress tensor using the method of planes * :doc:`stress/mop/profile ` - profile of the normal components of the local stress tensor using the method of planes +* :doc:`stress/spherical ` - stress tensor in spherical coordinates * :doc:`stress/tally ` - stress between two groups of atoms via the tally callback mechanism * :doc:`tdpd/cc/atom ` - per-atom chemical concentration of a specified species for each tDPD particle * :doc:`temp ` - temperature of group of atoms diff --git a/doc/src/compute_pressure_cylinder.rst b/doc/src/compute_pressure_cylinder.rst deleted file mode 100644 index 9913ef159b..0000000000 --- a/doc/src/compute_pressure_cylinder.rst +++ /dev/null @@ -1,88 +0,0 @@ -.. index:: compute pressure/cylinder - -compute pressure/cylinder command -================================= - -Syntax -"""""" - -.. parsed-literal:: - - compute ID group-ID pressure/cylinder zlo zhi Rmax bin_width - -* ID, group-ID are documented in :doc:`compute ` command -* pressure/cylinder = style name of this compute command -* zlo = minimum z-boundary for cylinder -* zhi = maximum z-boundary for cylinder -* Rmax = maximum radius to perform calculation to -* bin_width = width of radial bins to use for calculation - -Examples -"""""""" - -.. code-block:: LAMMPS - - compute 1 all pressure/cylinder -10.0 10.0 15.0 0.25 - -Description -""""""""""" - -Define a computation that calculates the pressure tensor of a system in -cylindrical coordinates, as discussed in :ref:`(Addington) `. -This is useful for systems with a single axis of rotational symmetry, -such as cylindrical micelles or carbon nanotubes. The compute splits the -system into radial, cylindrical-shell-type bins of width bin_width, -centered at x=0,y=0, and calculates the radial (P_rhorho), azimuthal -(P_phiphi), and axial (P_zz) components of the configurational pressure -tensor. The local density is also calculated for each bin, so that the -true pressure can be recovered as P_kin+P_conf=density\*k\*T+P_conf. The -output is a global array with 5 columns; one each for bin radius, local -number density, P_rhorho, P_phiphi, and P_zz. The number of rows is -governed by the values of Rmax and bin_width. Pressure tensor values are -output in pressure units. - -Output info -""""""""""" - -This compute calculates a global array with 5 columns and Rmax/bin_width -rows. The output columns are: R (distance units), number density (inverse -volume units), configurational radial pressure (pressure units), -configurational azimuthal pressure (pressure units), and configurational -axial pressure (pressure units). - -The values calculated by this compute are -"intensive". The pressure values will be in pressure -:doc:`units `. The number density values will be in -inverse volume :doc:`units `. - -Restrictions -"""""""""""" - -This compute currently calculates the pressure tensor contributions -for pair styles only (i.e. no bond, angle, dihedral, etc. contributions -and in the presence of bonded interactions, the result will be incorrect -due to exclusions for special bonds) and requires pairwise force -calculations not available for most many-body pair styles. K-space -calculations are also excluded. Note that this pressure compute outputs -the configurational terms only; the kinetic contribution is not included -and may be calculated from the number density output by P_kin=density\*k\*T. - -This compute is part of the EXTRA-COMPUTE package. It is only enabled -if LAMMPS was built with that package. See the :doc:`Build package ` page for more info. - -Related commands -"""""""""""""""" - -:doc:`compute temp `, :doc:`compute stress/atom `, -:doc:`thermo_style `, - -Default -""""""" - -none - ----------- - -.. _Addington1: - -**(Addington)** Addington, Long, Gubbins, J Chem Phys, 149, 084109 (2018). diff --git a/doc/src/compute_stress_cartesian.rst b/doc/src/compute_stress_cartesian.rst new file mode 100644 index 0000000000..9cd89fdb07 --- /dev/null +++ b/doc/src/compute_stress_cartesian.rst @@ -0,0 +1,165 @@ +.. index:: compute stress/cartesian +.. index:: compute stress/cylinder +.. index:: compute stress/spherical + + +compute stress/cartesian command +================================== + +compute stress/cylinder command +================================= + +compute stress/spherical command +================================== + +Syntax +"""""" + +.. parsed-literal:: + + compute ID group-ID style args + +* ID, group-ID are documented in :doc:`compute ` command +* style = stress/cartesian or stress/spherical or stress/cylinder +* args = argument specific to the compute style + +.. parsed-literal:: + + *stress/cartesian* args = dim bin_width + dim = x, y, or z. One or two dim/bin_width pairs may be appended + bin_width = width of the bin + *stress/cylinder* args = zlo zh Rmax bin_width keyword + zlo = minimum z-boundary for cylinder + zhi = maximum z-boundary for cylinder + Rmax = maximum radius to perform calculation to + bin_width = width of radial bins to use for calculation + keyword = ke (zero or one can be specified) + ke = yes or no + *stress/spherical* + x0, y0, z0 = origin of the spherical coordinate system + bin_width = width of spherical shells + Rmax = maximum radius of spherical shells + +Examples +"""""""" + +.. code-block:: LAMMPS + + compute 1 all stress/cartesian x 0.1 + compute 1 all stress/cartesian y 0.25 z 0.1 + compute 1 all stress/cylinder -10.0 10.0 15.0 0.25 + compute 1 all stress/cylinder -10.0 10.0 15.0 0.25 ke no + compute 1 all stress/spherical 0 0 0 0.1 10 + +Description +""""""""""" + +Compute *stress/cartesian*, compute *stress/cylinder*, and compute +*stress/spherical* define computations that calculate profiles of the +diagonal components of the local stress tensor in the specified +coordinate system. The stress tensor is split into a kinetic +contribution :math:`P^k` and a virial contribution :math:`P^v`. The sum +gives the total stress tensor :math:`P = P^k+P^v`. These computes can +for example be used to calculate the diagonal components of the local +stress tensor of interfaces with flat, cylindrical, or spherical +symmetry. These computes obeys momentum balance through fluid +interfaces. They use the Irving-Kirkwood contour, which is the straight +line between particle pairs. + +The *stress/cartesian* computes the stress profile along one or two +Cartesian coordinates, as described in :ref:`(Ikeshoji)`. The +compute *stress/cylinder* computes the stress profile along the +radial direction in cylindrical coordinates, as described in +:ref:`(Addington)`. The compute *stress/spherical* +computes the stress profile along the radial direction in spherical +coordinates, as described in :ref:`(Ikeshoji)`. + + +Output info +""""""""""" + +The output columns for *stress/cartesian* are the position of the +center of the local volume in the first and second dimensions, number +density, :math:`P^k_{xx}`, :math:`P^k_{yy}`, :math:`P^k_{zz}`, +:math:`P^v_{xx}`, :math:`P^v_{yy}`, and :math:`P^v_{zz}`. There are 8 +columns when one dimension is specified and 9 columns when two +dimensions are specified. The number of bins/rows are +(L1/bin_width1)*(L2/bin_width2), L1 and L2 are the sizes of the +simulation box in the specified dimensions, and bin_width1 and +bin_width2 are the specified bin widths. When only one dimension is +specified the number of bins/rows are L1/bin_width. + +The default output columns for *stress/cylinder* are the radius to the +center of the cylindrical shell, number density, :math:`P^k_{rr}`, +:math:`P^k_{\phi\phi}`, :math:`P^k_{zz}`, :math:`P^v_{rr}`, +:math:`P^v_{\phi\phi}`, and :math:`P^v_{zz}`. When the keyword *ke* is +set to no, the kinetic contributions are not calculated, and +consequently there are only 5 columns the radius to the center of the +cylindrical shell, number density, :math:`P^v_{rr}`, +:math:`P^v_{\phi\phi}`, :math:`P^v_{zz}`. The number of bins/rows are +Rmax/bin_width. + +The output columns for *stress/spherical* are the radius to the center +of the spherical shell, number density, :math:`P^k_{rr}`, +:math:`P^k_{\theta\theta}`, :math:`P^k_{\phi\phi}`, :math:`P^v_{rr}`, +:math:`P^v_{\theta\theta}`, and :math:`P^v_{\phi\phi}`. There are 8 +columns and the number of bins/rows are Rmax/bin_width. + +This array can be output with :doc:`fix ave/time `, + +.. code-block:: LAMMPS + + compute p all stress/cartesian x 0.1 + fix 2 all ave/time 100 1 100 c_p[*] file dump_p.out mode vector + +The values calculated by this compute are "intensive". The stress +values will be in pressure :doc:`units `. The number density +values are in inverse volume :doc:`units `. + +NOTE 1: The local stress does not include any Lennard-Jones tail +corrections to the stress added by the :doc:`pair_modify tail yes ` +command, since those are contributions to the global system pressure. + +NOTE 2: The local stress profiles generated by these computes are +similar to those obtained by the +:doc:`method-of-planes (MOP) `. +A key difference +is that compute `stress/mop/profile ` +considers particles crossing a set of planes, while +*stress/cartesian* computes averages for a set of small volumes. +More information on the similarities and differences can be found in +:ref:`(Ikeshoji)`. + +Restrictions +"""""""""""" + +These computes calculate the stress tensor contributions for pair +styles only (i.e. no bond, angle, dihedral, etc. contributions, and in +the presence of bonded interactions, the result will be incorrect due to +exclusions for special bonds) and requires pairwise force calculations +not available for most many-body pair styles. K-space calculations are +also excluded. + +These computes are part of the EXTRA-COMPUTE package. They are only +enabled if LAMMPS was built with that package. See the :doc:`Build +package ` doc page for more info. + +Related commands +"""""""""""""""" + +:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute stress/mop/profile ` + +Default +""""""" + +The keyword default for ke in style *stress/cylinder* is yes. + +---------- + +.. _Ikeshoji2: + +**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). + +.. _Addington1: + +**(Addington)** Addington, Long, Gubbins, J Chem Phys, 149, 084109 (2018). diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index bcc1a87e5f..18b9e703c5 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -68,7 +68,19 @@ configurational stress (conf), and/or total stress (total). NOTE 1: The configurational stress is computed considering all pairs of atoms where at least one atom belongs to group group-ID. NOTE 2: The local stress does not include any Lennard-Jones tail -corrections to the pressure added by the :doc:`pair_modify tail yes ` command, since those are contributions to the global system pressure. +corrections to the stress added by the :doc:`pair_modify tail yes ` +command, since those are contributions to the global system pressure. + +NOTE 3: The local stress profile generated by compute *stress/mop/profile* +is similar to that obtained by compute +:doc:`stress/cartesian `. +A key difference +is that compute *stress/mop/profile* considers particles +crossing a set of planes, +while compute *stress/cartesian* computes averages for a set of +small volumes. More information +on the similarities and differences can be found in +:ref:`(Ikeshoji)`. Output info """"""""""" @@ -87,7 +99,10 @@ and stress_dir,z. The values are in pressure :doc:`units `. -The values produced by this compute can be accessed by various :doc:`output commands `. For instance, the results can be written to a file using the :doc:`fix ave/time ` command. Please see the example in the examples/PACKAGES/mop folder. +The values produced by this compute can be accessed by various :doc:`output commands `. +For instance, the results can be written to a file using the +:doc:`fix ave/time ` command. Please see the example +in the examples/PACKAGES/mop folder. Restrictions """""""""""" @@ -107,7 +122,7 @@ intra-molecular interactions, and long range (kspace) interactions. Related commands """""""""""""""" -:doc:`compute stress/atom ` +:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute stress/cartesian `, :doc:`compute stress/cylinder `, :doc:`compute stress/spherical ` Default """"""" @@ -120,3 +135,7 @@ none **(Todd)** B. D. Todd, Denis J. Evans, and Peter J. Daivis: "Pressure tensor for inhomogeneous fluids", Phys. Rev. E 52, 1627 (1995). + +.. _Ikeshoji3: + +**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). diff --git a/doc/src/pair_mesocnt.rst b/doc/src/pair_mesocnt.rst index 78a6680b6b..8779759618 100644 --- a/doc/src/pair_mesocnt.rst +++ b/doc/src/pair_mesocnt.rst @@ -94,10 +94,6 @@ boron nitride nanotubes. Atoms belonging to different CNTs need to be assigned different molecule IDs. -A full summary of the method and LAMMPS implementation details -is expected to soon become available in Computer Physics -Communications. - ---------- Mixing, shift, table, tail correction, restart, rRESPA info diff --git a/doc/src/pair_reaxff.rst b/doc/src/pair_reaxff.rst index d0c333af4b..4640307105 100644 --- a/doc/src/pair_reaxff.rst +++ b/doc/src/pair_reaxff.rst @@ -19,13 +19,14 @@ Syntax .. parsed-literal:: - keyword = *checkqeq* or *lgvdw* or *safezone* or *mincap* or *minhbonds* or *list/blocking* + keyword = *checkqeq* or *lgvdw* or *safezone* or *mincap* or *minhbonds* or *tabulate* or *list/blocking* *checkqeq* value = *yes* or *no* = whether or not to require qeq/reaxff or acks2/reaxff fix *enobonds* value = *yes* or *no* = whether or not to tally energy of atoms with no bonds *lgvdw* value = *yes* or *no* = whether or not to use a low gradient vdW correction *safezone* = factor used for array allocation *mincap* = minimum size for array allocation *minhbonds* = minimum size use for storing hydrogen bonds + *tabulate* value = size of interpolation table for Lennard-Jones and Coulomb interactions *list/blocking* value = *yes* or *no* = whether or not to use "blocking" scheme for bond list build Examples @@ -159,6 +160,13 @@ the Kokkos version, which instead uses a more robust memory allocation scheme that checks if the sizes of the arrays have been exceeded and automatically allocates more memory. +The keyword *tabulate* controls the size of interpolation table for +Lennard-Jones and Coulomb interactions. Tabulation may also be set in the +control file (see below). If tabulation is set in both the input script and the +control file, the value in the control file will be ignored. A size of 10000 is +typically used for the interpolation table. A value of 0 means no tabulation +will be used. + The keyword *list/blocking* is only supported by the Kokkos version of ReaxFF and ignored otherwise. Setting the value to *yes* enables the "blocking" scheme (dynamically building interaction lists) for the @@ -369,8 +377,9 @@ Related commands Default """"""" -The keyword defaults are checkqeq = yes, enobonds = yes, lgvdw = no, -safezone = 1.2, mincap = 50, minhbonds = 25, list/blocking = yes on CPU, no on GPU. +The keyword defaults are checkqeq = yes, enobonds = yes, lgvdw = no, safezone = +1.2, mincap = 50, minhbonds = 25, tabulate = 0, list/blocking = yes on CPU, no +on GPU. ---------- diff --git a/doc/utils/check-styles.py b/doc/utils/check-styles.py index 4294f5a5bc..9633c1080f 100755 --- a/doc/utils/check-styles.py +++ b/doc/utils/check-styles.py @@ -256,12 +256,13 @@ print("Total number of style index entries:", total_index) skip_fix = ('python', 'NEIGH_HISTORY/omp','acks2/reax','qeq/reax','reax/c/bonds','reax/c/species') skip_pair = ('meam/c','lj/sf','reax/c') +skip_compute = ('pressure/cylinder') counter = 0 counter += check_style('Commands_all.rst', doc_dir, ":doc:`(.+) <.+>`",command,'Command',suffix=True) -counter += check_style('Commands_compute.rst', doc_dir, ":doc:`(.+) `",compute,'Compute',suffix=True) -counter += check_style('compute.rst', doc_dir, ":doc:`(.+) ` -",compute,'Compute',suffix=False) +counter += check_style('Commands_compute.rst', doc_dir, ":doc:`(.+) `",compute,'Compute',skip=skip_compute,suffix=True) +counter += check_style('compute.rst', doc_dir, ":doc:`(.+) ` -",compute,'Compute',skip=skip_compute,suffix=False) counter += check_style('Commands_fix.rst', doc_dir, ":doc:`(.+) `",fix,'Fix',skip=skip_fix,suffix=True) counter += check_style('fix.rst', doc_dir, ":doc:`(.+) ` -",fix,'Fix',skip=skip_fix,suffix=False) counter += check_style('Commands_pair.rst', doc_dir, ":doc:`(.+) `",pair,'Pair',skip=skip_pair,suffix=True) @@ -281,7 +282,7 @@ if counter: counter = 0 -counter += check_style_index("compute", compute, index["compute"]) +counter += check_style_index("compute", compute, index["compute"], skip=['pressure/cylinder']) counter += check_style_index("fix", fix, index["fix"], skip=['python','acks2/reax','qeq/reax','reax/c/bonds','reax/c/species']) counter += check_style_index("angle_style", angle, index["angle_style"]) counter += check_style_index("bond_style", bond, index["bond_style"]) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 31e03140f1..e033b9088f 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1112,6 +1112,7 @@ funcs functionalities functionals funroll +Furuholt fx fy fz @@ -1594,6 +1595,7 @@ Ki Kikugawa kim kinetostats +Kirkwood kJ kk Klahn diff --git a/examples/PACKAGES/stressprofile/in.cylinder b/examples/PACKAGES/stressprofile/in.cylinder new file mode 100644 index 0000000000..48e35b1959 --- /dev/null +++ b/examples/PACKAGES/stressprofile/in.cylinder @@ -0,0 +1,40 @@ +# compute stress/cylinder for a cylindrical liquid-vapor interface + +units lj +atom_style atomic + +lattice fcc 0.8442 +region box block -10 10 -10 10 0 10 +region liquid cylinder z 0 0 5 0 10 +create_box 1 box +create_atoms 1 region liquid +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.65 0.65 0.2 + +#dump id all atom 50 dump.cylinder + +#dump 2 all image 25 image.*.jpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter 0 0 NULL units lattice +compute p all stress/cylinder 0 10 15 0.25 +fix 3 all ave/time 100 1 100 c_p[*] file cylinder.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p[15][3] c_p[15][4] c_p[15][5] + +run 1000 diff --git a/examples/PACKAGES/stressprofile/in.flat b/examples/PACKAGES/stressprofile/in.flat new file mode 100644 index 0000000000..8b484a423f --- /dev/null +++ b/examples/PACKAGES/stressprofile/in.flat @@ -0,0 +1,41 @@ +# compute stress/cartesian for a flat liquid-vapor interface + +units lj +atom_style atomic +processors * * 1 + +lattice fcc 0.8442 +region box block 0 10 0 10 0 30 +region liquid block 0 10 0 10 10 20 +create_box 1 box +create_atoms 1 region liquid +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.7 0.7 0.2 + +#dump id all atom 50 dump.flat + +#dump 2 all image 25 image.*.jpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter NULL NULL 15 units lattice +compute p1 all stress/cartesian z 0.5 +fix 3 all ave/time 100 1 100 c_p1[*] file flat.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p1[50][3] c_p1[50][4] c_p1[50][5] c_p1[50][6] c_p1[50][7] c_p1[50][8] + +run 1000 diff --git a/examples/PACKAGES/stressprofile/in.sphere b/examples/PACKAGES/stressprofile/in.sphere new file mode 100644 index 0000000000..42084f018b --- /dev/null +++ b/examples/PACKAGES/stressprofile/in.sphere @@ -0,0 +1,40 @@ +# compute stress/spherical for a spherical droplet + +units lj +atom_style atomic + +lattice fcc 0.8442 +region box block -10 10 -10 10 -10 10 +region liquid sphere 0 0 0 5 +create_box 1 box +create_atoms 1 region liquid +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.65 0.65 0.2 + +#dump id all atom 50 dump.sphere + +#dump 2 all image 25 image.*.jpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter 0 0 0 units lattice +compute p all stress/spherical 0 0 0 0.25 15 +fix 3 all ave/time 100 1 100 c_p[*] file sphere.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p[15][3] c_p[15][4] c_p[15][5] c_p[15][6] c_p[15][7] c_p[15][8] + +run 1000 diff --git a/examples/PACKAGES/stressprofile/log.6Mar2022.cylinder.g++.1 b/examples/PACKAGES/stressprofile/log.6Mar2022.cylinder.g++.1 new file mode 100644 index 0000000000..f1991ddbfc --- /dev/null +++ b/examples/PACKAGES/stressprofile/log.6Mar2022.cylinder.g++.1 @@ -0,0 +1,131 @@ +LAMMPS (17 Feb 2022) +# compute stress/cylinder for a cylindrical liquid-vapor interface + +units lj +atom_style atomic + +lattice fcc 0.8442 +Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962 +region box block -10 10 -10 10 0 10 +region liquid cylinder z 0 0 5 0 10 +create_box 1 box +Created orthogonal box = (-16.795962 -16.795962 0) to (16.795962 16.795962 16.795962) + 1 by 1 by 1 MPI processor grid +create_atoms 1 region liquid +Created 3170 atoms + using lattice units in orthogonal box = (-16.795962 -16.795962 0) to (16.795962 16.795962 16.795962) + create_atoms CPU = 0.001 seconds +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.65 0.65 0.2 + +#dump id all atom 50 dump.cylinder + +#dump 2 all image 25 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter 0 0 NULL units lattice +compute p all stress/cylinder 0 10 15 0.25 +fix 3 all ave/time 100 1 100 c_p[*] file cylinder.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p[15][3] c_p[15][4] c_p[15][5] + +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- compute stress/cylinder: + +@Article{Addington, + author = {C. K. Addington, Y. Long, K. E. Gubbins}, + title = {The pressure in interfaces having cylindrical geometry}, + journal = {J.~Chem.~Phys.}, + year = 2018, + volume = 149, + pages = {084109} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 20 steps, delay 0 steps, check no + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 24 24 12 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute stress/cylinder, occasional, copy from (1) + attributes: half, newton on + pair build: copy + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 3.878 | 3.878 | 3.878 Mbytes +Step Temp E_pair E_mol TotEng Press c_p[15][3] c_p[15][4] c_p[15][5] + 0 0.65 -6.2219331 0 -5.2472407 -1.0193897 0.32064195 0.17340743 0.25100229 + 50 0.40121817 -5.7782233 0 -5.1765859 -0.33373915 0.25363113 0.28726307 0.31257228 + 100 0.56963398 -5.8789288 0 -5.0247474 -0.16859926 0.44360668 0.51390018 0.49962451 + 150 0.68424117 -5.9319873 0 -4.9059493 0.062850222 0.79698857 0.82006332 0.54174427 + 200 0.68608162 -5.9987099 0 -4.9699121 0.21439145 0.5262416 0.35324632 0.36677402 + 250 0.63422098 -6.047104 0 -5.0960726 0.30980602 0.31990528 0.51794384 0.55439151 + 300 0.64028254 -6.107331 0 -5.1472102 0.32133372 0.25974932 0.23423969 0.38800678 + 350 0.64906334 -6.1101542 0 -5.1368663 0.22288375 0.40593338 0.33184138 0.38346588 + 400 0.61848053 -6.0090821 0 -5.081654 0.053336092 0.32361049 0.23590707 0.30278183 + 450 0.60600519 -5.8710484 0 -4.9623273 -0.085701075 0.25062204 0.19408866 0.31948875 + 500 0.60383908 -5.7254198 0 -4.8199469 -0.15560848 0.4914663 0.20423135 0.31502277 + 550 0.60342483 -5.582958 0 -4.6781063 -0.18389998 0.81893511 0.48595334 0.52329443 + 600 0.61415824 -5.4571678 0 -4.5362211 -0.18398358 0.6604736 0.49706653 0.69658417 + 650 0.61997958 -5.3337392 0 -4.4040632 -0.13933776 0.51589832 0.70322669 0.59111363 + 700 0.65521411 -5.2724025 0 -4.2898914 -0.13977767 0.69933963 0.5964547 0.59421757 + 750 0.6525752 -5.18782 0 -4.2092659 -0.087418448 0.63261975 0.49555785 0.71379101 + 800 0.6711302 -5.1682283 0 -4.1618506 -0.080863195 0.66609099 0.56779202 0.64594057 + 850 0.64374266 -5.1290236 0 -4.1637142 -0.012480639 0.46355003 0.63364111 0.64701994 + 900 0.64904492 -5.1463816 0 -4.1731214 -0.015999133 0.50996272 0.40697988 0.69606954 + 950 0.64624835 -5.1529515 0 -4.1838847 0.0037696411 0.46323559 0.64562517 0.6484849 + 1000 0.64602274 -5.1525985 0 -4.1838701 0.022248112 0.62372474 0.46065491 0.45844619 +Loop time of 4.13231 on 1 procs for 1000 steps with 3170 atoms + +Performance: 104542.050 tau/day, 241.995 timesteps/s +99.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 | 1.1551 | 1.1551 | 1.1551 | 0.0 | 27.95 +Neigh | 0.17391 | 0.17391 | 0.17391 | 0.0 | 4.21 +Comm | 0.0064512 | 0.0064512 | 0.0064512 | 0.0 | 0.16 +Output | 1.7974 | 1.7974 | 1.7974 | 0.0 | 43.50 +Modify | 0.99617 | 0.99617 | 0.99617 | 0.0 | 24.11 +Other | | 0.003226 | | | 0.08 + +Nlocal: 3170 ave 3170 max 3170 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1074 ave 1074 max 1074 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 101768 ave 101768 max 101768 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 101768 +Ave neighs/atom = 32.10347 +Neighbor list builds = 50 +Dangerous builds not checked +Total wall time: 0:00:04 diff --git a/examples/PACKAGES/stressprofile/log.6Mar2022.cylinder.g++.4 b/examples/PACKAGES/stressprofile/log.6Mar2022.cylinder.g++.4 new file mode 100644 index 0000000000..450d6698de --- /dev/null +++ b/examples/PACKAGES/stressprofile/log.6Mar2022.cylinder.g++.4 @@ -0,0 +1,131 @@ +LAMMPS (17 Feb 2022) +# compute stress/cylinder for a cylindrical liquid-vapor interface + +units lj +atom_style atomic + +lattice fcc 0.8442 +Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962 +region box block -10 10 -10 10 0 10 +region liquid cylinder z 0 0 5 0 10 +create_box 1 box +Created orthogonal box = (-16.795962 -16.795962 0) to (16.795962 16.795962 16.795962) + 2 by 2 by 1 MPI processor grid +create_atoms 1 region liquid +Created 3170 atoms + using lattice units in orthogonal box = (-16.795962 -16.795962 0) to (16.795962 16.795962 16.795962) + create_atoms CPU = 0.000 seconds +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.65 0.65 0.2 + +#dump id all atom 50 dump.cylinder + +#dump 2 all image 25 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter 0 0 NULL units lattice +compute p all stress/cylinder 0 10 15 0.25 +fix 3 all ave/time 100 1 100 c_p[*] file cylinder.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p[15][3] c_p[15][4] c_p[15][5] + +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- compute stress/cylinder: + +@Article{Addington, + author = {C. K. Addington, Y. Long, K. E. Gubbins}, + title = {The pressure in interfaces having cylindrical geometry}, + journal = {J.~Chem.~Phys.}, + year = 2018, + volume = 149, + pages = {084109} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 20 steps, delay 0 steps, check no + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 24 24 12 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute stress/cylinder, occasional, copy from (1) + attributes: half, newton on + pair build: copy + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 3.023 | 3.033 | 3.043 Mbytes +Step Temp E_pair E_mol TotEng Press c_p[15][3] c_p[15][4] c_p[15][5] + 0 0.65 -6.2219331 0 -5.2472407 -1.0193897 0.32064195 0.17340743 0.25100229 + 50 0.40121817 -5.7782233 0 -5.1765859 -0.33373915 0.25363113 0.28726307 0.31257228 + 100 0.56963398 -5.8789288 0 -5.0247474 -0.16859926 0.44360668 0.51390018 0.49962451 + 150 0.68424117 -5.9319873 0 -4.9059493 0.062850222 0.79698857 0.82006332 0.54174427 + 200 0.68608162 -5.9987099 0 -4.9699121 0.21439145 0.5262416 0.35324632 0.36677402 + 250 0.63422098 -6.047104 0 -5.0960726 0.30980602 0.31990528 0.51794384 0.55439151 + 300 0.64028254 -6.107331 0 -5.1472102 0.32133372 0.25974932 0.23423969 0.38800678 + 350 0.64906334 -6.1101542 0 -5.1368663 0.22288375 0.40593338 0.33184138 0.38346588 + 400 0.61848053 -6.0090821 0 -5.081654 0.053336092 0.32361049 0.23590707 0.30278183 + 450 0.60600519 -5.8710484 0 -4.9623273 -0.085701075 0.25062204 0.19408866 0.31948875 + 500 0.60383908 -5.7254198 0 -4.8199469 -0.15560848 0.4914663 0.20423135 0.31502277 + 550 0.60342483 -5.582958 0 -4.6781063 -0.18389998 0.81893511 0.48595334 0.52329443 + 600 0.61415824 -5.4571678 0 -4.5362211 -0.18398358 0.6604736 0.49706653 0.69658417 + 650 0.61997958 -5.3337392 0 -4.4040632 -0.13933776 0.51589832 0.70322669 0.59111363 + 700 0.65521411 -5.2724025 0 -4.2898914 -0.13977767 0.69933963 0.5964547 0.59421757 + 750 0.6525752 -5.18782 0 -4.2092659 -0.087418448 0.63261975 0.49555785 0.71379101 + 800 0.6711302 -5.1682283 0 -4.1618506 -0.080863195 0.66609099 0.56779202 0.64594057 + 850 0.64374266 -5.1290236 0 -4.1637142 -0.012480639 0.46355003 0.63364111 0.64701994 + 900 0.64904492 -5.1463816 0 -4.1731214 -0.015999133 0.50996272 0.40697988 0.69606954 + 950 0.64624835 -5.1529515 0 -4.1838847 0.0037696411 0.46323559 0.64562517 0.6484849 + 1000 0.64602274 -5.1525985 0 -4.1838701 0.022248112 0.62372474 0.46065491 0.45844619 +Loop time of 1.33052 on 4 procs for 1000 steps with 3170 atoms + +Performance: 324683.906 tau/day, 751.583 timesteps/s +98.5% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.35212 | 0.36191 | 0.36751 | 1.0 | 27.20 +Neigh | 0.05132 | 0.052345 | 0.053278 | 0.3 | 3.93 +Comm | 0.060839 | 0.06792 | 0.079544 | 2.9 | 5.10 +Output | 0.54 | 0.54103 | 0.54137 | 0.1 | 40.66 +Modify | 0.30402 | 0.30522 | 0.30726 | 0.2 | 22.94 +Other | | 0.002104 | | | 0.16 + +Nlocal: 792.5 ave 794 max 791 min +Histogram: 1 0 0 1 0 0 1 0 0 1 +Nghost: 1292 ave 1302 max 1284 min +Histogram: 1 0 1 0 0 1 0 0 0 1 +Neighs: 25442 ave 26560 max 24446 min +Histogram: 1 0 0 1 0 1 0 0 0 1 + +Total # of neighbors = 101768 +Ave neighs/atom = 32.10347 +Neighbor list builds = 50 +Dangerous builds not checked +Total wall time: 0:00:01 diff --git a/examples/PACKAGES/stressprofile/log.6Mar2022.flat.g++.1 b/examples/PACKAGES/stressprofile/log.6Mar2022.flat.g++.1 new file mode 100644 index 0000000000..452b273dd3 --- /dev/null +++ b/examples/PACKAGES/stressprofile/log.6Mar2022.flat.g++.1 @@ -0,0 +1,135 @@ +LAMMPS (17 Feb 2022) +# compute stress/cartesian for a flat liquid-vapor interface + +units lj +atom_style atomic +processors * * 1 + +lattice fcc 0.8442 +Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962 +region box block 0 10 0 10 0 30 +region liquid block 0 10 0 10 10 20 +create_box 1 box +Created orthogonal box = (0 0 0) to (16.795962 16.795962 50.387886) + 1 by 1 by 1 MPI processor grid +create_atoms 1 region liquid +Created 4200 atoms + using lattice units in orthogonal box = (0 0 0) to (16.795962 16.795962 50.387886) + create_atoms CPU = 0.001 seconds +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.7 0.7 0.2 + +#dump id all atom 50 dump.flat + +#dump 2 all image 25 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter NULL NULL 15 units lattice +compute p1 all stress/cartesian z 0.5 +Adjusting first bin width for compute stress/cartesian from 0.500000 to 0.503879 +fix 3 all ave/time 100 1 100 c_p1[*] file flat.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p1[50][3] c_p1[50][4] c_p1[50][5] c_p1[50][6] c_p1[50][7] c_p1[50][8] + +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- compute stress/cartesian: + +@article{galteland2021nanothermodynamic, +title={Nanothermodynamic description and molecular simulation of a single-phase fluid in a slit pore}, +author={Galteland, Olav and Bedeaux, Dick and Kjelstrup, Signe}, +journal={Nanomaterials}, +volume={11}, +number={1}, +pages={165}, +year={2021}, +publisher={Multidisciplinary Digital Publishing Institute} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 20 steps, delay 0 steps, check no + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 12 12 36 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute stress/cartesian, occasional, copy from (1) + attributes: half, newton on + pair build: copy + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 3.943 | 3.943 | 3.943 Mbytes +Step Temp E_pair E_mol TotEng Press c_p1[50][3] c_p1[50][4] c_p1[50][5] c_p1[50][6] c_p1[50][7] c_p1[50][8] + 0 0.65 -6.5342767 0 -5.5595088 -1.9070205 0 0 0 -3.2273011 -3.2273011 -6.2353173 + 50 0.36842234 -6.0304191 0 -5.4779172 -0.76896135 0.17498049 0.24679132 0.30689944 -2.7027121 -3.7561009 -1.9919263 + 100 0.50896152 -6.0786202 0 -5.3153597 -0.58839893 0.23650081 0.36888111 0.20899869 0.022887179 -0.64485123 -2.1340762 + 150 0.63567071 -6.0832159 0 -5.1299368 -0.29587266 0.33559137 0.37138538 0.35269743 -0.68803817 -0.68430121 -1.7978609 + 200 0.72324528 -6.0689996 0 -4.98439 -0.020342078 0.34858492 0.37486254 0.35223764 -0.36879601 0.20311125 -1.0543778 + 250 0.74387008 -6.1188743 0 -5.0033349 0.11337395 0.55467125 0.43963204 0.5365495 1.5554907 1.4490947 0.71944827 + 300 0.69112666 -6.1838992 0 -5.1474561 0.18290797 0.7992109 0.68033596 0.58700814 3.5089443 4.2857349 3.2581159 + 350 0.67772633 -6.2400592 0 -5.2237117 0.27698807 0.67830305 0.6761273 0.49704933 4.5557554 4.9263741 3.1723378 + 400 0.70714238 -6.2783031 0 -5.2178421 0.41150934 0.49425756 0.60546702 0.7065831 4.2198909 3.9825086 2.8430036 + 450 0.71843478 -6.2870874 0 -5.2096918 0.57099811 0.46302073 0.39182703 0.63984313 3.4046591 4.6556487 1.9030295 + 500 0.69813385 -6.3041653 0 -5.2572139 0.53883987 0.68729617 0.59378012 0.48664837 7.3244236 5.6670237 2.596186 + 550 0.67043069 -6.3035289 0 -5.2981223 0.36370002 0.60222672 0.48812986 0.43026583 3.4315746 3.580443 1.541178 + 600 0.68196102 -6.26442 0 -5.241722 0.22122892 0.62489919 0.52111415 0.54877849 2.8361857 2.3873253 1.2353165 + 650 0.69413189 -6.1759937 0 -5.1350438 0.12782621 0.53663901 0.4268154 0.48481915 2.55077 2.4568322 0.98505597 + 700 0.70034968 -6.1028735 0 -5.0525991 0.029208853 0.40182056 0.43835043 0.4079067 2.639108 2.0850376 0.84200793 + 750 0.70266272 -6.036839 0 -4.9830959 -0.088703619 0.45987327 0.44507175 0.51137827 0.80703415 0.9388271 -0.94688133 + 800 0.68551399 -5.9410263 0 -4.9130002 -0.18134075 0.41401386 0.52006295 0.48363173 -0.51532128 -0.59039802 -1.6540483 + 850 0.6866836 -5.8390431 0 -4.8092629 -0.27593375 0.44348212 0.4806576 0.51909045 -0.32773941 -0.19125952 -1.746798 + 900 0.67608249 -5.711593 0 -4.6977107 -0.28650991 0.41295263 0.58244529 0.51061419 1.1176204 0.85808642 -0.50262868 + 950 0.68080988 -5.6043546 0 -4.5833829 -0.29765481 0.50435084 0.49611677 0.5263358 -1.0396644 -0.85737705 -1.3764034 + 1000 0.68792271 -5.5015077 0 -4.4698694 -0.27955533 0.63890467 0.66446292 0.51353613 -0.39241484 -0.64122487 -0.78501452 +Loop time of 2.06097 on 1 procs for 1000 steps with 4200 atoms + +Performance: 209609.664 tau/day, 485.208 timesteps/s +99.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 | 1.4899 | 1.4899 | 1.4899 | 0.0 | 72.29 +Neigh | 0.22785 | 0.22785 | 0.22785 | 0.0 | 11.06 +Comm | 0.017142 | 0.017142 | 0.017142 | 0.0 | 0.83 +Output | 0.15511 | 0.15511 | 0.15511 | 0.0 | 7.53 +Modify | 0.16608 | 0.16608 | 0.16608 | 0.0 | 8.06 +Other | | 0.004898 | | | 0.24 + +Nlocal: 4200 ave 4200 max 4200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 3393 ave 3393 max 3393 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 144737 ave 144737 max 144737 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 144737 +Ave neighs/atom = 34.46119 +Neighbor list builds = 50 +Dangerous builds not checked +Total wall time: 0:00:02 diff --git a/examples/PACKAGES/stressprofile/log.6Mar2022.flat.g++.4 b/examples/PACKAGES/stressprofile/log.6Mar2022.flat.g++.4 new file mode 100644 index 0000000000..2b1c8b2b9d --- /dev/null +++ b/examples/PACKAGES/stressprofile/log.6Mar2022.flat.g++.4 @@ -0,0 +1,135 @@ +LAMMPS (17 Feb 2022) +# compute stress/cartesian for a flat liquid-vapor interface + +units lj +atom_style atomic +processors * * 1 + +lattice fcc 0.8442 +Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962 +region box block 0 10 0 10 0 30 +region liquid block 0 10 0 10 10 20 +create_box 1 box +Created orthogonal box = (0 0 0) to (16.795962 16.795962 50.387886) + 2 by 2 by 1 MPI processor grid +create_atoms 1 region liquid +Created 4200 atoms + using lattice units in orthogonal box = (0 0 0) to (16.795962 16.795962 50.387886) + create_atoms CPU = 0.000 seconds +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.7 0.7 0.2 + +#dump id all atom 50 dump.flat + +#dump 2 all image 25 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter NULL NULL 15 units lattice +compute p1 all stress/cartesian z 0.5 +Adjusting first bin width for compute stress/cartesian from 0.500000 to 0.503879 +fix 3 all ave/time 100 1 100 c_p1[*] file flat.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p1[50][3] c_p1[50][4] c_p1[50][5] c_p1[50][6] c_p1[50][7] c_p1[50][8] + +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- compute stress/cartesian: + +@article{galteland2021nanothermodynamic, +title={Nanothermodynamic description and molecular simulation of a single-phase fluid in a slit pore}, +author={Galteland, Olav and Bedeaux, Dick and Kjelstrup, Signe}, +journal={Nanomaterials}, +volume={11}, +number={1}, +pages={165}, +year={2021}, +publisher={Multidisciplinary Digital Publishing Institute} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 20 steps, delay 0 steps, check no + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 12 12 36 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute stress/cartesian, occasional, copy from (1) + attributes: half, newton on + pair build: copy + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 3.083 | 3.083 | 3.083 Mbytes +Step Temp E_pair E_mol TotEng Press c_p1[50][3] c_p1[50][4] c_p1[50][5] c_p1[50][6] c_p1[50][7] c_p1[50][8] + 0 0.65 -6.5342767 0 -5.5595088 -1.9070205 0 0 0 -3.2273011 -3.2273011 -6.2353173 + 50 0.36842234 -6.0304191 0 -5.4779172 -0.76896135 0.17498049 0.24679132 0.30689944 -2.7166373 -3.7637224 -2.0127226 + 100 0.50896152 -6.0786202 0 -5.3153597 -0.58839893 0.23650081 0.36888111 0.20899869 0.075982565 -0.67149414 -2.0813638 + 150 0.63567071 -6.0832159 0 -5.1299368 -0.29587266 0.33559137 0.37138538 0.35269743 -0.594738 -0.64300667 -1.8205987 + 200 0.72324528 -6.0689996 0 -4.98439 -0.020342078 0.34858492 0.37486254 0.35223764 -0.41021281 0.2947434 -1.1236003 + 250 0.74387008 -6.1188743 0 -5.0033349 0.11337395 0.55467125 0.43963204 0.5365495 1.6429753 1.5080502 0.71159566 + 300 0.69112666 -6.1838992 0 -5.1474561 0.18290797 0.7992109 0.68033596 0.58700814 3.7385773 4.4487825 3.2496799 + 350 0.67772633 -6.2400592 0 -5.2237117 0.27698807 0.67830305 0.6761273 0.49704933 4.417328 4.2774375 2.9659443 + 400 0.70714238 -6.2783031 0 -5.2178421 0.41150934 0.49425756 0.60546702 0.7065831 4.0688803 3.6955596 2.4302757 + 450 0.71843478 -6.2870874 0 -5.2096918 0.57099811 0.46302073 0.39182703 0.63984313 3.2262414 4.6575131 1.7427299 + 500 0.69813385 -6.3041653 0 -5.2572139 0.53883987 0.68729617 0.59378012 0.48664837 7.3183445 5.4826447 2.4408851 + 550 0.67043069 -6.3035289 0 -5.2981223 0.36370002 0.60222672 0.48812986 0.43026583 3.150271 3.4293302 1.3715771 + 600 0.68196102 -6.26442 0 -5.241722 0.22122892 0.62489919 0.52111415 0.54877849 2.7015405 2.3052992 1.1698065 + 650 0.69413189 -6.1759937 0 -5.1350438 0.12782621 0.53663901 0.4268154 0.48481915 2.5493901 2.4516896 0.94798771 + 700 0.70034968 -6.1028735 0 -5.0525991 0.029208853 0.40182056 0.43835043 0.4079067 2.3705988 1.8595619 0.58948475 + 750 0.70266272 -6.036839 0 -4.9830959 -0.088703619 0.45987327 0.44507175 0.51137827 0.81818861 0.92355985 -0.96989084 + 800 0.68551399 -5.9410263 0 -4.9130002 -0.18134075 0.41401386 0.52006295 0.48363173 -0.5096947 -0.71814258 -1.7601911 + 850 0.6866836 -5.8390431 0 -4.8092629 -0.27593375 0.44348212 0.4806576 0.51909045 -0.35276239 -0.19119571 -1.8079633 + 900 0.67608249 -5.711593 0 -4.6977107 -0.28650991 0.41295263 0.58244529 0.51061419 1.0812494 0.85110914 -0.52125789 + 950 0.68080988 -5.6043546 0 -4.5833829 -0.29765481 0.50435084 0.49611677 0.5263358 -1.1084255 -0.87093225 -1.4488231 + 1000 0.68792271 -5.5015077 0 -4.4698694 -0.27955533 0.63890467 0.66446292 0.51353613 -0.39754859 -0.7422202 -0.84836654 +Loop time of 0.67272 on 4 procs for 1000 steps with 4200 atoms + +Performance: 642168.946 tau/day, 1486.502 timesteps/s +99.2% 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.42649 | 0.43416 | 0.44515 | 1.2 | 64.54 +Neigh | 0.063766 | 0.064411 | 0.065468 | 0.3 | 9.57 +Comm | 0.053491 | 0.065409 | 0.07366 | 3.2 | 9.72 +Output | 0.050856 | 0.052036 | 0.052435 | 0.3 | 7.74 +Modify | 0.054128 | 0.054608 | 0.055873 | 0.3 | 8.12 +Other | | 0.002091 | | | 0.31 + +Nlocal: 1050 ave 1071 max 1026 min +Histogram: 1 0 0 0 0 2 0 0 0 1 +Nghost: 1952.75 ave 1977 max 1936 min +Histogram: 1 0 1 0 1 0 0 0 0 1 +Neighs: 36184.2 ave 37407 max 34670 min +Histogram: 1 0 0 0 1 0 0 1 0 1 + +Total # of neighbors = 144737 +Ave neighs/atom = 34.46119 +Neighbor list builds = 50 +Dangerous builds not checked +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/stressprofile/log.6Mar2022.sphere.g++.1 b/examples/PACKAGES/stressprofile/log.6Mar2022.sphere.g++.1 new file mode 100644 index 0000000000..7c93a95c97 --- /dev/null +++ b/examples/PACKAGES/stressprofile/log.6Mar2022.sphere.g++.1 @@ -0,0 +1,130 @@ +LAMMPS (17 Feb 2022) +# compute stress/spherical for a spherical droplet + +units lj +atom_style atomic + +lattice fcc 0.8442 +Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962 +region box block -10 10 -10 10 -10 10 +region liquid sphere 0 0 0 5 +create_box 1 box +Created orthogonal box = (-16.795962 -16.795962 -16.795962) to (16.795962 16.795962 16.795962) + 1 by 1 by 1 MPI processor grid +create_atoms 1 region liquid +Created 2123 atoms + using lattice units in orthogonal box = (-16.795962 -16.795962 -16.795962) to (16.795962 16.795962 16.795962) + create_atoms CPU = 0.001 seconds +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.65 0.65 0.2 + +#dump id all atom 50 dump.sphere + +#dump 2 all image 25 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter 0 0 0 units lattice +compute p all stress/spherical 0 0 0 0.25 15 +Adjusting bin width for compute stress/spherical from 0.250000 to 0.245902 +fix 3 all ave/time 100 1 100 c_p[*] file sphere.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p[15][3] c_p[15][4] c_p[15][5] c_p[15][6] c_p[15][7] c_p[15][8] + +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- compute stress/spherical: + +@article{galteland2022defining, +title={Defining the pressures of a fluid in a nanoporous, heterogeneous medium}, +author={Galteland, Olav and Rauter, Michael T and Varughese, Kevin K and Bedeaux, Dick and Kjelstrup, Signe}, +journal={arXiv preprint arXiv:2201.13060}, +year={2022} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 20 steps, delay 0 steps, check no + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 24 24 24 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute stress/spherical, occasional, copy from (1) + attributes: half, newton on + pair build: copy + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 3.11 | 3.11 | 3.11 Mbytes +Step Temp E_pair E_mol TotEng Press c_p[15][3] c_p[15][4] c_p[15][5] c_p[15][6] c_p[15][7] c_p[15][8] + 0 0.65 -5.982005 0 -5.0074642 -0.32476388 0.35627939 0.62462251 0.46815062 -6.0757313 -6.2674721 -6.2664951 + 50 0.42414771 -5.5700167 0 -4.9340948 -0.074492286 0.28886433 0.24978381 0.44948344 -3.0743795 -3.1577945 -3.3227869 + 100 0.64021145 -5.7405134 0 -4.7806486 -0.0054535408 0.66078235 0.50006981 0.71100403 -1.4906387 -2.2744728 -2.4525275 + 150 0.72663247 -5.8366691 0 -4.7472338 0.089984367 0.67171939 0.88397719 0.68237586 1.7071253 0.70667671 0.24254734 + 200 0.63460122 -5.8577473 0 -4.9062939 0.14140872 0.42462947 0.59385606 0.7268978 3.72768 5.4212679 5.6873694 + 250 0.62199115 -5.9027866 0 -4.9702393 0.13328919 0.59870532 0.36146182 0.42120197 4.6777028 2.6837762 2.5065016 + 300 0.62406364 -5.8889104 0 -4.9532559 0.063550326 0.52789691 0.2680398 0.54676177 0.46537388 -0.050263067 0.083348197 + 350 0.6028994 -5.7552274 0 -4.8513043 -0.027499706 0.50997812 0.70982549 0.6490879 -1.0217051 -2.1273075 -1.9062299 + 400 0.56811588 -5.5416058 0 -4.6898334 -0.061577561 0.47083533 0.77746521 0.675965 -1.3048699 -2.2462223 -2.1474791 + 450 0.54946762 -5.3409786 0 -4.5171654 -0.060007836 0.79992593 0.45761929 0.41283856 -1.6618299 -2.8617998 -2.6660581 + 500 0.57962648 -5.2096808 0 -4.3406506 -0.052541306 0.58252285 0.62111149 0.53587504 -2.0015685 -3.0227113 -2.7113064 + 550 0.61149882 -5.0920642 0 -4.175248 -0.03806361 0.69036525 0.44434221 0.43153208 -1.919538 -2.3974949 -2.3053297 + 600 0.63683327 -4.9975996 0 -4.0427996 -0.016868781 0.61515828 0.47182625 0.4742184 -1.2064203 -1.1407252 -0.58758361 + 650 0.67007543 -4.9684574 0 -3.9638177 -0.00087204466 0.78120956 1.0550498 0.80318482 0.51859121 -0.46675133 -0.49805387 + 700 0.65648313 -4.9612522 0 -3.9769913 0.012954904 0.94001121 0.61816695 0.54104923 -0.95635736 -1.4524645 -1.0781047 + 750 0.62636818 -4.9944273 0 -4.0553176 0.01206773 0.75957119 0.70733827 0.60927279 -0.034744141 -1.0763778 -1.160248 + 800 0.64474901 -5.0498682 0 -4.0832003 -0.0022579262 0.63509307 0.56543999 0.51633686 -0.84957679 -0.13098346 -0.76445249 + 850 0.64765539 -5.0405969 0 -4.0695714 0.0061653637 0.56204713 0.59190191 0.44560131 -0.45171595 -0.58981086 0.10218425 + 900 0.65308258 -5.0187376 0 -4.0395752 0.016798783 0.50392257 0.49473611 0.46727165 -0.096394732 -1.3622008 -1.0134429 + 950 0.65225966 -4.9974305 0 -4.0195019 0.0195366 0.47764992 0.56974826 0.58927977 0.93251392 -0.29722045 0.17614353 + 1000 0.6407875 -4.9770134 0 -4.0162849 0.0064419231 0.87635667 0.51303644 0.45437033 0.14319333 0.10005421 0.29188404 +Loop time of 1.69288 on 1 procs for 1000 steps with 2123 atoms + +Performance: 255186.474 tau/day, 590.709 timesteps/s +99.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.71479 | 0.71479 | 0.71479 | 0.0 | 42.22 +Neigh | 0.10962 | 0.10962 | 0.10962 | 0.0 | 6.48 +Comm | 0.0014258 | 0.0014258 | 0.0014258 | 0.0 | 0.08 +Output | 0.53333 | 0.53333 | 0.53333 | 0.0 | 31.50 +Modify | 0.3319 | 0.3319 | 0.3319 | 0.0 | 19.61 +Other | | 0.001817 | | | 0.11 + +Nlocal: 2123 ave 2123 max 2123 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 63677 ave 63677 max 63677 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 63677 +Ave neighs/atom = 29.993877 +Neighbor list builds = 50 +Dangerous builds not checked +Total wall time: 0:00:01 diff --git a/examples/PACKAGES/stressprofile/log.6Mar2022.sphere.g++.4 b/examples/PACKAGES/stressprofile/log.6Mar2022.sphere.g++.4 new file mode 100644 index 0000000000..3a0e5a5e63 --- /dev/null +++ b/examples/PACKAGES/stressprofile/log.6Mar2022.sphere.g++.4 @@ -0,0 +1,130 @@ +LAMMPS (17 Feb 2022) +# compute stress/spherical for a spherical droplet + +units lj +atom_style atomic + +lattice fcc 0.8442 +Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962 +region box block -10 10 -10 10 -10 10 +region liquid sphere 0 0 0 5 +create_box 1 box +Created orthogonal box = (-16.795962 -16.795962 -16.795962) to (16.795962 16.795962 16.795962) + 1 by 2 by 2 MPI processor grid +create_atoms 1 region liquid +Created 2123 atoms + using lattice units in orthogonal box = (-16.795962 -16.795962 -16.795962) to (16.795962 16.795962 16.795962) + create_atoms CPU = 0.000 seconds +mass 1 1.0 + +velocity all create 0.65 87287 loop geom + +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify every 20 delay 0 check no + +fix 1 all nvt temp 0.65 0.65 0.2 + +#dump id all atom 50 dump.sphere + +#dump 2 all image 25 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type # axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +fix 2 all recenter 0 0 0 units lattice +compute p all stress/spherical 0 0 0 0.25 15 +Adjusting bin width for compute stress/spherical from 0.250000 to 0.245902 +fix 3 all ave/time 100 1 100 c_p[*] file sphere.out mode vector + +thermo 50 +thermo_style custom step temp epair emol etotal press c_p[15][3] c_p[15][4] c_p[15][5] c_p[15][6] c_p[15][7] c_p[15][8] + +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- compute stress/spherical: + +@article{galteland2022defining, +title={Defining the pressures of a fluid in a nanoporous, heterogeneous medium}, +author={Galteland, Olav and Rauter, Michael T and Varughese, Kevin K and Bedeaux, Dick and Kjelstrup, Signe}, +journal={arXiv preprint arXiv:2201.13060}, +year={2022} +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + + generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update every 20 steps, delay 0 steps, check no + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 24 24 24 + 2 neighbor lists, perpetual/occasional/extra = 1 1 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard + (2) compute stress/spherical, occasional, copy from (1) + attributes: half, newton on + pair build: copy + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 3.068 | 3.078 | 3.082 Mbytes +Step Temp E_pair E_mol TotEng Press c_p[15][3] c_p[15][4] c_p[15][5] c_p[15][6] c_p[15][7] c_p[15][8] + 0 0.65 -5.982005 0 -5.0074642 -0.32476388 0.35627939 0.62462251 0.46815062 -6.0757313 -6.2674721 -6.2664951 + 50 0.42414771 -5.5700167 0 -4.9340948 -0.074492286 0.28886433 0.24978381 0.44948344 -3.0740097 -3.1912376 -3.3440998 + 100 0.64021145 -5.7405134 0 -4.7806486 -0.0054535408 0.66078235 0.50006981 0.71100403 -1.475414 -2.2837434 -2.4415617 + 150 0.72663247 -5.8366691 0 -4.7472338 0.089984367 0.67171939 0.88397719 0.68237586 1.6770061 0.61270415 0.21817975 + 200 0.63460122 -5.8577473 0 -4.9062939 0.14140872 0.42462947 0.59385606 0.7268978 3.724825 5.4164976 5.6793442 + 250 0.62199115 -5.9027866 0 -4.9702393 0.13328919 0.59870532 0.36146182 0.42120197 4.6915309 2.7849546 2.5902987 + 300 0.62406364 -5.8889104 0 -4.9532559 0.063550326 0.52789691 0.2680398 0.54676177 0.46527871 -0.070774015 0.067168511 + 350 0.6028994 -5.7552274 0 -4.8513043 -0.027499706 0.50997812 0.70982549 0.6490879 -1.0149299 -2.1276797 -1.9078706 + 400 0.56811588 -5.5416058 0 -4.6898334 -0.061577561 0.47083533 0.77746521 0.675965 -1.2938321 -2.202316 -2.1025453 + 450 0.54946762 -5.3409786 0 -4.5171654 -0.060007836 0.79992593 0.45761929 0.41283856 -1.652204 -2.8165097 -2.6321599 + 500 0.57962648 -5.2096808 0 -4.3406506 -0.052541306 0.58252285 0.62111149 0.53587504 -1.9875759 -2.9154918 -2.5749065 + 550 0.61149882 -5.0920642 0 -4.175248 -0.03806361 0.69036525 0.44434221 0.43153208 -1.9183958 -2.3974591 -2.3022723 + 600 0.63683327 -4.9975996 0 -4.0427996 -0.016868781 0.61515828 0.47182625 0.4742184 -1.1994753 -1.1131664 -0.56565765 + 650 0.67007543 -4.9684574 0 -3.9638177 -0.00087204466 0.78120956 1.0550498 0.80318482 0.5193751 -0.45357228 -0.48936452 + 700 0.65648313 -4.9612522 0 -3.9769913 0.012954904 0.94001121 0.61816695 0.54104923 -0.9625773 -1.4649033 -1.0873728 + 750 0.62636818 -4.9944273 0 -4.0553176 0.01206773 0.75957119 0.70733827 0.60927279 -0.054590821 -1.1571206 -1.2288301 + 800 0.64474901 -5.0498682 0 -4.0832003 -0.0022579262 0.63509307 0.56543999 0.51633686 -0.85275527 -0.12649302 -0.79080252 + 850 0.64765539 -5.0405969 0 -4.0695714 0.0061653637 0.56204713 0.59190191 0.44560131 -0.51984418 -0.92559078 -0.14336782 + 900 0.65308258 -5.0187376 0 -4.0395752 0.016798783 0.50392257 0.49473611 0.46727165 -0.093317056 -1.3498298 -0.99991957 + 950 0.65225966 -4.9974305 0 -4.0195019 0.0195366 0.47764992 0.56974826 0.58927977 0.93251392 -0.29722045 0.17614353 + 1000 0.6407875 -4.9770134 0 -4.0162849 0.006441923 0.87635667 0.51303643 0.45437033 0.19199806 0.09464003 0.42241535 +Loop time of 0.482332 on 4 procs for 1000 steps with 2123 atoms + +Performance: 895649.023 tau/day, 2073.262 timesteps/s +99.5% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.16099 | 0.1807 | 0.19799 | 3.5 | 37.46 +Neigh | 0.024387 | 0.027158 | 0.030308 | 1.6 | 5.63 +Comm | 0.022206 | 0.043381 | 0.066483 | 8.5 | 8.99 +Output | 0.14055 | 0.14125 | 0.14149 | 0.1 | 29.29 +Modify | 0.087967 | 0.088908 | 0.090377 | 0.3 | 18.43 +Other | | 0.0009305 | | | 0.19 + +Nlocal: 530.75 ave 542 max 513 min +Histogram: 1 0 0 0 1 0 0 0 0 2 +Nghost: 627.75 ave 650 max 612 min +Histogram: 1 0 1 0 1 0 0 0 0 1 +Neighs: 15919.2 ave 17564 max 14498 min +Histogram: 2 0 0 0 0 0 0 0 1 1 + +Total # of neighbors = 63677 +Ave neighs/atom = 29.993877 +Neighbor list builds = 50 +Dangerous builds not checked +Total wall time: 0:00:00 diff --git a/src/.gitignore b/src/.gitignore index 8a18f5b29f..8803d8a7e3 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -492,8 +492,6 @@ /compute_plasticity_atom.h /compute_pressure_bocs.cpp /compute_pressure_bocs.h -/compute_pressure_cylinder.cpp -/compute_pressure_cylinder.h /compute_pressure_grem.cpp /compute_pressure_grem.h /compute_ptm_atom.cpp @@ -504,10 +502,16 @@ /compute_smd_triangle_vertices.h /compute_spec_atom.cpp /compute_spec_atom.h +/compute_stress_cartesian.cpp +/compute_stress_cartesian.h +/compute_stress_cylinder.cpp +/compute_stress_cylinder.h /compute_stress_mop.cpp /compute_stress_mop.h /compute_stress_mop_profile.cpp /compute_stress_mop_profile.h +/compute_stress_spherical.cpp +/compute_stress_spherical.h /compute_stress_tally.cpp /compute_stress_tally.h /compute_temp_asphere.cpp diff --git a/src/EXTRA-COMPUTE/compute_pressure_cylinder.cpp b/src/EXTRA-COMPUTE/compute_pressure_cylinder.cpp deleted file mode 100644 index a2a44ca084..0000000000 --- a/src/EXTRA-COMPUTE/compute_pressure_cylinder.cpp +++ /dev/null @@ -1,483 +0,0 @@ -// clang-format off -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "compute_pressure_cylinder.h" - -#include -#include "atom.h" -#include "update.h" -#include "force.h" -#include "pair.h" -#include "neighbor.h" -#include "neigh_request.h" -#include "neigh_list.h" -#include "memory.h" -#include "error.h" -#include "citeme.h" -#include "domain.h" -#include "math_const.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -static const char cite_compute_pressure_cylinder[] = - "compute pressure/cylinder:\n\n" - "@Article{Addington,\n" - " author = {C. K. Addington, Y. Long, K. E. Gubbins},\n" - " title = {The pressure in interfaces having cylindrical geometry},\n" - " journal = {J.~Chem.~Phys.},\n" - " year = 2018,\n" - " volume = 149,\n" - " pages = {084109}\n" - "}\n\n"; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Calculate the configurational components of the pressure tensor in - cylindrical geometry, according to the formulation of Addington et al. (2018) - +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - -ComputePressureCyl::ComputePressureCyl(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - Pr_temp(nullptr), Pr_all(nullptr), Pz_temp(nullptr), Pz_all(nullptr), Pphi_temp(nullptr), - Pphi_all(nullptr), R(nullptr), Rinv(nullptr), R2(nullptr), PrAinv(nullptr), PzAinv(nullptr), - R2kin(nullptr), density_temp(nullptr), invVbin(nullptr), density_all(nullptr), - tangent(nullptr), ephi_x(nullptr), ephi_y(nullptr), binz(nullptr) -{ - if (lmp->citeme) lmp->citeme->add(cite_compute_pressure_cylinder); - if (narg != 7) error->all(FLERR,"Illegal compute pressure/cylinder command"); - - zlo=utils::numeric(FLERR,arg[3],false,lmp); - zhi=utils::numeric(FLERR,arg[4],false,lmp); - Rmax=utils::numeric(FLERR,arg[5],false,lmp); - bin_width=utils::numeric(FLERR,arg[6],false,lmp); - - if ((bin_width <= 0.0) || (bin_width > Rmax)) - error->all(FLERR,"Illegal compute pressure/cylinder command"); - if ((zhi < zlo) || ((zhi-zlo) < bin_width)) - error->all(FLERR,"Illegal compute pressure/cylinder command"); - if ((zhi > domain->boxhi[2]) || (zlo < domain->boxlo[2])) - error->all(FLERR,"Illegal compute pressure/cylinder command"); - - nbins=(int)(Rmax/bin_width); - nzbins=(int)((zhi-zlo)/bin_width); - - // NOTE: at 2^22 = 4.2M bins, we will be close to exhausting allocatable - // memory on a 32-bit environment. so we use this as an upper limit. - - if ((nbins < 1) || (nzbins < 1) || (nbins > 2<<22) || (nzbins > 2<<22)) - error->all(FLERR,"Illegal compute pressure/cylinder command"); - - array_flag=1; - vector_flag=0; - extarray=0; - size_array_cols = 5; // r, number density, Pr, Pphi, Pz - size_array_rows = nbins; - - Pr_temp = new double[nbins]; - Pr_all = new double[nbins]; - Pz_temp = new double[nbins]; - Pz_all = new double[nbins]; - Pphi_temp = new double[nbins]; - Pphi_all = new double[nbins]; - R = new double[nbins]; - R2 = new double[nbins]; - PrAinv = new double[nbins]; - PzAinv = new double[nbins]; - Rinv = new double[nbins]; - binz = new double[nzbins]; - - R2kin = new double[nbins]; - density_temp = new double[nbins]; - invVbin = new double[nbins]; - density_all = new double[nbins]; - - memory->create(array,nbins,5,"PN:array"); - - nphi=360; - tangent = new double[nphi]; - ephi_x = new double[nphi]; - ephi_y = new double[nphi]; - - nktv2p = force->nktv2p; - -} - -/* ---------------------------------------------------------------------- */ - -ComputePressureCyl::~ComputePressureCyl() -{ - // count all of these for memory usage - memory->destroy(array); - delete [] R; - delete [] Rinv; - delete [] R2; - delete [] R2kin; - delete [] invVbin; - delete [] density_temp; - delete [] density_all; - delete [] tangent; - delete [] ephi_x; - delete [] ephi_y; - delete [] Pr_temp; - delete [] Pr_all; - delete [] Pz_temp; - delete [] Pz_all; - delete [] Pphi_temp; - delete [] Pphi_all; - delete [] PrAinv; - delete [] PzAinv; - delete [] binz; -} - -/* ---------------------------------------------------------------------- */ - -void ComputePressureCyl::init() -{ - if (force->pair == nullptr) - error->all(FLERR,"No pair style is defined for compute pressure/cylinder"); - if (force->pair->single_enable == 0) - error->all(FLERR,"Pair style does not support compute pressure/cylinder"); - - double phi; - - for (int iphi = 0; iphi < nphi; iphi++) { - phi=((double)iphi)*MY_PI/180.0; - tangent[iphi]=tan(phi); - ephi_x[iphi]=-sin(phi); - ephi_y[iphi]=cos(phi); - } - - for (int iq = 0; iq < nbins; iq++) { - R[iq]=((double)iq+0.5)*bin_width; - Rinv[iq]=1.0/R[iq]; - R2[iq]=R[iq]*R[iq]; - R2kin[iq]=(((double)iq)+1.0)*bin_width; - R2kin[iq]*=R2kin[iq]; - PrAinv[iq]=1.0/(2.0*MY_PI*(zhi-zlo)*R[iq]); - } - PphiAinv=1.0/((zhi-zlo)*bin_width*2.0*(double)nphi); - - invVbin[0]=1.0/((zhi-zlo)*MY_PI*R2kin[0]); - PzAinv[0]=1.0/(MY_PI*R2kin[0]*((double)nzbins)); - - for (int jq = 1; jq < nbins; jq++) { - invVbin[jq]=1.0/((zhi-zlo)*MY_PI*(R2kin[jq]-R2kin[jq-1])); - PzAinv[jq]=1.0/(MY_PI*(R2kin[jq]-R2kin[jq-1])*((double)nzbins)); - } - - // need an occasional half neighbor list - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->pair = 0; - neighbor->requests[irequest]->compute = 1; - neighbor->requests[irequest]->occasional = 1; - - for (int zzz = 0; zzz < nzbins; zzz++) binz[zzz]=(((double)zzz)+0.5)*bin_width+zlo; - -} - -/* ---------------------------------------------------------------------- */ - -void ComputePressureCyl::init_list(int /* id */, NeighList *ptr) -{ - list = ptr; -} - -/* ---------------------------------------------------------------------- */ - - -/* ---------------------------------------------------------------------- - count pairs and compute pair info on this proc - only count pair once if newton_pair is off - both atom I,J must be in group - if flag is set, compute requested info about pair -------------------------------------------------------------------------- */ - -void ComputePressureCyl::compute_array() -{ - invoked_array = update->ntimestep; - - int ibin; - - // clear pressures - for (ibin = 0; ibin < nbins; ibin++) { - density_temp[ibin]=0.0; - density_all[ibin]=0.0; - Pr_temp[ibin]=0.0; - Pr_all[ibin]=0.0; - Pphi_temp[ibin]=0.0; - Pphi_all[ibin]=0.0; - Pz_temp[ibin]=0.0; - Pz_all[ibin]=0.0; - } - - // what processor am I? - int me; - MPI_Comm_rank(world,&me); - - int i,j,ii,jj,inum,jnum,itype,jtype; - tagint itag,jtag; - double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,fpair,factor_coul,factor_lj; - int *ilist,*jlist,*numneigh,**firstneigh; - - double **x = atom->x; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - int nlocal = atom->nlocal; - double *special_coul = force->special_coul; - double *special_lj = force->special_lj; - int newton_pair = force->newton_pair; - - // invoke half neighbor list (will copy or build if necessary) - neighbor->build_one(list); - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - // calculate number density (by radius) - double temp_R2; - for (i = 0; i < nlocal; i++) if ((x[i][2] < zhi) && (x[i][2] > zlo)) { - temp_R2=x[i][0]*x[i][0]+x[i][1]*x[i][1]; - if (temp_R2 > R2kin[nbins-1]) continue; // outside of Rmax - - for (j = 0; j < nbins; j++) if (temp_R2 < R2kin[j]) break; - - density_temp[j]+=invVbin[j]; - } - MPI_Allreduce(density_temp,density_all,nbins,MPI_DOUBLE,MPI_SUM,world); - for (i = 0; i < nbins; i++) array[i][1]=density_all[i]; // NEW - - // loop over neighbors of my atoms - // skip if I or J are not in group - // for newton = 0 and J = ghost atom, - // need to insure I,J pair is only output by one proc - // use same itag,jtag logic as in Neighbor::neigh_half_nsq() - // for flag = 0, just count pair interactions within force cutoff - // for flag = 1, calculate requested output fields - - Pair *pair = force->pair; - double **cutsq = force->pair->cutsq; - - double r1=0.0; - double r2=0.0; - double risq,rjsq; - double A,B,C,D; - double alpha1,alpha2; - double xi,yi,zi,dx,dy,dz; - double xR,yR,zR,fn; - double alpha,xL,yL,zL,L2,ftphi,ftz; - double sqrtD; - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - if (!(mask[i] & groupbit)) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - itag = tag[i]; - itype = type[i]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - r1=x[i][0]*x[i][0]+x[i][1]*x[i][1]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - factor_lj = special_lj[sbmask(j)]; - factor_coul = special_coul[sbmask(j)]; - j &= NEIGHMASK; - - if (!(mask[j] & groupbit)) continue; - - // itag = jtag is possible for long cutoffs that include images of self - // do calculation only on appropriate processor - if (newton_pair == 0 && j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - - r2=x[j][0]*x[j][0]+x[j][1]*x[j][1]; - - // ri is smaller of r1 and r2 - if (r2 < r1) { - risq=r2; - rjsq=r1; - xi=x[j][0]; - yi=x[j][1]; - zi=x[j][2]; - dx=x[i][0]-x[j][0]; - dy=x[i][1]-x[j][1]; - dz=x[i][2]-x[j][2]; - } else { - risq=r1; - rjsq=r2; - xi=x[i][0]; - yi=x[i][1]; - zi=x[i][2]; - dx=x[j][0]-x[i][0]; - dy=x[j][1]-x[i][1]; - dz=x[j][2]-x[i][2]; - } - - rsq = delx*delx + dely*dely + delz*delz; - jtype = type[j]; - if (rsq >= cutsq[itype][jtype]) continue; - - pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); - - A=dx*dx+dy*dy; - B=2.0*(xi*dx+yi*dy); - - // normal pressure contribution P_rhorho - for (ibin = 0; ibin < nbins; ibin++) { - // completely inside of R - if (rjsq < R2[ibin]) continue; - - C=risq-R2[ibin]; - D=B*B-4.0*A*C; - - // completely outside of R - if (D < 0.0) continue; - - sqrtD=sqrt(D); - alpha1=0.5*(-B+sqrtD)/A; - alpha2=0.5*(-B-sqrtD)/A; - - if ((alpha1 > 0.0) && (alpha1 < 1.0)) { - zR=zi+alpha1*dz; - if ((zR < zhi) && (zR > zlo)) - { - xR=xi+alpha1*dx; - yR=yi+alpha1*dy; - fn=fpair*fabs(xR*dx+yR*dy); - - Pr_temp[ibin]+=fn; - } - } - if ((alpha2 > 0.0) && (alpha2 < 1.0)) { - zR=zi+alpha2*dz; - if ((zR < zhi) && (zR > zlo)) { - xR=xi+alpha2*dx; - yR=yi+alpha2*dy; - fn=fpair*fabs(xR*dx+yR*dy); - - Pr_temp[ibin]+=fn; - } - } - } - - // azimuthal pressure contribution (P_phiphi) - for (int iphi = 0; iphi < nphi; iphi++) { - alpha=(yi-xi*tangent[iphi])/(dx*tangent[iphi]-dy); - - // no intersection with phi surface - if ((alpha >= 1.0) || (alpha <= 0.0)) continue; - - // no contribution (outside of averaging region) - zL=zi+alpha*dz; - if ((zL > zhi) || (zL < zlo)) continue; - - xL=xi+alpha*dx; - yL=yi+alpha*dy; - - L2=xL*xL+yL*yL; - - // no intersection (outside of Rmax) - if (L2 > R2kin[nbins-1]) continue; - - ftphi=fabs(dx*ephi_x[iphi]+dy*ephi_y[iphi])*fpair; - - // add to appropriate bin - for (ibin = 0; ibin < nbins; ibin++) if (L2 < R2kin[ibin]) { - Pphi_temp[ibin]+=ftphi; - break; - } - } - - // z pressure contribution (P_zz) - for (int zbin = 0; zbin < nzbins; zbin++) { - // check if interaction contributes - if ((x[i][2] > binz[zbin]) && (x[j][2] > binz[zbin])) continue; - if ((x[i][2] < binz[zbin]) && (x[j][2] < binz[zbin])) continue; - - alpha=(binz[zbin]-zi)/dz; - - xL=xi+alpha*dx; - yL=yi+alpha*dy; - - L2=xL*xL+yL*yL; - - if (L2 > R2kin[nbins-1]) continue; - - ftz=fabs(dz)*fpair; - - // add to appropriate bin - for (ibin = 0; ibin < nbins; ibin++) if (L2 < R2kin[ibin]) { - Pz_temp[ibin]+=ftz; - break; - } - } - } - } - - // calculate pressure (force over area) - for (ibin = 0; ibin < nbins; ibin++) { - Pr_temp[ibin]*=PrAinv[ibin]*Rinv[ibin]; - Pphi_temp[ibin]*=PphiAinv; - Pz_temp[ibin]*=PzAinv[ibin]; - } - - // communicate these values across processors - MPI_Allreduce(Pr_temp,Pr_all,nbins,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(Pphi_temp,Pphi_all,nbins,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(Pz_temp,Pz_all,nbins,MPI_DOUBLE,MPI_SUM,world); - - // populate array - for (ibin = 0; ibin < nbins; ibin++) { - array[ibin][0]=R[ibin]; - array[ibin][2]=Pr_all[ibin]*nktv2p; - array[ibin][3]=Pphi_all[ibin]*nktv2p; - array[ibin][4]=Pz_all[ibin]*nktv2p; - } - -} - -/* ---------------------------------------------------------------------- -memory usage of data -------------------------------------------------------------------------- */ - -double ComputePressureCyl::memory_usage() -{ - double bytes = - (3.0*(double)nphi + 16.0*(double)nbins+5.0*(double)nbins) * sizeof(double); - return bytes; -} diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp new file mode 100644 index 0000000000..c9d8513622 --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -0,0 +1,537 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS dir1ectory. +------------------------------------------------------------------------- */ + +#include "compute_stress_cartesian.h" + +#include "atom.h" +#include "citeme.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "modify.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "pair.h" + +#include +#include + +using namespace LAMMPS_NS; + +#define SMALL 1.0e-10 +/*----------------------------------------------------------------------------------- + Contributing author: Olav Galteland (Norwegian University of Science and Technology) + olav.galteland@ntnu.no +------------------------------------------------------------------------------------*/ + +static const char cite_compute_stress_cartesian[] = + "compute stress/cartesian:\n\n" + "@article{galteland2021nanothermodynamic,\n" + "title={Nanothermodynamic description and molecular simulation of a single-phase fluid in a " + "slit pore},\n" + "author={Galteland, Olav and Bedeaux, Dick and Kjelstrup, Signe},\n" + "journal={Nanomaterials},\n" + "volume={11},\n" + "number={1},\n" + "pages={165},\n" + "year={2021},\n" + "publisher={Multidisciplinary Digital Publishing Institute}\n" + "}\n\n"; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ + +ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), dens(NULL), pkxx(NULL), pkyy(NULL), pkzz(NULL), pcxx(NULL), pcyy(NULL), + pczz(NULL), tdens(NULL), tpkxx(NULL), tpkyy(NULL), tpkzz(NULL), tpcxx(NULL), tpcyy(NULL), + tpczz(NULL) +{ + + if (lmp->citeme) lmp->citeme->add(cite_compute_stress_cartesian); + + // narg == 5 for one-dimensional and narg == 7 for two-dimensional + if (narg == 5) + dims = 1; + else if (narg == 7) + dims = 2; + else + error->all(FLERR, "Illegal compute stress/cartesian command. Illegal number of arguments."); + + if (strcmp(arg[3], "x") == 0) + dir1 = 0; + else if (strcmp(arg[3], "y") == 0) + dir1 = 1; + else if (strcmp(arg[3], "z") == 0) + dir1 = 2; + else + error->all(FLERR, "Illegal compute stress/cartesian command."); + + dir2 = 0; + bin_width1 = utils::numeric(FLERR, arg[4], false, lmp); + bin_width2 = 0.0; + nbins1 = (int) ((domain->boxhi[dir1] - domain->boxlo[dir1]) / bin_width1); + nbins2 = 1; + // adjust bin width if not a perfect match + invV = (domain->boxhi[dir1] - domain->boxlo[dir1]) / nbins1; + if ((fabs(invV - bin_width1) > SMALL) && (comm->me == 0)) + utils::logmesg(lmp, "Adjusting first bin width for compute {} from {:.6f} to {:.6f}\n", style, + bin_width1, invV); + bin_width1 = invV; + + if (bin_width1 <= 0.0) + error->all(FLERR, "Illegal compute stress/cartesian command. Bin width must be > 0"); + else if (bin_width1 > domain->boxhi[dir1] - domain->boxlo[dir1]) + error->all(FLERR, "Illegal compute stress/cartesian command. Bin width larger than box."); + + if (dims == 2) { + if (strcmp(arg[5], "x") == 0) + dir2 = 0; + else if (strcmp(arg[5], "y") == 0) + dir2 = 1; + else if (strcmp(arg[5], "z") == 0) + dir2 = 2; + else + error->all(FLERR, "Illegal compute stress/cartesian command."); + + bin_width2 = utils::numeric(FLERR, arg[6], false, lmp); + nbins2 = (int) ((domain->boxhi[dir2] - domain->boxlo[dir2]) / bin_width2); + double tmp_binwidth = (domain->boxhi[dir2] - domain->boxlo[dir2]) / nbins2; + if ((fabs(tmp_binwidth - bin_width2) > SMALL) && (comm->me == 0)) + utils::logmesg(lmp, "Adjusting second bin width for compute {} from {:.6f} to {:.6f}\n", + style, bin_width2, tmp_binwidth); + bin_width2 = tmp_binwidth; + + invV *= bin_width2; + + if (bin_width2 <= 0.0) + error->all(FLERR, "Illegal compute stress/cartesian command. Bin width must be > 0"); + else if (bin_width2 > domain->boxhi[dir2] - domain->boxlo[dir2]) + error->all(FLERR, "Illegal compute stress/cartesian command. Bin width larger than box"); + } + + for (int i = 0; i < 3; i++) + if ((dims == 1 && i != dir1) || (dims == 2 && (i != dir1 && i != dir2))) + invV *= domain->boxhi[i] - domain->boxlo[i]; + invV = 1.0 / invV; + + array_flag = 1; + vector_flag = 0; + extarray = 0; + size_array_cols = 7 + dims; // dir1, dir2, number density, pkxx, pkyy, pkzz, pcxx, pcyy, pczz + size_array_rows = nbins1 * nbins2; + + memory->create(dens, nbins1 * nbins2, "dens"); + memory->create(pkxx, nbins1 * nbins2, "pkxx"); + memory->create(pkyy, nbins1 * nbins2, "pkyy"); + memory->create(pkzz, nbins1 * nbins2, "pkzz"); + memory->create(pcxx, nbins1 * nbins2, "pcxx"); + memory->create(pcyy, nbins1 * nbins2, "pcyy"); + memory->create(pczz, nbins1 * nbins2, "pczz"); + memory->create(tdens, nbins1 * nbins2, "tdens"); + memory->create(tpkxx, nbins1 * nbins2, "tpkxx"); + memory->create(tpkyy, nbins1 * nbins2, "tpkyy"); + memory->create(tpkzz, nbins1 * nbins2, "tpkzz"); + memory->create(tpcxx, nbins1 * nbins2, "tpcxx"); + memory->create(tpcyy, nbins1 * nbins2, "tpcyy"); + memory->create(tpczz, nbins1 * nbins2, "tpczz"); + memory->create(array, size_array_rows, size_array_cols, "stress:cartesian:output"); +} + +/* ---------------------------------------------------------------------- */ + +ComputeStressCartesian::~ComputeStressCartesian() +{ + memory->destroy(dens); + memory->destroy(pkxx); + memory->destroy(pkyy); + memory->destroy(pkzz); + memory->destroy(pcxx); + memory->destroy(pcyy); + memory->destroy(pczz); + memory->destroy(tdens); + memory->destroy(tpkxx); + memory->destroy(tpkyy); + memory->destroy(tpkzz); + memory->destroy(tpcxx); + memory->destroy(tpcyy); + memory->destroy(tpczz); + memory->destroy(array); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeStressCartesian::init() +{ + if (force->pair == NULL) + error->all(FLERR, "No pair style is defined for compute stress/cartesian"); + if (force->pair->single_enable == 0) + error->all(FLERR, "Pair style does not support compute stress/cartesian"); + + // need an occasional half neighbor list. + int irequest = neighbor->request(this, instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeStressCartesian::init_list(int /* id */, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + count pairs and compute pair info on this proc + only count pair once if newton_pair is off + both atom I,J must be in group + if flag is set, compute requested info about pair +------------------------------------------------------------------------- */ + +void ComputeStressCartesian::compute_array() +{ + int i, j, ii, jj, inum, jnum, itype, jtype; + int bin, bin1, bin2, bin3; + tagint itag, jtag; + double xtmp, ytmp, ztmp, delx, dely, delz; + double rsq, fpair, factor_coul, factor_lj; + int *ilist, *jlist, *numneigh, **firstneigh; + + double **x = atom->x; + double **v = atom->v; + double *mass = atom->mass; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + // invoke half neighbor list (will copy or build if necessary) + neighbor->build_one(list); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // Zero arrays + for (bin = 0; bin < nbins1 * nbins2; bin++) { + tdens[bin] = 0; + tpkxx[bin] = 0; + tpkyy[bin] = 0; + tpkzz[bin] = 0; + tpcxx[bin] = 0; + tpcyy[bin] = 0; + tpczz[bin] = 0; + } + + // calculate number density and kinetic contribution to pressure + for (i = 0; i < nlocal; i++) { + bin1 = (int) (x[i][dir1] / bin_width1) % nbins1; + bin2 = 0; + if (dims == 2) bin2 = (int) (x[i][dir2] / bin_width2) % nbins2; + + j = bin1 + bin2 * nbins1; + tdens[j] += 1; + tpkxx[j] += mass[type[i]] * v[i][0] * v[i][0]; + tpkyy[j] += mass[type[i]] * v[i][1] * v[i][1]; + tpkzz[j] += mass[type[i]] * v[i][2] * v[i][2]; + } + + // loop over neighbors of my atoms + // skip if I or J are not in group + // for newton = 0 and J = ghost atom, + // need to insure I,J pair is only output by one proc + // use same itag,jtag logic as in Neighbor::neigh_half_nsq() + // for flag = 0, just count pair interactions within force cutoff + // for flag = 1, calculate requested output fields + + Pair *pair = force->pair; + double **cutsq = force->pair->cutsq; + + double risq, rjsq; + double xi1, xi2, xj1, xj2; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (!(mask[i] & groupbit)) continue; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + xi1 = x[i][dir1]; + xi2 = x[i][dir2]; + itag = tag[i]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + if (!(mask[j] & groupbit)) continue; + + // itag = jtag is possible for long cutoffs that include images of self + // do calculation only on appropriate processor + if (newton_pair == 0 && j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + xj1 = x[j][dir1]; + xj2 = x[j][dir2]; + + delx = x[j][0] - xtmp; + dely = x[j][1] - ytmp; + delz = x[j][2] - ztmp; + + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + + // Check if inside cut-off + if (rsq >= cutsq[itype][jtype]) continue; + pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); + if (dims == 1) compute_pressure_1d(fpair, xi1, xj1, delx, dely, delz); + if (dims == 2) compute_pressure_2d(fpair, xi1, xi2, xj1, xj2, delx, dely, delz); + } + } + + // normalize pressure + for (bin = 0; bin < nbins1 * nbins2; bin++) { + tdens[bin] *= invV; + tpkxx[bin] *= invV; + tpkyy[bin] *= invV; + tpkzz[bin] *= invV; + tpcxx[bin] *= invV; + tpcyy[bin] *= invV; + tpczz[bin] *= invV; + } + + // communicate across processors + MPI_Allreduce(tdens, dens, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpkxx, pkxx, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpkyy, pkyy, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpkzz, pkzz, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpcxx, pcxx, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpcyy, pcyy, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpczz, pczz, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); + + // populate array to output. + for (bin = 0; bin < nbins1 * nbins2; bin++) { + array[bin][0] = (bin % nbins1 + 0.5) * bin_width1; + if (dims == 2) array[bin][1] = ((int) (bin / nbins1) + 0.5) * bin_width2; + array[bin][0 + dims] = dens[bin]; + array[bin][1 + dims] = pkxx[bin]; + array[bin][2 + dims] = pkyy[bin]; + array[bin][3 + dims] = pkzz[bin]; + array[bin][4 + dims] = pcxx[bin]; + array[bin][5 + dims] = pcyy[bin]; + array[bin][6 + dims] = pczz[bin]; + } +} + +void ComputeStressCartesian::compute_pressure_1d(double fpair, double xi, double xj, double delx, + double dely, double delz) +{ + int bin_s, bin_e, bin_step, bin, bin_limit; + double xa, xb, l_sum; + + if (xi < domain->boxlo[dir1]) + xi += (domain->boxhi[dir1] - domain->boxlo[dir1]); + else if (xi > domain->boxhi[dir1]) + xi -= (domain->boxhi[dir1] - domain->boxlo[dir1]); + if (xj < domain->boxlo[dir1]) + xj += (domain->boxhi[dir1] - domain->boxlo[dir1]); + else if (xj > domain->boxhi[dir1]) + xj -= (domain->boxhi[dir1] - domain->boxlo[dir1]); + + // Integrating contour from bin_s to bin_e + bin_s = ((int) lround((xi - domain->boxlo[dir1]) / bin_width1)) % nbins1; + bin_e = ((int) lround((xj - domain->boxlo[dir1]) / bin_width1)) % nbins1; + + // If not periodic in dir1 + if (domain->periodicity[dir1] == 0) { + bin_s = ((int) lround((xi - domain->boxlo[dir1]) / bin_width1)); + bin_e = ((int) lround((xj - domain->boxlo[dir1]) / bin_width1)); + + if (bin_e == nbins1) bin_e--; + if (bin_s == nbins1) bin_s--; + } + + bin_step = 1; + if (domain->periodicity[dir1] == 1) { + if (bin_e - bin_s > 0.5 * nbins1) + bin_step = -1; + else if (bin_s - bin_e > 0.5 * nbins1) + bin_step = 1; + else if (bin_s > bin_e) + bin_step = -1; + } else { + if (bin_s > bin_e) bin_step = -1; + } + if (domain->periodicity[dir1] == 1) + bin_limit = (bin_e + bin_step) % nbins1 < 0 ? (bin_e + bin_step) % nbins1 + nbins1 + : (bin_e + bin_step) % nbins1; + else + bin_limit = bin_e + bin_step; + + bin = bin_s; + // Integrate from bin_s to bin_e with step bin_step. + while (bin < bin_limit) { + + // Calculating exit and entry point (xa, xb). Checking if inside current bin. + if (bin == bin_s) { + if (domain->periodicity[dir1] == 1) + xa = fmod(xi, domain->boxhi[dir1]) + domain->boxlo[dir1]; + else + xa = xi; + } else + xa = (bin_step == 1) ? bin * bin_width1 : (bin + 1) * bin_width1; + if (bin == bin_e) { + if (domain->periodicity[dir1] == 1) + xb = fmod(xj, domain->boxhi[dir1]) + domain->boxlo[dir1]; + else + xb = xj; + } else + xb = (bin_step == 1) ? (bin + 1) * bin_width1 : bin * bin_width1; + + if (bin < 0 || bin >= nbins1) error->all(FLERR, "ERROR: Bin outside simulation."); + + if (bin_s != bin_e) { + if (dir1 == 0) { + tpcxx[bin] += (fpair * delx * delx) * (xb - xa) / delx; + tpcyy[bin] += (fpair * dely * dely) * (xb - xa) / delx; + tpczz[bin] += (fpair * delz * delz) * (xb - xa) / delx; + } else if (dir1 == 1) { + tpcxx[bin] += (fpair * delx * delx) * (xb - xa) / dely; + tpcyy[bin] += (fpair * dely * dely) * (xb - xa) / dely; + tpczz[bin] += (fpair * delz * delz) * (xb - xa) / dely; + } else if (dir1 == 2) { + tpcxx[bin] += (fpair * delx * delx) * (xb - xa) / delz; + tpcyy[bin] += (fpair * dely * dely) * (xb - xa) / delz; + tpczz[bin] += (fpair * delz * delz) * (xb - xa) / delz; + } + } + // Particle i and j in same bin. Avoiding zero divided by zero. + else { + tpcxx[bin] += fpair * delx * delx; + tpcyy[bin] += fpair * dely * dely; + tpczz[bin] += fpair * delz * delz; + } + + // Stepping bin to next bin + if (domain->periodicity[dir1] == 1) + bin = (bin + bin_step) % nbins1 < 0 ? (bin + bin_step) % nbins1 + nbins1 + : (bin + bin_step) % nbins1; + else + bin = bin + bin_step; + } +} + +void ComputeStressCartesian::compute_pressure_2d(double fpair, double xi, double yi, double xj, + double yj, double delx, double dely, double delz) +{ + int bin1, bin2, next_bin1, next_bin2; + double la = 0.0, lb = 0.0, l_sum = 0.0; + double rij[3] = {delx, dely, delz}; + double l1 = 0.0, l2, rij1, rij2; + rij1 = rij[dir1]; + rij2 = rij[dir2]; + + next_bin1 = (int) floor(xi / bin_width1); + next_bin2 = (int) floor(yi / bin_width2); + + // Integrating along line + while (lb < 1.0) { + bin1 = next_bin1; + bin2 = next_bin2; + + if (rij1 > 0) + l1 = ((bin1 + 1) * bin_width1 - xi) / rij1; + else + l1 = (bin1 * bin_width1 - xi) / rij1; + if (rij2 > 0) + l2 = ((bin2 + 1) * bin_width2 - yi) / rij2; + else + l2 = (bin2 * bin_width2 - yi) / rij2; + + if ((l1 < l2 || l2 < lb + SMALL) && l1 <= 1.0 && l1 > lb) { + lb = l1; + next_bin1 = bin1 + (int) (rij1 / fabs(rij1)); + } else if (l2 <= 1.0 && l2 > lb) { + lb = l2; + next_bin2 = bin2 + (int) (rij2 / fabs(rij2)); + } else + lb = 1.0; + + // Periodic boundary conditions + if (domain->periodicity[dir1] == 1) { + if (bin1 < 0) + bin1 = (bin1 + nbins1) % nbins1; + else if (bin1 >= nbins1) + bin1 = (bin1 - nbins1) % nbins1; + } else if (bin1 < 0) + bin1 = 0; + else if (bin1 >= nbins1) + bin1 = nbins1 - 1; + + if (domain->periodicity[dir2] == 1) { + if (bin2 < 0) + bin2 = (bin2 + nbins2) % nbins2; + else if (bin2 >= nbins2) + bin2 = (bin2 - nbins2) % nbins2; + } else if (bin2 < 0) + bin2 = 0; + else if (bin2 >= nbins2) + bin2 = nbins2 - 1; + + if (bin1 + bin2 * nbins1 > nbins1 * nbins2) error->all(FLERR, "Bin outside: lb={:.16g}", lb); + + tpcxx[bin1 + bin2 * nbins1] += (fpair * delx * delx * (lb - la)); + tpcyy[bin1 + bin2 * nbins1] += (fpair * dely * dely * (lb - la)); + tpczz[bin1 + bin2 * nbins1] += (fpair * delz * delz * (lb - la)); + + l_sum += lb - la; + la = lb; + } + + if (l_sum > 1.0 + SMALL || l_sum < 1.0 - SMALL) + error->all(FLERR, "Sum of fractional line segments does not equal 1."); +} + +/* ---------------------------------------------------------------------- +memory usage of data +------------------------------------------------------------------------- */ + +double ComputeStressCartesian::memory_usage() +{ + return (14.0 + dims + 7) * (double) (nbins1 * nbins2) * sizeof(double); +} diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.h b/src/EXTRA-COMPUTE/compute_stress_cartesian.h new file mode 100644 index 0000000000..aa44e82269 --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(stress/cartesian,ComputeStressCartesian); +// clang-format on +#else + +#ifndef LMP_COMPUTE_STRESS_CARTESIAN_H +#define LMP_COMPUTE_STRESS_CARTESIAN_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeStressCartesian : public Compute { + public: + ComputeStressCartesian(class LAMMPS *, int, char **); + ~ComputeStressCartesian() override; + void init() override; + void init_list(int, class NeighList *) override; + void compute_array() override; + double memory_usage() override; + + private: + int nbins1, nbins2, dir1, dir2, dims; + double bin_width1, bin_width2, invV; + + // Number density, kinetic and configurational contribution to the pressure. + double *dens, *pkxx, *pkyy, *pkzz, *pcxx, *pcyy, *pczz; + double *tdens, *tpkxx, *tpkyy, *tpkzz, *tpcxx, *tpcyy, *tpczz; + class NeighList *list; + void compute_pressure_1d(double, double, double, double, double, double); + void compute_pressure_2d(double, double, double, double, double, double, double, double); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: No pair style is defined for compute stress/cartesian + +Self-explanatory. + +E: Pair style does not support compute stress/cartesian + +The pair style does not have a single() function, so it can +not be invoked by compute stress/cartesian. + +*/ diff --git a/src/EXTRA-COMPUTE/compute_stress_cylinder.cpp b/src/EXTRA-COMPUTE/compute_stress_cylinder.cpp new file mode 100644 index 0000000000..c829871ccd --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_stress_cylinder.cpp @@ -0,0 +1,565 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "compute_stress_cylinder.h" + +#include "atom.h" +#include "citeme.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "math_const.h" +#include "math_special.h" +#include "memory.h" +#include "modify.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "pair.h" +#include "update.h" + +#include +#include +#include + +using namespace LAMMPS_NS; +using namespace MathConst; +using MathSpecial::square; + +/*----------------------------------------------------------------------------------- + Contributing authors: Cody K. Addington (North Carolina State University) + (Kinetic contribution) : Olav Galteland, + (Norwegian University of Science and Technology), + olav.galteland@ntnu.no +------------------------------------------------------------------------------------*/ + +static const char cite_compute_stress_cylinder[] = + "compute stress/cylinder:\n\n" + "@Article{Addington,\n" + " author = {C. K. Addington, Y. Long, K. E. Gubbins},\n" + " title = {The pressure in interfaces having cylindrical geometry},\n" + " journal = {J.~Chem.~Phys.},\n" + " year = 2018,\n" + " volume = 149,\n" + " pages = {084109}\n" + "}\n\n"; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Calculate the configurational components of the stress tensor in + cylindrical geometry, according to the formulation of Addington et al. (2018) + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ + +ComputeStressCylinder::ComputeStressCylinder(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), Pvr_temp(nullptr), Pvr_all(nullptr), Pvz_temp(nullptr), + Pvz_all(nullptr), Pvphi_temp(nullptr), Pvphi_all(nullptr), R(nullptr), Rinv(nullptr), + R2(nullptr), PrAinv(nullptr), PzAinv(nullptr), R2kin(nullptr), density_temp(nullptr), + invVbin(nullptr), density_all(nullptr), tangent(nullptr), ephi_x(nullptr), ephi_y(nullptr), + binz(nullptr) +{ + if (lmp->citeme) lmp->citeme->add(cite_compute_stress_cylinder); + if ((narg != 7) && (narg != 9)) error->all(FLERR, "Illegal compute stress/cylinder command"); + + zlo = utils::numeric(FLERR, arg[3], false, lmp); + zhi = utils::numeric(FLERR, arg[4], false, lmp); + Rmax = utils::numeric(FLERR, arg[5], false, lmp); + bin_width = utils::numeric(FLERR, arg[6], false, lmp); + + // Option to include/exclude kinetic contribution. Default is to include + kinetic_flag = 1; + int iarg = 7; + if (narg > iarg) { + if (strcmp("ke", arg[iarg]) == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid compute stress/cylinder command"); + kinetic_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else + error->all(FLERR, "Unknown compute stress/cylinder command"); + } + + if ((bin_width <= 0.0) || (bin_width > Rmax)) + error->all(FLERR, "Illegal compute stress/cylinder command"); + if ((zhi < zlo) || ((zhi - zlo) < bin_width)) + error->all(FLERR, "Illegal compute stress/cylinder command"); + if ((zhi > domain->boxhi[2]) || (zlo < domain->boxlo[2])) + error->all(FLERR, "Illegal compute stress/cylinder command"); + + nbins = (int) (Rmax / bin_width); + nzbins = (int) ((zhi - zlo) / bin_width); + + // NOTE: at 2^22 = 4.2M bins, we will be close to exhausting allocatable + // memory on a 32-bit environment. so we use this as an upper limit. + + if ((nbins < 1) || (nzbins < 1) || (nbins > 2 << 22) || (nzbins > 2 << 22)) + error->all(FLERR, "Illegal compute stress/cylinder command"); + + array_flag = 1; + vector_flag = 0; + extarray = 0; + size_array_cols = 5; // r, number density, pvr, pvphi, pz + size_array_rows = nbins; + + if (kinetic_flag == 1) { + size_array_cols = 8; // r, number density, pkr, pkphi, pkz, pvr, pvphi, pz + Pkr_temp = new double[nbins]; + Pkr_all = new double[nbins]; + Pkz_temp = new double[nbins]; + Pkz_all = new double[nbins]; + Pkphi_temp = new double[nbins]; + Pkphi_all = new double[nbins]; + } + Pvr_temp = new double[nbins]; + Pvr_all = new double[nbins]; + Pvz_temp = new double[nbins]; + Pvz_all = new double[nbins]; + Pvphi_temp = new double[nbins]; + Pvphi_all = new double[nbins]; + R = new double[nbins]; + R2 = new double[nbins]; + PrAinv = new double[nbins]; + PzAinv = new double[nbins]; + Rinv = new double[nbins]; + binz = new double[nzbins]; + + R2kin = new double[nbins]; + density_temp = new double[nbins]; + invVbin = new double[nbins]; + density_all = new double[nbins]; + + nphi = 360; + tangent = new double[nphi]; + ephi_x = new double[nphi]; + ephi_y = new double[nphi]; + + memory->create(array, size_array_rows, size_array_cols, "PN:array"); + + nktv2p = force->nktv2p; +} + +/* ---------------------------------------------------------------------- */ + +ComputeStressCylinder::~ComputeStressCylinder() +{ + memory->destroy(array); + if (kinetic_flag == 1) { + delete[] Pkr_temp; + delete[] Pkr_all; + delete[] Pkz_temp; + delete[] Pkz_all; + delete[] Pkphi_temp; + delete[] Pkphi_all; + } + delete[] R; + delete[] Rinv; + delete[] R2; + delete[] R2kin; + delete[] invVbin; + delete[] density_temp; + delete[] density_all; + delete[] tangent; + delete[] ephi_x; + delete[] ephi_y; + delete[] Pvr_temp; + delete[] Pvr_all; + delete[] Pvz_temp; + delete[] Pvz_all; + delete[] Pvphi_temp; + delete[] Pvphi_all; + delete[] PrAinv; + delete[] PzAinv; + delete[] binz; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeStressCylinder::init() +{ + if (force->pair == nullptr) + error->all(FLERR, "No pair style is defined for compute stress/cylinder"); + if (force->pair->single_enable == 0) + error->all(FLERR, "Pair style does not support compute stress/cylinder"); + + double phi; + for (int iphi = 0; iphi < nphi; iphi++) { + phi = ((double) iphi) * MY_PI / 180.0; + tangent[iphi] = tan(phi); + ephi_x[iphi] = -sin(phi); + ephi_y[iphi] = cos(phi); + } + for (int iq = 0; iq < nbins; iq++) { + R[iq] = ((double) iq + 0.5) * bin_width; + Rinv[iq] = 1.0 / R[iq]; + R2[iq] = R[iq] * R[iq]; + R2kin[iq] = (((double) iq) + 1.0) * bin_width; + R2kin[iq] *= R2kin[iq]; + PrAinv[iq] = 1.0 / (2.0 * MY_PI * (zhi - zlo) * R[iq]); + } + PphiAinv = 1.0 / ((zhi - zlo) * bin_width * 2.0 * (double) nphi); + + invVbin[0] = 1.0 / ((zhi - zlo) * MY_PI * R2kin[0]); + PzAinv[0] = 1.0 / (MY_PI * R2kin[0] * ((double) nzbins)); + + for (int jq = 1; jq < nbins; jq++) { + invVbin[jq] = 1.0 / ((zhi - zlo) * MY_PI * (R2kin[jq] - R2kin[jq - 1])); + PzAinv[jq] = 1.0 / (MY_PI * (R2kin[jq] - R2kin[jq - 1]) * ((double) nzbins)); + } + + // need an occasional half neighbor list + int irequest = neighbor->request(this, instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; + + for (int zzz = 0; zzz < nzbins; zzz++) binz[zzz] = (((double) zzz) + 0.5) * bin_width + zlo; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeStressCylinder::init_list(int /* id */, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + count pairs and compute pair info on this proc + only count pair once if newton_pair is off + both atom I,J must be in group + if flag is set, compute requested info about pair +------------------------------------------------------------------------- */ + +void ComputeStressCylinder::compute_array() +{ + invoked_array = update->ntimestep; + + int ibin; + // clear pressures + for (ibin = 0; ibin < nbins; ibin++) { + if (kinetic_flag == 1) { + Pkr_temp[ibin] = 0.0; + Pkr_all[ibin] = 0.0; + Pkphi_temp[ibin] = 0.0; + Pkphi_all[ibin] = 0.0; + Pkz_temp[ibin] = 0.0; + Pkz_all[ibin] = 0.0; + } + density_temp[ibin] = 0.0; + density_all[ibin] = 0.0; + Pvr_temp[ibin] = 0.0; + Pvr_all[ibin] = 0.0; + Pvphi_temp[ibin] = 0.0; + Pvphi_all[ibin] = 0.0; + Pvz_temp[ibin] = 0.0; + Pvz_all[ibin] = 0.0; + } + + // what processor am I? + int me; + MPI_Comm_rank(world, &me); + + int i, j, ii, jj, inum, jnum, itype, jtype; + tagint itag, jtag; + double xtmp, ytmp, ztmp, delx, dely, delz; + double rsq, fpair, factor_coul, factor_lj; + int *ilist, *jlist, *numneigh, **firstneigh; + + double vr, vp; + double **x = atom->x; + double **v = atom->v; + double *mass = atom->mass; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + // invoke half neighbor list (will copy or build if necessary) + neighbor->build_one(list); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // calculate number density and kinetic contribution (by radius) + double temp_R2; + for (i = 0; i < nlocal; i++) + if ((x[i][2] < zhi) && (x[i][2] > zlo)) { + temp_R2 = x[i][0] * x[i][0] + x[i][1] * x[i][1]; + if (temp_R2 > R2kin[nbins - 1]) continue; // outside of Rmax + + for (j = 0; j < nbins; j++) + if (temp_R2 < R2kin[j]) break; + + density_temp[j] += invVbin[j]; + + // Check if kinetic option is set to yes + if (kinetic_flag == 1) { + if ((temp_R2 != 0.0) && (x[i][0] != 0.0)) { + // Radial velocity times R + vr = (x[i][0] * v[i][0] + x[i][1] * v[i][1]); + // Azimuthal velocity divided by R + vp = (v[i][1] / x[i][0] - x[i][1] * v[i][0] / (x[i][0] * x[i][0])) / + (square(x[i][1] / x[i][0]) + 1.0); + + Pkr_temp[j] += mass[type[i]] * vr * vr / temp_R2; + Pkphi_temp[j] += mass[type[i]] * temp_R2 * vp * vp; + Pkz_temp[j] += mass[type[i]] * v[i][2] * v[i][2]; + } + } + } + MPI_Allreduce(density_temp, density_all, nbins, MPI_DOUBLE, MPI_SUM, world); + for (i = 0; i < nbins; i++) array[i][1] = density_all[i]; // NEW + + // loop over neighbors of my atoms + // skip if I or J are not in group + // for newton = 0 and J = ghost atom, + // need to insure I,J pair is only output by one proc + // use same itag,jtag logic as in Neighbor::neigh_half_nsq() + // for flag = 0, just count pair interactions within force cutoff + // for flag = 1, calculate requested output fields + + Pair *pair = force->pair; + double **cutsq = force->pair->cutsq; + + double r1 = 0.0; + double r2 = 0.0; + double risq, rjsq; + double A, B, C, D; + double alpha1, alpha2; + double xi, yi, zi, dx, dy, dz; + double xR, yR, zR, fn; + double alpha, xL, yL, zL, L2, ftphi, ftz; + double sqrtD; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (!(mask[i] & groupbit)) continue; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itag = tag[i]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + r1 = x[i][0] * x[i][0] + x[i][1] * x[i][1]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + if (!(mask[j] & groupbit)) continue; + + // itag = jtag is possible for long cutoffs that include images of self + // do calculation only on appropriate processor + if (newton_pair == 0 && j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + + r2 = x[j][0] * x[j][0] + x[j][1] * x[j][1]; + + // ri is smaller of r1 and r2 + if (r2 < r1) { + risq = r2; + rjsq = r1; + xi = x[j][0]; + yi = x[j][1]; + zi = x[j][2]; + dx = x[i][0] - x[j][0]; + dy = x[i][1] - x[j][1]; + dz = x[i][2] - x[j][2]; + } else { + risq = r1; + rjsq = r2; + xi = x[i][0]; + yi = x[i][1]; + zi = x[i][2]; + dx = x[j][0] - x[i][0]; + dy = x[j][1] - x[i][1]; + dz = x[j][2] - x[i][2]; + } + + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + if (rsq >= cutsq[itype][jtype]) continue; + + pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); + + A = dx * dx + dy * dy; + B = 2.0 * (xi * dx + yi * dy); + + // normal pressure contribution P_rhorho + for (ibin = 0; ibin < nbins; ibin++) { + // completely inside of R + if (rjsq < R2[ibin]) continue; + + C = risq - R2[ibin]; + D = B * B - 4.0 * A * C; + + // completely outside of R or zero size bin + if ((D < 0.0) || (A == 0.0)) continue; + + sqrtD = sqrt(D); + alpha1 = 0.5 * (-B + sqrtD) / A; + alpha2 = 0.5 * (-B - sqrtD) / A; + + if ((alpha1 > 0.0) && (alpha1 < 1.0)) { + zR = zi + alpha1 * dz; + if ((zR < zhi) && (zR > zlo)) { + xR = xi + alpha1 * dx; + yR = yi + alpha1 * dy; + fn = fpair * fabs(xR * dx + yR * dy); + + Pvr_temp[ibin] += fn; + } + } + if ((alpha2 > 0.0) && (alpha2 < 1.0)) { + zR = zi + alpha2 * dz; + if ((zR < zhi) && (zR > zlo)) { + xR = xi + alpha2 * dx; + yR = yi + alpha2 * dy; + fn = fpair * fabs(xR * dx + yR * dy); + + Pvr_temp[ibin] += fn; + } + } + } + + // azimuthal pressure contribution (P_phiphi) + for (int iphi = 0; iphi < nphi; iphi++) { + if ((dx * tangent[iphi] - dy) == 0.0) continue; + alpha = (yi - xi * tangent[iphi]) / (dx * tangent[iphi] - dy); + + // no intersection with phi surface + if ((alpha >= 1.0) || (alpha <= 0.0)) continue; + + // no contribution (outside of averaging region) + zL = zi + alpha * dz; + if ((zL > zhi) || (zL < zlo)) continue; + + xL = xi + alpha * dx; + yL = yi + alpha * dy; + + L2 = xL * xL + yL * yL; + + // no intersection (outside of Rmax) + if (L2 > R2kin[nbins - 1]) continue; + + ftphi = fabs(dx * ephi_x[iphi] + dy * ephi_y[iphi]) * fpair; + + // add to appropriate bin + for (ibin = 0; ibin < nbins; ibin++) + if (L2 < R2kin[ibin]) { + Pvphi_temp[ibin] += ftphi; + break; + } + } + + // z pressure contribution (P_zz) + for (int zbin = 0; zbin < nzbins; zbin++) { + // check if interaction contributes + if ((x[i][2] > binz[zbin]) && (x[j][2] > binz[zbin])) continue; + if ((x[i][2] < binz[zbin]) && (x[j][2] < binz[zbin])) continue; + + alpha = (binz[zbin] - zi) / dz; + + xL = xi + alpha * dx; + yL = yi + alpha * dy; + + L2 = xL * xL + yL * yL; + + if (L2 > R2kin[nbins - 1]) continue; + + ftz = fabs(dz) * fpair; + + // add to appropriate bin + for (ibin = 0; ibin < nbins; ibin++) + if (L2 < R2kin[ibin]) { + Pvz_temp[ibin] += ftz; + break; + } + } + } + } + + // calculate pressure (force over area) + for (ibin = 0; ibin < nbins; ibin++) { + if (kinetic_flag == 1) { + Pkr_temp[ibin] *= invVbin[ibin]; + Pkphi_temp[ibin] *= invVbin[ibin]; + Pkz_temp[ibin] *= invVbin[ibin]; + } + Pvr_temp[ibin] *= PrAinv[ibin] * Rinv[ibin]; + Pvphi_temp[ibin] *= PphiAinv; + Pvz_temp[ibin] *= PzAinv[ibin]; + } + + // communicate these values across processors + if (kinetic_flag == 1) { + MPI_Allreduce(Pkr_temp, Pkr_all, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(Pkphi_temp, Pkphi_all, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(Pkz_temp, Pkz_all, nbins, MPI_DOUBLE, MPI_SUM, world); + } + MPI_Allreduce(Pvr_temp, Pvr_all, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(Pvphi_temp, Pvphi_all, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(Pvz_temp, Pvz_all, nbins, MPI_DOUBLE, MPI_SUM, world); + + // populate array + for (ibin = 0; ibin < nbins; ibin++) { + array[ibin][0] = R[ibin]; + if (kinetic_flag == 1) { + array[ibin][2] = Pkr_all[ibin] * nktv2p; + array[ibin][3] = Pkphi_all[ibin] * nktv2p; + array[ibin][4] = Pkz_all[ibin] * nktv2p; + array[ibin][5] = Pvr_all[ibin] * nktv2p; + array[ibin][6] = Pvphi_all[ibin] * nktv2p; + array[ibin][7] = Pvz_all[ibin] * nktv2p; + } else { + array[ibin][2] = Pvr_all[ibin] * nktv2p; + array[ibin][3] = Pvphi_all[ibin] * nktv2p; + array[ibin][4] = Pvz_all[ibin] * nktv2p; + } + } +} + +/* ---------------------------------------------------------------------- +memory usage of data +------------------------------------------------------------------------- */ +double ComputeStressCylinder::memory_usage() +{ + double bytes = + (3.0 * (double) nphi + 16.0 * (double) nbins + (5.0 + 3.0 * kinetic_flag) * (double) nbins) * + sizeof(double); + return bytes; +} diff --git a/src/EXTRA-COMPUTE/compute_pressure_cylinder.h b/src/EXTRA-COMPUTE/compute_stress_cylinder.h similarity index 70% rename from src/EXTRA-COMPUTE/compute_pressure_cylinder.h rename to src/EXTRA-COMPUTE/compute_stress_cylinder.h index 871c820910..76be8aff9a 100644 --- a/src/EXTRA-COMPUTE/compute_pressure_cylinder.h +++ b/src/EXTRA-COMPUTE/compute_stress_cylinder.h @@ -13,29 +13,32 @@ #ifdef COMPUTE_CLASS // clang-format off -ComputeStyle(pressure/cylinder,ComputePressureCyl); +ComputeStyle(stress/cylinder,ComputeStressCylinder); +ComputeStyle(pressure/cylinder,ComputeStressCylinder); // clang-format on #else -#ifndef LMP_COMPUTE_PRESSURE_CYLINDER -#define LMP_COMPUTE_PRESSURE_CYLINDER +#ifndef LMP_COMPUTE_STRESS_CYLINDER_H +#define LMP_COMPUTE_STRESS_CYLINDER_H #include "compute.h" namespace LAMMPS_NS { -class ComputePressureCyl : public Compute { +class ComputeStressCylinder : public Compute { public: - ComputePressureCyl(class LAMMPS *, int, char **); - ~ComputePressureCyl() override; + ComputeStressCylinder(class LAMMPS *, int, char **); + ~ComputeStressCylinder() override; void init() override; void init_list(int, class NeighList *) override; void compute_array() override; double memory_usage() override; private: + int kinetic_flag; int nbins, nphi, nzbins; - double *Pr_temp, *Pr_all, *Pz_temp, *Pz_all, *Pphi_temp, *Pphi_all; + double *Pvr_temp, *Pvr_all, *Pvz_temp, *Pvz_all, *Pvphi_temp, *Pvphi_all; + double *Pkr_temp, *Pkr_all, *Pkz_temp, *Pkz_all, *Pkphi_temp, *Pkphi_all; double *R, *Rinv, *R2, *PrAinv, *PzAinv, PphiAinv; double Rmax, bin_width, nktv2p; double *R2kin, *density_temp, *invVbin, *density_all; @@ -60,13 +63,13 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: No pair style is defined for compute pressure/cylinder +E: No pair style is defined for compute stress/cylinder Self-explanatory. -E: Pair style does not support compute pressure/cylinder +E: Pair style does not support compute stress/cylinder The pair style does not have a single() function, so it can -not be invoked by compute pressure/cylinder. +not be invoked by compute stress/cylinder. */ diff --git a/src/EXTRA-COMPUTE/compute_stress_spherical.cpp b/src/EXTRA-COMPUTE/compute_stress_spherical.cpp new file mode 100644 index 0000000000..4f4570048f --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_stress_spherical.cpp @@ -0,0 +1,422 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS dir1ectory. +------------------------------------------------------------------------- */ + +#include "compute_stress_spherical.h" + +#include "atom.h" +#include "citeme.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "lattice.h" +#include "math_const.h" +#include "math_special.h" +#include "memory.h" +#include "modify.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "pair.h" +#include "update.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace MathConst; +using MathSpecial::cube; +using MathSpecial::square; + +#define SMALL 1.0e-10 + +/*----------------------------------------------------------------------------------- + Contributing author: Olav Galteland (Norwegian University of Science and Technology) + olav.galteland@ntnu.no +------------------------------------------------------------------------------------*/ + +static const char cite_compute_stress_sphere[] = + "compute stress/spherical:\n\n" + "@article{galteland2022defining,\n" + "title={Defining the pressures of a fluid in a nanoporous, heterogeneous medium},\n" + "author={Galteland, Olav and Rauter, Michael T and Varughese, Kevin K and Bedeaux, Dick and " + "Kjelstrup, Signe},\n" + "journal={arXiv preprint arXiv:2201.13060},\n" + "year={2022}\n" + "}\n\n"; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ + +ComputeStressSpherical::ComputeStressSpherical(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), dens(nullptr), pkrr(nullptr), pktt(nullptr), pkpp(nullptr), + pcrr(nullptr), pctt(nullptr), pcpp(nullptr), tdens(nullptr), tpkrr(nullptr), tpktt(nullptr), + tpkpp(nullptr), tpcrr(nullptr), tpctt(nullptr), tpcpp(nullptr) +{ + + if (lmp->citeme) lmp->citeme->add(cite_compute_stress_sphere); + if (narg != 8) + error->all(FLERR, "Illegal compute stress/spherical command. Illegal number of arguments."); + + x0 = utils::numeric(FLERR, arg[3], false, lmp); + y0 = utils::numeric(FLERR, arg[4], false, lmp); + z0 = utils::numeric(FLERR, arg[5], false, lmp); + bin_width = utils::numeric(FLERR, arg[6], false, lmp); + Rmax = utils::numeric(FLERR, arg[7], false, lmp); + nbins = (int) (Rmax / bin_width) + 1; + double tmp_width = Rmax / nbins; + if ((fabs(bin_width - tmp_width) > SMALL) && (comm->me == 0)) + utils::logmesg(lmp, "Adjusting bin width for compute {} from {:.6f} to {:.6f}\n", style, + bin_width, tmp_width); + bin_width = tmp_width; + + if (bin_width <= 0.0) + error->all(FLERR, "Illegal compute stress/spherical command. Bin width must be > 0"); + + array_flag = 1; + vector_flag = 0; + extarray = 0; + size_array_cols = 8; // r, dens, pkrr, pktt, pkpp, pcrr, pctt, pcpp + size_array_rows = nbins; + + memory->create(invV, nbins, "compute/stress/spherical:invV"); + memory->create(dens, nbins, "compute/stress/spherical:dens"); + memory->create(pkrr, nbins, "compute/stress/spherical:pkrr"); + memory->create(pktt, nbins, "compute/stress/spherical:pktt"); + memory->create(pkpp, nbins, "compute/stress/spherical:pkpp"); + memory->create(pcrr, nbins, "compute/stress/spherical:pcrr"); + memory->create(pctt, nbins, "compute/stress/spherical:pctt"); + memory->create(pcpp, nbins, "compute/stress/spherical:pcpp"); + memory->create(tdens, nbins, "compute/stress/spherical:tdens"); + memory->create(tpkrr, nbins, "compute/stress/spherical:tpkrr"); + memory->create(tpktt, nbins, "compute/stress/spherical:tpktt"); + memory->create(tpkpp, nbins, "compute/stress/spherical:tpkpp"); + memory->create(tpcrr, nbins, "compute/stress/spherical:tpcrr"); + memory->create(tpctt, nbins, "compute/stress/spherical:tpctt"); + memory->create(tpcpp, nbins, "compute/stress/spherical:tpcpp"); + memory->create(array, size_array_rows, size_array_cols, "compute/stress/spherical:array"); +} + +/* ---------------------------------------------------------------------- */ + +ComputeStressSpherical::~ComputeStressSpherical() +{ + memory->destroy(invV); + memory->destroy(dens); + memory->destroy(pkrr); + memory->destroy(pktt); + memory->destroy(pkpp); + memory->destroy(pcrr); + memory->destroy(pctt); + memory->destroy(pcpp); + memory->destroy(tdens); + memory->destroy(tpkrr); + memory->destroy(tpktt); + memory->destroy(tpkpp); + memory->destroy(tpcrr); + memory->destroy(tpctt); + memory->destroy(tpcpp); + memory->destroy(array); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeStressSpherical::init() +{ + if (force->pair == nullptr) + error->all(FLERR, "No pair style is defined for compute stress/spherical"); + if (force->pair->single_enable == 0) + error->all(FLERR, "Pair style does not support compute stress/spherical"); + + // Inverse volume of each spherical shell (bin) + for (int bin = 0; bin < nbins; bin++) + invV[bin] = 0.75 / (MY_PI * (cube((bin + 1) * bin_width) - cube(bin * bin_width))); + + int irequest = neighbor->request(this, instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeStressSpherical::init_list(int /* id */, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + count pairs and compute pair info on this proc + only count pair once if newton_pair is off + both atom I,J must be in group + if flag is set, compute requested info about pair +------------------------------------------------------------------------- */ + +void ComputeStressSpherical::compute_array() +{ + invoked_array = update->ntimestep; + + int bin; + // Zero arrays + for (int bin = 0; bin < nbins; bin++) { + tdens[bin] = 0.0; + tpkrr[bin] = 0.0; + tpktt[bin] = 0.0; + tpkpp[bin] = 0.0; + tpcrr[bin] = 0.0; + tpctt[bin] = 0.0; + tpcpp[bin] = 0.0; + } + + int i, j, ii, jj, inum, jnum, itype, jtype; + tagint itag, jtag; + double ri[3], xtmp, ytmp, ztmp, tmp; + double rsq, fpair, factor_coul, factor_lj; + int *ilist, *jlist, *numneigh, **firstneigh; + + double r, vr, vt, vp, theta; + double **x = atom->x; + double **v = atom->v; + double *mass = atom->mass; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + // invoke half neighbor list (will copy or build if necessary) + neighbor->build_one(list); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // calculate number density and kinetic contribution to pressure + for (i = 0; i < nlocal; i++) { + ri[0] = x[i][0] - x0; + ri[1] = x[i][1] - y0; + ri[2] = x[i][2] - z0; + for (j = 0; j < 3; j++) { + tmp = domain->boxhi[j] - domain->boxlo[j]; + if (ri[j] > 0.5 * tmp) + ri[j] -= tmp; + else if (ri[j] < -0.5 * tmp) + ri[j] += tmp; + } + r = sqrt(ri[0] * ri[0] + ri[1] * ri[1] + ri[2] * ri[2]); + if (r >= Rmax) continue; + bin = (int) (r / bin_width); + + // Avoiding division by zero + if ((r != 0.0) && (ri[0] != 0.0)) { + theta = acos(ri[2] / r); + tdens[bin] += 1.0; + vr = (ri[0] * v[i][0] + ri[1] * v[i][1] + ri[2] * v[i][2]) / r; + vt = r * sin(theta) / (square(ri[1] / ri[0]) + 1.0) * + ((ri[0] * v[i][1] - ri[1] * v[i][0]) / (ri[0] * ri[0])); + vp = (ri[2] * vr - r * v[i][2]) / (r * sqrt(1.0 - square(ri[2] / r))); + tpkrr[bin] += vr * vr; + tpktt[bin] += vt * vt; + tpkpp[bin] += vp * vp; + } + } + + // loop over neighbors of my atoms + // skip if I or J are not in group + // for newton = 0 and J = ghost atom, + // need to insure I,J pair is only output by one proc + // use same itag,jtag logic as in Neighbor::neigh_half_nsq() + // for flag = 0, just count pair interactions within force cutoff + // for flag = 1, calculate requested output fields + + Pair *pair = force->pair; + double **cutsq = force->pair->cutsq; + + double risq, rjsq; + double dir1i, dir2i, dir3i, dir1j, dir2j, dir3j; + double xi, yi, zi, xj, yj, zj; + + double qi[3], l1, l2, l3, l4, R1, R2, Fa, Fb, l_sum; + double rij, f, ririj, sqr, la, lb, sql0, lambda0; + double rsqxy, ririjxy, sqrixy, sqlxy0, A, B, C; + int end_bin; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (!(mask[i] & groupbit)) continue; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itag = tag[i]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + if (!(mask[j] & groupbit)) continue; + + // itag = jtag is possible for long cutoffs that include images of self + // do calculation only on appropriate processor + if (newton_pair == 0 && j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag + jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag + jtag) % 2 == 1) continue; + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + + ri[0] = x[j][0] - xtmp; + ri[1] = x[j][1] - ytmp; + ri[2] = x[j][2] - ztmp; + + rsq = ri[0] * ri[0] + ri[1] * ri[1] + ri[2] * ri[2]; + jtype = type[j]; + + // Check if inside cut-off + if (rsq >= cutsq[itype][jtype]) continue; + + pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); + qi[0] = xtmp - x0; + qi[1] = ytmp - y0; + qi[2] = ztmp - z0; + for (int k = 0; k < 3; k++) { + tmp = domain->boxhi[k] - domain->boxlo[k]; + if (qi[k] > 0.5 * tmp) + qi[k] -= tmp; + else if (qi[k] < -0.5 * tmp) + qi[k] += tmp; + } + l_sum = 0.0; + rij = sqrt(rsq); + f = -rij * fpair; + ririj = qi[0] * ri[0] + qi[1] * ri[1] + qi[2] * ri[2]; + sqr = qi[0] * qi[0] + qi[1] * qi[1] + qi[2] * qi[2]; + la = 0.0; + lb = 0.0; + sql0 = sqr - ririj * ririj / rsq; + lambda0 = -ririj / rsq; + rsqxy = ri[0] * ri[0] + ri[1] * ri[1]; + ririjxy = qi[0] * ri[0] + qi[1] * ri[1]; + sqrixy = qi[0] * qi[0] + qi[1] * qi[1]; + sqlxy0 = (rsqxy != 0.0) ? sqrixy - ririjxy * ririjxy / rsqxy : 0.0; + A = square(qi[0] * ri[1] - qi[1] * ri[0]); + if (sqlxy0 > SMALL) C = sqrt(rsqxy * sqrixy - ririjxy * ririjxy); + if (sql0 > SMALL) B = sqrt(rsq * sqr - ririj * ririj); + end_bin = (int) (sqrt(rsq + 2.0 * ririj + sqr) / bin_width); + + while (lb < 1.0) { + l1 = lb + SMALL; + bin = (int) floor(sqrt(rsq * l1 * l1 + 2.0 * ririj * l1 + sqr) / bin_width); + R1 = bin * bin_width; + R2 = (bin + 1) * bin_width; + + // we must not take the square root of a negative number or divide by zero. + if ((R1 * R1 < sql0) || (R2 * R2 < sql0) || (rsq <= 0.0)) { + lb = 1.0; + } else { + l1 = lambda0 + sqrt((R1 * R1 - sql0) / rsq); + l2 = lambda0 - sqrt((R1 * R1 - sql0) / rsq); + l3 = lambda0 + sqrt((R2 * R2 - sql0) / rsq); + l4 = lambda0 - sqrt((R2 * R2 - sql0) / rsq); + + if (l4 >= 0.0 && l4 <= 1.0 && l4 > la) + lb = l4; + else if (l3 >= 0.0 && l3 <= 1.0 && l3 > la) + lb = l3; + else if (l2 >= 0.0 && l2 <= 1.0 && l2 > la) + lb = l2; + else if (l1 >= 0.0 && l1 <= 1.0 && l1 > la) + lb = l1; + else + lb = 1.0; + } + + if (bin == end_bin) lb = 1.0; + if (la > lb) error->all(FLERR, "Error: la > lb\n"); + if (bin >= 0 && bin < nbins) { + if (sql0 > SMALL) { + Fa = -B * atan2(rsq * la + ririj, B); + Fb = -B * atan2(rsq * lb + ririj, B); + tpcrr[bin] -= (f / rij) * (rsq * (lb - la) + Fb - Fa); + tpcpp[bin] -= (f / rij) * (Fa - Fb) / 2.0; + } else + tpcrr[bin] -= f * rij * (lb - la); + + if (sqlxy0 > SMALL) + tpctt[bin] -= (f / rij) * A / C * + (atan2(rsqxy * lb + ririjxy, C) - atan2(rsqxy * la + ririjxy, C)); + } + l_sum += lb - la; + la = lb; + } + + // Error check + if (fabs(l_sum - 1.0) > SMALL) + error->all(FLERR, "ERROR: The sum of the fractional line segments is not 1.0"); + } + } + + // normalize pressure + for (bin = 0; bin < nbins; bin++) { + tdens[bin] *= invV[bin]; + tpkrr[bin] *= invV[bin]; + tpktt[bin] *= invV[bin]; + tpkpp[bin] *= invV[bin]; + tpcrr[bin] *= invV[bin]; + tpctt[bin] *= invV[bin]; + tpcpp[bin] *= invV[bin]; + } + // communicate across processors + MPI_Allreduce(tdens, dens, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpkrr, pkrr, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpktt, pktt, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpkpp, pkpp, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpcrr, pcrr, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpctt, pctt, nbins, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(tpcpp, pcpp, nbins, MPI_DOUBLE, MPI_SUM, world); + + // populate array to output. + for (bin = 0; bin < nbins; bin++) { + array[bin][0] = (bin + 0.5) * bin_width; + array[bin][1] = dens[bin]; + array[bin][2] = pkrr[bin]; + array[bin][3] = pktt[bin]; + array[bin][4] = pkpp[bin]; + array[bin][5] = pcrr[bin]; + array[bin][6] = pctt[bin]; + array[bin][7] = pcpp[bin]; + } +} + +double ComputeStressSpherical::memory_usage() +{ + return 15.0 * (double) (nbins + size_array_rows * size_array_cols) * sizeof(double); +} diff --git a/src/EXTRA-COMPUTE/compute_stress_spherical.h b/src/EXTRA-COMPUTE/compute_stress_spherical.h new file mode 100644 index 0000000000..61a32e3ff2 --- /dev/null +++ b/src/EXTRA-COMPUTE/compute_stress_spherical.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(stress/spherical,ComputeStressSpherical); +// clang-format on +#else + +#ifndef LMP_COMPUTE_STRESS_SPHERICAL_H +#define LMP_COMPUTE_STRESS_SPHERICAL_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeStressSpherical : public Compute { + public: + ComputeStressSpherical(class LAMMPS *, int, char **); + ~ComputeStressSpherical() override; + void init() override; + void init_list(int, class NeighList *) override; + void compute_array() override; + double memory_usage() override; + + private: + int nbins; + double bin_width, x0, y0, z0, Rmax; + + // Number density, kinetic and configurational contribution to the pressure. + double *invV, *dens, *pkrr, *pktt, *pkpp, *pcrr, *pctt, *pcpp; + double *tdens, *tpkrr, *tpktt, *tpkpp, *tpcrr, *tpctt, *tpcpp; + class NeighList *list; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: No pair style is defined for compute stress/spherical + +Self-explanatory. + +E: Pair style does not support compute stress/spherical + +The pair style does not have a single() function, so it can +not be invoked by compute stress/spherical + +*/ diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp index 2f7ed201a4..b131cc2be1 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp @@ -115,7 +115,6 @@ void FixACKS2ReaxFFKokkos::init() neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->ghost = 1; } int ntypes = atom->ntypes; diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp index bdac648772..ba4c85e98c 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp @@ -117,7 +117,6 @@ void FixQEqReaxFFKokkos::init() neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->ghost = 1; } int ntypes = atom->ntypes; @@ -788,7 +787,7 @@ int FixQEqReaxFFKokkos::cg_solve() } // tmp = parallel_dot(d, q, nn); - Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nn),*this,my_dot); + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nn),*this,my_dot); MPI_Allreduce(&my_dot.v, &dot_sqr.v, 2, MPI_DOUBLE, MPI_SUM, world); tmp = dot_sqr; if (!(converged & 1)) @@ -858,6 +857,19 @@ void FixQEqReaxFFKokkos::sparse_matvec_kokkos(typename AT::t_ffloat2 Kokkos::parallel_for(Kokkos::RangePolicy(0,nn),*this); + int teamsize; + int vectorsize; + int leaguesize; + if (execution_space == Host) { + teamsize = 1; + vectorsize = 1; + leaguesize = nn; + } else { + teamsize = FixQEqReaxFFKokkos::spmv_teamsize; + vectorsize = FixQEqReaxFFKokkos::vectorsize; + leaguesize = (nn + teamsize - 1) / (teamsize); + } + if (neighflag != FULL) { Kokkos::parallel_for(Kokkos::RangePolicy(nn,NN),*this); @@ -865,28 +877,14 @@ void FixQEqReaxFFKokkos::sparse_matvec_kokkos(typename AT::t_ffloat2 dup_o.reset_except(d_o); if (neighflag == HALF) - Kokkos::parallel_for(Kokkos::RangePolicy >(0,nn),*this); + Kokkos::parallel_for(Kokkos::TeamPolicy>(leaguesize, teamsize, vectorsize), *this); else if (neighflag == HALFTHREAD) - Kokkos::parallel_for(Kokkos::RangePolicy >(0,nn),*this); + Kokkos::parallel_for(Kokkos::TeamPolicy>(leaguesize, teamsize, vectorsize), *this); if (need_dup) Kokkos::Experimental::contribute(d_o, dup_o); - } else { // FULL - int teamsize; - int vectorsize; - int leaguesize; - if (execution_space == Host) { - teamsize = 1; - vectorsize = 1; - leaguesize = nn; - } else { - teamsize = FixQEqReaxFFKokkos::spmv_teamsize; - vectorsize = FixQEqReaxFFKokkos::vectorsize; - leaguesize = (nn + teamsize - 1) / (teamsize); - } - + } else // FULL Kokkos::parallel_for(Kokkos::TeamPolicy (leaguesize, teamsize, vectorsize), *this); - } } /* ---------------------------------------------------------------------- */ @@ -925,34 +923,39 @@ void FixQEqReaxFFKokkos::operator()(TagQEqZeroQGhosts, const int &i) template template KOKKOS_INLINE_FUNCTION -void FixQEqReaxFFKokkos::operator()(TagQEqSparseMatvec2_Half, const int &ii) const +void FixQEqReaxFFKokkos::operator()(TagQEqSparseMatvec2_Half, const typename Kokkos::TeamPolicy>::member_type &team) const { - // The q array is duplicated for OpenMP, atomic for CUDA, and neither for Serial - auto v_o = ScatterViewHelper,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); - auto a_o = v_o.template access>(); + int k = team.league_rank() * team.team_size() + team.team_rank(); + if (k < nn) { + // The q array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + auto v_o = ScatterViewHelper,decltype(dup_o),decltype(ndup_o)>::get(dup_o,ndup_o); + auto a_o = v_o.template access>(); - const int i = d_ilist[ii]; - if (mask[i] & groupbit) { - F_FLOAT2 tmp; - const auto d_xx_i0 = d_xx(i,0); - const auto d_xx_i1 = d_xx(i,1); + const int i = d_ilist[k]; + if (mask[i] & groupbit) { + F_FLOAT2 doitmp; + const double d_xx_i0 = d_xx(i,0); + const double d_xx_i1 = d_xx(i,1); - for (int jj = d_firstnbr[i]; jj < d_firstnbr[i] + d_numnbrs[i]; jj++) { - const int j = d_jlist(jj); - const auto d_val_jj = d_val(jj); - if (!(converged & 1)) { - tmp.v[0] += d_val_jj * d_xx(j,0); - a_o(j,0) += d_val_jj * d_xx_i0; - } - if (!(converged & 2)) { - tmp.v[1] += d_val_jj * d_xx(j,1); - a_o(j,1) += d_val_jj * d_xx_i1; - } + Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT2& doi) { + const int j = d_jlist(jj); + const auto d_val_jj = d_val(jj); + if (!(converged & 1)) { + doi.v[0] += d_val_jj * d_xx(j,0); + a_o(j,0) += d_val_jj * d_xx_i0; + } + if (!(converged & 2)) { + doi.v[1] += d_val_jj * d_xx(j,1); + a_o(j,1) += d_val_jj * d_xx_i1; + } + }, doitmp); + Kokkos::single(Kokkos::PerThread(team), [&] () { + if (!(converged & 1)) + a_o(i,0) += doitmp.v[0]; + if (!(converged & 2)) + a_o(i,1) += doitmp.v[1]; + }); } - if (!(converged & 1)) - a_o(i,0) += tmp.v[0]; - if (!(converged & 2)) - a_o(i,1) += tmp.v[1]; } } @@ -962,7 +965,7 @@ template KOKKOS_INLINE_FUNCTION void FixQEqReaxFFKokkos::operator()(TagQEqSparseMatvec2_Full, const membertype_vec &team) const { - int k = team.league_rank () * team.team_size () + team.team_rank (); + int k = team.league_rank() * team.team_size() + team.team_rank(); if (k < nn) { const int i = d_ilist[k]; if (mask[i] & groupbit) { diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.h b/src/KOKKOS/fix_qeq_reaxff_kokkos.h index 9a22a0f0d0..bd38522811 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.h +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.h @@ -82,7 +82,7 @@ class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase { template KOKKOS_INLINE_FUNCTION - void compute_h_team(const typename Kokkos::TeamPolicy ::member_type &team, int, int) const; + void compute_h_team(const typename Kokkos::TeamPolicy::member_type &team, int, int) const; KOKKOS_INLINE_FUNCTION void operator()(TagQEqSparseMatvec1, const int&) const; @@ -92,9 +92,9 @@ class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase { template KOKKOS_INLINE_FUNCTION - void operator()(TagQEqSparseMatvec2_Half, const int&) const; + void operator()(TagQEqSparseMatvec2_Half, const typename Kokkos::TeamPolicy>::member_type &team) const; - typedef typename Kokkos::TeamPolicy ::member_type membertype_vec; + typedef typename Kokkos::TeamPolicy::member_type membertype_vec; KOKKOS_INLINE_FUNCTION void operator()(TagQEqSparseMatvec2_Full, const membertype_vec &team) const; diff --git a/src/KOKKOS/pair_reaxff_kokkos.cpp b/src/KOKKOS/pair_reaxff_kokkos.cpp index 70c034a70a..876654e628 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.cpp +++ b/src/KOKKOS/pair_reaxff_kokkos.cpp @@ -21,6 +21,7 @@ number of exponentials evaluated, etc. - Added blocking to the Torsion and (optionally) BuildLists kernels, to reduce thread divergence on GPUs + - Added preview to BuildLists kernels along with full version ------------------------------------------------------------------------- */ #include "pair_reaxff_kokkos.h" @@ -704,7 +705,7 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) k_params_fbp.template sync(); k_params_hbp.template sync(); - if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + if (eflag_either || vflag_either) atomKK->modified(execution_space,datamask_modify); else atomKK->modified(execution_space,F_MASK); x = atomKK->k_x.view(); @@ -761,15 +762,15 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) // Polarization (self) if (neighflag == HALF) { - if (evflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); - else - Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); + if (eflag_global) + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); + else if (eflag_atom) + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { //if (neighflag == HALFTHREAD) { - if (evflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); - else - Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); + if (eflag_global) + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); + else if (eflag_atom) + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } ev_all += ev; pvector[13] = ev.ecoul; @@ -838,16 +839,23 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) // zero Kokkos::parallel_for(Kokkos::RangePolicy(0,nmax),*this); - if (list_blocking_flag) { + if (execution_space == Host) { // CPU if (neighflag == HALF) - Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); else if (neighflag == HALFTHREAD) - Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); } else { - if (neighflag == HALF) - Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); - else if (neighflag == HALFTHREAD) - Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + if (list_blocking_flag) { + if (neighflag == HALF) + Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + else if (neighflag == HALFTHREAD) + Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + } else { + if (neighflag == HALF) + Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + else if (neighflag == HALFTHREAD) + Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); + } } k_resize_bo.modify(); @@ -873,6 +881,9 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) } } + if (execution_space != Host) // GPU + Kokkos::parallel_for(Kokkos::RangePolicy(0,ignum),*this); + // allocate duplicated memory if (need_dup) { dup_CdDelta = Kokkos::Experimental::create_scatter_view(d_CdDelta); @@ -897,14 +908,14 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) // Bond energy if (neighflag == HALF) { - if (evflag) + if (eflag_either) Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); ev_all += ev; pvector[0] = ev.evdwl; } else { //if (neighflag == HALFTHREAD) { - if (evflag) + if (eflag_either) Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); @@ -914,15 +925,15 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) // Multi-body corrections if (neighflag == HALF) { - Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); - if (evflag) + Kokkos::parallel_for(Kokkos::RangePolicy(0,inum),*this); + if (eflag_either) Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); ev_all += ev; } else { //if (neighflag == HALFTHREAD) { - Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); - if (evflag) + Kokkos::parallel_for(Kokkos::RangePolicy(0,inum),*this); + if (eflag_either) Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); @@ -976,15 +987,15 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (evflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,nnz),*this,ev); + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,nnz),*this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy>(0,nnz),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,nnz),*this); ev_all += ev; } else { if (evflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,nnz),*this,ev); + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,nnz),*this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy>(0,nnz),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,nnz),*this); ev_all += ev; } @@ -1035,7 +1046,7 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) // Kokkos::Experimental::contribute(d_Cdbopi2, dup_Cdbopi2); // needed in ComputeBond2 //} - if (evflag) + if (vflag_either) Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,ignum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); @@ -1051,7 +1062,7 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) // Kokkos::Experimental::contribute(d_Cdbopi2, dup_Cdbopi2); // needed in ComputeBond2 //} - if (evflag) + if (vflag_either) Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,ignum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy>(0,ignum),*this); @@ -1067,6 +1078,7 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) eng_vdwl += ev_all.evdwl; eng_coul += ev_all.ecoul; } + if (vflag_global) { virial[0] += ev_all.v[0]; virial[1] += ev_all.v[1]; @@ -1114,9 +1126,9 @@ void PairReaxFFKokkos::compute(int eflag_in, int vflag_in) /* ---------------------------------------------------------------------- */ template -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputePolar, const int &ii, EV_FLOAT_REAX& ev) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputePolar, const int &ii, EV_FLOAT_REAX& ev) const { const int i = d_ilist[ii]; const int itype = type(i); @@ -1130,17 +1142,17 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputePolartemplate ev_tally(ev,i,i,epol,0.0,0.0,0.0,0.0); if (eflag_atom) this->template e_tally_single(ev,i,epol); } template -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputePolar, const int &ii) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputePolar, const int &ii) const { EV_FLOAT_REAX ev; - this->template operator()(TagPairReaxComputePolar(), ii, ev); + this->template operator()(TagPairReaxComputePolar(), ii, ev); } /* ---------------------------------------------------------------------- */ @@ -1318,10 +1330,12 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeLJCoulombtemplate ev_tally(ev,i,j,evdwl+ecoul,-ftotal,delx,dely,delz); + if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,evdwl+ecoul,-ftotal,delx,dely,delz); + } } a_f(i,0) += fxtmp; @@ -1463,10 +1477,12 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTabulatedLJCoulo a_f(j,1) -= dely*ftotal; a_f(j,2) -= delz*ftotal; - if (eflag) ev.evdwl += evdwl; - if (eflag) ev.ecoul += ecoul; + if (EVFLAG) { + if (eflag_global) ev.evdwl += evdwl; + if (eflag_global) ev.ecoul += ecoul; - if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,evdwl+ecoul,-ftotal,delx,dely,delz); + if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,evdwl+ecoul,-ftotal,delx,dely,delz); + } } a_f(i,0) += fxtmp; @@ -1586,7 +1602,8 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< const int three = 3; F_FLOAT C12, C34, C56, BO_s, BO_pi, BO_pi2, BO, delij[three], dBOp_i[three], dln_BOp_pi_i[three], dln_BOp_pi2_i[three]; - F_FLOAT total_bo = 0.0; + F_FLOAT dDeltap_self_i[3] = {0.0,0.0,0.0}; + F_FLOAT total_bo_i = 0.0; int j_index,i_index; d_bo_first[i] = i*maxbo; @@ -1609,7 +1626,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< int jj_current = 0; while (jj_current < jnum) { - nnz=0; + nnz = 0; while (nnz < blocksize) { int jj = jj_current; @@ -1625,7 +1642,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< const F_FLOAT rsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2]; double cutoffsq; - if(i < nlocal) cutoffsq = MAX(cut_bosq,cut_hbsq); + if (i < nlocal) cutoffsq = MAX(cut_bosq,cut_hbsq); else cutoffsq = cut_bosq; if (rsq <= cutoffsq) { selected_jj[nnz] = jj_current; @@ -1646,10 +1663,6 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< delij[2] = x(j,2) - ztmp; const F_FLOAT rsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2]; - double cutoffsq; - if(i < nlocal) cutoffsq = MAX(cut_bosq,cut_hbsq); - else cutoffsq = cut_bosq; - // hbond list if (i < nlocal && cut_hbsq > 0.0 && (ihb == 1 || ihb == 2) && rsq <= cut_hbsq) { jhb = paramssing(jtype).p_hbond; @@ -1657,9 +1670,8 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< if (NEIGHFLAG == HALF) { j_index = hb_first_i + d_hb_num[i]; d_hb_num[i]++; - } else { + } else j_index = hb_first_i + Kokkos::atomic_fetch_add(&d_hb_num[i],1); - } const int jj_index = j_index - hb_first_i; @@ -1698,22 +1710,19 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< const F_FLOAT r_pi2 = paramstwbp(itype,jtype).r_pi2; if (paramssing(itype).r_s > 0.0 && paramssing(jtype).r_s > 0.0) { - C12 = p_bo1*pow(rij/r_s,p_bo2); + C12 = p_bo1 * ((p_bo2 != 0) ? (pow(rij/r_s,p_bo2)) : 1.0); BO_s = (1.0+bo_cut)*exp(C12); - } - else BO_s = C12 = 0.0; + } else BO_s = C12 = 0.0; if (paramssing(itype).r_pi > 0.0 && paramssing(jtype).r_pi > 0.0) { - C34 = p_bo3*pow(rij/r_pi,p_bo4); + C34 = p_bo3 * ((p_bo4 != 0) ? (pow(rij/r_pi,p_bo4)) : 1.0); BO_pi = exp(C34); - } - else BO_pi = C34 = 0.0; + } else BO_pi = C34 = 0.0; if (paramssing(itype).r_pi2 > 0.0 && paramssing(jtype).r_pi2 > 0.0) { - C56 = p_bo5*pow(rij/r_pi2,p_bo6); + C56 = p_bo5 * ((p_bo6 != 0) ? (pow(rij/r_pi2,p_bo6)) : 1.0); BO_pi2 = exp(C56); - } - else BO_pi2 = C56 = 0.0; + } else BO_pi2 = C56 = 0.0; BO = BO_s + BO_pi + BO_pi2; if (BO < bo_cut) continue; @@ -1723,8 +1732,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< i_index = d_bo_first[j] + d_bo_num[j]; d_bo_num[i]++; d_bo_num[j]++; - } - else { + } else { j_index = bo_first_i + Kokkos::atomic_fetch_add(&d_bo_num[i],1); i_index = d_bo_first[j] + Kokkos::atomic_fetch_add(&d_bo_num[j],1); } @@ -1736,69 +1744,72 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< const int max_val = MAX(ii_index+1,jj_index+1); d_resize_bo() = MAX(d_resize_bo(),max_val); } else { - d_bo_list[j_index] = j; - d_bo_list[i_index] = i; + d_bo_list[j_index] = j; + d_bo_list[i_index] = i; - // from BondOrder1 + // from BondOrder1 - d_BO(i,jj_index) = BO; - d_BO_s(i,jj_index) = BO_s; - d_BO_pi(i,jj_index) = BO_pi; - d_BO_pi2(i,jj_index) = BO_pi2; + d_BO(i,jj_index) = BO; + d_BO_s(i,jj_index) = BO_s; + d_BO_pi(i,jj_index) = BO_pi; + d_BO_pi2(i,jj_index) = BO_pi2; - d_BO(j,ii_index) = BO; - d_BO_s(j,ii_index) = BO_s; - d_BO_pi(j,ii_index) = BO_pi; - d_BO_pi2(j,ii_index) = BO_pi2; + d_BO(j,ii_index) = BO; + d_BO_s(j,ii_index) = BO_s; + d_BO_pi(j,ii_index) = BO_pi; + d_BO_pi2(j,ii_index) = BO_pi2; - F_FLOAT Cln_BOp_s = p_bo2 * C12 / rij / rij; - F_FLOAT Cln_BOp_pi = p_bo4 * C34 / rij / rij; - F_FLOAT Cln_BOp_pi2 = p_bo6 * C56 / rij / rij; + F_FLOAT Cln_BOp_s = p_bo2 * C12 / rij / rij; + F_FLOAT Cln_BOp_pi = p_bo4 * C34 / rij / rij; + F_FLOAT Cln_BOp_pi2 = p_bo6 * C56 / rij / rij; - if (nlocal == 0) - Cln_BOp_s = Cln_BOp_pi = Cln_BOp_pi2 = 0.0; + if (nlocal == 0) + Cln_BOp_s = Cln_BOp_pi = Cln_BOp_pi2 = 0.0; - for (int d = 0; d < 3; d++) dln_BOp_pi_i[d] = -(BO_pi*Cln_BOp_pi)*delij[d]; - for (int d = 0; d < 3; d++) dln_BOp_pi2_i[d] = -(BO_pi2*Cln_BOp_pi2)*delij[d]; - for (int d = 0; d < 3; d++) dBOp_i[d] = -(BO_s*Cln_BOp_s+BO_pi*Cln_BOp_pi+BO_pi2*Cln_BOp_pi2)*delij[d]; - for (int d = 0; d < 3; d++) a_dDeltap_self(i,d) += dBOp_i[d]; - for (int d = 0; d < 3; d++) a_dDeltap_self(j,d) += -dBOp_i[d]; + for (int d = 0; d < 3; d++) dln_BOp_pi_i[d] = -(BO_pi*Cln_BOp_pi)*delij[d]; + for (int d = 0; d < 3; d++) dln_BOp_pi2_i[d] = -(BO_pi2*Cln_BOp_pi2)*delij[d]; + for (int d = 0; d < 3; d++) dBOp_i[d] = -(BO_s*Cln_BOp_s+BO_pi*Cln_BOp_pi+BO_pi2*Cln_BOp_pi2)*delij[d]; + for (int d = 0; d < 3; d++) dDeltap_self_i[d] += dBOp_i[d]; + for (int d = 0; d < 3; d++) a_dDeltap_self(j,d) += -dBOp_i[d]; - d_dln_BOp_pix(i,jj_index) = dln_BOp_pi_i[0]; - d_dln_BOp_piy(i,jj_index) = dln_BOp_pi_i[1]; - d_dln_BOp_piz(i,jj_index) = dln_BOp_pi_i[2]; + d_dln_BOp_pix(i,jj_index) = dln_BOp_pi_i[0]; + d_dln_BOp_piy(i,jj_index) = dln_BOp_pi_i[1]; + d_dln_BOp_piz(i,jj_index) = dln_BOp_pi_i[2]; - d_dln_BOp_pix(j,ii_index) = -dln_BOp_pi_i[0]; - d_dln_BOp_piy(j,ii_index) = -dln_BOp_pi_i[1]; - d_dln_BOp_piz(j,ii_index) = -dln_BOp_pi_i[2]; + d_dln_BOp_pix(j,ii_index) = -dln_BOp_pi_i[0]; + d_dln_BOp_piy(j,ii_index) = -dln_BOp_pi_i[1]; + d_dln_BOp_piz(j,ii_index) = -dln_BOp_pi_i[2]; - d_dln_BOp_pi2x(i,jj_index) = dln_BOp_pi2_i[0]; - d_dln_BOp_pi2y(i,jj_index) = dln_BOp_pi2_i[1]; - d_dln_BOp_pi2z(i,jj_index) = dln_BOp_pi2_i[2]; + d_dln_BOp_pi2x(i,jj_index) = dln_BOp_pi2_i[0]; + d_dln_BOp_pi2y(i,jj_index) = dln_BOp_pi2_i[1]; + d_dln_BOp_pi2z(i,jj_index) = dln_BOp_pi2_i[2]; - d_dln_BOp_pi2x(j,ii_index) = -dln_BOp_pi2_i[0]; - d_dln_BOp_pi2y(j,ii_index) = -dln_BOp_pi2_i[1]; - d_dln_BOp_pi2z(j,ii_index) = -dln_BOp_pi2_i[2]; + d_dln_BOp_pi2x(j,ii_index) = -dln_BOp_pi2_i[0]; + d_dln_BOp_pi2y(j,ii_index) = -dln_BOp_pi2_i[1]; + d_dln_BOp_pi2z(j,ii_index) = -dln_BOp_pi2_i[2]; - d_dBOpx(i,jj_index) = dBOp_i[0]; - d_dBOpy(i,jj_index) = dBOp_i[1]; - d_dBOpz(i,jj_index) = dBOp_i[2]; + d_dBOpx(i,jj_index) = dBOp_i[0]; + d_dBOpy(i,jj_index) = dBOp_i[1]; + d_dBOpz(i,jj_index) = dBOp_i[2]; - d_dBOpx(j,ii_index) = -dBOp_i[0]; - d_dBOpy(j,ii_index) = -dBOp_i[1]; - d_dBOpz(j,ii_index) = -dBOp_i[2]; + d_dBOpx(j,ii_index) = -dBOp_i[0]; + d_dBOpy(j,ii_index) = -dBOp_i[1]; + d_dBOpz(j,ii_index) = -dBOp_i[2]; - d_BO(i,jj_index) -= bo_cut; - d_BO(j,ii_index) -= bo_cut; - d_BO_s(i,jj_index) -= bo_cut; - d_BO_s(j,ii_index) -= bo_cut; - total_bo += d_BO(i,jj_index); - a_total_bo[j] += d_BO(j,ii_index); + d_BO(i,jj_index) -= bo_cut; + d_BO(j,ii_index) -= bo_cut; + d_BO_s(i,jj_index) -= bo_cut; + d_BO_s(j,ii_index) -= bo_cut; + total_bo_i += d_BO(i,jj_index); + a_total_bo[j] += d_BO(j,ii_index); } } } - a_total_bo[i] += total_bo; + for (int d = 0; d < 3; d++) + a_dDeltap_self(i,d) += dDeltap_self_i[d]; + + a_total_bo[i] += total_bo_i; } /* ---------------------------------------------------------------------- */ @@ -1806,13 +1817,8 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlocking< template template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalf, const int &ii) const { - - const auto v_dDeltap_self = ScatterViewHelper,decltype(dup_dDeltap_self),decltype(ndup_dDeltap_self)>::get(dup_dDeltap_self,ndup_dDeltap_self); - const auto a_dDeltap_self = v_dDeltap_self.template access>(); - - const auto v_total_bo = ScatterViewHelper,decltype(dup_total_bo),decltype(ndup_total_bo)>::get(dup_total_bo,ndup_total_bo); - const auto a_total_bo = v_total_bo.template access>(); +void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfBlockingPreview, const int &ii) const { + constexpr int blocksize = PairReaxFFKokkos::build_lists_half_blocksize; const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); @@ -1821,9 +1827,170 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalf 0.0) { + ihb = paramssing(itype).p_hbond; + if (ihb == 1) { + d_hb_first[i] = i*maxhb; + hb_first_i = d_hb_first[i]; + } + } + + int nnz; + blocking_t selected_jj[blocksize]; + int jj_current = 0; + + double cutoffsq; + if (i < nlocal) cutoffsq = MAX(cut_bosq,cut_hbsq); + else cutoffsq = cut_bosq; + + while (jj_current < jnum) { + nnz = 0; + + while (nnz < blocksize) { + int jj = jj_current; + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + + d_bo_first[j] = j*maxbo; + d_hb_first[j] = j*maxhb; + + delij[0] = x(j,0) - xtmp; + delij[1] = x(j,1) - ytmp; + delij[2] = x(j,2) - ztmp; + const F_FLOAT rsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2]; + + if (rsq <= cutoffsq) { + selected_jj[nnz] = jj_current; + nnz++; + } + jj_current++; + + if (jj_current == jnum) break; + } + + for (int jj_inner = 0; jj_inner < nnz; jj_inner++) { + const int jj = selected_jj[jj_inner]; + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + const int jtype = type(j); + delij[0] = x(j,0) - xtmp; + delij[1] = x(j,1) - ytmp; + delij[2] = x(j,2) - ztmp; + const F_FLOAT rsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2]; + + // hbond list + if (i < nlocal && cut_hbsq > 0.0 && (ihb == 1 || ihb == 2) && rsq <= cut_hbsq) { + jhb = paramssing(jtype).p_hbond; + if (ihb == 1 && jhb == 2) { + if (NEIGHFLAG == HALF) { + j_index = hb_first_i + d_hb_num[i]; + d_hb_num[i]++; + } else + j_index = hb_first_i + Kokkos::atomic_fetch_add(&d_hb_num[i],1); + + const int jj_index = j_index - hb_first_i; + + if (jj_index >= maxhb) + d_resize_hb() = MAX(d_resize_hb(),jj_index+1); + else + d_hb_list[j_index] = j; + } else if (j < nlocal && ihb == 2 && jhb == 1) { + if (NEIGHFLAG == HALF) { + i_index = d_hb_first[j] + d_hb_num[j]; + d_hb_num[j]++; + } else + i_index = d_hb_first[j] + Kokkos::atomic_fetch_add(&d_hb_num[j],1); + + const int ii_index = i_index - d_hb_first[j]; + + if (ii_index >= maxhb) + d_resize_hb() = MAX(d_resize_hb(),ii_index+1); + else + d_hb_list[i_index] = i; + } + } + + if (rsq > cut_bosq) continue; + + // bond_list + const F_FLOAT rij = sqrt(rsq); + const F_FLOAT p_bo1 = paramstwbp(itype,jtype).p_bo1; + const F_FLOAT p_bo2 = paramstwbp(itype,jtype).p_bo2; + const F_FLOAT p_bo3 = paramstwbp(itype,jtype).p_bo3; + const F_FLOAT p_bo4 = paramstwbp(itype,jtype).p_bo4; + const F_FLOAT p_bo5 = paramstwbp(itype,jtype).p_bo5; + const F_FLOAT p_bo6 = paramstwbp(itype,jtype).p_bo6; + const F_FLOAT r_s = paramstwbp(itype,jtype).r_s; + const F_FLOAT r_pi = paramstwbp(itype,jtype).r_pi; + const F_FLOAT r_pi2 = paramstwbp(itype,jtype).r_pi2; + + if (paramssing(itype).r_s > 0.0 && paramssing(jtype).r_s > 0.0) { + C12 = p_bo1 * ((p_bo2 != 0) ? (pow(rij/r_s,p_bo2)) : 1.0); + BO_s = (1.0+bo_cut)*exp(C12); + } else BO_s = C12 = 0.0; + + if (paramssing(itype).r_pi > 0.0 && paramssing(jtype).r_pi > 0.0) { + C34 = p_bo3 * ((p_bo4 != 0) ? (pow(rij/r_pi,p_bo4)) : 1.0); + BO_pi = exp(C34); + } else BO_pi = C34 = 0.0; + + if (paramssing(itype).r_pi2 > 0.0 && paramssing(jtype).r_pi2 > 0.0) { + C56 = p_bo5 * ((p_bo6 != 0) ? (pow(rij/r_pi2,p_bo6)) : 1.0); + BO_pi2 = exp(C56); + } else BO_pi2 = C56 = 0.0; + + BO = BO_s + BO_pi + BO_pi2; + if (BO < bo_cut) continue; + + if (NEIGHFLAG == HALF) { + j_index = bo_first_i + d_bo_num[i]; + i_index = d_bo_first[j] + d_bo_num[j]; + d_bo_num[i]++; + d_bo_num[j]++; + } else { + j_index = bo_first_i + Kokkos::atomic_fetch_add(&d_bo_num[i],1); + i_index = d_bo_first[j] + Kokkos::atomic_fetch_add(&d_bo_num[j],1); + } + + const int jj_index = j_index - bo_first_i; + const int ii_index = i_index - d_bo_first[j]; + + if (jj_index >= maxbo || ii_index >= maxbo) { + const int max_val = MAX(ii_index+1,jj_index+1); + d_resize_bo() = MAX(d_resize_bo(),max_val); + } else { + d_bo_list[j_index] = j; + d_bo_list[i_index] = i; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalfPreview, const int &ii) const { + + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + const int jnum = d_numneigh[i]; + + F_FLOAT C12, C34, C56, BO_s, BO_pi, BO_pi2, BO, delij[3]; int j_index,i_index; d_bo_first[i] = i*maxbo; @@ -1854,11 +2021,6 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalf cutoffsq) continue; - // hbond list if (i < nlocal && cut_hbsq > 0.0 && (ihb == 1 || ihb == 2) && rsq <= cut_hbsq) { jhb = paramssing(jtype).p_hbond; @@ -1866,9 +2028,8 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalf::operator()(TagPairReaxBuildListsHalf::operator()(TagPairReaxBuildListsHalf 0.0 && paramssing(jtype).r_s > 0.0) { - C12 = p_bo1*pow(rij/r_s,p_bo2); + C12 = p_bo1 * ((p_bo2 != 0) ? (pow(rij/r_s,p_bo2)) : 1.0); BO_s = (1.0+bo_cut)*exp(C12); - } - else BO_s = C12 = 0.0; + } else BO_s = C12 = 0.0; if (paramssing(itype).r_pi > 0.0 && paramssing(jtype).r_pi > 0.0) { - C34 = p_bo3*pow(rij/r_pi,p_bo4); + C34 = p_bo3 * ((p_bo4 != 0) ? (pow(rij/r_pi,p_bo4)) : 1.0); BO_pi = exp(C34); - } - else BO_pi = C34 = 0.0; + } else BO_pi = C34 = 0.0; if (paramssing(itype).r_pi2 > 0.0 && paramssing(jtype).r_pi2 > 0.0) { - C56 = p_bo5*pow(rij/r_pi2,p_bo6); + C56 = p_bo5 * ((p_bo6 != 0) ? (pow(rij/r_pi2,p_bo6)) : 1.0); BO_pi2 = exp(C56); - } - else BO_pi2 = C56 = 0.0; + } else BO_pi2 = C56 = 0.0; BO = BO_s + BO_pi + BO_pi2; if (BO < bo_cut) continue; @@ -1947,65 +2104,108 @@ void PairReaxFFKokkos::operator()(TagPairReaxBuildListsHalf +KOKKOS_INLINE_FUNCTION +void PairReaxFFKokkos::operator()(TagPairReaxBuildListsFull, const int &ii) const { + + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + F_FLOAT C12, C34, C56, BO_s, BO_pi, BO_pi2, BO, delij[3], dBOp_i[3], dln_BOp_pi_i[3], dln_BOp_pi2_i[3]; + F_FLOAT dDeltap_self_i[3] = {0.0,0.0,0.0}; + F_FLOAT total_bo_i = 0.0; + + const int j_start = d_bo_first[i]; + const int j_end = j_start + d_bo_num[i]; + for (int jj = j_start; jj < j_end; jj++) { + int j = d_bo_list[jj]; + j &= NEIGHMASK; + const int jtype = type(j); + const int j_index = jj - j_start; + delij[0] = x(j,0) - xtmp; + delij[1] = x(j,1) - ytmp; + delij[2] = x(j,2) - ztmp; + const F_FLOAT rsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2]; + const F_FLOAT rsq_inv = 1.0 / rsq; + + // bond_list + const F_FLOAT rij = sqrt(rsq); + const F_FLOAT p_bo1 = paramstwbp(itype,jtype).p_bo1; + const F_FLOAT p_bo2 = paramstwbp(itype,jtype).p_bo2; + const F_FLOAT p_bo3 = paramstwbp(itype,jtype).p_bo3; + const F_FLOAT p_bo4 = paramstwbp(itype,jtype).p_bo4; + const F_FLOAT p_bo5 = paramstwbp(itype,jtype).p_bo5; + const F_FLOAT p_bo6 = paramstwbp(itype,jtype).p_bo6; + const F_FLOAT r_s = paramstwbp(itype,jtype).r_s; + const F_FLOAT r_pi = paramstwbp(itype,jtype).r_pi; + const F_FLOAT r_pi2 = paramstwbp(itype,jtype).r_pi2; + + if (paramssing(itype).r_s > 0.0 && paramssing(jtype).r_s > 0.0) { + C12 = p_bo1 * ((p_bo2 != 0) ? (pow(rij/r_s,p_bo2)) : 1.0); + BO_s = (1.0+bo_cut)*exp(C12); + } else BO_s = C12 = 0.0; + + if (paramssing(itype).r_pi > 0.0 && paramssing(jtype).r_pi > 0.0) { + C34 = p_bo3 * ((p_bo4 != 0) ? (pow(rij/r_pi,p_bo4)) : 1.0); + BO_pi = exp(C34); + } else BO_pi = C34 = 0.0; + + if (paramssing(itype).r_pi2 > 0.0 && paramssing(jtype).r_pi2 > 0.0) { + C56 = p_bo5 * ((p_bo6 != 0) ? (pow(rij/r_pi2,p_bo6)) : 1.0); + BO_pi2 = exp(C56); + } else BO_pi2 = C56 = 0.0; + + BO = BO_s + BO_pi + BO_pi2; + + // from BondOrder1 + + d_BO(i,j_index) = BO; + d_BO_s(i,j_index) = BO_s; + d_BO_pi(i,j_index) = BO_pi; + d_BO_pi2(i,j_index) = BO_pi2; + + F_FLOAT Cln_BOp_s = p_bo2 * C12 * rsq_inv; + F_FLOAT Cln_BOp_pi = p_bo4 * C34 * rsq_inv; + F_FLOAT Cln_BOp_pi2 = p_bo6 * C56 * rsq_inv; + + if (nlocal == 0) + Cln_BOp_s = Cln_BOp_pi = Cln_BOp_pi2 = 0.0; + + for (int d = 0; d < 3; d++) dln_BOp_pi_i[d] = -(BO_pi*Cln_BOp_pi)*delij[d]; + for (int d = 0; d < 3; d++) dln_BOp_pi2_i[d] = -(BO_pi2*Cln_BOp_pi2)*delij[d]; + for (int d = 0; d < 3; d++) dBOp_i[d] = -(BO_s*Cln_BOp_s+BO_pi*Cln_BOp_pi+BO_pi2*Cln_BOp_pi2)*delij[d]; + for (int d = 0; d < 3; d++) dDeltap_self_i[d] += dBOp_i[d]; + + d_dln_BOp_pix(i,j_index) = dln_BOp_pi_i[0]; + d_dln_BOp_piy(i,j_index) = dln_BOp_pi_i[1]; + d_dln_BOp_piz(i,j_index) = dln_BOp_pi_i[2]; + + d_dln_BOp_pi2x(i,j_index) = dln_BOp_pi2_i[0]; + d_dln_BOp_pi2y(i,j_index) = dln_BOp_pi2_i[1]; + d_dln_BOp_pi2z(i,j_index) = dln_BOp_pi2_i[2]; + + d_dBOpx(i,j_index) = dBOp_i[0]; + d_dBOpy(i,j_index) = dBOp_i[1]; + d_dBOpz(i,j_index) = dBOp_i[2]; + + d_BO(i,j_index) -= bo_cut; + d_BO_s(i,j_index) -= bo_cut; + total_bo_i += d_BO(i,j_index); + } + + for (int d = 0; d < 3; d++) + d_dDeltap_self(i,d) = dDeltap_self_i[d]; + + d_total_bo[i] = total_bo_i; } /* ---------------------------------------------------------------------- */ @@ -2192,9 +2392,8 @@ void PairReaxFFKokkos::operator()(TagPairReaxBondOrder3, const int & /* ---------------------------------------------------------------------- */ template -template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti1, const int &ii) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti1, const int &ii) const { const int i = d_ilist[ii]; const int itype = type(i); @@ -2226,9 +2425,9 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti1 -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2, const int &ii, EV_FLOAT_REAX& ev) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2, const int &ii, EV_FLOAT_REAX& ev) const { auto v_CdDelta = ScatterViewHelper,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); auto a_CdDelta = v_CdDelta.template access>(); @@ -2270,7 +2469,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2 0 || enobondsflag) a_CdDelta[i] += CElp; - if (eflag) ev.ereax[0] += e_lp; + if (EFLAG && eflag_global) ev.ereax[0] += e_lp; //if (vflag_either || eflag_atom) this->template ev_tally(ev,i,i,e_lp,0.0,0.0,0.0,0.0); //if (eflag_atom) this->template e_tally(ev,i,i,e_lp); @@ -2286,7 +2485,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2template ev_tally(ev,i,i,e_ov,0.0,0.0,0.0,0.0); //if (eflag_atom) this->template e_tally(ev,i,i,e_ov); @@ -2307,7 +2506,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2 0 || enobondsflag) e_un = -p_ovun5 * (1.0 - exp_ovun6) * inv_exp_ovun2n * inv_exp_ovun8; - if (eflag) ev.ereax[2] += e_un; + if (EFLAG && eflag_global) ev.ereax[2] += e_un; //if (eflag_atom) this->template ev_tally(ev,i,i,e_un,0.0,0.0,0.0,0.0); //if (eflag_atom) this->template e_tally(ev,i,i,e_un); @@ -2350,8 +2549,10 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2template e_tally(ev,i,j,e_lph); + if (EFLAG) { + if (eflag_global) ev.ereax[0] += e_lph; + if (eflag_atom) this->template e_tally(ev,i,j,e_lph); + } } } @@ -2367,11 +2568,11 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2 -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2, const int &ii) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeMulti2, const int &ii) const { EV_FLOAT_REAX ev; - this->template operator()(TagPairReaxComputeMulti2(), ii, ev); + this->template operator()(TagPairReaxComputeMulti2(), ii, ev); } /* ---------------------------------------------------------------------- */ @@ -2591,7 +2792,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeAngular::operator()(TagPairReaxComputeAngular::operator()(TagPairReaxComputeAngular KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionPreview, const int &ii) const { - F_FLOAT bo_ij, bo_ik, bo_jl; + F_FLOAT bo_ij, bo_ik; int counter = 0; const int i = d_ilist[ii]; @@ -2770,7 +2971,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionPreview, template template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking, const int &iii, EV_FLOAT_REAX& ev) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsion, const int &iii, EV_FLOAT_REAX& ev) const { constexpr int blocksize = PairReaxFFKokkos::compute_torsion_blocksize; @@ -2954,7 +3155,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking< sin_ijk = sin(theta_ijk); if (sin_ijk >= 0 && sin_ijk <= 1e-10) tan_ijk_i = cos_ijk / 1e-10; - else if(sin_ijk <= 0 && sin_ijk >= -1e-10) + else if (sin_ijk <= 0 && sin_ijk >= -1e-10) tan_ijk_i = -cos_ijk / 1e-10; else tan_ijk_i = cos_ijk / sin_ijk; @@ -2996,7 +3197,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking< sin_jil = sin(theta_jil); if (sin_jil >= 0 && sin_jil <= 1e-10) tan_jil_i = cos_jil / 1e-10; - else if(sin_jil <= 0 && sin_jil >= -1e-10) + else if (sin_jil <= 0 && sin_jil >= -1e-10) tan_jil_i = -cos_jil / 1e-10; else tan_jil_i = cos_jil / sin_jil; @@ -3047,9 +3248,9 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking< F_FLOAT sin_jil_rnd = sin_jil; if (sin_ijk >= 0 && sin_ijk <= 1e-10) sin_ijk_rnd = 1e-10; - else if(sin_ijk <= 0 && sin_ijk >= -1e-10) sin_ijk_rnd = -1e-10; + else if (sin_ijk <= 0 && sin_ijk >= -1e-10) sin_ijk_rnd = -1e-10; if (sin_jil >= 0 && sin_jil <= 1e-10) sin_jil_rnd = 1e-10; - else if(sin_jil <= 0 && sin_jil >= -1e-10) sin_jil_rnd = -1e-10; + else if (sin_jil <= 0 && sin_jil >= -1e-10) sin_jil_rnd = -1e-10; // dcos_omega_di for (int d = 0; d < 3; d++) dcos_omega_dk[d] = ((htra-arg*hnra)/rik) * delik[d] - dellk[d]; @@ -3093,7 +3294,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking< CV = 0.5 * (V1 * (1.0 + cos_omega) + V2 * exp_tor1 * (1.0 - cos2omega) + V3 * (1.0 + cos3omega)); e_tor = fn10 * sin_ijk * sin_jil * CV; - if (eflag) ev.ereax[6] += e_tor; + if (EVFLAG && eflag_global) ev.ereax[6] += e_tor; dfn11 = (-p_tor3 * exp_tor3_DiDj + (p_tor3 * exp_tor3_DiDj - p_tor4 * exp_tor4_DiDj) * (2.0 + exp_tor3_DiDj) * exp_tor34_inv) * exp_tor34_inv; @@ -3119,7 +3320,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking< fn12 = exp_cot2_ik * exp_cot2_ij * exp_cot2_jl; e_con = p_cot1 * fn12 * (1.0 + (SQR(cos_omega) - 1.0) * sin_ijk * sin_jil); - if (eflag) ev.ereax[7] += e_con; + if (EVFLAG && eflag_global) ev.ereax[7] += e_con; Cconj = -2.0 * fn12 * p_cot1 * p_cot2 * (1.0 + (SQR(cos_omega) - 1.0) * sin_ijk * sin_jil); @@ -3197,10 +3398,10 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking< template template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsionBlocking, const int &ii) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeTorsion, const int &ii) const { EV_FLOAT_REAX ev; - this->template operator()(TagPairReaxComputeTorsionBlocking(), ii, ev); + this->template operator()(TagPairReaxComputeTorsion(), ii, ev); } /* ---------------------------------------------------------------------- */ @@ -3310,7 +3511,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeHydrogen::operator()(TagPairReaxComputeHydrogentemplate e_tally(ev,i,j,e_hb); - if (vflag_either) this->template v_tally3(ev,i,j,k,fj_tmp,fk_tmp,delji,delki); + + if (EVFLAG) { + if (eflag_atom) this->template e_tally(ev,i,j,e_hb); + if (vflag_either) this->template v_tally3(ev,i,j,k,fj_tmp,fk_tmp,delji,delki); + } } } for (int d = 0; d < 3; d++) a_f(i,d) += fitmp[d]; @@ -3406,11 +3610,9 @@ void PairReaxFFKokkos::operator()(TagPairReaxUpdateBond, /* ---------------------------------------------------------------------- */ template -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1, const int &ii, EV_FLOAT_REAX& ev) const { - - auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); +void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1, const int &ii, EV_FLOAT_REAX& ev) const { auto v_CdDelta = ScatterViewHelper,decltype(dup_CdDelta),decltype(ndup_CdDelta)>::get(dup_CdDelta,ndup_CdDelta); auto a_CdDelta = v_CdDelta.template access>(); @@ -3468,7 +3670,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1template ev_tally(ev,i,j,ebond,0.0,0.0,0.0,0.0); //if (eflag_atom) this->template e_tally(ev,i,j,ebond); @@ -3490,7 +3692,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1template ev_tally(ev,i,j,estriph,0.0,0.0,0.0,0.0); //if (eflag_atom) this->template e_tally(ev,i,j,estriph); @@ -3513,19 +3715,19 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1 -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1, const int &ii) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeBond1, const int &ii) const { EV_FLOAT_REAX ev; - this->template operator()(TagPairReaxComputeBond1(), ii, ev); + this->template operator()(TagPairReaxComputeBond1(), ii, ev); } /* ---------------------------------------------------------------------- */ template -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2, const int &ii, EV_FLOAT_REAX& ev) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2, const int &ii, EV_FLOAT_REAX& ev) const { auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); auto a_f = v_f.template access>(); @@ -3627,8 +3829,7 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2template v_tally(ev,i,temp,delij); + if (VFLAG && vflag_either) this->template v_tally(ev,i,temp,delij); fitmp[0] -= temp[0]; fitmp[1] -= temp[1]; @@ -3650,11 +3851,10 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2template v_tally(ev,j,temp,tmpvec); - } + if (VFLAG && vflag_either) { + for (int d = 0; d < 3; d++) tmpvec[d] = -delij[d]; + this->template v_tally(ev,j,temp,tmpvec); + } // forces on k: i neighbor for (int kk = j_start; kk < j_end; kk++) { @@ -3672,14 +3872,13 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2template v_tally(ev,k,temp,tmpvec); - } + if (VFLAG && vflag_either) { + delik[0] = x(k,0) - xtmp; + delik[1] = x(k,1) - ytmp; + delik[2] = x(k,2) - ztmp; + for (int d = 0; d < 3; d++) tmpvec[d] = x(j,d) - x(k,d) - delik[d]; + this->template v_tally(ev,k,temp,tmpvec); + } } @@ -3699,25 +3898,22 @@ void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2template v_tally(ev,k,temp,tmpvec); - } + if (VFLAG && vflag_either) { + for (int d = 0; d < 3; d++) deljk[d] = x(k,d) - x(j,d); + for (int d = 0; d < 3; d++) tmpvec[d] = x(i,d) - x(k,d) - deljk[d]; + this->template v_tally(ev,k,temp,tmpvec); } - } } for (int d = 0; d < 3; d++) a_f(i,d) += fitmp[d]; } template -template +template KOKKOS_INLINE_FUNCTION -void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2, const int &ii) const { +void PairReaxFFKokkos::operator()(TagPairReaxComputeBond2, const int &ii) const { EV_FLOAT_REAX ev; - this->template operator()(TagPairReaxComputeBond2(), ii, ev); + this->template operator()(TagPairReaxComputeBond2(), ii, ev); } /* ---------------------------------------------------------------------- */ @@ -3729,8 +3925,6 @@ void PairReaxFFKokkos::ev_tally(EV_FLOAT_REAX &ev, const int &i, con const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const { - const int VFLAG = vflag_either; - // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); @@ -3745,7 +3939,7 @@ void PairReaxFFKokkos::ev_tally(EV_FLOAT_REAX &ev, const int &i, con a_eatom[j] += epairhalf; } - if (VFLAG) { + if (vflag_either) { const E_FLOAT v0 = delx*delx*fpair; const E_FLOAT v1 = dely*dely*fpair; const E_FLOAT v2 = delz*delz*fpair; @@ -3787,18 +3981,14 @@ KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::e_tally(EV_FLOAT_REAX & /*ev*/, const int &i, const int &j, const F_FLOAT &epair) const { - // The eatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); + auto a_eatom = v_eatom.template access>(); - if (eflag_atom) { - auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); - auto a_eatom = v_eatom.template access>(); - - const E_FLOAT epairhalf = 0.5 * epair; - a_eatom[i] += epairhalf; - a_eatom[j] += epairhalf; - } + const E_FLOAT epairhalf = 0.5 * epair; + a_eatom[i] += epairhalf; + a_eatom[j] += epairhalf; } /* ---------------------------------------------------------------------- */ @@ -3810,6 +4000,7 @@ void PairReaxFFKokkos::e_tally_single(EV_FLOAT_REAX & /*ev*/, const const F_FLOAT &epair) const { // The eatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + auto v_eatom = ScatterViewHelper,decltype(dup_eatom),decltype(ndup_eatom)>::get(dup_eatom,ndup_eatom); auto a_eatom = v_eatom.template access>(); @@ -3824,7 +4015,6 @@ KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::v_tally(EV_FLOAT_REAX &ev, const int &i, F_FLOAT *fi, F_FLOAT *drij) const { - F_FLOAT v[6]; v[0] = 0.5*drij[0]*fi[0]; @@ -3860,7 +4050,6 @@ KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::v_tally3(EV_FLOAT_REAX &ev, const int &i, const int &j, const int &k, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drij, F_FLOAT *drik) const { - // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, and neither for Serial auto v_vatom = ScatterViewHelper,decltype(dup_vatom),decltype(ndup_vatom)>::get(dup_vatom,ndup_vatom); auto a_vatom = v_vatom.template access>(); @@ -3901,7 +4090,6 @@ KOKKOS_INLINE_FUNCTION void PairReaxFFKokkos::v_tally4(EV_FLOAT_REAX &ev, const int &i, const int &j, const int &k, const int &l, F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *dril, F_FLOAT *drjl, F_FLOAT *drkl) const { - // The vatom array is duplicated for OpenMP, atomic for CUDA, and neither for Serial F_FLOAT v[6]; diff --git a/src/KOKKOS/pair_reaxff_kokkos.h b/src/KOKKOS/pair_reaxff_kokkos.h index 7606ecc630..782704b0ca 100644 --- a/src/KOKKOS/pair_reaxff_kokkos.h +++ b/src/KOKKOS/pair_reaxff_kokkos.h @@ -46,7 +46,7 @@ struct LR_lookup_table_kk t_cubic_spline_coef_1d d_ele, d_CEclmb; }; -template +template struct TagPairReaxComputePolar{}; template @@ -61,7 +61,12 @@ template struct TagPairReaxBuildListsHalfBlocking{}; template -struct TagPairReaxBuildListsHalf{}; +struct TagPairReaxBuildListsHalfBlockingPreview{}; + +template +struct TagPairReaxBuildListsHalfPreview{}; + +struct TagPairReaxBuildListsFull{}; struct TagPairReaxZero{}; @@ -74,16 +79,15 @@ struct TagPairReaxBondOrder3{}; template struct TagPairReaxUpdateBond{}; -template +template struct TagPairReaxComputeBond1{}; -template +template struct TagPairReaxComputeBond2{}; -template struct TagPairReaxComputeMulti1{}; -template +template struct TagPairReaxComputeMulti2{}; template @@ -92,7 +96,7 @@ struct TagPairReaxComputeAngular{}; struct TagPairReaxComputeTorsionPreview{}; template -struct TagPairReaxComputeTorsionBlocking{}; +struct TagPairReaxComputeTorsion{}; template struct TagPairReaxComputeHydrogen{}; @@ -133,13 +137,13 @@ class PairReaxFFKokkos : public PairReaxFF { void PackBondBuffer(DAT::tdual_ffloat_1d, int &); void FindBondSpecies(); - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputePolar, const int&, EV_FLOAT_REAX&) const; + void operator()(TagPairReaxComputePolar, const int&, EV_FLOAT_REAX&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputePolar, const int&) const; + void operator()(TagPairReaxComputePolar, const int&) const; template KOKKOS_INLINE_FUNCTION @@ -166,7 +170,14 @@ class PairReaxFFKokkos : public PairReaxFF { template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxBuildListsHalf, const int&) const; + void operator()(TagPairReaxBuildListsHalfBlockingPreview, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairReaxBuildListsHalfPreview, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairReaxBuildListsFull, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(TagPairReaxZero, const int&) const; @@ -184,33 +195,32 @@ class PairReaxFFKokkos : public PairReaxFF { KOKKOS_INLINE_FUNCTION void operator()(TagPairReaxUpdateBond, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeBond1, const int&, EV_FLOAT_REAX&) const; + void operator()(TagPairReaxComputeBond1, const int&, EV_FLOAT_REAX&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeBond1, const int&) const; + void operator()(TagPairReaxComputeBond1, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeBond2, const int&, EV_FLOAT_REAX&) const; + void operator()(TagPairReaxComputeBond2, const int&, EV_FLOAT_REAX&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeBond2, const int&) const; + void operator()(TagPairReaxComputeBond2, const int&) const; - template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeMulti1, const int&) const; + void operator()(TagPairReaxComputeMulti1, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeMulti2, const int&, EV_FLOAT_REAX&) const; + void operator()(TagPairReaxComputeMulti2, const int&, EV_FLOAT_REAX&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeMulti2, const int&) const; + void operator()(TagPairReaxComputeMulti2, const int&) const; template KOKKOS_INLINE_FUNCTION @@ -225,11 +235,11 @@ class PairReaxFFKokkos : public PairReaxFF { template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeTorsionBlocking, const int&, EV_FLOAT_REAX&) const; + void operator()(TagPairReaxComputeTorsion, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION - void operator()(TagPairReaxComputeTorsionBlocking, const int&) const; + void operator()(TagPairReaxComputeTorsion, const int&) const; template KOKKOS_INLINE_FUNCTION diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 9ba677b31d..4d6e30c191 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -20,6 +19,7 @@ #include "pair_mesocnt.h" #include "atom.h" +#include "comm.h" #include "error.h" #include "force.h" #include "math_const.h" @@ -28,6 +28,7 @@ #include "neigh_list.h" #include "neigh_request.h" #include "neighbor.h" +#include "potential_file_reader.h" #include "update.h" #include @@ -73,8 +74,6 @@ PairMesoCNT::~PairMesoCNT() memory->destroy(phi_coeff); memory->destroy(usemi_coeff); - memory->destroy(reduced_neighlist); - memory->destroy(reduced_nlist); memory->destroy(numchainlist); memory->destroy(nchainlist); memory->destroy(endlist); @@ -98,27 +97,27 @@ PairMesoCNT::~PairMesoCNT() void PairMesoCNT::compute(int eflag, int vflag) { - int i,j,k,i1,i2,j1,j2; - int endflag,endindex; - int clen,numchain; - int *end,*nchain; + int i, j, k, i1, i2, j1, j2; + int endflag, endindex; + int clen, numchain; + int *end, *nchain; int **chain; - double fend,lp,scale,sumw,sumw_inv; - double evdwl,evdwl_chain; - double *r1,*r2,*q1,*q2,*qe; - double ftotal[3],ftorque[3],torque[3],delr1[3],delr2[3]; - double t1[3],t2[3]; - double dr1_sumw[3],dr2_sumw[3]; - double dr1_w[3],dr2_w[3],dq1_w[3],dq2_w[3]; - double fgrad_r1_p1[3],fgrad_r1_p2[3],fgrad_r2_p1[3],fgrad_r2_p2[3]; - double fgrad_q_p1[3],fgrad_q_p2[3]; - double q1_dr1_w[3][3],q1_dr2_w[3][3],q2_dr1_w[3][3],q2_dr2_w[3][3]; - double dr1_p1[3][3],dr1_p2[3][3],dr2_p1[3][3],dr2_p2[3][3]; - double dq_p1[3][3],dq_p2[3][3]; + double fend, lp, scale, sumw, sumw_inv; + double evdwl, evdwl_chain; + double *r1, *r2, *q1, *q2, *qe; + double ftotal[3], ftorque[3], torque[3], delr1[3], delr2[3]; + double t1[3], t2[3]; + double dr1_sumw[3], dr2_sumw[3]; + double dr1_w[3], dr2_w[3], dq1_w[3], dq2_w[3]; + double fgrad_r1_p1[3], fgrad_r1_p2[3], fgrad_r2_p1[3], fgrad_r2_p2[3]; + double fgrad_q_p1[3], fgrad_q_p2[3]; + double q1_dr1_w[3][3], q1_dr2_w[3][3], q2_dr1_w[3][3], q2_dr2_w[3][3]; + double dr1_p1[3][3], dr1_p2[3][3], dr2_p1[3][3], dr2_p2[3][3]; + double dq_p1[3][3], dq_p2[3][3]; double temp[3][3]; evdwl = 0.0; - ev_init(eflag,vflag); + ev_init(eflag, vflag); double **x = atom->x; double **f = atom->f; @@ -156,7 +155,7 @@ void PairMesoCNT::compute(int eflag, int vflag) endindex = chain[j][0]; qe = x[endindex]; } else if (endflag == 2) { - endindex = chain[j][clen-1]; + endindex = chain[j][clen - 1]; qe = x[endindex]; } @@ -178,159 +177,161 @@ void PairMesoCNT::compute(int eflag, int vflag) } sumw = 0.0; - for (k = 0; k < clen-1; k++) { + for (k = 0; k < clen - 1; k++) { j1 = chain[j][k]; - j2 = chain[j][k+1]; + j2 = chain[j][k + 1]; j1 &= NEIGHMASK; j2 &= NEIGHMASK; q1 = x[j1]; q2 = x[j2]; - weight(r1,r2,q1,q2,w[k],dr1_w,dr2_w,dq1_w,dq2_w); + weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); if (w[k] == 0.0) { - if (endflag == 1 && k == 0) endflag = 0; - else if (endflag == 2 && k == clen-2) endflag = 0; + if (endflag == 1 && k == 0) + endflag = 0; + else if (endflag == 2 && k == clen - 2) + endflag = 0; continue; } sumw += w[k]; wnode[k] += w[k]; - wnode[k+1] += w[k]; + wnode[k + 1] += w[k]; - scaleadd3(w[k],q1,p1,p1); - scaleadd3(w[k],q2,p2,p2); + scaleadd3(w[k], q1, p1, p1); + scaleadd3(w[k], q2, p2, p2); // weight gradient terms - add3(dr1_w,dr1_sumw,dr1_sumw); - add3(dr2_w,dr2_sumw,dr2_sumw); + add3(dr1_w, dr1_sumw, dr1_sumw); + add3(dr2_w, dr2_sumw, dr2_sumw); - outer3(q1,dr1_w,temp); - plus3(temp,q1_dr1_w,q1_dr1_w); - outer3(q2,dr1_w,temp); - plus3(temp,q2_dr1_w,q2_dr1_w); - outer3(q1,dr2_w,temp); - plus3(temp,q1_dr2_w,q1_dr2_w); - outer3(q2,dr2_w,temp); - plus3(temp,q2_dr2_w,q2_dr2_w); + outer3(q1, dr1_w, temp); + plus3(temp, q1_dr1_w, q1_dr1_w); + outer3(q2, dr1_w, temp); + plus3(temp, q2_dr1_w, q2_dr1_w); + outer3(q1, dr2_w, temp); + plus3(temp, q1_dr2_w, q1_dr2_w); + outer3(q2, dr2_w, temp); + plus3(temp, q2_dr2_w, q2_dr2_w); - add3(dq1_w,dq_w[k],dq_w[k]); - add3(dq2_w,dq_w[k+1],dq_w[k+1]); + add3(dq1_w, dq_w[k], dq_w[k]); + add3(dq2_w, dq_w[k + 1], dq_w[k + 1]); - outer3(q1,dq1_w,temp); - plus3(temp,q1_dq_w[k],q1_dq_w[k]); - outer3(q1,dq2_w,temp); - plus3(temp,q1_dq_w[k+1],q1_dq_w[k+1]); - outer3(q2,dq1_w,temp); - plus3(temp,q2_dq_w[k],q2_dq_w[k]); - outer3(q2,dq2_w,temp); - plus3(temp,q2_dq_w[k+1],q2_dq_w[k+1]); + outer3(q1, dq1_w, temp); + plus3(temp, q1_dq_w[k], q1_dq_w[k]); + outer3(q1, dq2_w, temp); + plus3(temp, q1_dq_w[k + 1], q1_dq_w[k + 1]); + outer3(q2, dq1_w, temp); + plus3(temp, q2_dq_w[k], q2_dq_w[k]); + outer3(q2, dq2_w, temp); + plus3(temp, q2_dq_w[k + 1], q2_dq_w[k + 1]); } if (sumw == 0.0) continue; sumw_inv = 1.0 / sumw; - scale3(sumw_inv,p1); - scale3(sumw_inv,p2); + scale3(sumw_inv, p1); + scale3(sumw_inv, p2); // compute geometry and forces // infinite CNT case if (endflag == 0) { - geometry(r1,r2,p1,p2,nullptr,p,m,param,basis); + geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); if (param[0] > cutoff) continue; - finf(param,evdwl,flocal); + finf(param, evdwl, flocal); // semi-infinite CNT case with end at start of chain } else if (endflag == 1) { - geometry(r1,r2,p1,p2,qe,p,m,param,basis); + geometry(r1, r2, p1, p2, qe, p, m, param, basis); if (param[0] > cutoff) continue; - fsemi(param,evdwl,fend,flocal); + fsemi(param, evdwl, fend, flocal); // semi-infinite CNT case with end at end of chain } else { - geometry(r1,r2,p2,p1,qe,p,m,param,basis); + geometry(r1, r2, p2, p1, qe, p, m, param, basis); if (param[0] > cutoff) continue; - fsemi(param,evdwl,fend,flocal); + fsemi(param, evdwl, fend, flocal); } evdwl *= 0.5; // transform to global coordinate system - matvec(basis[0],basis[1],basis[2],flocal[0],fglobal[0]); - matvec(basis[0],basis[1],basis[2],flocal[1],fglobal[1]); + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); // forces acting on approximate chain - add3(fglobal[0],fglobal[1],ftotal); - if (endflag) scaleadd3(fend,m,ftotal,ftotal); - scale3(-0.5,ftotal); + add3(fglobal[0], fglobal[1], ftotal); + if (endflag) scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); - sub3(r1,p,delr1); - sub3(r2,p,delr2); - cross3(delr1,fglobal[0],t1); - cross3(delr2,fglobal[1],t2); - add3(t1,t2,torque); + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); - cross3(torque,m,ftorque); + cross3(torque, m, ftorque); lp = param[5] - param[4]; - scale3(1.0/lp,ftorque); + scale3(1.0 / lp, ftorque); if (endflag == 2) { - add3(ftotal,ftorque,fglobal[3]); - sub3(ftotal,ftorque,fglobal[2]); + add3(ftotal, ftorque, fglobal[3]); + sub3(ftotal, ftorque, fglobal[2]); } else { - add3(ftotal,ftorque,fglobal[2]); - sub3(ftotal,ftorque,fglobal[3]); + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); } - scale3(0.5,fglobal[0]); - scale3(0.5,fglobal[1]); - scale3(0.5,fglobal[2]); - scale3(0.5,fglobal[3]); + scale3(0.5, fglobal[0]); + scale3(0.5, fglobal[1]); + scale3(0.5, fglobal[2]); + scale3(0.5, fglobal[3]); // weight gradient terms acting on current segment - outer3(p1,dr1_sumw,temp); - minus3(q1_dr1_w,temp,dr1_p1); - outer3(p2,dr1_sumw,temp); - minus3(q2_dr1_w,temp,dr1_p2); - outer3(p1,dr2_sumw,temp); - minus3(q1_dr2_w,temp,dr2_p1); - outer3(p2,dr2_sumw,temp); - minus3(q2_dr2_w,temp,dr2_p2); + outer3(p1, dr1_sumw, temp); + minus3(q1_dr1_w, temp, dr1_p1); + outer3(p2, dr1_sumw, temp); + minus3(q2_dr1_w, temp, dr1_p2); + outer3(p1, dr2_sumw, temp); + minus3(q1_dr2_w, temp, dr2_p1); + outer3(p2, dr2_sumw, temp); + minus3(q2_dr2_w, temp, dr2_p2); - transpose_matvec(dr1_p1,fglobal[2],fgrad_r1_p1); - transpose_matvec(dr1_p2,fglobal[3],fgrad_r1_p2); - transpose_matvec(dr2_p1,fglobal[2],fgrad_r2_p1); - transpose_matvec(dr2_p2,fglobal[3],fgrad_r2_p2); + transpose_matvec(dr1_p1, fglobal[2], fgrad_r1_p1); + transpose_matvec(dr1_p2, fglobal[3], fgrad_r1_p2); + transpose_matvec(dr2_p1, fglobal[2], fgrad_r2_p1); + transpose_matvec(dr2_p2, fglobal[3], fgrad_r2_p2); // add forces to nodes in current segment - add3(fglobal[0],f[i1],f[i1]); - add3(fglobal[1],f[i2],f[i2]); + add3(fglobal[0], f[i1], f[i1]); + add3(fglobal[1], f[i2], f[i2]); - scaleadd3(sumw_inv,fgrad_r1_p1,f[i1],f[i1]); - scaleadd3(sumw_inv,fgrad_r1_p2,f[i1],f[i1]); - scaleadd3(sumw_inv,fgrad_r2_p1,f[i2],f[i2]); - scaleadd3(sumw_inv,fgrad_r2_p2,f[i2],f[i2]); + scaleadd3(sumw_inv, fgrad_r1_p1, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r1_p2, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r2_p1, f[i2], f[i2]); + scaleadd3(sumw_inv, fgrad_r2_p2, f[i2], f[i2]); // add forces in approximate chain - for (k = 0; k < clen-1; k++) { + for (k = 0; k < clen - 1; k++) { if (w[k] == 0.0) continue; j1 = chain[j][k]; - j2 = chain[j][k+1]; + j2 = chain[j][k + 1]; j1 &= NEIGHMASK; j2 &= NEIGHMASK; scale = w[k] * sumw_inv; - scaleadd3(scale,fglobal[2],f[j1],f[j1]); - scaleadd3(scale,fglobal[3],f[j2],f[j2]); + scaleadd3(scale, fglobal[2], f[j1], f[j1]); + scaleadd3(scale, fglobal[3], f[j2], f[j2]); } // weight gradient terms acting on approximate chain @@ -341,21 +342,21 @@ void PairMesoCNT::compute(int eflag, int vflag) j1 = chain[j][k]; j1 &= NEIGHMASK; - outer3(p1,dq_w[k],temp); - minus3(q1_dq_w[k],temp,dq_p1); - outer3(p2,dq_w[k],temp); - minus3(q2_dq_w[k],temp,dq_p2); + outer3(p1, dq_w[k], temp); + minus3(q1_dq_w[k], temp, dq_p1); + outer3(p2, dq_w[k], temp); + minus3(q2_dq_w[k], temp, dq_p2); - transpose_matvec(dq_p1,fglobal[2],fgrad_q_p1); - transpose_matvec(dq_p2,fglobal[3],fgrad_q_p2); + transpose_matvec(dq_p1, fglobal[2], fgrad_q_p1); + transpose_matvec(dq_p2, fglobal[3], fgrad_q_p2); - scaleadd3(sumw_inv,fgrad_q_p1,f[j1],f[j1]); - scaleadd3(sumw_inv,fgrad_q_p2,f[j1],f[j1]); + scaleadd3(sumw_inv, fgrad_q_p1, f[j1], f[j1]); + scaleadd3(sumw_inv, fgrad_q_p2, f[j1], f[j1]); } // force on node at CNT end - if (endflag) scaleadd3(0.5*fend,m,f[endindex],f[endindex]); + if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); // compute energy @@ -364,10 +365,10 @@ void PairMesoCNT::compute(int eflag, int vflag) if (eflag_atom) { eatom[i1] += 0.25 * evdwl; eatom[i2] += 0.25 * evdwl; - for (k = 0; k < clen-1; k++) { + for (k = 0; k < clen - 1; k++) { if (w[k] == 0.0) continue; j1 = chain[j][k]; - j2 = chain[j][k+1]; + j2 = chain[j][k + 1]; j1 &= NEIGHMASK; j2 &= NEIGHMASK; evdwl_chain = 0.5 * w[k] * sumw_inv * evdwl; @@ -388,41 +389,35 @@ void PairMesoCNT::allocate() { allocated = 1; int ntypes = atom->ntypes; - nlocal_size = 512; - reduced_neigh_size = 64; + int np1 = ntypes + 1; + int init_size = 1; - memory->create(cutsq,ntypes+1,ntypes+1,"pair:cutsq"); - memory->create(setflag,ntypes+1,ntypes+1,"pair:setflag"); + memory->create(cutsq, np1, np1, "pair:cutsq"); + memory->create(setflag, np1, np1, "pair:setflag"); for (int i = 1; i <= ntypes; i++) - for (int j = i; j <= ntypes; j++) - setflag[i][j] = 0; + for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; - memory->create(uinf_coeff,uinf_points,4,"pair:uinf_coeff"); - memory->create(gamma_coeff,gamma_points,4,"pair:gamma_coeff"); - memory->create(phi_coeff,phi_points,phi_points,4,4,"pair:phi_coeff"); - memory->create(usemi_coeff,usemi_points,usemi_points,4,4,"pair:usemi_coeff"); + memory->create(uinf_coeff, uinf_points, 4, "pair:uinf_coeff"); + memory->create(gamma_coeff, gamma_points, 4, "pair:gamma_coeff"); + memory->create(phi_coeff, phi_points, phi_points, 4, 4, "pair:phi_coeff"); + memory->create(usemi_coeff, usemi_points, usemi_points, 4, 4, "pair:usemi_coeff"); - memory->create(reduced_nlist,nlocal_size,"pair:reduced_nlist"); - memory->create(numchainlist,nlocal_size,"pair:numchainlist"); + memory->create(numchainlist, init_size, "pair:numchainlist"); + memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); + memory->create(endlist, init_size, init_size, "pair:endlist"); + memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); - memory->create(reduced_neighlist, - nlocal_size,reduced_neigh_size,"pair:reduced_neighlist"); - memory->create(nchainlist,nlocal_size,reduced_neigh_size,"pair:nchainlist"); - memory->create(endlist,nlocal_size,reduced_neigh_size,"pair:endlist"); - memory->create(chainlist,nlocal_size, - reduced_neigh_size,reduced_neigh_size,"pair:chainlist"); + memory->create(w, init_size, "pair:w"); + memory->create(wnode, init_size, "pair:wnode"); + memory->create(dq_w, init_size, 3, "pair:dq_w"); + memory->create(q1_dq_w, init_size, 3, 3, "pair:q1_dq_w"); + memory->create(q2_dq_w, init_size, 3, 3, "pair:q2_dq_w"); - memory->create(w,reduced_neigh_size,"pair:w"); - memory->create(wnode,reduced_neigh_size,"pair:wnode"); - memory->create(dq_w,reduced_neigh_size,3,"pair:dq_w"); - memory->create(q1_dq_w,reduced_neigh_size,3,3,"pair:q1_dq_w"); - memory->create(q2_dq_w,reduced_neigh_size,3,3,"pair:q2_dq_w"); + memory->create(param, 7, "pair:param"); - memory->create(param,7,"pair:param"); - - memory->create(flocal,2,3,"pair:flocal"); - memory->create(fglobal,4,3,"pair:fglobal"); - memory->create(basis,3,3,"pair:basis"); + memory->create(flocal, 2, 3, "pair:flocal"); + memory->create(fglobal, 4, 3, "pair:fglobal"); + memory->create(basis, 3, 3, "pair:basis"); } /* ---------------------------------------------------------------------- @@ -431,7 +426,7 @@ void PairMesoCNT::allocate() void PairMesoCNT::settings(int narg, char ** /* arg */) { - if (narg != 0) error->all(FLERR,"Illegal pair_style command"); + if (narg != 0) error->all(FLERR, "Illegal pair_style command"); } /* ---------------------------------------------------------------------- @@ -440,24 +435,31 @@ void PairMesoCNT::settings(int narg, char ** /* arg */) void PairMesoCNT::coeff(int narg, char **arg) { - if (narg != 3) error->all(FLERR,"Incorrect args for pair coefficients"); - file = arg[2]; - read_file(); + if (narg != 3) error->all(FLERR, "Incorrect args for pair coefficients"); + read_file(arg[2]); if (!allocated) allocate(); // units, eV to energy unit conversion ang = force->angstrom; ang_inv = 1.0 / ang; - if (strcmp(update->unit_style,"lj") == 0) - error->all(FLERR,"Pair style mesocnt does not support lj units"); - else if (strcmp(update->unit_style,"real") == 0) eunit = 23.06054966; - else if (strcmp(update->unit_style,"metal") == 0) eunit = 1.0; - else if (strcmp(update->unit_style,"si") == 0) eunit = 1.6021765e-19; - else if (strcmp(update->unit_style,"cgs") == 0) eunit = 1.6021765e-12; - else if (strcmp(update->unit_style,"electron") == 0) eunit = 3.674932248e-2; - else if (strcmp(update->unit_style,"micro") == 0) eunit = 1.6021765e-4; - else if (strcmp(update->unit_style,"nano") == 0) eunit = 1.6021765e2; - else error->all(FLERR,"Pair style mesocnt does not recognize this units style"); + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Pair style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Pair style mesocnt does not recognize this units style"); funit = eunit * ang_inv; // potential variables @@ -471,14 +473,14 @@ void PairMesoCNT::coeff(int narg, char **arg) cutoffsq = cutoff * cutoff; cutoff_ang = cutoff * ang_inv; cutoffsq_ang = cutoff_ang * cutoff_ang; - comega = 0.275 * (1.0 - 1.0/(1.0 + 0.59*r_ang)); - ctheta = 0.35 + 0.0226*(r_ang - 6.785); + comega = 0.275 * (1.0 - 1.0 / (1.0 + 0.59 * r_ang)); + ctheta = 0.35 + 0.0226 * (r_ang - 6.785); // compute spline coefficients - spline_coeff(uinf_data,uinf_coeff,delh_uinf,uinf_points); - spline_coeff(gamma_data,gamma_coeff,delh_gamma,gamma_points); - spline_coeff(phi_data,phi_coeff,delh_phi,delpsi_phi,phi_points); - spline_coeff(usemi_data,usemi_coeff,delh_usemi,delxi_usemi,usemi_points); + spline_coeff(uinf_data, uinf_coeff, delh_uinf, uinf_points); + spline_coeff(gamma_data, gamma_coeff, delh_gamma, gamma_points); + spline_coeff(phi_data, phi_coeff, delh_phi, delpsi_phi, phi_points); + spline_coeff(usemi_data, usemi_coeff, delh_usemi, delxi_usemi, usemi_points); memory->destroy(uinf_data); memory->destroy(gamma_data); @@ -487,8 +489,7 @@ void PairMesoCNT::coeff(int narg, char **arg) int ntypes = atom->ntypes; for (int i = 1; i <= ntypes; i++) - for (int j = i; j <= ntypes; j++) - setflag[i][j] = 1; + for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; } /* ---------------------------------------------------------------------- @@ -497,14 +498,12 @@ void PairMesoCNT::coeff(int narg, char **arg) void PairMesoCNT::init_style() { - if (atom->tag_enable == 0) - error->all(FLERR,"Pair style mesocnt requires atom IDs"); - if (force->newton_pair == 0) - error->all(FLERR,"Pair style mesocnt requires newton pair on"); + if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt requires atom IDs"); + if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt requires newton pair on"); // need a full neighbor list - int irequest = neighbor->request(this,instance_me); + int irequest = neighbor->request(this, instance_me); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; } @@ -524,82 +523,117 @@ double PairMesoCNT::init_one(int /* i */, int /* j */) void PairMesoCNT::bond_neigh() { + int nlocal = atom->nlocal; + int nghost = atom->nghost; int **bondlist = neighbor->bondlist; int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int update_memory = 0; - if (nbondlist > nlocal_size) { - nlocal_size = 2 * nbondlist; - update_memory = 1; - } int *numneigh = list->numneigh; int numneigh_max = 0; for (int i = 0; i < nbondlist; i++) { int i1 = bondlist[i][0]; int i2 = bondlist[i][1]; - int numneigh1,numneigh2; - if (i1 > nlocal-1 && false) numneigh1 = 0; - else numneigh1 = numneigh[i1]; - if (i2 > nlocal-1 && false) numneigh2 = 0; - else numneigh2 = numneigh[i2]; + int numneigh1, numneigh2; + + // prevent ghost atom with undefined neighbors + + if (i1 > nlocal - 1) + numneigh1 = 0; + else + numneigh1 = numneigh[i1]; + if (i2 > nlocal - 1) + numneigh2 = 0; + else + numneigh2 = numneigh[i2]; int numneigh_max_local = numneigh1 + numneigh2; if (numneigh_max_local > numneigh_max) numneigh_max = numneigh_max_local; } - if (numneigh_max > reduced_neigh_size) { - reduced_neigh_size = 2 * numneigh_max; - update_memory = 1; - } - // grow arrays if necessary + // create temporary arrays for chain creation - if (update_memory) { - memory->destroy(reduced_neighlist); - memory->destroy(numchainlist); - memory->destroy(reduced_nlist); - memory->destroy(nchainlist); - memory->destroy(endlist); - memory->destroy(chainlist); + memory->create(reduced_nlist, nbondlist, "pair:reduced_nlist"); + memory->create(reduced_neighlist, nbondlist, numneigh_max, "pair:reduced_neighlist"); - memory->create(reduced_nlist,nlocal_size,"pair:reduced_nlist"); - memory->create(numchainlist,nlocal_size,"pair:numchainlist"); - memory->create(reduced_neighlist, - nlocal_size,reduced_neigh_size,"pair:reduced_neighlist"); - memory->create(nchainlist,nlocal_size,reduced_neigh_size,"pair:nchainlist"); - memory->create(endlist,nlocal_size,reduced_neigh_size,"pair:endlist"); - memory->create(chainlist,nlocal_size, - reduced_neigh_size,reduced_neigh_size,"pair:chainlist"); - - memory->grow(w,reduced_neigh_size,"pair:w"); - memory->grow(wnode,reduced_neigh_size,"pair:wnode"); - memory->grow(dq_w,reduced_neigh_size,3,"pair:dq_w"); - memory->grow(q1_dq_w,reduced_neigh_size,3,3,"pair:q1_dq_w"); - memory->grow(q2_dq_w,reduced_neigh_size,3,3,"pair:q2_dq_w"); - } + // reduce neighbors to common list and find longest common list size + numneigh_max = 0; for (int i = 0; i < nbondlist; i++) { int i1 = bondlist[i][0]; int i2 = bondlist[i][1]; + int *reduced_neigh = reduced_neighlist[i]; + neigh_common(i1, i2, reduced_nlist[i], reduced_neigh); + + // sort list according to atom-id + + sort(reduced_neigh, reduced_nlist[i]); + + if (numneigh_max < reduced_nlist[i]) numneigh_max = reduced_nlist[i]; + } + + // resize chain arrays + + memory->destroy(numchainlist); + memory->destroy(nchainlist); + memory->destroy(endlist); + memory->destroy(chainlist); + + // count neighbor chains per bond + + memory->create(numchainlist, nbondlist, "pair:numchainlist"); + + int numchain_max = 0; + for (int i = 0; i < nbondlist; i++) { + numchainlist[i] = count_chains(reduced_neighlist[i], reduced_nlist[i]); + if (numchain_max < numchainlist[i]) numchain_max = numchainlist[i]; + } + + // count neighbor chain lengths per bond + + memory->create_ragged(nchainlist, nbondlist, numchainlist, "pair:nchainlist"); + + for (int i = 0; i < nbondlist; i++) + chain_lengths(reduced_neighlist[i], reduced_nlist[i], nchainlist[i]); + + // create connected neighbor chains and check for ends + // MEMORY: prevent zero-size array creation for chainlist + + memory->create_ragged(endlist, nbondlist, numchainlist, "pair:endlist"); + if (numchain_max > 0) + memory->create_ragged(chainlist, nbondlist, numchainlist, nchainlist, "pair:chainlist"); + else + memory->create(chainlist, 1, 1, 1, "pair:chainlist"); + + int nchain_max = 0; + for (int i = 0; i < nbondlist; i++) { int *reduced_neigh = reduced_neighlist[i]; int *end = endlist[i]; int *nchain = nchainlist[i]; int **chain = chainlist[i]; - // reduce neighbors to common list + // set up connected chains and check for ends - neigh_common(i1,i2,reduced_nlist[i],reduced_neigh); + chain_split(reduced_neigh, reduced_nlist[i], nchain, chain, end); - // sort list according to atom-id + // find longest chain - sort(reduced_neigh,reduced_nlist[i]); - - // set up connected chains - - chain_split(reduced_neigh, - reduced_nlist[i],numchainlist[i],chain,nchain,end); + for (int j = 0; j < numchainlist[i]; j++) + if (nchain_max < nchain[j]) nchain_max = nchain[j]; } + + // resize potential arrays + + memory->grow(w, nchain_max, "pair:w"); + memory->grow(wnode, nchain_max, "pair:wnode"); + memory->grow(dq_w, nchain_max, 3, "pair:dq_w"); + memory->grow(q1_dq_w, nchain_max, 3, 3, "pair:q1_dq_w"); + memory->grow(q2_dq_w, nchain_max, 3, 3, "pair:q2_dq_w"); + + // destroy temporary arrays for chain creation + + memory->destroy(reduced_neighlist); + memory->destroy(reduced_nlist); } /* ---------------------------------------------------------------------- @@ -613,18 +647,20 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) tagint *mol = atom->molecule; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; - int numneigh1,numneigh2; - int *neighlist1,*neighlist2; + int numneigh1, numneigh2; + int *neighlist1, *neighlist2; - if (i1 > nlocal-1) { + // prevent ghost atom with undefined neighbors + + if (i1 > nlocal - 1) numneigh1 = 0; - } else { + else { neighlist1 = firstneigh[i1]; numneigh1 = numneigh[i1]; } - if (i2 > nlocal-1) { + if (i2 > nlocal - 1) numneigh2 = 0; - } else { + else { neighlist2 = firstneigh[i2]; numneigh2 = numneigh[i2]; } @@ -635,8 +671,7 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) for (int j = 0; j < numneigh1; j++) { int ind = neighlist1[j]; - if (mol[ind] == mol[i1] && abs(tag[ind] - tag[i1]) < SELF_CUTOFF) - continue; + if (mol[ind] == mol[i1] && abs(tag[ind] - tag[i1]) < SELF_CUTOFF) continue; redlist[numred++] = ind; } int inflag = 0; @@ -644,7 +679,7 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) for (int j1 = 0; j1 < numneigh1; j1++) { if (neighlist1[j1] == neighlist2[j2]) { inflag = 1; - break; + break; } } if (inflag) { @@ -652,26 +687,41 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) continue; } int ind = neighlist2[j2]; - if (mol[ind] == mol[i2] && abs(tag[ind] - tag[i2]) < SELF_CUTOFF) - continue; + if (mol[ind] == mol[i2] && abs(tag[ind] - tag[i2]) < SELF_CUTOFF) continue; redlist[numred++] = ind; } } /* ---------------------------------------------------------------------- - split neighbors into chains and identify ends + count neighbor chains of given bond ------------------------------------------------------------------------- */ -void PairMesoCNT::chain_split(int *redlist, int numred, - int &numchain, int **chain, int *nchain, int *end) +int PairMesoCNT::count_chains(int *redlist, int numred) { - // empty neighbor list + if (numred == 0) return 0; - if (numred == 0) { - numchain = 0; - return; + tagint *tag = atom->tag; + tagint *mol = atom->molecule; + int count = 1; + + // split neighbor list and count chains + + for (int j = 0; j < numred - 1; j++) { + int j1 = redlist[j]; + int j2 = redlist[j + 1]; + if (tag[j2] - tag[j1] != 1 || mol[j1] != mol[j2]) count++; } + return count; +} +/* ---------------------------------------------------------------------- + count lengths of neighbor chains of given bond +------------------------------------------------------------------------- */ + +void PairMesoCNT::chain_lengths(int *redlist, int numred, int *nchain) +{ + if (numred == 0) return; + tagint *tag = atom->tag; tagint *mol = atom->molecule; int clen = 0; @@ -679,41 +729,67 @@ void PairMesoCNT::chain_split(int *redlist, int numred, // split neighbor list into connected chains - for (int j = 0; j < numred-1; j++) { + for (int j = 0; j < numred - 1; j++) { int j1 = redlist[j]; - int j2 = redlist[j+1]; - chain[cid][clen++] = j1; + int j2 = redlist[j + 1]; + clen++; if (tag[j2] - tag[j1] != 1 || mol[j1] != mol[j2]) { nchain[cid++] = clen; clen = 0; } } - chain[cid][clen++] = redlist[numred-1]; + clen++; nchain[cid++] = clen; +} + +/* ---------------------------------------------------------------------- + split neighbors into chains and identify ends +------------------------------------------------------------------------- */ + +void PairMesoCNT::chain_split(int *redlist, int numred, int *nchain, int **chain, int *end) +{ + if (numred == 0) return; + + tagint *tag = atom->tag; + tagint *mol = atom->molecule; + int clen = 0; + int cid = 0; + + // split neighbor list into connected chains + + for (int j = 0; j < numred - 1; j++) { + int j1 = redlist[j]; + int j2 = redlist[j + 1]; + chain[cid][clen++] = j1; + if (tag[j2] - tag[j1] != 1 || mol[j1] != mol[j2]) { + cid++; + clen = 0; + } + } + chain[cid][clen++] = redlist[numred - 1]; + cid++; // check for chain ends for (int j = 0; j < cid; j++) { int cstart = chain[j][0]; - int cend = chain[j][nchain[j]-1]; + int cend = chain[j][nchain[j] - 1]; tagint tagstart = tag[cstart]; tagint tagend = tag[cend]; end[j] = 0; if (tagstart == 1) { end[j] = 1; } else { - int idprev = atom->map(tagstart-1); + int idprev = atom->map(tagstart - 1); if (mol[cstart] != mol[idprev]) end[j] = 1; } if (tagend == atom->natoms) { end[j] = 2; } else { - int idnext = atom->map(tagend+1); + int idnext = atom->map(tagend + 1); if (mol[cend] != mol[idnext]) end[j] = 2; } } - - numchain = cid; } /* ---------------------------------------------------------------------- @@ -722,17 +798,17 @@ void PairMesoCNT::chain_split(int *redlist, int numred, void PairMesoCNT::sort(int *list, int size) { - int i,j,temp1,temp2; + int i, j, temp1, temp2; tagint *tag = atom->tag; for (i = 1; i < size; i++) { j = i; - temp1 = list[j-1]; + temp1 = list[j - 1]; temp2 = list[j]; while (j > 0 && tag[temp1] > tag[temp2]) { list[j] = temp1; - list[j-1] = temp2; + list[j - 1] = temp2; j--; - temp1 = list[j-1]; + temp1 = list[j - 1]; temp2 = list[j]; } } @@ -742,263 +818,235 @@ void PairMesoCNT::sort(int *list, int size) read mesocnt potential file ------------------------------------------------------------------------- */ -void PairMesoCNT::read_file() +void PairMesoCNT::read_file(const char *file) { - int me, num; - MPI_Comm_rank(world,&me); + if (comm->me == 0) { - FILE *fp; + // open file and skip first line - if (me == 0) { - char line[MAXLINE]; + PotentialFileReader reader(lmp, file, "mesocnt"); + reader.skip_line(); - // open file + // parse global parameters: 4x integer then 4x double - fp = utils::open_potential(file,lmp,nullptr); - if (fp == nullptr) - error->one(FLERR,"Cannot open mesocnt file: {}",file); + try { + auto values = reader.next_values(4); + uinf_points = values.next_int(); + gamma_points = values.next_int(); + phi_points = values.next_int(); + usemi_points = values.next_int(); - utils::sfgets(FLERR,line,MAXLINE,fp,file,error); + values = reader.next_values(4); + r_ang = values.next_double(); + sig_ang = values.next_double(); + delta1 = values.next_double(); + delta2 = values.next_double(); + } catch (std::exception &e) { + error->one(FLERR, "Error parsing mesocnt potential file header: {}", e.what()); + } - // potential parameters + // allocate and read potential tables - utils::sfgets(FLERR,line,MAXLINE,fp,file,error); - num = sscanf(line,"%d %d %d %d", - &uinf_points,&gamma_points,&phi_points,&usemi_points); - if (num != 4) - error->one(FLERR,"Could not correctly parse line 2 in " - "mesocnt file: {}",file); + memory->create(uinf_data, uinf_points, "pair:uinf_data"); + memory->create(gamma_data, gamma_points, "pair:gamma_data"); + memory->create(phi_data, phi_points, phi_points, "pair:phi_data"); + memory->create(usemi_data, usemi_points, usemi_points, "pair:usemi_data"); - utils::sfgets(FLERR,line,MAXLINE,fp,file,error); - num = sscanf(line,"%lg %lg %lg %lg",&r_ang,&sig_ang,&delta1,&delta2); - if (num != 4) - error->one(FLERR,"Could not correctly parse line 3 in " - "mesocnt file: {}",file); + read_data(reader, uinf_data, hstart_uinf, delh_uinf, uinf_points); + read_data(reader, gamma_data, hstart_gamma, delh_gamma, gamma_points); + read_data(reader, phi_data, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_points); + read_data(reader, usemi_data, hstart_usemi, xistart_usemi, delh_usemi, delxi_usemi, + usemi_points); } - MPI_Bcast(&uinf_points,1,MPI_INT,0,world); - MPI_Bcast(&gamma_points,1,MPI_INT,0,world); - MPI_Bcast(&phi_points,1,MPI_INT,0,world); - MPI_Bcast(&usemi_points,1,MPI_INT,0,world); - MPI_Bcast(&r_ang,1,MPI_DOUBLE,0,world); - MPI_Bcast(&sig_ang,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delta1,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delta2,1,MPI_DOUBLE,0,world); + MPI_Bcast(&uinf_points, 1, MPI_INT, 0, world); + MPI_Bcast(&gamma_points, 1, MPI_INT, 0, world); + MPI_Bcast(&phi_points, 1, MPI_INT, 0, world); + MPI_Bcast(&usemi_points, 1, MPI_INT, 0, world); + MPI_Bcast(&r_ang, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&sig_ang, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delta1, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delta2, 1, MPI_DOUBLE, 0, world); - // potential tables + // allocate table arrays on other MPI ranks - memory->create(uinf_data,uinf_points,"pair:uinf_data"); - memory->create(gamma_data,gamma_points,"pair:gamma_data"); - memory->create(phi_data,phi_points,phi_points,"pair:phi_data"); - memory->create(usemi_data,usemi_points,usemi_points,"pair:usemi_data"); - - if (me == 0) { - read_data(fp,uinf_data,hstart_uinf,delh_uinf,uinf_points); - read_data(fp,gamma_data,hstart_gamma,delh_gamma,gamma_points); - read_data(fp,phi_data,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_points); - read_data(fp,usemi_data,hstart_usemi,xistart_usemi, - delh_usemi,delxi_usemi,usemi_points); - - fclose(fp); + if (comm->me != 0) { + memory->create(uinf_data, uinf_points, "pair:uinf_data"); + memory->create(gamma_data, gamma_points, "pair:gamma_data"); + memory->create(phi_data, phi_points, phi_points, "pair:phi_data"); + memory->create(usemi_data, usemi_points, usemi_points, "pair:usemi_data"); } - MPI_Bcast(&hstart_uinf,1,MPI_DOUBLE,0,world); - MPI_Bcast(&hstart_gamma,1,MPI_DOUBLE,0,world); - MPI_Bcast(&hstart_phi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&psistart_phi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&hstart_usemi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&xistart_usemi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delh_uinf,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delh_gamma,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delh_phi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delpsi_phi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delh_usemi,1,MPI_DOUBLE,0,world); - MPI_Bcast(&delxi_usemi,1,MPI_DOUBLE,0,world); + // broadcast tables - MPI_Bcast(uinf_data,uinf_points,MPI_DOUBLE,0,world); - MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); - for (int i = 0; i < phi_points; i++) - MPI_Bcast(phi_data[i],phi_points,MPI_DOUBLE,0,world); - for (int i = 0; i < usemi_points; i++) - MPI_Bcast(usemi_data[i],usemi_points,MPI_DOUBLE,0,world); + MPI_Bcast(&hstart_uinf, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&hstart_gamma, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&hstart_phi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&psistart_phi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&hstart_usemi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&xistart_usemi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delh_uinf, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delh_gamma, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delh_phi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delpsi_phi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delh_usemi, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&delxi_usemi, 1, MPI_DOUBLE, 0, world); + + MPI_Bcast(uinf_data, uinf_points, MPI_DOUBLE, 0, world); + MPI_Bcast(gamma_data, gamma_points, MPI_DOUBLE, 0, world); + MPI_Bcast(&phi_data[0][0], phi_points*phi_points, MPI_DOUBLE, 0, world); + MPI_Bcast(&usemi_data[0][0], usemi_points*usemi_points, MPI_DOUBLE, 0, world); } /* ---------------------------------------------------------------------- - read 1D data file + read 1D data file. Only called from MPI rank 0 ------------------------------------------------------------------------- */ -void PairMesoCNT::read_data(FILE *fp, double *data, - double &xstart, double &dx, int ninput) +void PairMesoCNT::read_data(PotentialFileReader &reader, double *data, double &xstart, double &dx, + int ninput) { - char line[MAXLINE]; - utils::sfgets(FLERR,line,MAXLINE,fp,file,error); - // read values from file - int cerror = 0; int serror = 0; - double x,xtemp,dxtemp; + double x, xtemp, dxtemp; for (int i = 0; i < ninput; i++) { - if (nullptr == fgets(line,MAXLINE,fp)) - error->one(FLERR,"Premature end of file in pair table: {}",file); + try { + auto values = reader.next_values(2); - if (i > 0) xtemp = x; - if (2 != sscanf(line,"%lg %lg",&x,&data[i])) cerror++; - if (i == 0) { - xstart = x; - } else { - dxtemp = x - xtemp; - if (i == 1) dx = dxtemp; - if (fabs(dxtemp - dx)/dx > SMALL) serror++; + if (i > 0) xtemp = x; + x = values.next_double(); + data[i] = values.next_double(); + + if (i == 0) { + xstart = x; + } else { + dxtemp = x - xtemp; + if (i == 1) dx = dxtemp; + if (fabs(dxtemp - dx) / dx > SMALL) serror++; + } + } catch (std::exception &e) { + error->one(FLERR, "Error parsing data for mesocnt potential: {}", e.what()); } - } - // warn if data was read incompletely, e.g. columns were missing + // warn if spacing between data points is not constant - if (cerror) { - std::string mesg = fmt::format("{} of {} lines were incomplete or could " - "or could not be parsed completely in " - " pair table: {}",cerror,ninput,file); - error->warning(FLERR,mesg); - } - - // warn if spacing between data points is not constant - - if (serror) { - std::string mesg = fmt::format("{} spacings in first column were different " - " from first spacing in pair table: {}",serror,file); - error->warning(FLERR,mesg); + if (serror) + error->warning(FLERR, "{} spacings in first column were different from first", serror); } } /* ---------------------------------------------------------------------- - read 2D data file + read 2D data file only called from MPI rank 0 ------------------------------------------------------------------------- */ -void PairMesoCNT::read_data(FILE *fp, double **data, - double &xstart, double &ystart, - double &dx, double &dy, int ninput) +void PairMesoCNT::read_data(PotentialFileReader &reader, double **data, double &xstart, + double &ystart, double &dx, double &dy, int ninput) { - char line[MAXLINE]; - fgets(line,MAXLINE,fp); - // read values from file - int cerror = 0; int sxerror = 0; int syerror = 0; - double x,y,xtemp,ytemp,dxtemp,dytemp; + double x, y, xtemp, ytemp, dxtemp, dytemp; for (int i = 0; i < ninput; i++) { - if (i > 0) xtemp = x; - for (int j = 0; j < ninput; j++) { - if (nullptr == fgets(line,MAXLINE,fp)) - error->one(FLERR,"Premature end of file in pair table: {}",file); + try { + if (i > 0) xtemp = x; + for (int j = 0; j < ninput; j++) { + if (j > 0) ytemp = y; - if (j > 0) ytemp = y; - if (3 != sscanf(line,"%lg %lg %lg",&x,&y,&data[i][j])) cerror++; - if (i == 0 && j == 0) ystart = y; - if (j > 0) { - dytemp = y - ytemp; + auto values = reader.next_values(3); + x = values.next_double(); + y = values.next_double(); + data[i][j] = values.next_double(); + + if (i == 0 && j == 0) ystart = y; + if (j > 0) { + dytemp = y - ytemp; if (j == 1) dy = dytemp; - if (fabs(dytemp - dy)/dy > SMALL) syerror++; + if (fabs(dytemp - dy) / dy > SMALL) syerror++; + } } - } - if (i == 0) { - xstart = x; - } else { - dxtemp = x - xtemp; - if (i == 1) dx = dxtemp; - if (fabs(dxtemp - dx)/dx > SMALL) sxerror++; + if (i == 0) { + xstart = x; + } else { + dxtemp = x - xtemp; + if (i == 1) dx = dxtemp; + if (fabs(dxtemp - dx) / dx > SMALL) sxerror++; + } + } catch (std::exception &e) { + error->one(FLERR, "Error parsing data for mesocnt potential: {}", e.what()); } } - // warn if data was read incompletely, e.g. columns were missing - - if (cerror) - error->warning(FLERR,"{} of {} lines were incomplete or could not be parsed " - "completely in pair table: {}",cerror,ninput*ninput,file); - // warn if spacing between data points is not constant if (sxerror) - error->warning(FLERR,"{} spacings in first column were different from " - "first spacing in pair table: {}",sxerror,file); + error->warning(FLERR, "{} spacings in first column were different from first", sxerror); if (syerror) - error->warning(FLERR,"{} spacings in second column were different from " - "first spacing in pair table: {}",syerror,file); + error->warning(FLERR, "{} spacings in second column were different from first", syerror); } /* ---------------------------------------------------------------------- compute cubic spline coefficients ------------------------------------------------------------------------- */ -void PairMesoCNT::spline_coeff(double *data, double **coeff, - double dx, int size) +void PairMesoCNT::spline_coeff(double *data, double **coeff, double dx, int size) { double *u = data; double **g = coeff; int n = size; - double d,*p,*bprime,*dprime,**b; - memory->create(p,n,"pair:p"); - memory->create(b,n,n,"pair:b"); - memory->create(bprime,n,"pair:bprime"); - memory->create(dprime,n,"pair:dprime"); + double d, *p, *bprime, *dprime, **b; + memory->create(p, n, "pair:p"); + memory->create(b, n, n, "pair:b"); + memory->create(bprime, n, "pair:bprime"); + memory->create(dprime, n, "pair:dprime"); double dx_inv = 1.0 / dx; double dxsq_inv = dx_inv * dx_inv; double dxcb_inv = dx_inv * dxsq_inv; - double ax[4][4] = - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {-3*dxsq_inv, -2*dx_inv, 3*dxsq_inv, -dx_inv}, - {2*dxcb_inv, dxsq_inv, -2*dxcb_inv, dxsq_inv} - }; + double ax[4][4] = {{1, 0, 0, 0}, + {0, 1, 0, 0}, + {-3 * dxsq_inv, -2 * dx_inv, 3 * dxsq_inv, -dx_inv}, + {2 * dxcb_inv, dxsq_inv, -2 * dxcb_inv, dxsq_inv}}; // compute finite difference derivatives at boundaries p[0] = (u[1] - u[0]) * dx_inv; - p[n-1] = (u[n-1] - u[n-2]) * dx_inv; + p[n - 1] = (u[n - 1] - u[n - 2]) * dx_inv; // compute derivatives inside domain - for (int i = 1; i < n-1; i++) { - if (i > 1) b[i][i-1] = dx; + for (int i = 1; i < n - 1; i++) { + if (i > 1) b[i][i - 1] = dx; b[i][i] = 4 * dx; - if (i < n-2) b[i][i+1] = dx; + if (i < n - 2) b[i][i + 1] = dx; } bprime[1] = b[1][1]; - for (int i = 2; i < n-1; i++) - bprime[i] = b[i][i] - b[i][i-1]*b[i-1][i]/bprime[i-1]; + for (int i = 2; i < n - 1; i++) bprime[i] = b[i][i] - b[i][i - 1] * b[i - 1][i] / bprime[i - 1]; - for (int i = 1; i < n-1; i++) { - d = 3 * (u[i+1] - u[i-1]); - if (i == 1) d -= dx * p[i-1]; - if (i == n-2) d -= dx * p[i+1]; + for (int i = 1; i < n - 1; i++) { + d = 3 * (u[i + 1] - u[i - 1]); + if (i == 1) d -= dx * p[i - 1]; + if (i == n - 2) d -= dx * p[i + 1]; dprime[i] = d; - if (i != 1) dprime[i] -= b[i][i-1] * dprime[i-1] / bprime[i-1]; + if (i != 1) dprime[i] -= b[i][i - 1] * dprime[i - 1] / bprime[i - 1]; } - p[n-2] = dprime[n-2] / bprime[n-2]; - for (int i = n-3; i > 0; i--) - p[i] = (dprime[i] - b[i][i+1]*p[i+1]) / bprime[i]; + p[n - 2] = dprime[n - 2] / bprime[n - 2]; + for (int i = n - 3; i > 0; i--) p[i] = (dprime[i] - b[i][i + 1] * p[i + 1]) / bprime[i]; // compute spline coefficients for (int i = 1; i < n; i++) { - for (int j = 0; j < 4; j++) - g[i][j] = 0; + for (int j = 0; j < 4; j++) g[i][j] = 0; - double k[4] = {u[i-1], p[i-1], u[i], p[i]}; + double k[4] = {u[i - 1], p[i - 1], u[i], p[i]}; for (int j = 0; j < 4; j++) - for (int l = 0; l < 4; l++) - g[i][j] += ax[j][l] * k[l]; + for (int l = 0; l < 4; l++) g[i][j] += ax[j][l] * k[l]; } memory->destroy(p); @@ -1011,20 +1059,19 @@ void PairMesoCNT::spline_coeff(double *data, double **coeff, compute bicubic spline coefficients ------------------------------------------------------------------------- */ -void PairMesoCNT::spline_coeff(double **data, double ****coeff, - double dx, double dy, int size) +void PairMesoCNT::spline_coeff(double **data, double ****coeff, double dx, double dy, int size) { double **u = data; double ****g = coeff; int n = size; - double d,*bprime,*dprime,**p,**q,**s,**b; - memory->create(p,n,n,"pair:p"); - memory->create(q,n,n,"pair:q"); - memory->create(s,n,n,"pair:s"); - memory->create(b,n,n,"pair:b"); - memory->create(bprime,n,"pair:bprime"); - memory->create(dprime,n,"pair:dprime"); + double d, *bprime, *dprime, **p, **q, **s, **b; + memory->create(p, n, n, "pair:p"); + memory->create(q, n, n, "pair:q"); + memory->create(s, n, n, "pair:s"); + memory->create(b, n, n, "pair:b"); + memory->create(bprime, n, "pair:bprime"); + memory->create(dprime, n, "pair:dprime"); double dx_inv = 1.0 / dx; double dy_inv = 1.0 / dy; @@ -1033,145 +1080,128 @@ void PairMesoCNT::spline_coeff(double **data, double ****coeff, double dxcb_inv = dx_inv * dxsq_inv; double dycb_inv = dy_inv * dysq_inv; - double ax[4][4] = - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {-3*dxsq_inv, -2*dx_inv, 3*dxsq_inv, -dx_inv}, - {2*dxcb_inv, dxsq_inv, -2*dxcb_inv, dxsq_inv} - }; - double ay[4][4] = - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {-3*dysq_inv, -2*dy_inv, 3*dysq_inv, -dy_inv}, - {2*dycb_inv, dysq_inv, -2*dycb_inv, dysq_inv} - }; + double ax[4][4] = {{1, 0, 0, 0}, + {0, 1, 0, 0}, + {-3 * dxsq_inv, -2 * dx_inv, 3 * dxsq_inv, -dx_inv}, + {2 * dxcb_inv, dxsq_inv, -2 * dxcb_inv, dxsq_inv}}; + double ay[4][4] = {{1, 0, 0, 0}, + {0, 1, 0, 0}, + {-3 * dysq_inv, -2 * dy_inv, 3 * dysq_inv, -dy_inv}, + {2 * dycb_inv, dysq_inv, -2 * dycb_inv, dysq_inv}}; // compute finite difference derivatives at boundaries for (int i = 0; i < n; i++) { p[0][i] = (u[1][i] - u[0][i]) * dx_inv; - p[n-1][i] = (u[n-1][i] - u[n-2][i]) * dx_inv; + p[n - 1][i] = (u[n - 1][i] - u[n - 2][i]) * dx_inv; } for (int i = 0; i < n; i++) { q[i][0] = (u[i][1] - u[i][0]) * dy_inv; - q[i][n-1] = (u[i][n-1] - u[i][n-2]) * dy_inv; + q[i][n - 1] = (u[i][n - 1] - u[i][n - 2]) * dy_inv; } s[0][0] = (p[0][1] - p[0][0]) * dy_inv; - s[0][n-1] = (p[0][n-1] - p[0][n-2]) * dy_inv; - s[n-1][0] = (p[n-1][1] - p[n-1][0]) * dy_inv; - s[n-1][n-1] = (p[n-1][n-1] - p[n-1][n-2]) * dy_inv; + s[0][n - 1] = (p[0][n - 1] - p[0][n - 2]) * dy_inv; + s[n - 1][0] = (p[n - 1][1] - p[n - 1][0]) * dy_inv; + s[n - 1][n - 1] = (p[n - 1][n - 1] - p[n - 1][n - 2]) * dy_inv; // compute derivatives inside domain // sweep in x - for (int i = 1; i < n-1; i++) { - if (i > 1) b[i][i-1] = dx; + for (int i = 1; i < n - 1; i++) { + if (i > 1) b[i][i - 1] = dx; b[i][i] = 4 * dx; - if (i < n-2) b[i][i+1] = dx; + if (i < n - 2) b[i][i + 1] = dx; } bprime[1] = b[1][1]; - for (int i = 2; i < n-1; i++) - bprime[i] = b[i][i] - b[i][i-1]*b[i-1][i]/bprime[i-1]; + for (int i = 2; i < n - 1; i++) bprime[i] = b[i][i] - b[i][i - 1] * b[i - 1][i] / bprime[i - 1]; // compute p for (int j = 0; j < n; j++) { - for (int i = 1; i < n-1; i++) { - d = 3 * (u[i+1][j] - u[i-1][j]); - if (i == 1) d -= dx * p[i-1][j]; - if (i == n-2) d -= dx * p[i+1][j]; + for (int i = 1; i < n - 1; i++) { + d = 3 * (u[i + 1][j] - u[i - 1][j]); + if (i == 1) d -= dx * p[i - 1][j]; + if (i == n - 2) d -= dx * p[i + 1][j]; dprime[i] = d; - if (i != 1) dprime[i] -= b[i][i-1] * dprime[i-1] / bprime[i-1]; + if (i != 1) dprime[i] -= b[i][i - 1] * dprime[i - 1] / bprime[i - 1]; } - p[n-2][j] = dprime[n-2] / bprime[n-2]; - for (int i = n-3; i > 0; i--) - p[i][j] = (dprime[i] - b[i][i+1]*p[i+1][j]) / bprime[i]; + p[n - 2][j] = dprime[n - 2] / bprime[n - 2]; + for (int i = n - 3; i > 0; i--) p[i][j] = (dprime[i] - b[i][i + 1] * p[i + 1][j]) / bprime[i]; } // compute s - for (int j = 0; j < n; j += n-1) { - for (int i = 1; i < n-1; i++) { - d = 3 * (q[i+1][j] - q[i-1][j]); - if (i == 1) d -= dx * s[i-1][j]; - if (i == n-2) d -= dx * s[i+1][j]; + for (int j = 0; j < n; j += n - 1) { + for (int i = 1; i < n - 1; i++) { + d = 3 * (q[i + 1][j] - q[i - 1][j]); + if (i == 1) d -= dx * s[i - 1][j]; + if (i == n - 2) d -= dx * s[i + 1][j]; dprime[i] = d; - if (i != 1) dprime[i] -= b[i][i-1] * dprime[i-1] / bprime[i-1]; + if (i != 1) dprime[i] -= b[i][i - 1] * dprime[i - 1] / bprime[i - 1]; } - s[n-2][j] = dprime[n-2] / bprime[n-2]; - for (int i = n-3; i > 0; i--) - s[i][j] = (dprime[i] - b[i][i+1]*s[i+1][j]) / bprime[i]; + s[n - 2][j] = dprime[n - 2] / bprime[n - 2]; + for (int i = n - 3; i > 0; i--) s[i][j] = (dprime[i] - b[i][i + 1] * s[i + 1][j]) / bprime[i]; } // sweep in y - for (int i = 1; i < n-1; i++) { - if (i > 1) b[i][i-1] = dy; + for (int i = 1; i < n - 1; i++) { + if (i > 1) b[i][i - 1] = dy; b[i][i] = 4 * dy; - if (i < n-2) b[i][i+1] = dy; + if (i < n - 2) b[i][i + 1] = dy; } bprime[1] = b[1][1]; - for (int i = 2; i < n-1; i++) - bprime[i] = b[i][i] - b[i][i-1]*b[i-1][i]/bprime[i-1]; + for (int i = 2; i < n - 1; i++) bprime[i] = b[i][i] - b[i][i - 1] * b[i - 1][i] / bprime[i - 1]; // compute q for (int i = 0; i < n; i++) { - for (int j = 1; j < n-1; j++) { - d = 3 * (u[i][j+1] - u[i][j-1]); - if (j == 1) d -= dy * q[i][j-1]; - if (j == n-2) d -= dy * q[i][j+1]; + for (int j = 1; j < n - 1; j++) { + d = 3 * (u[i][j + 1] - u[i][j - 1]); + if (j == 1) d -= dy * q[i][j - 1]; + if (j == n - 2) d -= dy * q[i][j + 1]; dprime[j] = d; - if (j != 1) dprime[j] -= b[j][j-1] * dprime[j-1] / bprime[j-1]; + if (j != 1) dprime[j] -= b[j][j - 1] * dprime[j - 1] / bprime[j - 1]; } - q[i][n-2] = dprime[n-2] / bprime[n-2]; - for (int j = n-3; j > 0; j--) - q[i][j] = (dprime[j] - b[j][j+1]*q[i][j+1]) / bprime[j]; + q[i][n - 2] = dprime[n - 2] / bprime[n - 2]; + for (int j = n - 3; j > 0; j--) q[i][j] = (dprime[j] - b[j][j + 1] * q[i][j + 1]) / bprime[j]; } // compute s for (int i = 0; i < n; i++) { - for (int j = 1; j < n-1; j++) { - d = 3 * (p[i][j+1] - p[i][j-1]); - if (j == 1) d -= dy * s[i][j-1]; - if (j == n-2) d -= dy * s[i][j+1]; + for (int j = 1; j < n - 1; j++) { + d = 3 * (p[i][j + 1] - p[i][j - 1]); + if (j == 1) d -= dy * s[i][j - 1]; + if (j == n - 2) d -= dy * s[i][j + 1]; dprime[j] = d; - if (j != 1) dprime[j] -= b[j][j-1] * dprime[j-1] / bprime[j-1]; + if (j != 1) dprime[j] -= b[j][j - 1] * dprime[j - 1] / bprime[j - 1]; } - s[i][n-2] = dprime[n-2] / bprime[n-2]; - for (int j = n-3; j > 0; j--) - s[i][j] = (dprime[j] - b[j][j+1]*s[i][j+1]) / bprime[j]; + s[i][n - 2] = dprime[n - 2] / bprime[n - 2]; + for (int j = n - 3; j > 0; j--) s[i][j] = (dprime[j] - b[j][j + 1] * s[i][j + 1]) / bprime[j]; } for (int i = 1; i < n; i++) for (int j = 1; j < n; j++) { for (int l = 0; l < 4; l++) - for (int m = 0; m < 4; m++) - g[i][j][l][m] = 0; + for (int m = 0; m < 4; m++) g[i][j][l][m] = 0; - double k[4][4] = - { - {u[i-1][j-1], q[i-1][j-1], u[i-1][j], q[i-1][j]}, - {p[i-1][j-1], s[i-1][j-1], p[i-1][j], s[i-1][j]}, - {u[i][j-1], q[i][j-1], u[i][j], q[i][j]}, - {p[i][j-1], s[i][j-1], p[i][j], s[i][j]} - }; + double k[4][4] = {{u[i - 1][j - 1], q[i - 1][j - 1], u[i - 1][j], q[i - 1][j]}, + {p[i - 1][j - 1], s[i - 1][j - 1], p[i - 1][j], s[i - 1][j]}, + {u[i][j - 1], q[i][j - 1], u[i][j], q[i][j]}, + {p[i][j - 1], s[i][j - 1], p[i][j], s[i][j]}}; for (int l = 0; l < 4; l++) for (int m = 0; m < 4; m++) for (int n = 0; n < 4; n++) - for (int o = 0; o < 4; o++) - g[i][j][l][m] += ax[l][n] * k[n][o] * ay[m][o]; + for (int o = 0; o < 4; o++) g[i][j][l][m] += ax[l][n] * k[n][o] * ay[m][o]; } memory->destroy(p); @@ -1182,313 +1212,284 @@ void PairMesoCNT::spline_coeff(double **data, double ****coeff, memory->destroy(dprime); } - /* ---------------------------------------------------------------------- cubic spline evaluation ------------------------------------------------------------------------- */ -double PairMesoCNT::spline(double x, double xstart, double dx, - double **coeff, int coeff_size) +double PairMesoCNT::spline(double x, double xstart, double dx, double **coeff, int coeff_size) { - int i = ceil((x - xstart)/dx); + int i = ceil((x - xstart) / dx); // linear extrapolation if (i < 1) { - return coeff[1][0] + coeff[1][1]*(x - xstart); + return coeff[1][0] + coeff[1][1] * (x - xstart); - // constant extrapolation + // constant extrapolation - } else if (i > coeff_size-1) { + } else if (i > coeff_size - 1) { i = coeff_size - 1; - x = xstart + (coeff_size-1)*dx; + x = xstart + (coeff_size - 1) * dx; } // cubic interpolation - double xlo = xstart + (i-1)*dx; + double xlo = xstart + (i - 1) * dx; double xbar = x - xlo; - return coeff[i][0] - + xbar*(coeff[i][1] + xbar*(coeff[i][2] + xbar*coeff[i][3])); + return coeff[i][0] + xbar * (coeff[i][1] + xbar * (coeff[i][2] + xbar * coeff[i][3])); } /* ---------------------------------------------------------------------- cubic spline derivative ------------------------------------------------------------------------- */ -double PairMesoCNT::dspline(double x, double xstart, double dx, - double **coeff, int coeff_size) +double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, int coeff_size) { - int i = ceil((x - xstart)/dx); + int i = ceil((x - xstart) / dx); // constant extrapolation if (i < 1) { return coeff[1][1]; - // constant extrapolation + // constant extrapolation - } else if (i > coeff_size-1) { + } else if (i > coeff_size - 1) { i = coeff_size - 1; - x = xstart + (coeff_size-1)*dx; + x = xstart + (coeff_size - 1) * dx; } // cubic interpolation - double xlo = xstart + (i-1)*dx; + double xlo = xstart + (i - 1) * dx; double xbar = x - xlo; - return coeff[i][1] + xbar*(2*coeff[i][2] + 3*xbar*coeff[i][3]); + return coeff[i][1] + xbar * (2 * coeff[i][2] + 3 * xbar * coeff[i][3]); } /* ---------------------------------------------------------------------- bicubic spline evaluation ------------------------------------------------------------------------- */ -double PairMesoCNT::spline(double x, double y, - double xstart, double ystart, - double dx, double dy, - double ****coeff, int coeff_size) +double PairMesoCNT::spline(double x, double y, double xstart, double ystart, double dx, double dy, + double ****coeff, int coeff_size) { - int i = ceil((x - xstart)/dx); - int j = ceil((y - ystart)/dy); + int i = ceil((x - xstart) / dx); + int j = ceil((y - ystart) / dy); // constant extrapolation if (i < 1) { i = 1; x = xstart; - } else if (i > coeff_size-1) { + } else if (i > coeff_size - 1) { i = coeff_size - 1; - x = xstart + (coeff_size-1)*dx; + x = xstart + (coeff_size - 1) * dx; } if (j < 1) { j = 1; y = ystart; - } else if (j > coeff_size-1) { + } else if (j > coeff_size - 1) { j = coeff_size - 1; - y = ystart + (coeff_size-1)*dy; + y = ystart + (coeff_size - 1) * dy; } // cubic interpolation - double xlo = xstart + (i-1)*dx; - double ylo = ystart + (j-1)*dy; + double xlo = xstart + (i - 1) * dx; + double ylo = ystart + (j - 1) * dy; double xbar = x - xlo; double ybar = y - ylo; - double y0 = coeff[i][j][0][0] - + ybar*(coeff[i][j][0][1] - + ybar*(coeff[i][j][0][2] - + ybar*(coeff[i][j][0][3]))); - double y1 = coeff[i][j][1][0] - + ybar*(coeff[i][j][1][1] - + ybar*(coeff[i][j][1][2] - + ybar*(coeff[i][j][1][3]))); - double y2 = coeff[i][j][2][0] - + ybar*(coeff[i][j][2][1] - + ybar*(coeff[i][j][2][2] - + ybar*(coeff[i][j][2][3]))); - double y3 = coeff[i][j][3][0] - + ybar*(coeff[i][j][3][1] - + ybar*(coeff[i][j][3][2] - + ybar*(coeff[i][j][3][3]))); + double y0 = coeff[i][j][0][0] + + ybar * (coeff[i][j][0][1] + ybar * (coeff[i][j][0][2] + ybar * (coeff[i][j][0][3]))); + double y1 = coeff[i][j][1][0] + + ybar * (coeff[i][j][1][1] + ybar * (coeff[i][j][1][2] + ybar * (coeff[i][j][1][3]))); + double y2 = coeff[i][j][2][0] + + ybar * (coeff[i][j][2][1] + ybar * (coeff[i][j][2][2] + ybar * (coeff[i][j][2][3]))); + double y3 = coeff[i][j][3][0] + + ybar * (coeff[i][j][3][1] + ybar * (coeff[i][j][3][2] + ybar * (coeff[i][j][3][3]))); - return y0 + xbar*(y1 + xbar*(y2 + xbar*y3)); + return y0 + xbar * (y1 + xbar * (y2 + xbar * y3)); } /* ---------------------------------------------------------------------- bicubic spline partial x derivative ------------------------------------------------------------------------- */ -double PairMesoCNT::dxspline(double x, double y, - double xstart, double ystart, - double dx, double dy, - double ****coeff, int coeff_size) +double PairMesoCNT::dxspline(double x, double y, double xstart, double ystart, double dx, double dy, + double ****coeff, int coeff_size) { - int i = ceil((x - xstart)/dx); - int j = ceil((y - ystart)/dy); + int i = ceil((x - xstart) / dx); + int j = ceil((y - ystart) / dy); // constant extrapolation if (i < 1) { i = 1; x = xstart; - } else if (i > coeff_size-1) { + } else if (i > coeff_size - 1) { i = coeff_size - 1; - x = xstart + (coeff_size-1)*dx; + x = xstart + (coeff_size - 1) * dx; } if (j < 1) { j = 1; y = ystart; - } else if (j > coeff_size-1) { + } else if (j > coeff_size - 1) { j = coeff_size - 1; - y = ystart + (coeff_size-1)*dy; + y = ystart + (coeff_size - 1) * dy; } // cubic interpolation - double xlo = xstart + (i-1)*dx; - double ylo = ystart + (j-1)*dy; + double xlo = xstart + (i - 1) * dx; + double ylo = ystart + (j - 1) * dy; double xbar = x - xlo; double ybar = y - ylo; - double y1 = coeff[i][j][1][0] - + ybar*(coeff[i][j][1][1] - + ybar*(coeff[i][j][1][2] - + ybar*(coeff[i][j][1][3]))); - double y2 = coeff[i][j][2][0] - + ybar*(coeff[i][j][2][1] - + ybar*(coeff[i][j][2][2] - + ybar*(coeff[i][j][2][3]))); - double y3 = coeff[i][j][3][0] - + ybar*(coeff[i][j][3][1] - + ybar*(coeff[i][j][3][2] - + ybar*(coeff[i][j][3][3]))); + double y1 = coeff[i][j][1][0] + + ybar * (coeff[i][j][1][1] + ybar * (coeff[i][j][1][2] + ybar * (coeff[i][j][1][3]))); + double y2 = coeff[i][j][2][0] + + ybar * (coeff[i][j][2][1] + ybar * (coeff[i][j][2][2] + ybar * (coeff[i][j][2][3]))); + double y3 = coeff[i][j][3][0] + + ybar * (coeff[i][j][3][1] + ybar * (coeff[i][j][3][2] + ybar * (coeff[i][j][3][3]))); - return y1 + xbar*(2*y2 + 3*xbar*y3); + return y1 + xbar * (2 * y2 + 3 * xbar * y3); } /* ---------------------------------------------------------------------- bicubic spline partial y derivative ------------------------------------------------------------------------- */ -double PairMesoCNT::dyspline(double x, double y, - double xstart, double ystart, - double dx, double dy, - double ****coeff, int coeff_size) +double PairMesoCNT::dyspline(double x, double y, double xstart, double ystart, double dx, double dy, + double ****coeff, int coeff_size) { - int i = ceil((x - xstart)/dx); - int j = ceil((y - ystart)/dy); + int i = ceil((x - xstart) / dx); + int j = ceil((y - ystart) / dy); // constant extrapolation if (i < 1) { i = 1; x = xstart; - } else if (i > coeff_size-1) { + } else if (i > coeff_size - 1) { i = coeff_size - 1; - x = xstart + (coeff_size-1)*dx; + x = xstart + (coeff_size - 1) * dx; } if (j < 1) { j = 1; y = ystart; - } else if (j > coeff_size-1) { + } else if (j > coeff_size - 1) { j = coeff_size - 1; - y = ystart + (coeff_size-1)*dy; + y = ystart + (coeff_size - 1) * dy; } // cubic interpolation - double xlo = xstart + (i-1)*dx; - double ylo = ystart + (j-1)*dy; + double xlo = xstart + (i - 1) * dx; + double ylo = ystart + (j - 1) * dy; double xbar = x - xlo; double ybar = y - ylo; - double y0 = coeff[i][j][0][1] - + ybar*(2*coeff[i][j][0][2] - + 3*ybar*coeff[i][j][0][3]); - double y1 = coeff[i][j][1][1] - + ybar*(2*coeff[i][j][1][2] - + 3*ybar*coeff[i][j][1][3]); - double y2 = coeff[i][j][2][1] - + ybar*(2*coeff[i][j][2][2] - + 3*ybar*coeff[i][j][2][3]); - double y3 = coeff[i][j][3][1] - + ybar*(2*coeff[i][j][3][2] - + 3*ybar*coeff[i][j][3][3]); + double y0 = coeff[i][j][0][1] + ybar * (2 * coeff[i][j][0][2] + 3 * ybar * coeff[i][j][0][3]); + double y1 = coeff[i][j][1][1] + ybar * (2 * coeff[i][j][1][2] + 3 * ybar * coeff[i][j][1][3]); + double y2 = coeff[i][j][2][1] + ybar * (2 * coeff[i][j][2][2] + 3 * ybar * coeff[i][j][2][3]); + double y3 = coeff[i][j][3][1] + ybar * (2 * coeff[i][j][3][2] + 3 * ybar * coeff[i][j][3][3]); - return y0 + xbar*(y1 + xbar*(y2 + xbar*y3)); + return y0 + xbar * (y1 + xbar * (y2 + xbar * y3)); } /* ---------------------------------------------------------------------- compute local geometric parameters ------------------------------------------------------------------------- */ -void PairMesoCNT::geometry(const double *r1, const double *r2, - const double *p1, const double *p2, const double *qe, - double *p, double *m, double *param, double **basis) +void PairMesoCNT::geometry(const double *r1, const double *r2, const double *p1, const double *p2, + const double *qe, double *p, double *m, double *param, double **basis) { - double r[3],delr[3],l[3],rbar[3],pbar[3],delrbar[3]; - double psil[3],psim[3],dell_psim[3],delpsil_m[3]; - double delr1[3],delr2[3],delp1[3],delp2[3],delpqe[3]; + double r[3], delr[3], l[3], rbar[3], pbar[3], delrbar[3]; + double psil[3], psim[3], dell_psim[3], delpsil_m[3]; + double delr1[3], delr2[3], delp1[3], delp2[3], delpqe[3]; double *ex = basis[0]; double *ey = basis[1]; double *ez = basis[2]; - add3(r1,r2,r); - scale3(0.5,r); - add3(p1,p2,p); - scale3(0.5,p); + add3(r1, r2, r); + scale3(0.5, r); + add3(p1, p2, p); + scale3(0.5, p); - sub3(p,r,delr); + sub3(p, r, delr); - sub3(r2,r1,l); + sub3(r2, r1, l); norm3(l); - sub3(p2,p1,m); + sub3(p2, p1, m); norm3(m); - double psi = dot3(l,m); - if (psi > 1.0) psi = 1.0; - else if (psi < -1.0) psi = -1.0; - double denom = 1.0 - psi*psi; + double psi = dot3(l, m); + if (psi > 1.0) + psi = 1.0; + else if (psi < -1.0) + psi = -1.0; + double denom = 1.0 - psi * psi; - copy3(l,psil); - scale3(psi,psil); - copy3(m,psim); - scale3(psi,psim); + copy3(l, psil); + scale3(psi, psil); + copy3(m, psim); + scale3(psi, psim); - double rhoe,etae,taur,taup; + double rhoe, etae, taur, taup; if (qe) { - sub3(p,qe,delpqe); - rhoe = dot3(delpqe,m); - } else rhoe = 0; + sub3(p, qe, delpqe); + rhoe = dot3(delpqe, m); + } else + rhoe = 0; // parallel case if (denom < SWITCH) { - taur = dot3(delr,l) - rhoe*psi; + taur = dot3(delr, l) - rhoe * psi; taup = -rhoe; etae = 0; - // non-parallel case + // non-parallel case } else { double frac = 1.0 / denom; - sub3(l,psim,dell_psim); - sub3(psil,m,delpsil_m); - taur = dot3(delr,dell_psim) * frac; - taup = dot3(delr,delpsil_m) * frac; + sub3(l, psim, dell_psim); + sub3(psil, m, delpsil_m); + taur = dot3(delr, dell_psim) * frac; + taup = dot3(delr, delpsil_m) * frac; etae = -rhoe - taup; } - scaleadd3(taur,l,r,rbar); - scaleadd3(taup,m,p,pbar); - sub3(pbar,rbar,delrbar); + scaleadd3(taur, l, r, rbar); + scaleadd3(taup, m, p, pbar); + sub3(pbar, rbar, delrbar); double h = len3(delrbar); + if (h * ang_inv < SMALL) h = SMALL * ang; - copy3(delrbar,ex); - copy3(l,ez); - scale3(1.0/h,ex); - cross3(ez,ex,ey); + copy3(delrbar, ex); + copy3(l, ez); + scale3(1.0 / h, ex); + cross3(ez, ex, ey); double alpha; - alpha = (dot3(m,ey) < 0) ? acos(psi) : MY_2PI - acos(psi); + alpha = (dot3(m, ey) < 0) ? acos(psi) : MY_2PI - acos(psi); - sub3(r1,rbar,delr1); - sub3(r2,rbar,delr2); - sub3(p1,pbar,delp1); - sub3(p2,pbar,delp2); - double xi1 = dot3(delr1,l); - double xi2 = dot3(delr2,l); - double eta1 = dot3(delp1,m); - double eta2 = dot3(delp2,m); + sub3(r1, rbar, delr1); + sub3(r2, rbar, delr2); + sub3(p1, pbar, delp1); + sub3(p2, pbar, delp2); + double xi1 = dot3(delr1, l); + double xi2 = dot3(delr2, l); + double eta1 = dot3(delp1, m); + double eta2 = dot3(delp2, m); param[0] = h; param[1] = alpha; @@ -1499,30 +1500,27 @@ void PairMesoCNT::geometry(const double *r1, const double *r2, param[6] = etae; } - /* ---------------------------------------------------------------------- weight for substitute CNT chain ------------------------------------------------------------------------- */ -void PairMesoCNT::weight(const double *r1, const double *r2, - const double *p1, const double *p2, double &w, - double *dr1_w, double *dr2_w, - double *dp1_w, double *dp2_w) +void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, const double *p2, + double &w, double *dr1_w, double *dr2_w, double *dp1_w, double *dp2_w) { - double dr,dp,rhoc,rhomin,rho,frac,arg,factor; - double r[3],p[3]; - double dr_rho[3],dr_rhoc[3],dp_rhoc[3]; + double dr, dp, rhoc, rhomin, rho, frac, arg, factor; + double r[3], p[3]; + double dr_rho[3], dr_rhoc[3], dp_rhoc[3]; - add3(r1,r2,r); - add3(p1,p2,p); - scale3(0.5,r); - scale3(0.5,p); + add3(r1, r2, r); + add3(p1, p2, p); + scale3(0.5, r); + scale3(0.5, p); - dr = sqrt(0.25*distsq3(r1,r2) + rsq); - dp = sqrt(0.25*distsq3(p1,p2) + rsq); + dr = sqrt(0.25 * distsq3(r1, r2) + rsq); + dp = sqrt(0.25 * distsq3(p1, p2) + rsq); rhoc = dr + dp + rc; rhomin = 20.0 * ang; - rho = sqrt(distsq3(r,p)); + rho = sqrt(distsq3(r, p)); frac = 1.0 / (rhoc - rhomin); arg = frac * (rho - rhomin); @@ -1536,22 +1534,22 @@ void PairMesoCNT::weight(const double *r1, const double *r2, } else { factor = ds(arg) * frac; - sub3(r,p,dr_rho); - sub3(r1,r2,dr_rhoc); - sub3(p1,p2,dp_rhoc); - scale3(0.5/rho,dr_rho); - scale3(0.25/dr,dr_rhoc); - scale3(0.25/dp,dp_rhoc); + sub3(r, p, dr_rho); + sub3(r1, r2, dr_rhoc); + sub3(p1, p2, dp_rhoc); + scale3(0.5 / rho, dr_rho); + scale3(0.25 / dr, dr_rhoc); + scale3(0.25 / dp, dp_rhoc); - scaleadd3(-arg,dr_rhoc,dr_rho,dr1_w); - scaleadd3(arg,dr_rhoc,dr_rho,dr2_w); + scaleadd3(-arg, dr_rhoc, dr_rho, dr1_w); + scaleadd3(arg, dr_rhoc, dr_rho, dr2_w); negate3(dr_rho); - scaleadd3(-arg,dp_rhoc,dr_rho,dp1_w); - scaleadd3(arg,dp_rhoc,dr_rho,dp2_w); - scale3(factor,dr1_w); - scale3(factor,dr2_w); - scale3(factor,dp1_w); - scale3(factor,dp2_w); + scaleadd3(-arg, dp_rhoc, dr_rho, dp1_w); + scaleadd3(arg, dp_rhoc, dr_rho, dp2_w); + scale3(factor, dr1_w); + scale3(factor, dr2_w); + scale3(factor, dp1_w); + scale3(factor, dp2_w); } } @@ -1572,11 +1570,9 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) // parallel case if (sin_alphasq < SWITCH) { - double ubar = spline(h,hstart_uinf,delh_uinf,uinf_coeff,uinf_points); + double ubar = spline(h, hstart_uinf, delh_uinf, uinf_coeff, uinf_points); double delxi = xi2 - xi1; - f[0][0] = 0.5 * delxi - * dspline(h,hstart_uinf,delh_uinf,uinf_coeff,uinf_points) - * funit; + f[0][0] = 0.5 * delxi * dspline(h, hstart_uinf, delh_uinf, uinf_coeff, uinf_points) * funit; f[1][0] = f[0][0]; f[0][1] = 0; f[1][1] = 0; @@ -1584,7 +1580,7 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) f[1][2] = -f[0][2]; evdwl = ubar * delxi * eunit; - // non-parallel case + // non-parallel case } else { double sin_alpha_inv = 1.0 / sin_alpha; @@ -1592,16 +1588,14 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) double cos_alpha = cos(alpha); double cot_alpha = cos_alpha * sin_alpha_inv; - double omega = 1.0 / (1.0 - comega*sin_alphasq); + double omega = 1.0 / (1.0 - comega * sin_alphasq); double c1 = omega * sin_alpha; double c1_inv = 1.0 / c1; double domega = 2 * comega * cos_alpha * c1 * omega; - double gamma_orth = - spline(h,hstart_gamma,delh_gamma,gamma_coeff,gamma_points); - double dgamma_orth = - dspline(h,hstart_gamma,delh_gamma,gamma_coeff,gamma_points); - double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; + double gamma_orth = spline(h, hstart_gamma, delh_gamma, gamma_coeff, gamma_points); + double dgamma_orth = dspline(h, hstart_gamma, delh_gamma, gamma_coeff, gamma_points); + double gamma = 1.0 + (gamma_orth - 1.0) * sin_alphasq; double gamma_inv = 1.0 / gamma; double dalpha_gamma = 2 * (gamma_orth - 1) * sin_alpha * cos_alpha; double dh_gamma = dgamma_orth * sin_alphasq; @@ -1609,22 +1603,25 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) double zeta1 = xi1 * c1; double zeta2 = xi2 * c1; - double smooth = s5((h-d_ang-delta1)/(delta2-delta1)); - double dsmooth = ds5((h-d_ang-delta1)/(delta2-delta1)); + double smooth = s5((h - d_ang - delta1) / (delta2 - delta1)); + double dsmooth = ds5((h - d_ang - delta1) / (delta2 - delta1)); double g = d_ang + delta2; double hsq = h * h; double zetaminbar; - if (h >= g) zetaminbar = 0; - else zetaminbar = sqrt(g*g - hsq); + if (h >= g) + zetaminbar = 0; + else + zetaminbar = sqrt(g * g - hsq); double zetamin = smooth * zetaminbar; double zetamax = sqrt(cutoffsq_ang - hsq); double dzetaminbar; - if (h >= g) dzetaminbar = 0; - else dzetaminbar = -h / zetaminbar; - double dzetamin = - dzetaminbar*smooth + zetaminbar*dsmooth/(delta2-delta1); + if (h >= g) + dzetaminbar = 0; + else + dzetaminbar = -h / zetaminbar; + double dzetamin = dzetaminbar * smooth + zetaminbar * dsmooth / (delta2 - delta1); double dzetamax = -h / zetamax; double zeta_range_inv = 1.0 / (zetamax - zetamin); @@ -1634,24 +1631,24 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) double psi1 = delzeta1 * zeta_range_inv; double psi2 = delzeta2 * zeta_range_inv; - double phi1 = spline(h,psi1,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_coeff,phi_points); - double dh_phibar1 = dxspline(h,psi1,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_coeff,phi_points); - double dpsi_phibar1 = dyspline(h,psi1,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_coeff,phi_points); - double phi2 = spline(h,psi2,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_coeff,phi_points); - double dh_phibar2 = dxspline(h,psi2,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_coeff,phi_points); - double dpsi_phibar2 = dyspline(h,psi2,hstart_phi,psistart_phi, - delh_phi,delpsi_phi,phi_coeff,phi_points); + double phi1 = + spline(h, psi1, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + double dh_phibar1 = + dxspline(h, psi1, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + double dpsi_phibar1 = + dyspline(h, psi1, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + double phi2 = + spline(h, psi2, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + double dh_phibar2 = + dxspline(h, psi2, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + double dpsi_phibar2 = + dyspline(h, psi2, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); double dzeta_range = dzetamax - dzetamin; - double dh_psi1 = -zeta_range_inv * (dzetamin + dzeta_range*psi1); - double dh_psi2 = -zeta_range_inv * (dzetamin + dzeta_range*psi2); - double dh_phi1 = dh_phibar1 + dpsi_phibar1*dh_psi1; - double dh_phi2 = dh_phibar2 + dpsi_phibar2*dh_psi2; + double dh_psi1 = -zeta_range_inv * (dzetamin + dzeta_range * psi1); + double dh_psi2 = -zeta_range_inv * (dzetamin + dzeta_range * psi2); + double dh_phi1 = dh_phibar1 + dpsi_phibar1 * dh_psi1; + double dh_phi2 = dh_phibar2 + dpsi_phibar2 * dh_psi2; double dzeta_phi1 = dpsi_phibar1 * zeta_range_inv; double dzeta_phi2 = dpsi_phibar2 * zeta_range_inv; @@ -1672,19 +1669,19 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) double u = c2 * (phi2 - phi1); double c3 = u * gamma_inv; - double dh_u = dh_gamma*c3 + c2*(dh_phi2 - dh_phi1); - double dalpha_u = dalpha_gamma*c3 - + c1_inv*(domega*sin_alpha + omega*cos_alpha) - * (gamma*(xi2*dzeta_phi2 - xi1*dzeta_phi1) - u); + double dh_u = dh_gamma * c3 + c2 * (dh_phi2 - dh_phi1); + double dalpha_u = dalpha_gamma * c3 + + c1_inv * (domega * sin_alpha + omega * cos_alpha) * + (gamma * (xi2 * dzeta_phi2 - xi1 * dzeta_phi1) - u); double lr_inv = 1.0 / (xi2 - xi1); double cx = h * gamma * sin_alphasq_inv * deldzeta_phi; double cy = gamma * cot_alpha * deldzeta_phi; - f[0][0] = lr_inv * (xi2*dh_u - cx) * funit; - f[1][0] = lr_inv * (-xi1*dh_u + cx) * funit; - f[0][1] = lr_inv * (dalpha_u - xi2*cy) * funit; - f[1][1] = lr_inv * (-dalpha_u + xi1*cy) * funit; + f[0][0] = lr_inv * (xi2 * dh_u - cx) * funit; + f[1][0] = lr_inv * (-xi1 * dh_u + cx) * funit; + f[0][1] = lr_inv * (dalpha_u - xi2 * cy) * funit; + f[1][1] = lr_inv * (-dalpha_u + xi1 * cy) * funit; f[0][2] = gamma * dzeta_phi1 * funit; f[1][2] = -gamma * dzeta_phi2 * funit; evdwl = u * eunit; @@ -1695,8 +1692,7 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) forces for semi-infinite CNT case ------------------------------------------------------------------------- */ -void PairMesoCNT::fsemi(const double *param, double &evdwl, - double &fend, double **f) +void PairMesoCNT::fsemi(const double *param, double &evdwl, double &fend, double **f) { double h = param[0] * ang_inv; double alpha = param[1]; @@ -1708,22 +1704,20 @@ void PairMesoCNT::fsemi(const double *param, double &evdwl, double sin_alphasq = sin_alpha * sin_alpha; double cos_alpha = cos(alpha); - double omega = 1.0 / (1.0 - comega*sin_alphasq); + double omega = 1.0 / (1.0 - comega * sin_alphasq); double omegasq = omega * omega; double domega = 2 * comega * sin_alpha * cos_alpha * omegasq; - double theta = 1.0 - ctheta*sin_alphasq; + double theta = 1.0 - ctheta * sin_alphasq; double dtheta = -2 * ctheta * sin_alpha * cos_alpha; double c1 = omega * sin_alpha; double c1sq = c1 * c1; double c2 = theta * etae; - double gamma_orth = spline(h,hstart_gamma,delh_gamma, - gamma_coeff,gamma_points); - double dgamma_orth = dspline(h,hstart_gamma,delh_gamma, - gamma_coeff,gamma_points); - double gamma = 1.0 + (gamma_orth - 1)*sin_alphasq; + double gamma_orth = spline(h, hstart_gamma, delh_gamma, gamma_coeff, gamma_points); + double dgamma_orth = dspline(h, hstart_gamma, delh_gamma, gamma_coeff, gamma_points); + double gamma = 1.0 + (gamma_orth - 1) * sin_alphasq; double gamma_inv = 1.0 / gamma; double dalpha_gamma = 2 * (gamma_orth - 1) * sin_alpha * cos_alpha; double dh_gamma = dgamma_orth * sin_alphasq; @@ -1739,22 +1733,27 @@ void PairMesoCNT::fsemi(const double *param, double &evdwl, double ubar = 0; for (int i = 0; i < QUADRATURE; i++) { - double xibar = xi1 + i*delxi; + double xibar = xi1 + i * delxi; double g = xibar * c1; - double hbar = sqrt(h*h + g*g); - double thetabar = xibar*cos_alpha - c2; + double hbar = sqrt(h * h + g * g); + double thetabar = xibar * cos_alpha - c2; double c = 1.0; - if (i == 0 || i == QUADRATURE-1) c = 0.5; + if (i == 0 || i == QUADRATURE - 1) c = 0.5; - double u = c * spline(hbar,thetabar,hstart_usemi,xistart_usemi, - delh_usemi,delxi_usemi,usemi_coeff,usemi_points); + double u = c * + spline(hbar, thetabar, hstart_usemi, xistart_usemi, delh_usemi, delxi_usemi, usemi_coeff, + usemi_points); double uh; - if (hbar == 0) uh = 0; - else uh = c / hbar * dxspline(hbar,thetabar,hstart_usemi,xistart_usemi, - delh_usemi,delxi_usemi,usemi_coeff,usemi_points); - double uxi = c * dyspline(hbar,thetabar,hstart_usemi,xistart_usemi, - delh_usemi,delxi_usemi,usemi_coeff,usemi_points); + if (hbar == 0) + uh = 0; + else + uh = c / hbar * + dxspline(hbar, thetabar, hstart_usemi, xistart_usemi, delh_usemi, delxi_usemi, + usemi_coeff, usemi_points); + double uxi = c * + dyspline(hbar, thetabar, hstart_usemi, xistart_usemi, delh_usemi, delxi_usemi, usemi_coeff, + usemi_points); double uh1 = xibar * uh; jh += uh; @@ -1773,23 +1772,22 @@ void PairMesoCNT::fsemi(const double *param, double &evdwl, ubar *= c3; double c4 = gamma_inv * ubar; - double dh_ubar = dh_gamma*c4 + h*jh; - double dalpha_ubar = dalpha_gamma*c4 - + c1*(domega*sin_alpha + omega*cos_alpha)*jh2 - - sin_alpha*jxi1 - dtheta*etae*jxi; + double dh_ubar = dh_gamma * c4 + h * jh; + double dalpha_ubar = dalpha_gamma * c4 + c1 * (domega * sin_alpha + omega * cos_alpha) * jh2 - + sin_alpha * jxi1 - dtheta * etae * jxi; - double cx = h * (omegasq*jh1 + cos_alpha*ctheta*jxi); - double cy = sin_alpha * (cos_alpha*omegasq*jh1 + (ctheta-1)*jxi); - double cz1 = c1sq*jh1 + cos_alpha*jxi; - double cz2 = c1sq*jh2 + cos_alpha*jxi1; + double cx = h * (omegasq * jh1 + cos_alpha * ctheta * jxi); + double cy = sin_alpha * (cos_alpha * omegasq * jh1 + (ctheta - 1) * jxi); + double cz1 = c1sq * jh1 + cos_alpha * jxi; + double cz2 = c1sq * jh2 + cos_alpha * jxi1; double l_inv = 1.0 / (xi2 - xi1); - f[0][0] = l_inv * (xi2*dh_ubar - cx) * funit; - f[1][0] = l_inv * (cx - xi1*dh_ubar) * funit; - f[0][1] = l_inv * (dalpha_ubar - xi2*cy) * funit; - f[1][1] = l_inv * (xi1*cy - dalpha_ubar) * funit; - f[0][2] = l_inv * (cz2 + ubar - xi2*cz1) * funit; - f[1][2] = l_inv * (xi1*cz1 - cz2 - ubar) * funit; + f[0][0] = l_inv * (xi2 * dh_ubar - cx) * funit; + f[1][0] = l_inv * (cx - xi1 * dh_ubar) * funit; + f[0][1] = l_inv * (dalpha_ubar - xi2 * cy) * funit; + f[1][1] = l_inv * (xi1 * cy - dalpha_ubar) * funit; + f[0][2] = l_inv * (cz2 + ubar - xi2 * cz1) * funit; + f[1][2] = l_inv * (xi1 * cz1 - cz2 - ubar) * funit; evdwl = ubar * eunit; fend = theta * jxi * funit; diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index 559a260f3f..795b27f8ff 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -12,9 +12,7 @@ ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS -// clang-format off PairStyle(mesocnt, PairMesoCNT); -// clang-format on #else #ifndef LMP_PAIR_MESOCNT_H @@ -23,7 +21,7 @@ PairStyle(mesocnt, PairMesoCNT); #include "pair.h" namespace LAMMPS_NS { - +class PotentialFileReader; class PairMesoCNT : public Pair { public: PairMesoCNT(class LAMMPS *); @@ -36,7 +34,6 @@ class PairMesoCNT : public Pair { protected: int uinf_points, gamma_points, phi_points, usemi_points; - int nlocal_size, reduced_neigh_size; int *reduced_nlist, *numchainlist; int **reduced_neighlist, **nchainlist, **endlist; int ***chainlist; @@ -57,16 +54,18 @@ class PairMesoCNT : public Pair { double **uinf_coeff, **gamma_coeff, ****phi_coeff, ****usemi_coeff; double **flocal, **fglobal, **basis; - char *file; + int count_chains(int *, int); void allocate(); void bond_neigh(); void neigh_common(int, int, int &, int *); - void chain_split(int *, int, int &, int **, int *, int *); + void chain_lengths(int *, int, int *); + void chain_split(int *, int, int *, int **, int *); void sort(int *, int); - void read_file(); - void read_data(FILE *, double *, double &, double &, int); - void read_data(FILE *, double **, double &, double &, double &, double &, int); + void read_file(const char *); + void read_data(PotentialFileReader &, double *, double &, double &, int); + void read_data(PotentialFileReader &, double **, double &, double &, double &, double &, + int); void spline_coeff(double *, double **, double, int); void spline_coeff(double **, double ****, double, double, int); diff --git a/src/Purge.list b/src/Purge.list index feb30a9ad7..8284961e1e 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -51,6 +51,9 @@ lmpinstalledpkgs.h lmpgitversion.h mliap_model_python_couple.cpp mliap_model_python_couple.h +# renamed on 7 March 2022 +compute_pressure_cylinder.cpp +compute_pressure_cylinder.h # renamed on 21 July 2021 fix_qeq_reax_kokkos.cpp fix_qeq_reax_kokkos.h diff --git a/src/REAXFF/fix_qeq_reaxff.cpp b/src/REAXFF/fix_qeq_reaxff.cpp index 796d363972..db5d5100ba 100644 --- a/src/REAXFF/fix_qeq_reaxff.cpp +++ b/src/REAXFF/fix_qeq_reaxff.cpp @@ -416,14 +416,13 @@ void FixQEqReaxFF::init() "boundary when using charge equilibration with ReaxFF."); } - // we need a half neighbor list w/ Newton off and ghost neighbors + // we need a half neighbor list w/ Newton off // built whenever re-neighboring occurs int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->fix = 1; neighbor->requests[irequest]->newton = 2; - neighbor->requests[irequest]->ghost = 1; init_shielding(); init_taper(); diff --git a/src/REAXFF/pair_reaxff.cpp b/src/REAXFF/pair_reaxff.cpp index 39b6221d3d..991b6f0a30 100644 --- a/src/REAXFF/pair_reaxff.cpp +++ b/src/REAXFF/pair_reaxff.cpp @@ -263,6 +263,12 @@ void PairReaxFF::settings(int narg, char **arg) if (iarg+2 > narg) error->all(FLERR,"Illegal pair_style reaxff command"); list_blocking_flag = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; + } else if (strcmp(arg[iarg],"tabulate") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal pair_style reaxff command"); + api->control->tabulate = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + if (api->control->tabulate < 0) + error->all(FLERR,"Illegal pair_style reaxff tabulate command"); + iarg += 2; } else error->all(FLERR,"Illegal pair_style reaxff command"); } } diff --git a/src/memory.h b/src/memory.h index f7ea3bc4a7..5095cbb0a6 100644 --- a/src/memory.h +++ b/src/memory.h @@ -226,10 +226,38 @@ class Memory : protected Pointers { } template - TYPE ***create_ragged(TYPE ***& /*array*/, int /*n1*/, int * /*n2*/, const char *name) + TYPE ***create_ragged(TYPE ***& array, int n1, int *n2, int **n3, const char *name) { - fail(name); - return nullptr; + bigint size, nbytes; + int i, j; + + size = 0; + for (i = 0; i < n1; i++) + for (j = 0; j < n2[i]; j++) + size += n3[i][j]; + nbytes = ((bigint) sizeof(TYPE)) * size; + TYPE *data = (TYPE *) smalloc(nbytes, name); + + size = 0; + for (i = 0; i < n1; i++) size += n2[i]; + nbytes = ((bigint) sizeof(TYPE *)) * size; + TYPE **plane = (TYPE **) smalloc(nbytes, name); + + nbytes = ((bigint) sizeof(TYPE **)) * n1; + array = (TYPE ***) smalloc(nbytes, name); + + bigint m = 0; + bigint n = 0; + for (i = 0; i < n1; i++) { + array[i] = &plane[m]; + for (j = 0; j < n2[i]; j++) { + plane[m + j] = &data[n]; + n += n3[i][j]; + } + m += n2[i]; + } + + return array; } /* ---------------------------------------------------------------------- diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index d4f437dc4c..6d5ea802d4 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -41,6 +41,11 @@ target_compile_definitions(test_reset_ids PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CU target_link_libraries(test_reset_ids PRIVATE lammps GTest::GMock) add_test(NAME ResetIDs COMMAND test_reset_ids) +add_executable(test_compute_global test_compute_global.cpp) +target_compile_definitions(test_compute_global PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(test_compute_global PRIVATE lammps GTest::GMock) +add_test(NAME ComputeGlobal COMMAND test_compute_global) + add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp) target_link_libraries(test_mpi_load_balancing PRIVATE lammps GTest::GMock) target_compile_definitions(test_mpi_load_balancing PRIVATE ${TEST_CONFIG_DEFS}) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp new file mode 100644 index 0000000000..1c9be99ba4 --- /dev/null +++ b/unittest/commands/test_compute_global.cpp @@ -0,0 +1,325 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "../testing/core.h" +#include "info.h" +#include "input.h" +#include "lammps.h" +#include "library.h" +#include "utils.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include +#include + +// whether to print verbose output (i.e. not capturing LAMMPS screen output). +bool verbose = false; + +using LAMMPS_NS::utils::split_words; + +namespace LAMMPS_NS { + +#define STRINGIFY(val) XSTR(val) +#define XSTR(val) #val + +class ComputeGlobalTest : public LAMMPSTest { +protected: + void SetUp() override + { + testbinary = "ComputeGlobalTest"; + LAMMPSTest::SetUp(); + if (info->has_style("atom", "full")) { + BEGIN_HIDE_OUTPUT(); + command("variable input_dir index \"" STRINGIFY(TEST_INPUT_FOLDER) "\""); + command("include \"${input_dir}/in.fourmol\""); + command("group allwater molecule 3:6"); + command("region half block 0.0 INF INF INF INF INF"); + END_HIDE_OUTPUT(); + } + } + + double get_scalar(const char *id) + { + return *(double *)lammps_extract_compute(lmp, id, LMP_STYLE_GLOBAL, LMP_TYPE_SCALAR); + } + + double *get_vector(const char *id) + { + return (double *)lammps_extract_compute(lmp, id, LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR); + } + + double **get_array(const char *id) + { + return (double **)lammps_extract_compute(lmp, id, LMP_STYLE_GLOBAL, LMP_TYPE_ARRAY); + } +}; + +TEST_F(ComputeGlobalTest, Energy) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + int has_tally = lammps_config_has_package("TALLY"); + + BEGIN_HIDE_OUTPUT(); + command("pair_style lj/cut/coul/cut 10.0"); + command("pair_coeff * * 0.01 3.0"); + command("bond_style harmonic"); + command("bond_coeff * 100.0 1.5"); + + command("compute ke1 all ke"); + command("compute ke2 allwater ke"); + command("compute pe1 all pe"); + command("compute pe2 all pe bond"); + command("compute pe3 all pe angle dihedral"); + command("compute pr1 all pressure thermo_temp"); + command("compute pr2 all pressure NULL virial"); + command("compute pr3 all pressure NULL angle dihedral"); + std::string thermo_style = "c_ke1 c_ke2 c_pe1 c_pe2 c_pe3 c_pr1 c_pr2 c_pr3"; + + if (has_tally) { + command("compute pe4 all pe/tally allwater"); + command("compute pe5 all pe/mol/tally all"); + command("compute pe6 all pe pair"); + thermo_style += " c_pe4 c_pe5[*]"; + } + + command("thermo_style custom " + thermo_style); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + EXPECT_DOUBLE_EQ(get_scalar("ke1"), 2.3405256449146168); + EXPECT_DOUBLE_EQ(get_scalar("ke2"), 1.192924237073665); + EXPECT_DOUBLE_EQ(get_scalar("pe1"), 24155.155261642241); + EXPECT_DOUBLE_EQ(get_scalar("pe2"), 361.37528652881286); + EXPECT_DOUBLE_EQ(get_scalar("pe3"), 0.0); + EXPECT_DOUBLE_EQ(get_scalar("pr1"), 1956948.4735454607); + EXPECT_DOUBLE_EQ(get_scalar("pr2"), 1956916.7725807722); + EXPECT_DOUBLE_EQ(get_scalar("pr3"), 0.0); + auto pr1 = get_vector("pr1"); + auto pr2 = get_vector("pr2"); + auto pr3 = get_vector("pr3"); + EXPECT_DOUBLE_EQ(pr1[0], 2150600.9207200543); + EXPECT_DOUBLE_EQ(pr1[1], 1466949.7512112649); + EXPECT_DOUBLE_EQ(pr1[2], 2253294.7487050635); + EXPECT_DOUBLE_EQ(pr1[3], 856643.16926486336); + EXPECT_DOUBLE_EQ(pr1[4], 692710.86929464422); + EXPECT_DOUBLE_EQ(pr1[5], -44403.909298603547); + EXPECT_DOUBLE_EQ(pr2[0], 2150575.6989334146); + EXPECT_DOUBLE_EQ(pr2[1], 1466911.3911461537); + EXPECT_DOUBLE_EQ(pr2[2], 2253263.2276627473); + EXPECT_DOUBLE_EQ(pr2[3], 856632.34707690508); + EXPECT_DOUBLE_EQ(pr2[4], 692712.89222328411); + EXPECT_DOUBLE_EQ(pr2[5], -44399.277068014424); + EXPECT_DOUBLE_EQ(pr3[0], 0.0); + EXPECT_DOUBLE_EQ(pr3[1], 0.0); + EXPECT_DOUBLE_EQ(pr3[2], 0.0); + EXPECT_DOUBLE_EQ(pr3[3], 0.0); + EXPECT_DOUBLE_EQ(pr3[4], 0.0); + EXPECT_DOUBLE_EQ(pr3[5], 0.0); + + if (has_tally) { + EXPECT_DOUBLE_EQ(get_scalar("pe4"), 15425.840923850392); + auto pe5 = get_vector("pe5"); + EXPECT_DOUBLE_EQ(pe5[0], 23803.966677151559); + EXPECT_DOUBLE_EQ(pe5[1], -94.210004432380643); + EXPECT_DOUBLE_EQ(pe5[2], 115.58040355478101); + EXPECT_DOUBLE_EQ(pe5[3], -31.557101160514257); + } + + TEST_FAILURE(".*ERROR: Compute pressure must use group all.*", + command("compute pr5 allwater pressure thermo_temp");); + TEST_FAILURE(".*ERROR: Compute pressure requires temperature ID to include kinetic energy.*", + command("compute pr5 all pressure NULL");); + TEST_FAILURE(".*ERROR: Could not find compute pressure temperature ID", + command("compute pr5 all pressure xxx");); + + TEST_FAILURE(".*ERROR: Reuse of compute ID 'pe2'.*", command("compute pe2 all pe");); + TEST_FAILURE(".*ERROR: Compute pe must use group all.*", command("compute pe allwater pe");); + TEST_FAILURE(".*ERROR: Illegal compute command.*", command("compute pe potential");); +} + +TEST_F(ComputeGlobalTest, Geometry) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + int has_extra = lammps_config_has_package("EXTRA-COMPUTE"); + + BEGIN_HIDE_OUTPUT(); + command("pair_style lj/cut 10.0"); + command("pair_coeff * * 0.01 3.0"); + command("bond_style harmonic"); + command("bond_coeff * 100.0 1.5"); + + command("compute com1 all com"); + command("compute com2 allwater com"); + command("compute mu1 all dipole"); + command("compute mu2 allwater dipole geometry "); + command("compute rg1 all gyration"); + command("compute rg2 allwater gyration"); + std::string thermo_style = "c_com1[*] c_com2[*] c_rg1[*] c_rg2[*]"; + + if (has_extra) { + command("compute mom1 all momentum"); + command("compute mom2 allwater momentum"); + command("compute mop1 all stress/mop x 0.0 total"); + command("compute mop2 all stress/mop/profile z lower 0.5 kin conf"); + thermo_style += " c_mu1 c_mu2 c_mop1[*] c_mop2[1][1]"; + } + + command("thermo_style custom " + thermo_style); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + auto com1 = get_vector("com1"); + auto com2 = get_vector("com2"); + auto mu1 = get_vector("mu1"); + auto mu2 = get_vector("mu2"); + auto rg1 = get_vector("rg1"); + auto rg2 = get_vector("rg2"); + + EXPECT_DOUBLE_EQ(com1[0], 1.4300952724948282); + EXPECT_DOUBLE_EQ(com1[1], -0.29759806705328351); + EXPECT_DOUBLE_EQ(com1[2], -0.7245120195899285); + EXPECT_DOUBLE_EQ(com2[0], 1.7850913321989679); + EXPECT_DOUBLE_EQ(com2[1], -0.45168408952146238); + EXPECT_DOUBLE_EQ(com2[2], -0.60215022088294912); + + EXPECT_DOUBLE_EQ(get_scalar("mu1"), 1.8335537504770163); + EXPECT_DOUBLE_EQ(get_scalar("mu2"), 1.7849382239204072); + EXPECT_DOUBLE_EQ(mu1[0], 0.41613191281297729); + EXPECT_DOUBLE_EQ(mu1[1], 1.0056523085627747); + EXPECT_DOUBLE_EQ(mu1[2], -1.4756073398127658); + EXPECT_DOUBLE_EQ(mu2[0], -0.029474795088977768); + EXPECT_DOUBLE_EQ(mu2[1], 1.153516133030746); + EXPECT_DOUBLE_EQ(mu2[2], -1.3618135814069394); + + EXPECT_DOUBLE_EQ(get_scalar("rg1"), 3.8495643473797196); + EXPECT_DOUBLE_EQ(get_scalar("rg2"), 5.4558163385611342); + EXPECT_DOUBLE_EQ(rg1[0], 3.6747807397432752); + EXPECT_DOUBLE_EQ(rg1[1], 6.5440303159316278); + EXPECT_DOUBLE_EQ(rg1[2], 4.6003346089421457); + EXPECT_DOUBLE_EQ(rg1[3], -0.4639249501367636); + EXPECT_DOUBLE_EQ(rg1[4], -1.8859032304357459); + EXPECT_DOUBLE_EQ(rg1[5], 0.2339161878440186); + EXPECT_DOUBLE_EQ(rg2[0], 6.2582260148310143); + EXPECT_DOUBLE_EQ(rg2[1], 13.353763805454184); + EXPECT_DOUBLE_EQ(rg2[2], 10.153942099825425); + EXPECT_DOUBLE_EQ(rg2[3], 1.2965604701522486); + EXPECT_DOUBLE_EQ(rg2[4], -5.0315240817290841); + EXPECT_DOUBLE_EQ(rg2[5], 1.1103378503822141); + if (has_extra) { + auto mom1 = get_vector("mom1"); + auto mom2 = get_vector("mom2"); + auto mop1 = get_vector("mop1"); + auto mop2 = get_array("mop2"); + EXPECT_DOUBLE_EQ(mom1[0], 0.0054219056685341164); + EXPECT_DOUBLE_EQ(mom1[1], -0.054897225112275558); + EXPECT_DOUBLE_EQ(mom1[2], 0.059097392692385661); + EXPECT_DOUBLE_EQ(mom2[0], -0.022332069630161717); + EXPECT_DOUBLE_EQ(mom2[1], -0.056896553865696115); + EXPECT_DOUBLE_EQ(mom2[2], 0.069179891052881484); + EXPECT_DOUBLE_EQ(mop1[0], 3522311.3572200728); + EXPECT_DOUBLE_EQ(mop1[1], 2871104.9055934539); + EXPECT_DOUBLE_EQ(mop1[2], -4136077.5224247416); + EXPECT_DOUBLE_EQ(mop2[0][0], -8.0869239999999998); + EXPECT_DOUBLE_EQ(mop2[0][1], 0.0); + EXPECT_DOUBLE_EQ(mop2[0][2], 0.0); + EXPECT_DOUBLE_EQ(mop2[1][0], -7.5869239999999998); + EXPECT_DOUBLE_EQ(mop2[1][1], 0.0); + EXPECT_DOUBLE_EQ(mop2[1][2], 0.0); + } +} + +TEST_F(ComputeGlobalTest, Reduction) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("pair_style lj/cut 10.0"); + command("pair_coeff * * 0.01 3.0"); + command("bond_style harmonic"); + command("bond_coeff * 100.0 1.5"); + + command("variable v atom sqrt(vx*vx+vy*vy+vz*vz)"); + command("variable id atom id"); + command("fix chg all store/state 0 q"); + command("compute ke all ke/atom"); + command("compute min allwater reduce min x fx v_v"); + command("compute chg all reduce max f_chg"); + command("compute max all reduce max y fy v_v"); + command("compute ave all reduce/region half ave z fz v_v"); + command("compute sum allwater reduce/region half sum vx vy vz"); + command("compute rep all reduce max v_id v_v v_id y replace 1 2 replace 3 4"); + std::string thermo_style = "c_min[*] c_chg c_max[*] c_sum[*] c_ave[*] c_rep[*]"; + + command("thermo_style custom " + thermo_style); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + auto min = get_vector("min"); + auto max = get_vector("max"); + auto sum = get_vector("sum"); + auto ave = get_vector("ave"); + auto rep = get_vector("rep"); + + EXPECT_DOUBLE_EQ(get_scalar("chg"), 0.51000000000000001); + + EXPECT_DOUBLE_EQ(min[0], -2.7406520384725965); + EXPECT_DOUBLE_EQ(min[1], -20385.448391361348); + EXPECT_DOUBLE_EQ(min[2], 0.00071995632406981081); + + EXPECT_DOUBLE_EQ(max[0], 4.0120175892854135); + EXPECT_DOUBLE_EQ(max[1], 21193.39005673242); + EXPECT_DOUBLE_EQ(max[2], 0.0072167889062371513); + + EXPECT_DOUBLE_EQ(sum[0], 0.0021436162503408024); + EXPECT_DOUBLE_EQ(sum[1], -0.013760203913131267); + EXPECT_DOUBLE_EQ(sum[2], 0.017517003988402391); + + EXPECT_DOUBLE_EQ(ave[0], -1.3013763067943667); + EXPECT_DOUBLE_EQ(ave[1], -619.60864441905312); + EXPECT_DOUBLE_EQ(ave[2], 0.0035263629500884397); + + // index of max v_v + EXPECT_DOUBLE_EQ(rep[0], 20); + EXPECT_DOUBLE_EQ(rep[1], max[2]); + // index of max y + EXPECT_DOUBLE_EQ(rep[2], 26); + EXPECT_DOUBLE_EQ(rep[3], max[0]); +} + +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = split_words(var); + for (auto arg : env) { + if (arg == "-v") { + verbose = true; + } + } + } + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + MPI_Finalize(); + return rv; +} diff --git a/unittest/force-styles/tests/atomic-pair-reaxff_tabulate_flag.yaml b/unittest/force-styles/tests/atomic-pair-reaxff_tabulate_flag.yaml new file mode 100644 index 0000000000..cc75136ead --- /dev/null +++ b/unittest/force-styles/tests/atomic-pair-reaxff_tabulate_flag.yaml @@ -0,0 +1,178 @@ +--- +lammps_version: 17 Feb 2022 +tags: slow, unstable, noWindows +date_generated: Fri Mar 4 16:03:19 2022 +epsilon: 1e-10 +skip_tests: +prerequisites: ! | + pair reaxff + fix qeq/reaxff +pre_commands: ! | + echo screen + shell cp ${input_dir}/reaxff.control reaxff-1.control + variable newton_pair delete + variable newton_pair index on + atom_modify map array + units real + atom_style charge + lattice diamond 3.77 + region box block 0 2 0 2 0 2 + create_box 3 box + create_atoms 1 box + displace_atoms all random 0.1 0.1 0.1 623426 + mass 1 1.0 + mass 2 12.0 + mass 3 16.0 + set type 1 type/fraction 2 0.5 998877 + set type 2 type/fraction 3 0.5 887766 + set type 1 charge 0.00 + set type 2 charge 0.01 + set type 3 charge -0.01 + velocity all create 100 4534624 loop geom +post_commands: ! | + fix qeq all qeq/reaxff 1 0.0 8.0 1.0e-20 reaxff +input_file: in.empty +pair_style: reaxff NULL checkqeq yes tabulate 10000 +pair_coeff: ! | + * * ffield.reax.mattsson H C O +extract: ! "" +natoms: 64 +init_vdwl: -3296.3503506626625 +init_coul: -327.06551252279456 +init_stress: ! |- + -1.0522112314767783e+03 -1.2629480788300502e+03 -8.6765541430814096e+02 -2.5149818635818667e+02 2.0624598409312171e+02 -6.4309968343212176e+02 +init_forces: ! |2 + 1 -8.8484559491556311e+01 -2.5824737864573919e+01 1.0916228789487879e+02 + 2 -1.1227736122977259e+02 -1.8092349731667591e+02 -2.2420586526897358e+02 + 3 -1.7210817575848930e+02 1.8292439782307812e+02 1.3552618819707996e+01 + 4 3.2997500231077133e+01 -5.1076027616179566e+01 9.0475628837081729e+01 + 5 1.8144778146276320e+02 1.6797701000584901e+01 -8.1725507301130719e+01 + 6 1.3634094180728027e+02 -3.0056789473999606e+02 2.9661495129812735e+01 + 7 -5.3287158661290654e+01 -1.2872927610193426e+02 -1.6347871108898190e+02 + 8 -1.5334883257588743e+02 4.0171483324132673e+01 1.5317461163040247e+02 + 9 1.8364155867626707e+01 8.1986572088184730e+01 2.8272397798085997e+01 + 10 8.4246730110716001e+01 1.4177487113457059e+02 1.2330079878579895e+02 + 11 -4.3218423112503736e+01 6.5551082199269430e+01 1.3464882148701872e+02 + 12 -9.7317470492946029e+01 -2.6234999414165394e+01 7.2277941881737986e+00 + 13 -6.3183329836750751e+01 -4.7368101002963456e+01 -3.7592654029327335e+01 + 14 7.8642975316494343e+01 -6.7997612991911723e+01 -9.9044775614588801e+01 + 15 -6.6373732796047989e+01 2.1787558547533163e+02 8.0103149369097395e+01 + 16 1.9216166082224797e+02 5.3228015320736127e+01 6.6260214054225145e+01 + 17 1.4496007689503486e+02 -3.9700923044581373e+01 -9.7503851828125278e+01 + 18 -4.4989550233791114e+01 -1.9360605894359682e+02 1.1274792197022767e+02 + 19 2.6657528138946049e+02 3.7189510796653087e+02 -3.3847307488286714e+02 + 20 -7.6341040242475458e+01 -8.8478925962195476e+01 1.3557778211945350e+00 + 21 -7.1188591900927975e+01 -5.1591439985149563e+01 -1.2279442803768845e+02 + 22 1.5504836733040739e+02 -1.3094504458747133e+02 8.1474408030773787e+01 + 23 7.8015302036850315e+01 -1.3272310040531950e+01 -2.2771427736555761e+01 + 24 -2.0546718065740683e+02 2.1611071031056338e+02 -1.2423208053538573e+02 + 25 -1.1402686646199389e+02 1.9100238121127509e+02 -8.3504908417575109e+01 + 26 2.8663576552100710e+02 -2.1773884754172596e+02 2.3144300100085047e+02 + 27 -6.3247409025600724e+01 6.9122196748088982e+01 1.8606936744368682e+02 + 28 -3.5426011056021354e+00 3.8764809029448436e+01 3.2874001946771685e+01 + 29 -7.1069178571898220e+01 3.5485903180456084e+01 2.7311648896337775e+01 + 30 -1.7036987830119276e+02 -1.9851827590032582e+02 -1.1511401829122866e+02 + 31 -1.3970409889743564e+02 1.6660943915627308e+02 -1.2913930522474990e+02 + 32 2.7179130444097289e+01 -6.0169059447608035e+01 -1.7669495182016857e+02 + 33 -6.2659679124097778e+01 -6.4422131921802787e+01 6.4150928205326551e+01 + 34 -2.2119065265688906e+01 1.0450386886831188e+02 -7.3998379587547575e+01 + 35 2.6982987783289082e+02 -2.1519317040004481e+02 1.3051628460667428e+02 + 36 1.0368628874510237e+02 1.8817377639771817e+02 -1.9748944223862600e+02 + 37 -1.8009522406830379e+02 1.2993653092252060e+02 -6.3523043394127292e+01 + 38 -2.9571205878459318e+02 1.0441609933480134e+02 1.5582204859043426e+02 + 39 8.7398805727037910e+01 -6.0025559644662437e+01 2.2209742009840294e+01 + 40 2.0540672579010501e+01 -1.0735874009092470e+02 5.8655918369889896e+01 + 41 -5.8895846271433264e+01 1.1852345624580526e+01 -6.6147257724520202e+01 + 42 -9.6895512314625066e+01 3.8928741136637001e+01 -7.5791929957169600e+01 + 43 2.2476051812062838e+02 9.5505204283227684e+01 1.2309042240718360e+02 + 44 8.9817373579481654e+01 -1.0616333580629222e+02 -8.6321519086261901e+01 + 45 1.7202629662563513e+01 1.2890307246702790e+02 5.2916171301120244e+01 + 46 1.3547783972599857e+01 -2.9276223331262678e+01 2.2187412696868783e+01 + 47 3.3389762514713034e+01 -1.9217585014964843e+02 -6.9956213241084782e+01 + 48 7.3631720332058023e+01 -2.0953007324684350e+02 -2.3183566221369460e+01 + 49 -3.7589944473226200e+02 -2.4083165714761812e+01 1.0770339502610176e+02 + 50 3.8603083564804351e+01 -7.3616481568807856e+01 9.0414065019653634e+01 + 51 1.3736420686697048e+02 -1.0204157331499390e+02 1.5813725581140869e+02 + 52 -1.0797257051088970e+02 1.1876975735152035e+02 -1.3295758126487456e+02 + 53 -5.3807540206216466e+01 3.3259462625846481e+02 -3.8426832264377708e-03 + 54 -1.0690184616179764e+01 6.2820270853641873e+01 1.8343158343322312e+02 + 55 1.1231900459987538e+02 -1.7906654831317351e+02 7.6533681064342247e+01 + 56 -4.1027190034880718e+01 -1.4085413191126113e+02 3.7483064289929565e+01 + 57 9.9904315214043478e+01 7.0938939080466696e+01 -6.8654961257655216e+01 + 58 -2.7563642882025157e+01 -6.7445498717118166e+00 -1.8442640542825114e+01 + 59 -6.6628933617811725e+01 1.0613066354106411e+02 8.7736153919801964e+01 + 60 -1.7748415247445266e+01 6.3757605316885879e+01 -1.5086907478327478e+02 + 61 -3.3560907195794982e+01 -1.0076987083174131e+02 -7.4536106106935335e+01 + 62 1.5883428926665676e+01 -5.8433760297919051e+00 2.8392494016028817e+01 + 63 1.3294494001299771e+02 -1.2724568063769999e+02 -6.4886848316829841e+01 + 64 1.0738157273931067e+02 1.2062173788161793e+02 7.4541400611720690e+01 +run_vdwl: -3296.3468823779367 +run_coul: -327.065399507389 +run_stress: ! |- + -1.0521225462933094e+03 -1.2628780139897610e+03 -8.6757617693170891e+02 -2.5158592653599595e+02 2.0619472152439258e+02 -6.4312943979319141e+02 +run_forces: ! |2 + 1 -8.8486129396000166e+01 -2.5824483374468670e+01 1.0916517213634302e+02 + 2 -1.1227648453174439e+02 -1.8093214754186079e+02 -2.2420118533941442e+02 + 3 -1.7210894875994904e+02 1.8292263268450841e+02 1.3551979435674342e+01 + 4 3.2999405001001634e+01 -5.1077312719540167e+01 9.0478579144055772e+01 + 5 1.8144963583124775e+02 1.6798391906829387e+01 -8.1723378082079023e+01 + 6 1.3640835897739180e+02 -3.0059507544861378e+02 2.9594750460791829e+01 + 7 -5.3287619129788197e+01 -1.2872953167027578e+02 -1.6348317368624896e+02 + 8 -1.5334990952322417e+02 4.0171746946782790e+01 1.5317542403105386e+02 + 9 1.8362961213920698e+01 8.1984428717781981e+01 2.8273598253031487e+01 + 10 8.4245458094792369e+01 1.4177227430519417e+02 1.2329899933660860e+02 + 11 -4.3217035356327358e+01 6.5547850976490437e+01 1.3463983671941662e+02 + 12 -9.7319343004584653e+01 -2.6236499899243690e+01 7.2232061905837615e+00 + 13 -6.3184735475527191e+01 -4.7368090836529937e+01 -3.7590268076048019e+01 + 14 7.8642680121812262e+01 -6.7994653297660548e+01 -9.9042134233426268e+01 + 15 -6.6371195967091907e+01 2.1787700653340673e+02 8.0102624694811539e+01 + 16 1.9215832443893075e+02 5.3231888618096207e+01 6.6253846562708489e+01 + 17 1.4496126989603599e+02 -3.9700366098755531e+01 -9.7506725874205443e+01 + 18 -4.4989211400009481e+01 -1.9360716191976402e+02 1.1274798810456159e+02 + 19 2.6657546213783030e+02 3.7189369483259844e+02 -3.3847202166066995e+02 + 20 -7.6352829159886937e+01 -8.8469178952293859e+01 1.3384778816960481e+00 + 21 -7.1188597560669123e+01 -5.1592404200753641e+01 -1.2279357314243131e+02 + 22 1.5504965184742042e+02 -1.3094582932681607e+02 8.1473922626951364e+01 + 23 7.8017376001381663e+01 -1.3263023728618043e+01 -2.2771654676285653e+01 + 24 -2.0547634460481828e+02 2.1612342044351524e+02 -1.2423651650061259e+02 + 25 -1.1402944116092229e+02 1.9100648219390607e+02 -8.3505645569840254e+01 + 26 2.8664542299412386e+02 -2.1774609219882657e+02 2.3144720166991996e+02 + 27 -6.3243843868032563e+01 6.9123801262967206e+01 1.8607035157681565e+02 + 28 -3.5444604842081140e+00 3.8760531647711296e+01 3.2869123667284754e+01 + 29 -7.1069494158200598e+01 3.5486459158788925e+01 2.7311657876198531e+01 + 30 -1.7037059987991734e+02 -1.9851840131670701e+02 -1.1511410156294959e+02 + 31 -1.3970663440086241e+02 1.6660841802304265e+02 -1.2914070628113083e+02 + 32 2.7179939937123105e+01 -6.0162678551463884e+01 -1.7668459764112279e+02 + 33 -6.2659124615696278e+01 -6.4421915847949109e+01 6.4151176691093482e+01 + 34 -2.2118740875414915e+01 1.0450303589341836e+02 -7.3997370482692659e+01 + 35 2.6987081482971496e+02 -2.1523754104001341e+02 1.3052736086177524e+02 + 36 1.0368798521809144e+02 1.8816694370717582e+02 -1.9748485159165222e+02 + 37 -1.8012152563997313e+02 1.2997662140310993e+02 -6.3547259053662522e+01 + 38 -2.9571525697590329e+02 1.0441941743732623e+02 1.5582112543443273e+02 + 39 8.7399620724583841e+01 -6.0025787992404162e+01 2.2209357601285014e+01 + 40 2.0541458171950477e+01 -1.0735817059033120e+02 5.8656280350522032e+01 + 41 -5.8893965304960815e+01 1.1850504754255629e+01 -6.6138932258972176e+01 + 42 -9.6894702780974512e+01 3.8926449644122947e+01 -7.5794133002818526e+01 + 43 2.2475651760389809e+02 9.5503072846826768e+01 1.2308683766845004e+02 + 44 8.9821846939836348e+01 -1.0615882525758133e+02 -8.6326896770196470e+01 + 45 1.7193681344320954e+01 1.2889564928825573e+02 5.2922372841304153e+01 + 46 1.3549091739277978e+01 -2.9276447091759906e+01 2.2187152043657633e+01 + 47 3.3389460345593953e+01 -1.9217121673024195e+02 -6.9954603582949176e+01 + 48 7.3644268618797824e+01 -2.0953201921818757e+02 -2.3192562071377562e+01 + 49 -3.7593958318939679e+02 -2.4028439106858276e+01 1.0779151134440338e+02 + 50 3.8603926624309238e+01 -7.3615255297997734e+01 9.0412505212301156e+01 + 51 1.3736689552205240e+02 -1.0204490780180460e+02 1.5814099219642884e+02 + 52 -1.0797151154268900e+02 1.1876989597627048e+02 -1.3296150756378307e+02 + 53 -5.3843453069379677e+01 3.3257024143948763e+02 -2.3416395286659508e-02 + 54 -1.0678049522660388e+01 6.2807424617051886e+01 1.8344969045861680e+02 + 55 1.1232135576105590e+02 -1.7906994470562014e+02 7.6534265234549295e+01 + 56 -4.1035945990490148e+01 -1.4084577238057466e+02 3.7489705598222940e+01 + 57 9.9903872061949016e+01 7.0936213558029195e+01 -6.8656338416446374e+01 + 58 -2.7563844572722473e+01 -6.7426705471903592e+00 -1.8442803060446948e+01 + 59 -6.6637290503326199e+01 1.0613630918456350e+02 8.7741455199743768e+01 + 60 -1.7749706497443679e+01 6.3756413885649771e+01 -1.5086911682893657e+02 + 61 -3.3559889608753309e+01 -1.0076809277084797e+02 -7.4536003122045500e+01 + 62 1.5883833834736830e+01 -5.8439916924713566e+00 2.8393403991140676e+01 + 63 1.3294237052897739e+02 -1.2724619636182949e+02 -6.4882384014241481e+01 + 64 1.0738250214939015e+02 1.2062290362869132e+02 7.4541927445538889e+01 +...